Passed
Push — 4.1 ( 6d2665...02ad0f )
by
unknown
32:36 queued 24:09
created

ParameterConfirmationToken::reloadWithToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 0
dl 0
loc 15
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Core\Startup;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Control\HTTPResponse;
9
use SilverStripe\Core\Convert;
10
use SilverStripe\Security\RandomGenerator;
11
12
/**
13
 * This is used to protect dangerous GET parameters that need to be detected early in the request
14
 * lifecycle by generating a one-time-use token & redirecting with that token included in the
15
 * redirected URL
16
 *
17
 * @internal This class is designed specifically for use pre-startup and may change without warning
18
 */
19
class ParameterConfirmationToken extends AbstractConfirmationToken
20
{
21
    /**
22
     * The name of the parameter
23
     *
24
     * @var string
25
     */
26
    protected $parameterName = null;
27
    
28
    /**
29
     * The parameter given in the main request
30
     *
31
     * @var string|null The string value, or null if not provided
32
     */
33
    protected $parameter = null;
34
35
    /**
36
     * The parameter given in the backURL
37
     *
38
     * @var string|null
39
     */
40
    protected $parameterBackURL = null;
41
42
    /**
43
     * @param string $parameterName Name of the querystring parameter to check
44
     * @param HTTPRequest $request
45
     */
46
    public function __construct($parameterName, HTTPRequest $request)
47
    {
48
        // Store the parameter name
49
        $this->parameterName = $parameterName;
50
        $this->request = $request;
51
52
        // Store the parameter value
53
        $this->parameter = $request->getVar($parameterName);
54
        $this->parameterBackURL = $this->backURLToken($request);
55
56
        // If the token provided is valid, mark it as such
57
        $token = $request->getVar($parameterName . 'token');
58
        if ($this->checkToken($token)) {
59
            $this->token = $token;
60
        }
61
    }
62
63
    /**
64
     * Check if this token exists in the BackURL
65
     *
66
     * @param HTTPRequest $request
67
     * @return string Value of token in backurl, or null if not in backurl
68
     */
69
    protected function backURLToken(HTTPRequest $request)
70
    {
71
        $backURL = $request->getVar('BackURL');
72
        if (!strstr($backURL, '?')) {
73
            return null;
74
        }
75
76
        // Filter backURL if it contains the given request parameter
77
        list(,$query) = explode('?', $backURL);
78
        parse_str($query, $queryArgs);
79
        $name = $this->getName();
80
        if (isset($queryArgs[$name])) {
81
            return $queryArgs[$name];
82
        }
83
        return null;
84
    }
85
86
    /**
87
     * Get the name of this token
88
     *
89
     * @return string
90
     */
91
    public function getName()
92
    {
93
        return $this->parameterName;
94
    }
95
96
    /**
97
     * Is the parameter requested?
98
     * ?parameter and ?parameter=1 are both considered requested
99
     *
100
     * @return bool
101
     */
102
    public function parameterProvided()
103
    {
104
        return $this->parameter !== null;
105
    }
106
107
    /**
108
     * Is the parmeter requested in a BackURL param?
109
     *
110
     * @return bool
111
     */
112
    public function existsInReferer()
113
    {
114
        return $this->parameterBackURL !== null;
115
    }
116
117
    public function reloadRequired()
118
    {
119
        return $this->parameterProvided() && !$this->tokenProvided();
120
    }
121
122
    public function reloadRequiredIfError()
123
    {
124
        // Don't reload if token exists
125
        return $this->reloadRequired() || $this->existsInReferer();
126
    }
127
    
128
    public function suppress()
129
    {
130
        unset($_GET[$this->parameterName]);
131
        $this->request->offsetUnset($this->parameterName);
132
    }
133
134
    public function params($includeToken = true)
135
    {
136
        $params = array(
137
            $this->parameterName => $this->parameter,
138
        );
139
        if ($includeToken) {
140
            $params[$this->parameterName . 'token'] = $this->genToken();
141
        }
142
        return $params;
143
    }
144
145
    public function getRedirectUrlBase()
146
    {
147
        return ($this->existsInReferer() && !$this->parameterProvided()) ? Director::baseURL() : $this->currentURL();
148
    }
149
150
    public function getRedirectUrlParams()
151
    {
152
        return ($this->existsInReferer() && !$this->parameterProvided())
153
            ? $this->params()
154
            : array_merge($this->request->getVars(), $this->params());
155
    }
156
    
157
    protected function redirectURL()
158
    {
159
        $query = http_build_query($this->getRedirectUrlParams());
160
        return Controller::join_links($this->getRedirectUrlBase(), '?' . $query);
161
    }
162
}
163