Completed
Push — master ( 7c7cea...ce111c )
by Aleksandr
01:40
created

Request::checksumIsEnabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
4
namespace carono\checksum;
5
6
use yii\helpers\ArrayHelper;
7
8
/**
9
 * Class Request
10
 *
11
 * @property mixed checksumKey
12
 * @package carono\checksum
13
 */
14
class Request extends \yii\web\Request
15
{
16
    public $checksumParam = '_checksum';
17
    public $enableChecksumValidation = true;
18
    public $redefineActiveField = true;
19
    public $activeFormClasses = [
20
        \yii\widgets\ActiveForm::class,
21
        \yii\bootstrap\ActiveForm::class,
22
        \carono\checksum\ActiveForm::class
23
    ];
24
    protected $_checksumKey;
25
26
    public function getChecksumKey()
27
    {
28
        return $this->_checksumKey ?: hash("sha256", $this->cookieValidationKey);
29
    }
30
31
    public function setChecksumKey($value)
32
    {
33
        $this->_checksumKey = $value;
34
    }
35
36
    public function init()
37
    {
38
        parent::init();
39
        if ($this->redefineActiveField) {
40
            $behavior = ['as caronoChecksumBehavior' => ChecksumBehavior::class];
41
            foreach ($this->activeFormClasses as $class) {
42
                if (class_exists($class)) {
43
                    \Yii::$container->set($class, $behavior);
44
                }
45
            }
46
        }
47
    }
48
49
    public function checksumIsEnabled()
50
    {
51
        return $this->enableChecksumValidation;
52
    }
53
54
    /**
55
     * @param null $clientSuppliedToken
56
     * @return bool
57
     */
58
    public function validateCsrfToken($clientSuppliedToken = null)
59
    {
60
        if ($this->isPost && $this->checksumIsEnabled()) {
61
            $post = $this->post();
62
            $checksum = ArrayHelper::remove($post, $this->checksumParam);
63
            $stack = $this->getStackByChecksum($checksum);
64
            $postPartials = Checksum::formKeyPartials($post);
65
            $stackPartials = Checksum::formKeyPartials($stack);
66
            foreach (array_diff($stackPartials, $postPartials) as $lostPartial) {
67
                list($formName, $attribute) = explode('=', $lostPartial);
68
                $post[$formName][$attribute] = '';
69
            }
70
            if (!Checksum::validate($post, $checksum, $this->checksumKey)) {
71
                return false;
72
            }
73
            $this->clearStack();
74
        }
75
        return parent::validateCsrfToken($clientSuppliedToken);
76
    }
77
78
    /**
79
     * @return string
80
     */
81
    protected function getStackKey()
82
    {
83
        return self::className() . $this->checksumParam;
0 ignored issues
show
Deprecated Code introduced by
The method yii\base\BaseObject::className() has been deprecated with message: since 2.0.14. On PHP >=5.5, use `::class` instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
84
    }
85
86
    /**
87
     * @param $widgetId
88
     * @param $stack
89
     * @return string
90
     */
91
    public function setStack($stack)
92
    {
93
        $checksum = Checksum::calculate($stack, $this->checksumKey);
94
        $key = $this->getStackKey();
95
        $data = $this->getStack();
96
        $data[$checksum] = $stack;
97
        \Yii::$app->session->set($key, $data);
98
        return $checksum;
99
    }
100
101
    public function clearStack()
102
    {
103
        return \Yii::$app->session->set($this->getStackKey(), []);
104
    }
105
106
    /**
107
     * @return mixed
108
     */
109
    public function getStack()
110
    {
111
        return \Yii::$app->session->get($this->getStackKey(), []);
112
    }
113
114
    /**
115
     * @param $checksum
116
     * @return array
117
     */
118
    public function getStackByChecksum($checksum)
119
    {
120
        return ArrayHelper::getValue($this->getStack(), $checksum);
121
    }
122
}