BasicAuthMiddleware::getURLPatterns()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Security;
4
5
use SilverStripe\Control\HTTPRequest;
6
use SilverStripe\Control\HTTPResponse;
7
use SilverStripe\Control\HTTPResponse_Exception;
8
use SilverStripe\Control\Middleware\HTTPMiddleware;
9
use SilverStripe\Control\Middleware\CanonicalURLMiddleware;
10
11
class BasicAuthMiddleware implements HTTPMiddleware
12
{
13
    /**
14
     * URL Patterns for basic auth. Keys are the Regexp string to match, and the key can
15
     * be one of the below:
16
     *  - true (bool) - Enabled for this url
17
     *  - false (bool) - Disabled for this url
18
     *  - Any string / array - Enabled for this url, and require the given string as a permission code
19
     *  - null (default) - Calls BasicAuth::protect_site_if_necessary(), which falls back to config setting
20
     *
21
     * E.g.
22
     * [
23
     *   '#^home#i' => false,
24
     *   '#^secure#i' => true,
25
     *   '#^secure/admin#i' => 'ADMIN',
26
     * ]
27
     *
28
     * @see CanonicalURLMiddleware
29
     * @var array
30
     */
31
    protected $urlPatterns = [];
32
33
    /**
34
     * Generate response for the given request
35
     *
36
     * @param HTTPRequest $request
37
     * @param callable $delegate
38
     * @return HTTPResponse
39
     */
40
    public function process(HTTPRequest $request, callable $delegate)
41
    {
42
        // Check if url matches any patterns
43
        $match = $this->checkMatchingURL($request);
44
45
        // Check middleware unless specifically opting out
46
        if ($match !== false) {
47
            try {
48
                // Determine method to check
49
                if ($match) {
50
                    // Truthy values are explicit, check with optional permission code
51
                    $permission = $match === true ? null : $match;
52
                    BasicAuth::requireLogin(
53
                        $request,
54
                        BasicAuth::config()->get('entire_site_protected_message'),
55
                        $permission,
56
                        false
57
                    );
58
                } elseif ($match === null) {
0 ignored issues
show
introduced by
The condition $match === null is always false.
Loading history...
59
                    // Null implies fall back to default behaviour
60
                    BasicAuth::protect_site_if_necessary($request);
61
                }
62
            } catch (HTTPResponse_Exception $ex) {
63
                return $ex->getResponse();
64
            }
65
        }
66
67
        // Pass on to other middlewares
68
        return $delegate($request);
69
    }
70
71
    /**
72
     * Get list of url patterns
73
     *
74
     * @return array
75
     */
76
    public function getURLPatterns()
77
    {
78
        return $this->urlPatterns ?: [];
79
    }
80
81
    /**
82
     * @param array $urlPatterns
83
     * @return $this
84
     */
85
    public function setURLPatterns(array $urlPatterns)
86
    {
87
        $this->urlPatterns = $urlPatterns;
88
        return $this;
89
    }
90
91
    /**
92
     * Check if global basic auth is enabled for the given request
93
     *
94
     * @param HTTPRequest $request
95
     * @return bool|string|array|null boolean value if enabled/disabled explicitly for this request,
96
     * or null if should fall back to config value. Can also provide an explicit string / array of permission
97
     * codes to require for this requset.
98
     */
99
    protected function checkMatchingURL(HTTPRequest $request)
100
    {
101
        // Null if no permissions enabled
102
        $patterns = $this->getURLPatterns();
103
        if (!$patterns) {
104
            return null;
105
        }
106
107
        // Filter redirect based on url
108
        $relativeURL = $request->getURL(true);
109
        foreach ($patterns as $pattern => $result) {
110
            if (preg_match($pattern, $relativeURL)) {
111
                return $result;
112
            }
113
        }
114
115
        // No patterns match
116
        return null;
117
    }
118
}
119