Passed
Push — master ( b86ef6...5fed0d )
by Alexander
02:39
created

SessionMiddleware::process()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.0218

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 4
eloc 9
c 2
b 0
f 1
nc 4
nop 2
dl 0
loc 15
ccs 8
cts 9
cp 0.8889
crap 4.0218
rs 9.9666
1
<?php
2
3
namespace Yiisoft\Yii\Web\Session;
4
5
use Psr\Http\Message\ResponseInterface;
6
use Psr\Http\Message\ServerRequestInterface;
7
use Psr\Http\Server\MiddlewareInterface;
8
use Psr\Http\Server\RequestHandlerInterface;
9
use Yiisoft\Yii\Web\Cookie;
10
11
class SessionMiddleware implements MiddlewareInterface
12
{
13
    private SessionInterface $session;
14
15 4
    public function __construct(SessionInterface $session)
16
    {
17 4
        $this->session = $session;
18 4
    }
19
20 4
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
21
    {
22 4
        $requestSessionId = $this->getSidFromRequest($request);
23 4
        if ($requestSessionId !== null && $this->session->getId() === null) {
24
            $this->session->setId($requestSessionId);
25
        }
26
27
        try {
28 4
            $response = $handler->handle($request);
29 1
        } catch (\Throwable $e) {
30 1
            $this->session->discard();
31 1
            throw $e;
32
        }
33
34 3
        return $this->commitSession($request, $response);
35
    }
36
37 3
    private function commitSession(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
38
    {
39 3
        if (!$this->session->isActive()) {
40 1
            return $response;
41
        }
42
43 2
        $this->session->close();
44
45 2
        $currentSid = $this->session->getID();
46
47
        // SID changed, neeed to send new cookie
48 2
        if ($this->getSidFromRequest($request) !== $currentSid) {
49 2
            $cookieParameters = $this->session->getCookieParameters();
50
51 2
            $cookieDomain = $cookieParameters['domain'];
52 2
            if (empty($cookieDomain)) {
53 1
                $cookieDomain = $request->getUri()->getHost();
54
            }
55
56 2
            $useSecureCookie = $cookieParameters['secure'];
57 2
            if ($useSecureCookie && $request->getUri()->getScheme() !== 'https') {
58 1
                throw new SessionException('"cookie_secure" is on but connection is not secure. Either set Session "cookie_secure" option to "0" or make connection secure');
59
            }
60
61 1
            $sessionCookie = (new Cookie($this->session->getName(), $currentSid))
0 ignored issues
show
Bug introduced by
It seems like $currentSid can also be of type null; however, parameter $value of Yiisoft\Yii\Web\Cookie::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

61
            $sessionCookie = (new Cookie($this->session->getName(), /** @scrutinizer ignore-type */ $currentSid))
Loading history...
62 1
                ->withPath($cookieParameters['path'])
63 1
                ->withDomain($cookieDomain)
64 1
                ->withHttpOnly($cookieParameters['httponly'])
65 1
                ->withSecure($useSecureCookie)
66 1
                ->withSameSite($cookieParameters['samesite'] ?? Cookie::SAME_SITE_LAX);
67
68 1
            if ($cookieParameters['lifetime'] > 0) {
69 1
                $sessionCookie = $sessionCookie->withMaxAge(new \DateInterval('PT' . $cookieParameters['lifetime'] . 'S'));
70
            }
71
72 1
            return $sessionCookie->addToResponse($response);
73
        }
74
75
        return $response;
76
    }
77
78 4
    private function getSidFromRequest(ServerRequestInterface $request): ?string
79
    {
80 4
        $cookies = $request->getCookieParams();
81 4
        return $cookies[$this->session->getName()] ?? null;
82
    }
83
}
84