Passed
Push — 4.4 ( c5d3f8...dad80f )
by Ingo
08:04
created

URLSpecialsMiddleware   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 49
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 49
rs 10
c 0
b 0
f 0
wmc 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A buildImpactRedirect() 0 12 3
A confirmedEffect() 0 5 2
1
<?php
2
3
namespace SilverStripe\Control\Middleware;
4
5
use SilverStripe\Control\Middleware\URLSpecialsMiddleware\FlushScheduler;
6
use SilverStripe\Control\Middleware\URLSpecialsMiddleware\SessionEnvTypeSwitcher;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Control\HTTPResponse;
9
use SilverStripe\Security\RandomGenerator;
10
11
/**
12
 * Check the request for the URL special variables.
13
 * Performs authorisation, confirmation and actions for some of those.
14
 *
15
 * WARNING: Bypasses only disable authorisation and confirmation, but not actions nor redirects
16
 *
17
 * The rules are:
18
 *  - flush GET parameter
19
 *  - isDev GET parameter
20
 *  - isTest GET parameter
21
 *  - dev/build URL
22
 *
23
 * @see https://docs.silverstripe.org/en/4/developer_guides/debugging/url_variable_tools/ special variables docs
24
 *
25
 * {@inheritdoc}
26
 */
27
class URLSpecialsMiddleware extends PermissionAwareConfirmationMiddleware
28
{
29
    use FlushScheduler;
30
    use SessionEnvTypeSwitcher;
31
32
    /**
33
     * Initializes the middleware with the required rules
34
     */
35
    public function __construct()
36
    {
37
        parent::__construct(
38
            new ConfirmationMiddleware\GetParameter("flush"),
39
            new ConfirmationMiddleware\GetParameter("isDev"),
40
            new ConfirmationMiddleware\GetParameter("isTest"),
41
            new ConfirmationMiddleware\UrlPathStartswith("dev/build")
42
        );
43
    }
44
45
    /**
46
     * Looks up for the special flags passed in the request
47
     * and schedules the changes accordingly for the next request.
48
     * Returns a redirect to the same page (with a random token) if
49
     * there are changes introduced by the flags.
50
     * Returns null if there is no impact introduced by the flags.
51
     *
52
     * @param HTTPRequest $request
53
     *
54
     * @return null|HTTPResponse redirect to the same url
55
     */
56
    public function buildImpactRedirect(HTTPRequest $request)
57
    {
58
        $flush = $this->scheduleFlush($request);
59
        $env_type = $this->setSessionEnvType($request);
60
61
        if ($flush || $env_type) {
62
            // the token only purpose is to invalidate browser/proxy cache
63
            $request['urlspecialstoken'] = bin2hex(random_bytes(4));
64
65
            $result = new HTTPResponse();
66
            $result->redirect('/' . $request->getURL(true));
67
            return $result;
68
        }
69
    }
70
71
    protected function confirmedEffect(HTTPRequest $request)
72
    {
73
        if ($response = $this->buildImpactRedirect($request)) {
74
            HTTPCacheControlMiddleware::singleton()->disableCache(true);
75
            return $response;
76
        }
77
    }
78
}
79