CORSHeaders   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 95.35%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 1
dl 0
loc 114
ccs 41
cts 43
cp 0.9535
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A allowedOrigins() 0 5 1
A allowCredentials() 0 5 1
B __invoke() 0 22 5
A applyAll() 0 4 1
A applyMirror() 0 7 2
A applyCustom() 0 11 3
1
<?php
2
3
namespace Kelemen\ApiNette\Middleware;
4
5
use Kelemen\ApiNette\Exception\MiddlewareException;
6
use Kelemen\ApiNette\Response\JsonApiResponse;
7
use Nette\Http\Request;
8
use Nette\Http\Response;
9
10
class CORSHeaders implements MiddlewareInterface
11
{
12
    const MIRROR = 'mirror';
13
    const ALL = 'all';
14
    const CUSTOM = 'custom';
15
16
    /** @var string */
17
    private $behaviour;
18
19
    /** @var array */
20
    private $allowedOrigins = [];
21
22
    /** @var bool */
23
    private $allowedCredentials = false;
24
25
    /**
26
     * @param string $behaviour
27
     * @throws MiddlewareException
28
     */
29 6
    public function __construct($behaviour = self::ALL)
30
    {
31 6
        if (!in_array($behaviour, [self::MIRROR, self::ALL, self::CUSTOM])) {
32
            throw new MiddlewareException('Behaviour ' . $behaviour . ' is not allowed value');
33
        }
34
35 6
        $this->behaviour = $behaviour;
36 6
    }
37
38
    /**
39
     * @param array $allowedOrigins
40
     * @return CORSHeaders
41
     */
42 6
    public function allowedOrigins(array $allowedOrigins)
43
    {
44 6
        $this->allowedOrigins = $allowedOrigins;
45 6
        return $this;
46
    }
47
48
    /**
49
     * @param bool $allowCredentials
50
     * @return CORSHeaders
51
     */
52 6
    public function allowCredentials($allowCredentials = true)
53
    {
54 6
        $this->allowedCredentials = $allowCredentials;
55 6
        return $this;
56
    }
57
58
    /**
59
     * @param Request $request
60
     * @param Response $response
61
     * @param callable $next
62
     * @return JsonApiResponse
63
     */
64 6
    public function __invoke(Request $request, Response $response, callable $next)
65
    {
66 6
        $origin = $request->getHeader('Origin');
67
68
        // Add CORS headers only if mandatory "Origin" header is set
69 6
        if (!$origin) {
70
            return $next($request, $response);
71
        }
72
73 6
        switch ($this->behaviour) {
74 6
            case self::ALL:
75 2
                $this->applyAll($response);
76 2
                break;
77 4
            case self::MIRROR:
78 2
                $this->applyMirror($response, $origin);
79 2
                break;
80 2
            case self::CUSTOM:
81 2
                $this->applyCustom($response);
82 3
        }
83
84 6
        return $next($request, $response);
85
    }
86
87
    /**
88
     * @param Response $response
89
     * @throws MiddlewareException
90
     */
91 2
    private function applyAll(Response $response)
92
    {
93 2
        $response->setHeader('Access-Control-Allow-Origin', '*');
94 2
    }
95
96
    /**
97
     * @param Response $response
98
     * @param string $origin
99
     */
100 2
    private function applyMirror(Response $response, $origin)
101
    {
102 2
        $response->setHeader('Access-Control-Allow-Origin', $origin);
103 2
        if ($this->allowedCredentials) {
104 2
            $response->setHeader('Access-Control-Allow-Credentials', true);
105 1
        }
106 2
    }
107
108
    /**
109
     * @param Response $response
110
     * @throws MiddlewareException
111
     */
112 2
    private function applyCustom(Response $response)
113
    {
114 2
        if (!count($this->allowedOrigins)) {
115 2
            throw new MiddlewareException('Variable $allowedOrigins cannot be empty for CUSTOM behaviour');
116
        }
117
118 2
        $response->setHeader('Access-Control-Allow-Origin', implode(',', $this->allowedOrigins));
119 2
        if ($this->allowedCredentials) {
120 2
            $response->setHeader('Access-Control-Allow-Credentials', true);
121 1
        }
122 2
    }
123
}
124