Completed
Branch develop (8213ca)
by Neomerx
02:19
created

Settings::getValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 2
eloc 2
nc 2
nop 2
crap 2
1
<?php namespace Neomerx\Cors\Strategies;
2
3
/**
4
 * Copyright 2015 [email protected] (www.neomerx.com)
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use \Neomerx\Cors\Log\LoggerAwareTrait;
20
use \Psr\Http\Message\RequestInterface;
21
use \Neomerx\Cors\Contracts\Http\ParsedUrlInterface;
22
use \Neomerx\Cors\Contracts\Constants\CorsResponseHeaders;
23
use \Neomerx\Cors\Contracts\Strategies\SettingsStrategyInterface;
24
25
/**
26
 * Implements strategy as a simple set of setting identical for all resources and requests.
27
 *
28
 * @package Neomerx\Cors
29
 */
30
class Settings implements SettingsStrategyInterface
31
{
32
    use LoggerAwareTrait, DefaultSettingsTrait;
33
34
    /**
35
     * 'All' value for allowed origins.
36
     */
37
    const VALUE_ALLOW_ORIGIN_ALL = CorsResponseHeaders::VALUE_ALLOW_ORIGIN_ALL;
38
39
    /**
40
     * 'All' values for allowed headers.
41
     */
42
    const VALUE_ALLOW_ALL_HEADERS = '*';
43
44
    /** Settings key */
45
    const KEY_SERVER_ORIGIN = 0;
46
47
    /** Settings key */
48
    const KEY_SERVER_ORIGIN_SCHEME = 'scheme';
49
50
    /** Settings key */
51
    const KEY_SERVER_ORIGIN_HOST = 'host';
52
53
    /** Settings key */
54
    const KEY_SERVER_ORIGIN_PORT = 'port';
55
56
    /** Settings key */
57
    const KEY_ALLOWED_ORIGINS = 1;
58
59
    /** Settings key */
60
    const KEY_ALLOWED_METHODS = 2;
61
62
    /** Settings key */
63
    const KEY_ALLOWED_HEADERS = 3;
64
65
    /** Settings key */
66
    const KEY_EXPOSED_HEADERS = 4;
67
68
    /** Settings key */
69
    const KEY_IS_USING_CREDENTIALS = 5;
70
71
    /** Settings key */
72
    const KEY_FLIGHT_CACHE_MAX_AGE = 6;
73
74
    /** Settings key */
75
    const KEY_IS_FORCE_ADD_METHODS = 7;
76
77
    /** Settings key */
78
    const KEY_IS_FORCE_ADD_HEADERS = 8;
79
80
    /** Settings key */
81
    const KEY_IS_CHECK_HOST = 9;
82
83
    /**
84
     * @var array
85
     */
86
    protected $settings;
87
88
    /**
89
     * @param array $settings
90
     */
91 19
    public function __construct(array $settings = null)
92
    {
93 19
        $this->setSettings($settings !== null ? $settings : $this->getDefaultSettings());
94 19
    }
95
96
    /**
97
     * @inheritdoc
98
     */
99 8
    public function getSettings()
100
    {
101 8
        return $this->settings;
102
    }
103
104
    /**
105
     * @inheritdoc
106
     */
107 19
    public function setSettings(array $settings)
108
    {
109 19
        $this->settings = $settings;
110 19
    }
111
112
    /**
113
     * @inheritdoc
114
     */
115 12
    public function getServerOrigin()
116
    {
117 12
        return $this->settings[self::KEY_SERVER_ORIGIN];
118
    }
119
120
    /**
121
     * @inheritdoc
122
     */
123 19
    public function setServerOrigin($origin)
124
    {
125 19
        $this->settings[self::KEY_SERVER_ORIGIN] = is_string($origin) === true ? parse_url($origin) : $origin;
126
127 19
        return $this;
128
    }
129
130
    /**
131
     * @inheritdoc
132
     */
133 3
    public function isPreFlightCanBeCached(RequestInterface $request)
134
    {
135 3
        return $this->getPreFlightCacheMaxAge($request) > 0;
136
    }
137
138
    /**
139
     * @inheritdoc
140
     */
141 3
    public function getPreFlightCacheMaxAge(RequestInterface $request)
142
    {
143 3
        return $this->getValue(self::KEY_FLIGHT_CACHE_MAX_AGE, 0);
144
    }
145
146
    /**
147
     * @inheritdoc
148
     */
149 10
    public function setPreFlightCacheMaxAge($cacheMaxAge)
150
    {
151 10
        $this->settings[self::KEY_FLIGHT_CACHE_MAX_AGE] = $cacheMaxAge;
152
153 10
        return $this;
154
    }
155
156
    /**
157
     * @inheritdoc
158
     */
159 2
    public function isForceAddAllowedMethodsToPreFlightResponse()
160
    {
161 2
        return $this->getValue(self::KEY_IS_FORCE_ADD_METHODS, false);
162
    }
163
164
    /**
165
     * @inheritdoc
166
     */
167 10
    public function setForceAddAllowedMethodsToPreFlightResponse($forceFlag)
168
    {
169 10
        $this->settings[self::KEY_IS_FORCE_ADD_METHODS] = $forceFlag;
170
171 10
        return $this;
172
    }
173
174
    /**
175
     * @inheritdoc
176
     */
177 1
    public function isForceAddAllowedHeadersToPreFlightResponse()
178
    {
179 1
        return $this->getValue(self::KEY_IS_FORCE_ADD_HEADERS, false);
180
    }
181
182
    /**
183
     * @inheritdoc
184
     */
185 10
    public function setForceAddAllowedHeadersToPreFlightResponse($forceFlag)
186
    {
187 10
        $this->settings[self::KEY_IS_FORCE_ADD_HEADERS] = $forceFlag;
188
189 10
        return $this;
190
    }
191
192
    /**
193
     * @inheritdoc
194
     */
195 4
    public function isRequestCredentialsSupported(RequestInterface $request)
196
    {
197 4
        return $this->getValue(self::KEY_IS_USING_CREDENTIALS, false);
198
    }
199
200
    /**
201
     * @inheritdoc
202
     */
203 19
    public function setRequestCredentialsSupported($isSupported)
204
    {
205 19
        $this->settings[self::KEY_IS_USING_CREDENTIALS] = $isSupported;
206
207 19
        return $this;
208
    }
209
210
    /**
211
     * @inheritdoc
212
     */
213 8
    public function isRequestOriginAllowed(ParsedUrlInterface $requestOrigin)
214
    {
215
        // check if all origins are allowed with '*'
216
        $isAllowed =
217 8
            isset($this->settings[self::KEY_ALLOWED_ORIGINS][CorsResponseHeaders::VALUE_ALLOW_ORIGIN_ALL]);
218
219 8
        if ($isAllowed === false) {
220 8
            $requestOriginStr = strtolower($requestOrigin->getOrigin());
221 8
            $isAllowed        = isset($this->settings[self::KEY_ALLOWED_ORIGINS][$requestOriginStr]);
222 8
        }
223
224 8
        return $isAllowed;
225
    }
226
227
    /**
228
     * @inheritdoc
229
     */
230 19
    public function setRequestAllowedOrigins(array $origins)
231
    {
232 19
        $this->settings[self::KEY_ALLOWED_ORIGINS] = [];
233 19
        foreach ($origins as $origin => $enabled) {
234 19
            $lcOrigin                                             = strtolower($origin);
235 19
            $this->settings[self::KEY_ALLOWED_ORIGINS][$lcOrigin] = $enabled;
236 19
        }
237
238 19
        return $this;
239
    }
240
241
    /**
242
     * @inheritdoc
243
     */
244 5
    public function isRequestMethodSupported($method)
245
    {
246 5
        $isAllowed = isset($this->settings[self::KEY_ALLOWED_METHODS][$method]);
247
248 5
        return $isAllowed;
249
    }
250
251
    /**
252
     * @inheritdoc
253
     */
254 5
    public function isRequestAllHeadersSupported($headers)
255
    {
256 5
        $allSupported = true;
257
258 5
        if (isset($this->settings[self::KEY_ALLOWED_HEADERS][self::VALUE_ALLOW_ALL_HEADERS]) === true) {
259 1
            return $allSupported;
260
        }
261
262 4
        foreach ($headers as $header) {
263 4
            $lcHeader = strtolower($header);
264 4
            if (isset($this->settings[self::KEY_ALLOWED_HEADERS][$lcHeader]) === false) {
265 2
                $allSupported = false;
266 2
                $this->logInfo(
267 2
                    'Request header is not allowed. Check config settings for Allowed Headers.',
268 2
                    ['header' => $header]
269 2
                );
270 2
                break;
271
            }
272 4
        }
273
274 4
        return $allSupported;
275
    }
276
277
    /**
278
     * @inheritdoc
279
     */
280 3
    public function getRequestAllowedMethods(RequestInterface $request, $requestMethod)
281
    {
282 3
        return implode(', ', $this->getEnabledItems($this->settings[self::KEY_ALLOWED_METHODS]));
283
    }
284
285
    /**
286
     * @inheritdoc
287
     */
288 19
    public function setRequestAllowedMethods(array $methods)
289
    {
290 19
        $this->settings[self::KEY_ALLOWED_METHODS] = [];
291 19
        foreach ($methods as $method => $enabled) {
292 19
            $this->settings[self::KEY_ALLOWED_METHODS][$method] = $enabled;
293 19
        }
294
295 19
        return $this;
296
    }
297
298
    /**
299
     * @inheritdoc
300
     */
301 3
    public function getRequestAllowedHeaders(RequestInterface $request, array $requestHeaders)
302
    {
303 3
        return implode(', ', $this->getEnabledItems($this->settings[self::KEY_ALLOWED_HEADERS]));
304
    }
305
306
    /**
307
     * @inheritdoc
308
     */
309 19
    public function setRequestAllowedHeaders(array $headers)
310
    {
311 19
        $this->settings[self::KEY_ALLOWED_HEADERS] = [];
312 19
        foreach ($headers as $header => $enabled) {
313 19
            $lcHeader                                             = strtolower($header);
314 19
            $this->settings[self::KEY_ALLOWED_HEADERS][$lcHeader] = $enabled;
315 19
        }
316
317 19
        return $this;
318
    }
319
320
    /**
321
     * @inheritdoc
322
     */
323 2
    public function getResponseExposedHeaders(RequestInterface $request)
324
    {
325 2
        return $this->getEnabledItems($this->settings[self::KEY_EXPOSED_HEADERS]);
326
    }
327
328
    /**
329
     * @inheritdoc
330
     */
331 19
    public function setResponseExposedHeaders(array $headers)
332
    {
333 19
        $this->settings[self::KEY_EXPOSED_HEADERS] = $headers;
334
335 19
        return $this;
336
    }
337
338
    /**
339
     * @inheritdoc
340
     */
341 11
    public function isCheckHost()
342
    {
343 11
        return $this->getValue(self::KEY_IS_CHECK_HOST, false);
344
    }
345
346
    /**
347
     * @inheritdoc
348
     */
349 19
    public function setCheckHost($checkFlag)
350
    {
351 19
        $this->settings[self::KEY_IS_CHECK_HOST] = $checkFlag;
352
353 19
        return $this;
354
    }
355
356
    /**
357
     * Select only enabled items from $list.
358
     *
359
     * @param array $list
360
     *
361
     * @return array
362
     */
363 6
    protected function getEnabledItems(array $list)
364
    {
365 6
        $items = [];
366
367 6
        foreach ($list as $item => $enabled) {
368 6
            if ($enabled === true) {
369 6
                $items[] = $item;
370 6
            }
371 6
        }
372
373 6
        return $items;
374
    }
375
376
    /**
377
     * @param mixed $key
378
     * @param mixed $default
379
     *
380
     * @return mixed
381
     */
382 11
    private function getValue($key, $default)
383
    {
384 11
        return array_key_exists($key, $this->settings) === true ? $this->settings[$key] : $default;
385
    }
386
}
387