Passed
Push — main ( 2e91a7...db810f )
by Dimitri
03:15
created

Cors::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 10
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Middlewares;
13
14
use Psr\Http\Message\ResponseInterface;
15
use Psr\Http\Message\ServerRequestInterface;
16
use Psr\Http\Server\MiddlewareInterface;
17
use Psr\Http\Server\RequestHandlerInterface;
18
19
/**
20
 * Cors
21
 *  Middleware cors pour gerer les requetes d'origine croisees
22
 */
23
class Cors extends BaseMiddleware implements MiddlewareInterface
24
{
25
    protected $config = [
26
        'AllowOrigin'      => true,
27
        'AllowCredentials' => true,
28
        'AllowMethods'     => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
29
        'AllowHeaders'     => true,
30
        'ExposeHeaders'    => false,
31
        'MaxAge'           => 86400,                                       // 1 day
32
    ];
33
34
    /**
35
     * Constructor
36
     */
37
    public function init(array $config = []): self
38
    {
39
        $this->config = array_merge($this->config, $config);
40
41
        return parent::init($config);
0 ignored issues
show
Bug Best Practice introduced by
The expression return parent::init($config) returns the type BlitzPHP\Middlewares\BaseMiddleware which includes types incompatible with the type-hinted return BlitzPHP\Middlewares\Cors.
Loading history...
42
    }
43
44
    /**
45
     * Modifie le MaxAge
46
     *
47
     * @param float|int $maxAge
48
     */
49
    public function setMaxAge($maxAge): self
50
    {
51
        $this->config['MaxAge'] = $maxAge;
52
53
        return $this;
54
    }
55
56
    /**
57
     * Modifie les entetes exposes
58
     *
59
     * @param bool|string|string[] $exposeHeaders
60
     */
61
    public function setExposeHeaders($exposeHeaders): self
62
    {
63
        $this->config['ExposeHeaders'] = $exposeHeaders;
64
65
        return $this;
66
    }
67
68
    /**
69
     * Modifie les entetes autorises
70
     *
71
     * @param bool|string|string[] $headers
72
     */
73
    public function setHeaders($headers): self
74
    {
75
        $this->config['AllowHeaders'] = $headers;
76
77
        return $this;
78
    }
79
80
    /**
81
     * Modifie les methodes autorisees
82
     *
83
     * @param string|string[] $methods
84
     */
85
    public function setMethods($methods): self
86
    {
87
        $this->config['AlloMethods'] = $methods;
88
89
        return $this;
90
    }
91
92
    /**
93
     * Defini si on doit utiliser les informations d'identifications ou pas
94
     */
95
    public function setCredentials(bool $credentials): self
96
    {
97
        $this->config['AllowCredentials'] = $credentials;
98
99
        return $this;
100
    }
101
102
    /**
103
     * Modifie les origines autorisees
104
     *
105
     * @param bool|string|string[] $origin
106
     */
107
    public function setOrigin($origin): self
108
    {
109
        $this->config['AllowOrigin'] = $origin;
110
111
        return $this;
112
    }
113
114
    /**
115
     * Execution du middleware
116
     */
117
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
118
    {
119
        $response = $handler->handle($request);
120
121
        if ($request->getHeaderLine('Origin')) {
122
            $response = $response
123
                ->withHeader('Access-Control-Allow-Origin', $this->_allowOrigin($request))
124
                ->withHeader('Access-Control-Allow-Credentials', $this->_allowCredentials())
125
                ->withHeader('Access-Control-Max-Age', $this->_maxAge())
126
                ->withHeader('Access-Control-Expose-Headers', $this->_exposeHeaders());
127
128
            if (strtoupper($request->getMethod()) === 'OPTIONS') {
129
                $response = $response
130
                    ->withHeader('Access-Control-Allow-Headers', $this->_allowHeaders($request))
131
                    ->withHeader('Access-Control-Allow-Methods', $this->_allowMethods())
132
                    ->withStatus(200);
0 ignored issues
show
Bug introduced by
The method withStatus() does not exist on Psr\Http\Message\MessageInterface. It seems like you code against a sub-type of Psr\Http\Message\MessageInterface such as Psr\Http\Message\ResponseInterface or BlitzPHP\Http\ServerRequest. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

132
                    ->/** @scrutinizer ignore-call */ withStatus(200);
Loading history...
133
            }
134
        }
135
136
        return $response;
137
    }
138
139
    /**
140
     * Recupere les origines autorisees
141
     */
142
    private function _allowOrigin(ServerRequestInterface $request)
143
    {
144
        $allowOrigin = $this->config['AllowOrigin'];
145
        $origin      = $request->getHeaderLine('Origin');
146
147
        if ($allowOrigin === true || $allowOrigin === '*') {
148
            return $origin;
149
        }
150
151
        if (is_array($allowOrigin)) {
152
            $origin = (array) $origin;
153
154
            foreach ($origin as $o) {
155
                if (in_array($o, $allowOrigin, true)) {
156
                    return $origin;
157
                }
158
            }
159
160
            return '';
161
        }
162
163
        return (string) $allowOrigin;
164
    }
165
166
    /**
167
     * Autorise t-on les identifications ?
168
     */
169
    private function _allowCredentials(): string
170
    {
171
        return ($this->config['AllowCredentials']) ? 'true' : 'false';
172
    }
173
174
    /**
175
     * Recupere les methodes autorisees
176
     */
177
    private function _allowMethods(): string
178
    {
179
        return implode(', ', (array) $this->config['AllowMethods']);
180
    }
181
182
    /**
183
     * Recupere les entetes autorises
184
     */
185
    private function _allowHeaders(ServerRequestInterface $request): string
186
    {
187
        $allowHeaders = $this->config['AllowHeaders'];
188
189
        if ($allowHeaders === true) {
190
            return $request->getHeaderLine('Access-Control-Request-Headers');
191
        }
192
193
        return implode(', ', (array) $allowHeaders);
194
    }
195
196
    /**
197
     * Recupere les entetes exposes par l'application
198
     */
199
    private function _exposeHeaders(): string
200
    {
201
        $exposeHeaders = $this->config['ExposeHeaders'];
202
203
        if (is_string($exposeHeaders) || is_array($exposeHeaders)) {
204
            return implode(', ', (array) $exposeHeaders);
205
        }
206
207
        return '';
208
    }
209
210
    /**
211
     * Recupere la duree de mise en cache des donnees
212
     */
213
    private function _maxAge(): string
214
    {
215
        $maxAge = (string) $this->config['MaxAge'];
216
217
        return ($maxAge) ?: '0';
218
    }
219
}
220