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

URLConfirmationToken::reloadRequired()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 0
dl 0
loc 3
rs 10
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
9
/**
10
 * This is used to protect dangerous URLs that need to be detected early in the request lifecycle
11
 * by generating a one-time-use token & redirecting with that token included in the redirected URL
12
 *
13
 * @internal This class is designed specifically for use pre-startup and may change without warning
14
 */
15
class URLConfirmationToken extends AbstractConfirmationToken
16
{
17
    /**
18
     * @var string
19
     */
20
    protected $urlToCheck;
21
22
    /**
23
     * @var string
24
     */
25
    protected $currentURL;
26
27
    /**
28
     * @var string
29
     */
30
    protected $tokenParameterName;
31
32
    /**
33
     * @var bool
34
     */
35
    protected $urlExistsInBackURL;
36
37
    /**
38
     * @param string $urlToCheck URL to check
39
     * @param HTTPRequest $request
40
     */
41
    public function __construct($urlToCheck, HTTPRequest $request)
42
    {
43
        $this->urlToCheck = $urlToCheck;
44
        $this->request = $request;
45
        $this->currentURL = $request->getURL(false);
46
47
        $this->tokenParameterName = preg_replace('/[^a-z0-9]/i', '', $urlToCheck) . 'token';
48
        $this->urlExistsInBackURL = $this->getURLExistsInBackURL($request);
49
50
        // If the token provided is valid, mark it as such
51
        $token = $request->getVar($this->tokenParameterName);
52
        if ($this->checkToken($token)) {
53
            $this->token = $token;
54
        }
55
    }
56
57
    /**
58
     * @param HTTPRequest $request
59
     * @return bool
60
     */
61
    protected function getURLExistsInBackURL(HTTPRequest $request)
62
    {
63
        $backURL = ltrim($request->getVar('BackURL'), '/');
64
        return (strpos($backURL, $this->urlToCheck) === 0);
65
    }
66
67
    /**
68
     * @return bool
69
     */
70
    protected function urlMatches()
71
    {
72
        return ($this->currentURL === $this->urlToCheck);
73
    }
74
75
    /**
76
     * @return string
77
     */
78
    public function getURLToCheck()
79
    {
80
        return $this->urlToCheck;
81
    }
82
83
    /**
84
     * @return bool
85
     */
86
    public function urlExistsInBackURL()
87
    {
88
        return $this->urlExistsInBackURL;
89
    }
90
91
    public function reloadRequired()
92
    {
93
        return $this->urlMatches() && !$this->tokenProvided();
94
    }
95
96
    public function reloadRequiredIfError()
97
    {
98
        return $this->reloadRequired() || $this->urlExistsInBackURL();
99
    }
100
101
    public function suppress()
102
    {
103
        $_SERVER['REQUEST_URI'] = '/';
104
        $this->request->setURL('/');
105
    }
106
107
    public function params($includeToken = true)
108
    {
109
        $params = [];
110
        if ($includeToken) {
111
            $params[$this->tokenParameterName] = $this->genToken();
112
        }
113
114
        return $params;
115
    }
116
117
    public function currentURL()
118
    {
119
        return Controller::join_links(Director::baseURL(), $this->currentURL);
120
    }
121
122
    public function getRedirectUrlBase()
123
    {
124
        return ($this->urlExistsInBackURL && !$this->urlMatches()) ? Director::baseURL() : $this->currentURL();
125
    }
126
127
    public function getRedirectUrlParams()
128
    {
129
        return ($this->urlExistsInBackURL && !$this->urlMatches())
130
            ? $this->params()
131
            : array_merge($this->request->getVars(), $this->params());
132
    }
133
134
    protected function redirectURL()
135
    {
136
        $query = http_build_query($this->getRedirectUrlParams());
137
        return Controller::join_links($this->getRedirectUrlBase(), '?' . $query);
138
    }
139
}
140