Completed
Push — master ( e4c888...b002ee )
by Alexander
10:41 queued 05:38
created

SessionMiddleware::commitSession()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

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
ccs 0
cts 29
cp 0
crap 56
rs 8.6346
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
    public function __construct(SessionInterface $session)
15
    {
16
        $this->session = $session;
17
    }
18
19
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
20
    {
21
        try {
22
            $response = $handler->handle($request);
23
        } catch (\Throwable $e) {
24
            $this->session->discard();
25
            throw $e;
26
        }
27
28
        return $this->commitSession($request, $response);
29
    }
30
31
    private function commitSession(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
32
    {
33
        if (!$this->session->isActive()) {
34
            return $response;
35
        }
36
37
        $this->session->close();
38
39
        $currentSid = $this->session->getID();
40
41
        // SID changed, neeed to send new cookie
42
        if ($this->getSidFromRequest($request) !== $currentSid) {
43
            $cookieParameters = $this->session->getCookieParameters();
44
45
            $cookieDomain = $cookieParameters['domain'];
46
            if (empty($cookieDomain)) {
47
                $cookieDomain = $request->getUri()->getHost();
48
            }
49
50
            $useSecureCookie = $cookieParameters['secure'];
51
            if ($useSecureCookie && $request->getUri()->getScheme() !== 'https') {
52
                throw new SessionException('"cookie_secure" is on but connection is not secure. Either set Session "cookie_secure" option to "0" or make connection secure');
53
            }
54
55
            $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

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