Passed
Push — feature/0.7.0 ( 0c7d59...ae5b22 )
by Ryuichi
78:01 queued 33:04
created

CsrfProtection::onMethodInject()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 13
nc 6
nop 3
dl 0
loc 25
rs 6.7272
c 0
b 0
f 0
1
<?php
2
namespace WebStream\Annotation\Attributes;
3
4
use WebStream\Annotation\Base\Annotation;
5
use WebStream\Annotation\Base\IAnnotatable;
6
use WebStream\Annotation\Base\IMethod;
7
use WebStream\Container\Container;
8
use WebStream\Exception\Extend\CsrfException;
9
10
/**
11
 * CsrfProtection
12
 * @author Ryuichi TANAKA.
13
 * @since 2015/05/08
14
 * @version 0.7
15
 *
16
 * @Annotation
17
 * @Target("METHOD")
18
 */
19
class CsrfProtection extends Annotation implements IMethod
20
{
21
    /**
22
     * @var array<string> 注入アノテーション情報
23
     */
24
    private $injectAnnotation;
0 ignored issues
show
Unused Code introduced by
The property $injectAnnotation is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
25
26
    /**
27
     * @var array<string> 読み込みアノテーション情報
28
     */
29
    private $readAnnotation;
0 ignored issues
show
Unused Code introduced by
The property $readAnnotation is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
30
31
    /**
32
     * @var array<string, string> CSRF定数定義
33
     */
34
    private $csrfProtectionDefinitions = [
35
        'tokenKey' => '__CSRF_TOKEN__',
36
        'tokenHeader' => 'X-CSRF-Token'
37
    ];
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function onInject(array $injectAnnotation)
43
    {
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function onMethodInject(IAnnotatable $instance, \ReflectionMethod $method, Container $container)
50
    {
51
        $tokenByRequest = null;
52
        if (array_key_exists($this->csrfProtectionDefinitions['tokenKey'], $container->post)) {
0 ignored issues
show
Bug Best Practice introduced by
The property post does not exist on WebStream\Container\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
It seems like $container->post can also be of type null and string; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

52
        if (array_key_exists($this->csrfProtectionDefinitions['tokenKey'], /** @scrutinizer ignore-type */ $container->post)) {
Loading history...
53
            $tokenByRequest = $container->post[$this->csrfProtectionDefinitions['tokenKey']];
54
        } elseif (array_key_exists($this->csrfProtectionDefinitions['tokenHeader'], $container->header)) {
0 ignored issues
show
Bug Best Practice introduced by
The property header does not exist on WebStream\Container\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
55
            $tokenByRequest = $container->header[$this->csrfProtectionDefinitions['tokenHeader']];
56
        }
57
58
        $tokenInSession = $container->session->get($this->csrfProtectionDefinitions['tokenKey']);
0 ignored issues
show
Bug Best Practice introduced by
The property session does not exist on WebStream\Container\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method get() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

58
        /** @scrutinizer ignore-call */ 
59
        $tokenInSession = $container->session->get($this->csrfProtectionDefinitions['tokenKey']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
59
        $container->session->delete($this->csrfProtectionDefinitions['tokenKey']);
60
61
        // POSTリクエスト以外はチェックしない
62
        if ($container->requestMethod !== 'POST') {
0 ignored issues
show
Bug Best Practice introduced by
The property requestMethod does not exist on WebStream\Container\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
63
            return;
64
        }
65
66
        // リクエストトークン、セッショントークンが両方空はNG
67
        if ($tokenInSession === null && $tokenByRequest === null) {
68
            throw new CsrfException("Sent invalid CSRF token");
69
        }
70
71
        // リクエストトークンとセッショントークンが一致しない場合NG
72
        if ($tokenInSession !== $tokenByRequest) {
73
            throw new CsrfException("Sent invalid CSRF token");
74
        }
75
    }
76
}
77