SessionCookieMiddleware   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 62
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 30
dl 0
loc 62
ccs 0
cts 23
cp 0
rs 10
c 2
b 0
f 0
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B process() 0 42 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\OpenIDClient\Middleware;
6
7
use function class_exists;
8
use Dflydev\FigCookies\Cookies;
9
use Dflydev\FigCookies\FigResponseCookies;
10
use Dflydev\FigCookies\Modifier\SameSite;
11
use Dflydev\FigCookies\SetCookie;
12
use Facile\OpenIDClient\Exception\LogicException;
13
use Facile\OpenIDClient\Exception\RuntimeException;
14
use Facile\OpenIDClient\Session\AuthSession;
15
use Facile\OpenIDClient\Session\AuthSessionInterface;
16
use function is_array;
17
use function json_decode;
18
use function json_encode;
19
use Psr\Http\Message\ResponseInterface;
20
use Psr\Http\Message\ServerRequestInterface;
21
use Psr\Http\Server\MiddlewareInterface;
22
use Psr\Http\Server\RequestHandlerInterface;
23
use Psr\SimpleCache\CacheInterface;
24
25
/**
26
 * @psalm-import-type AuthSessionType from AuthSessionInterface
27
 */
28
class SessionCookieMiddleware implements MiddlewareInterface
29
{
30
    public const SESSION_ATTRIBUTE = AuthSessionInterface::class;
31
32
    /** @var string */
33
    private $cookieName;
34
35
    /** @var int */
36
    private $ttl;
37
38
    /** @var CacheInterface */
39
    private $cache;
40
41
    public function __construct(CacheInterface $cache, string $cookieName = 'openid', int $ttl = 300)
42
    {
43
        $this->cache = $cache;
44
        $this->cookieName = $cookieName;
45
        $this->ttl = $ttl;
46
    }
47
48
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
49
    {
50
        if (! class_exists(Cookies::class)) {
51
            throw new LogicException('To use the SessionCookieMiddleware you should install dflydev/fig-cookies package');
52
        }
53
54
        $cookies = Cookies::fromRequest($request);
55
        $sessionCookie = $cookies->get($this->cookieName);
56
57
        $sessionId = null !== $sessionCookie ? $sessionCookie->getValue() : null;
58
        /** @var string|null $sessionValue */
59
        $sessionValue = null !== $sessionId ? $this->cache->get($sessionId) : null;
60
        /** @var false|AuthSessionType $data */
61
        $data = null !== $sessionValue ? json_decode($sessionValue, true) : [];
62
63
        if (! is_array($data)) {
0 ignored issues
show
introduced by
The condition is_array($data) is always false.
Loading history...
64
            $data = [];
65
        }
66
67
        $authSession = AuthSession::fromArray($data);
68
69
        $response = $handler->handle($request->withAttribute(self::SESSION_ATTRIBUTE, $authSession));
70
71
        $sessionId = $sessionId ?? bin2hex(random_bytes(32));
72
73
        /** @var string $sessionValue */
74
        $sessionValue = json_encode($authSession);
75
76
        if (false === $this->cache->set($sessionId, $sessionValue, $this->ttl)) {
77
            throw new RuntimeException('Unable to save session');
78
        }
79
80
        $sessionCookie = SetCookie::create($this->cookieName)
81
            ->withValue($sessionId)
82
            ->withMaxAge($this->ttl)
83
            ->withHttpOnly()
84
            ->withPath('/')
85
            ->withSameSite(SameSite::strict());
86
87
        $response = FigResponseCookies::set($response, $sessionCookie);
88
89
        return $response;
90
    }
91
}
92