Completed
Pull Request — master (#4)
by
unknown
12:24
created

EnforceContentSecurity::handle()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3.0052

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 11
cts 12
cp 0.9167
rs 9.52
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3.0052
1
<?php namespace Stevenmaguire\Laravel\Http\Middleware;
2
3
use Closure;
4
use Exception;
5
use Illuminate\Http\Response;
6
use GuzzleHttp\Psr7\Response as PsrResponse;
7
use Psr\Http\Message\ResponseInterface;
8
use Stevenmaguire\Http\Middleware\EnforceContentSecurity as BaseMiddleware;
9
10
class EnforceContentSecurity extends BaseMiddleware
11
{
12
    /**
13
     * Config closure;
14
     *
15
     * @var Closure
16
     */
17
    protected $config;
18
19
    /**
20
     * Creates new middleware instance.
21
     */
22 6
    public function __construct()
23
    {
24 6
        $this->setConfigClosure(function ($key = null, $default = null) {
25
            // @codeCoverageIgnoreStart
26
            if (function_exists('config')) {
27
                return config($key, $default);
28
            }
29
30
            return null;
31
            // @codeCoverageIgnoreEnd
32 6
        });
33 6
    }
34
35
    /**
36
     * Handles an incoming request.
37
     *
38
     * @param  \Illuminate\Http\Request  $request
39
     * @param  \Closure  $next
40
     * @return mixed
41
     */
42 6
    public function handle($request, Closure $next)
43
    {
44 6
        $response = $next($request);
45
46 6
        if ($response instanceof Response) {
47 4
            $this->setProfiles($this->getProfileConfig());
48
49 4
            $this->setProfilesWithParameters(func_get_args());
50
51 4
            $exception = $response->exception;
52
53 4
            $psr7Response = $this->createPsr7Response($response);
54
55 4
            $psr7Response = $this->addPolicyHeader($psr7Response);
56
57 4
            $response = $this->createLaravelResponse($psr7Response);
58
59 4
            if ($exception instanceof Exception) {
60
                $response->withException($exception);
61
            }
62
63
        }
64
65 6
        return $response;
66
    }
67
68
    /**
69
     * Creates Laravel response object from PSR 7 response.
70
     *
71
     * @param  ResponseInterface  $response
72
     *
73
     * @return Response
74
     */
75 4
    protected function createLaravelResponse(ResponseInterface $response)
76
    {
77 4
        return new Response(
78 4
            (string) $response->getBody(),
79 4
            $response->getStatusCode(),
80 4
            $response->getHeaders()
81
        );
82
    }
83
84
    /**
85
     * Creates PSR 7 response object from Laravel response.
86
     *
87
     * @param  Response  $response
88
     *
89
     * @return ResponseInterface
90
     */
91 4
    protected function createPsr7Response(Response $response)
92
    {
93 4
        return new PsrResponse(
94 4
            $response->getStatusCode(),
95 4
            $response->headers->all(),
96 4
            $response->getContent(),
97 4
            $response->getProtocolVersion()
98
        );
99
    }
100
101
    /**
102
     * Retrives profile configuration from Laravel config object.
103
     *
104
     * @return array
105
     */
106 4
    protected function getProfileConfig()
107
    {
108 4
        $configCallable = $this->config;
109 4
        $config = $configCallable($this->getProfileConfigKey());
110
111 4
        if (!is_array($config)) {
112 1
            $config = [$config];
113
        }
114
115 4
        return array_filter($config);
116
    }
117
118
    /**
119
     * Retrieves configuration key associated with content security profiles.
120
     *
121
     * @return string
122
     */
123 4
    protected function getProfileConfigKey()
124
    {
125 4
        return 'security.content';
126
    }
127
128
    /**
129
     * Gets profiles from handle method arguments.
130
     *
131
     * @param  array $arguments
132
     *
133
     * @return array
134
     */
135 4
    protected function getProfilesFromArguments(array $arguments)
136
    {
137 4
        $profiles = [];
138 4
        if (count($arguments) > 2) {
139 2
            unset($arguments[0]);
140 2
            unset($arguments[1]);
141 2
            $profiles = $arguments;
142
        }
143 4
        return $profiles;
144
    }
145
146
    /**
147
     * Updates config callable used to access application configuration data.
148
     *
149
     * @param Closure  $config
150
     *
151
     * @return EnforceContentSecurity
152
     */
153 6
    public function setConfigClosure(Closure $config)
154
    {
155 6
        $this->config = $config;
156
157 6
        return $this;
158
    }
159
160
    /**
161
     * Updates policy configuration with rules from each profile in given parameters.
162
     *
163
     * @param array  $parameters
164
     *
165
     * @return void
166
     */
167 4
    protected function setProfilesWithParameters(array $parameters)
168
    {
169 4
        $profiles = $this->getProfilesFromArguments($parameters);
170 4
        array_map([$this, 'loadProfileByKey'], $profiles);
171 4
    }
172
}
173