Completed
Branch 2.x (1ad542)
by Julián
02:11
created

Configuration::setName()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 2
nop 1
1
<?php
2
3
/*
4
 * sessionware (https://github.com/juliangut/sessionware).
5
 * PSR7 compatible session management.
6
 *
7
 * @license BSD-3-Clause
8
 * @link https://github.com/juliangut/sessionware
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
declare(strict_types=1);
13
14
namespace Jgut\Sessionware;
15
16
use Defuse\Crypto\Key;
17
use Jgut\Sessionware\Traits\NativeSessionTrait;
18
19
/**
20
 * Session configuration.
21
 */
22
class Configuration
23
{
24
    use NativeSessionTrait;
25
26
    const SESSION_ID_LENGTH = 80;
27
    const SESSION_NAME_DEFAULT = 'PHPSESSID';
28
    const TIMEOUT_KEY_DEFAULT = '__SESSIONWARE_TIMEOUT__';
29
30
    const SAME_SITE_LAX = 'Lax';
31
    const SAME_SITE_STRICT = 'Strict';
32
33
    const LIFETIME_FLASH    = 300; // 5 minutes
34
    const LIFETIME_SHORT    = 600; // 10 minutes
35
    const LIFETIME_NORMAL   = 900; // 15 minutes
36
    const LIFETIME_DEFAULT  = 1440; // 24 minutes
37
    const LIFETIME_EXTENDED = 3600; // 1 hour
38
39
    const LIFETIME_INFINITE = PHP_INT_MAX; // Around 1145 years (x86_64)
40
41
    /**
42
     * @var string
43
     */
44
    protected $name;
45
46
    /**
47
     * @var string
48
     */
49
    protected $savePath;
50
51
    /**
52
     * @var int
53
     */
54
    protected $lifetime;
55
56
    /**
57
     * @var string
58
     */
59
    protected $cookiePath;
60
61
    /**
62
     * @var string
63
     */
64
    protected $cookieDomain;
65
66
    /**
67
     * @var bool
68
     */
69
    protected $cookieSecure;
70
71
    /**
72
     * @var bool
73
     */
74
    protected $cookieHttpOnly;
75
76
    /**
77
     * @var string
78
     */
79
    protected $cookieSameSite;
80
81
    /**
82
     * @var Key
83
     */
84
    protected $encryptionKey;
85
86
    /**
87
     * @var string
88
     */
89
    protected $timeoutKey;
90
91
    /**
92
     * Configuration constructor.
93
     *
94
     * @param array $configurations
95
     */
96
    public function __construct(array $configurations = [])
97
    {
98
        $configurations = array_merge(
99
            $this->getDefaultSessionSettings(),
100
            $configurations
101
        );
102
103
        $this->seedConfigurations($configurations);
104
    }
105
106
    /**
107
     * Retrieve default session settings.
108
     *
109
     * @return array
110
     */
111
    protected function getDefaultSessionSettings() : array
112
    {
113
        $sessionLifetime = $this->getIntegerIniSetting('cookie_lifetime') === 0
114
            ? $this->getIntegerIniSetting('gc_maxlifetime')
115
            : min($this->getIntegerIniSetting('cookie_lifetime'), $this->getIntegerIniSetting('gc_maxlifetime'));
116
        $sessionName = session_name() !== static::SESSION_NAME_DEFAULT ? session_name() : static::SESSION_NAME_DEFAULT;
117
118
        return [
119
            'name'           => $this->getStringIniSetting('name', $sessionName),
120
            'savePath'       => $this->getStringIniSetting('save_path', sys_get_temp_dir()),
121
            'lifetime'       => $sessionLifetime > 0 ? $sessionLifetime : static::LIFETIME_DEFAULT,
122
            'cookiePath'     => $this->getStringIniSetting('cookie_path', '/'),
123
            'cookieDomain'   => $this->getStringIniSetting('cookie_domain'),
124
            'cookieSecure'   => $this->hasBoolIniSetting('cookie_secure'),
125
            'cookieHttpOnly' => $this->hasBoolIniSetting('cookie_httponly'),
126
            'cookieSameSite' => static::SAME_SITE_LAX,
127
            'timeoutKey'     => static::TIMEOUT_KEY_DEFAULT,
128
        ];
129
    }
130
131
    /**
132
     * Seed configurations.
133
     *
134
     * @param array $configurations
135
     */
136
    protected function seedConfigurations(array $configurations)
137
    {
138
        $configs = [
139
            'name',
140
            'savePath',
141
            'lifetime',
142
            'cookiePath',
143
            'cookieDomain',
144
            'cookieSecure',
145
            'cookieHttpOnly',
146
            'cookieSameSite',
147
            'timeoutKey',
148
            'encryptionKey',
149
        ];
150
151
        foreach ($configs as $config) {
152
            if (isset($configurations[$config])) {
153
                $callback = [$this, 'set' . ucfirst($config)];
154
155
                call_user_func($callback, $configurations[$config]);
156
            }
157
        }
158
    }
159
160
    /**
161
     * Get session name.
162
     *
163
     * @return string
164
     */
165
    public function getName() : string
166
    {
167
        return $this->name;
168
    }
169
170
    /**
171
     * Set session name.
172
     *
173
     * @param string $name
174
     *
175
     * @throws \InvalidArgumentException
176
     *
177
     * @return self
178
     */
179
    public function setName(string $name)
180
    {
181
        if (empty(trim($name)) || !preg_match('/^[a-zA-Z0-9._-]+$/', $name)) {
182
            throw new \InvalidArgumentException('Session name must be a non empty valid string');
183
        }
184
185
        $this->name = $name;
186
187
        return $this;
188
    }
189
190
    /**
191
     * Get session cookie path.
192
     *
193
     * @return string
194
     */
195
    public function getCookiePath() : string
196
    {
197
        return $this->cookiePath;
198
    }
199
200
    /**
201
     * Set session cookie path.
202
     *
203
     * @param string $cookiePath
204
     *
205
     * @return self
206
     */
207
    public function setCookiePath(string $cookiePath)
208
    {
209
        $this->cookiePath = $cookiePath;
210
211
        return $this;
212
    }
213
214
    /**
215
     * Get session cookie domain.
216
     *
217
     * @return string
218
     */
219
    public function getCookieDomain() : string
220
    {
221
        return $this->cookieDomain;
222
    }
223
224
    /**
225
     * Set session cookie domain.
226
     *
227
     * @param string $cookieDomain
228
     *
229
     * @return self
230
     */
231
    public function setCookieDomain(string $cookieDomain)
232
    {
233
        $this->cookieDomain = $cookieDomain;
234
235
        return $this;
236
    }
237
238
    /**
239
     * Is session cookie HTTPS only.
240
     *
241
     * @return bool
242
     */
243
    public function isCookieSecure() : bool
244
    {
245
        return $this->cookieSecure;
246
    }
247
248
    /**
249
     * Set session cookie HTTPS only.
250
     *
251
     * @param bool $cookieSecure
252
     *
253
     * @return self
254
     */
255
    public function setCookieSecure(bool $cookieSecure)
256
    {
257
        $this->cookieSecure = $cookieSecure;
258
259
        return $this;
260
    }
261
262
    /**
263
     * Is session cookie HTTP only.
264
     *
265
     * @return bool
266
     */
267
    public function isCookieHttpOnly() : bool
268
    {
269
        return $this->cookieHttpOnly;
270
    }
271
272
    /**
273
     * Set session cookie HTTP only.
274
     *
275
     * @param bool $cookieHttpOnly
276
     *
277
     * @return self
278
     */
279
    public function setCookieHttpOnly(bool $cookieHttpOnly)
280
    {
281
        $this->cookieHttpOnly = $cookieHttpOnly;
282
283
        return $this;
284
    }
285
286
    /**
287
     * Get cookie SameSite restriction.
288
     *
289
     * @return string
290
     */
291
    public function getCookieSameSite(): string
292
    {
293
        return $this->cookieSameSite;
294
    }
295
296
    /**
297
     * Set cookie SameSite restriction.
298
     *
299
     * @param string $cookieSameSite
300
     *
301
     * @throws \InvalidArgumentException
302
     */
303
    public function setCookieSameSite(string $cookieSameSite)
304
    {
305
        if (!in_array($cookieSameSite, [static::SAME_SITE_LAX, static::SAME_SITE_STRICT])) {
306
            throw new \InvalidArgumentException(
307
                sprintf('"%s" is not a valid cookie SameSite restriction value', $cookieSameSite)
308
            );
309
        }
310
311
        $this->cookieSameSite = $cookieSameSite;
312
    }
313
314
    /**
315
     * Get session save path.
316
     *
317
     * @return string
318
     */
319
    public function getSavePath() : string
320
    {
321
        return $this->savePath;
322
    }
323
324
    /**
325
     * Set session save path.
326
     *
327
     * @param string $savePath
328
     *
329
     * @throws \InvalidArgumentException
330
     *
331
     * @return self
332
     */
333
    public function setSavePath(string $savePath)
334
    {
335
        if (trim($savePath) === '') {
336
            throw new \InvalidArgumentException('Session save path must be a non empty string');
337
        }
338
339
        $this->savePath = rtrim(trim($savePath), DIRECTORY_SEPARATOR);
340
341
        return $this;
342
    }
343
344
    /**
345
     * Get session lifetime.
346
     *
347
     * @return int
348
     */
349
    public function getLifetime() : int
350
    {
351
        return $this->lifetime;
352
    }
353
354
    /**
355
     * Set session lifetime.
356
     *
357
     * @param int $lifetime
358
     *
359
     * @throws \InvalidArgumentException
360
     *
361
     * @return self
362
     */
363
    public function setLifetime(int $lifetime)
364
    {
365
        if ((int) $lifetime < 1) {
366
            throw new \InvalidArgumentException('Session lifetime must be a positive integer');
367
        }
368
369
        $this->lifetime = (int) $lifetime;
370
371
        return $this;
372
    }
373
374
    /**
375
     * Set session encryption key.
376
     *
377
     * @return Key|null
378
     */
379
    public function getEncryptionKey()
380
    {
381
        return $this->encryptionKey;
382
    }
383
384
    /**
385
     * Set session encryption key.
386
     *
387
     * @param Key $encryptionKey
388
     *
389
     * @return self
390
     */
391
    public function setEncryptionKey(Key $encryptionKey) : self
392
    {
393
        $this->encryptionKey = $encryptionKey;
394
395
        return $this;
396
    }
397
398
    /**
399
     * Get session timeout control key.
400
     *
401
     * @return string
402
     */
403
    public function getTimeoutKey() : string
404
    {
405
        return $this->timeoutKey;
406
    }
407
408
    /**
409
     * Set session timeout control key.
410
     *
411
     * @param string $timeoutKey
412
     *
413
     * @throws \InvalidArgumentException
414
     *
415
     * @return self
416
     */
417
    public function setTimeoutKey(string $timeoutKey) : self
418
    {
419
        if (trim($timeoutKey) === '') {
420
            throw new \InvalidArgumentException('Session timeout key must be a non empty string');
421
        }
422
423
        $this->timeoutKey = $timeoutKey;
424
425
        return $this;
426
    }
427
}
428