Passed
Push — master ( 5679ef...aad9e9 )
by Kirill
04:11
created

CookieTransport::commitToken()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 40
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 27
c 1
b 0
f 0
dl 0
loc 40
rs 9.488
cc 3
nc 3
nop 4
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license MIT
7
 * @author  Anton Titov (Wolfy-J)
8
 * @author  Valentin V (vvval)
9
 */
10
11
declare(strict_types=1);
12
13
namespace Spiral\Auth\Transport;
14
15
use Psr\Http\Message\ResponseInterface as Response;
16
use Psr\Http\Message\ServerRequestInterface as Request;
17
use Spiral\Auth\HttpTransportInterface;
18
use Spiral\Cookies\Cookie;
19
use Spiral\Cookies\CookieQueue;
20
21
/**
22
 * Stores auth tokens in cookies.
23
 */
24
final class CookieTransport implements HttpTransportInterface
25
{
26
    /** @var string */
27
    private $cookie;
28
29
    /** @var string */
30
    private $basePath;
31
32
    /** @var string|null */
33
    private $domain;
34
35
    /** @var bool */
36
    private $secure;
37
38
    /** @var bool */
39
    private $httpOnly;
40
41
    /** @var string|null */
42
    private $sameSite;
43
44
    /**
45
     * @param string      $cookie
46
     * @param string      $basePath
47
     * @param string|null $domain
48
     * @param bool        $secure
49
     * @param bool        $httpOnly
50
     * @param string|null $sameSite
51
     */
52
    public function __construct(
53
        string $cookie,
54
        string $basePath = '/',
55
        ?string $domain = null,
56
        bool $secure = false,
57
        bool $httpOnly = true,
58
        ?string $sameSite = null
59
    ) {
60
        $this->cookie = $cookie;
61
        $this->basePath = $basePath;
62
        $this->domain = $domain;
63
        $this->secure = $secure;
64
        $this->httpOnly = $httpOnly;
65
        $this->sameSite = $sameSite;
66
    }
67
68
    /**
69
     * @inheritDoc
70
     */
71
    public function fetchToken(Request $request): ?string
72
    {
73
        $cookies = $request->getCookieParams();
74
        return $cookies[$this->cookie] ?? null;
75
    }
76
77
    /**
78
     * @inheritDoc
79
     */
80
    public function commitToken(
81
        Request $request,
82
        Response $response,
83
        string $tokenID = null,
84
        \DateTimeInterface $expiresAt = null
85
    ): Response {
86
        /** @var CookieQueue $cookieQueue */
87
        $cookieQueue = $request->getAttribute(CookieQueue::ATTRIBUTE);
88
        if ($cookieQueue === null) {
89
            return $response->withAddedHeader(
90
                'Set-Cookie',
91
                Cookie::create(
92
                    $this->cookie,
93
                    $tokenID,
94
                    $this->getLifetime($expiresAt),
95
                    $this->basePath,
96
                    $this->domain,
97
                    $this->secure,
98
                    $this->httpOnly,
99
                    $this->sameSite
100
                )->createHeader()
101
            );
102
        }
103
104
        if ($tokenID === null) {
105
            $cookieQueue->delete($this->cookie);
106
        } else {
107
            $cookieQueue->set(
108
                $this->cookie,
109
                $tokenID,
110
                $this->getLifetime($expiresAt),
111
                $this->basePath,
112
                $this->domain,
113
                $this->secure,
114
                $this->httpOnly,
115
                $this->sameSite
116
            );
117
        }
118
119
        return $response;
120
    }
121
122
    /**
123
     * @inheritDoc
124
     */
125
    public function removeToken(Request $request, Response $response, string $tokenID): Response
126
    {
127
        // reset to null
128
        return $this->commitToken($request, $response, null, null);
129
    }
130
131
    /**
132
     * @param \DateTimeInterface|null $expiresAt
133
     * @return int|null
134
     */
135
    private function getLifetime(\DateTimeInterface $expiresAt = null): ?int
136
    {
137
        if ($expiresAt === null) {
138
            return null;
139
        }
140
141
        return max($expiresAt->getTimestamp() - time(), 0);
142
    }
143
}
144