Completed
Push — master ( 7a685f...487635 )
by Alexander
01:57
created

SessionMiddleware::commitSession()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 7.004

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 7
eloc 22
c 1
b 0
f 1
nc 8
nop 2
dl 0
loc 39
rs 8.6346
ccs 22
cts 23
cp 0.9565
crap 7.004
1
<?php
2
namespace Yiisoft\Yii\Web\Session;
3
4
use Psr\Http\Message\ResponseInterface;
5
use Psr\Http\Message\ServerRequestInterface;
6
use Psr\Http\Server\MiddlewareInterface;
7
use Psr\Http\Server\RequestHandlerInterface;
8
use Yiisoft\Yii\Web\Cookie;
9
10
class SessionMiddleware implements MiddlewareInterface
11
{
12
    private $session;
13
14 4
    public function __construct(SessionInterface $session)
15
    {
16 4
        $this->session = $session;
17
    }
18
19 4
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
20
    {
21 4
        $requestSessionId = $this->getSidFromRequest($request);
22 4
        if ($requestSessionId !== null) {
23 3
            $this->session->setId($requestSessionId);
24
        }
25
26
        try {
27 4
            $response = $handler->handle($request);
28 1
        } catch (\Throwable $e) {
29 1
            $this->session->discard();
30 1
            throw $e;
31
        }
32
33 3
        return $this->commitSession($request, $response);
34
    }
35
36 3
    private function commitSession(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
37
    {
38 3
        if (!$this->session->isActive()) {
39 1
            return $response;
40
        }
41
42 2
        $this->session->close();
43
44 2
        $currentSid = $this->session->getID();
45
46
        // SID changed, neeed to send new cookie
47 2
        if ($this->getSidFromRequest($request) !== $currentSid) {
48 2
            $cookieParameters = $this->session->getCookieParameters();
49
50 2
            $cookieDomain = $cookieParameters['domain'];
51 2
            if (empty($cookieDomain)) {
52 1
                $cookieDomain = $request->getUri()->getHost();
53
            }
54
55 2
            $useSecureCookie = $cookieParameters['secure'];
56 2
            if ($useSecureCookie && $request->getUri()->getScheme() !== 'https') {
57 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');
58
            }
59
60 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

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