Passed
Push — main ( 69451c...874877 )
by Garbuz
03:25
created

TokenManager::deactivationAccessToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Garbuzivan\Laraveltokens;
6
7
use DateTime;
8
use Garbuzivan\Laraveltokens\Exceptions\TokenIsNotNalidException;
9
use Garbuzivan\Laraveltokens\Interfaces\AccessTokenRepositoryInterface;
10
use Garbuzivan\Laraveltokens\Models\AccessToken;
11
use Illuminate\Support\Str;
12
13
class TokenManager
14
{
15
    /**
16
     * @var Config $config
17
     */
18
    protected Config $config;
19
20
    /**
21
     * @var AccessTokenRepositoryInterface
22
     */
23
    protected AccessTokenRepositoryInterface $accessTokenRepository;
24
25
    /**
26
     * Configuration constructor.
27
     * @param Config $config
28
     * @param AccessTokenRepositoryInterface $TokenRepository
29
     */
30
    public function __construct(Config $config, AccessTokenRepositoryInterface $TokenRepository)
31
    {
32
        $this->config = $config;
33
        $this->accessTokenRepository = $TokenRepository;
34
    }
35
36
    /**
37
     * Авторизация по токену
38
     * @param string $token
39
     * @return AccessToken
40
     * @throws TokenIsNotNalidException
41
     */
42
    public function auth(string $token): AccessToken
43
    {
44
        $token = $this->config->isEncryption() ? $this->getHash($token) : $token;
45
        $tokenDb = $this->accessTokenRepository->getAccessToken($token);
46
        if (is_null($tokenDb) || !$tokenDb->isValid()) {
47
            throw new TokenIsNotNalidException;
48
        }
49
        if ($this->config->isLastUse()) {
50
            $this->accessTokenRepository->setLastUseAccessToken($token);
51
        }
52
        return $tokenDb;
53
    }
54
55
    /**
56
     * Проверить актуальность токена (наличие токена и дата активности)
57
     * @param string $token
58
     * @return bool
59
     */
60
    public function isValid(string $token): bool
61
    {
62
        $token = $this->config->isEncryption() ? $this->getHash($token) : $token;
63
        $tokenInfo = $this->accessTokenRepository->getAccessToken($token);
64
        if (is_null($tokenInfo) || !$tokenInfo->isValid()) {
65
            return false;
66
        }
67
        return true;
68
    }
69
70
    /**
71
     * Создать токен
72
     * @param string $title - заголовок токена
73
     * @param int $user_id - ID клиента
74
     * @param DateTime|null $expiration - до когда действует токен, null - бессрочно
75
     * @param string|null $user_type - класс полиморфной связи, null == App\Models\User
76
     * @param string|null $token - токен, null == автоматическая генерация токена
77
     * @return AccessToken
78
     * @throws Exceptions\UserNotExistsException
79
     */
80
    public function createAccessToken(
81
        string    $title,
82
        ?DateTime $expiration = null,
83
        int       $user_id,
84
        ?string   $user_type = null,
85
        ?string   $token = null
86
    ): AccessToken {
87
        $token = is_null($token) || mb_strlen($token) < 32 ? $this->generateAccessToken() : $token;
88
        $user_type = is_null($user_type) ? $this->getDefaultMorph() : $user_type;
89
        $this->accessTokenRepository->isMorph($user_id, $user_type);
90
        $tokenDB = $this->accessTokenRepository->createAccessToken(
91
            $title,
92
            $expiration,
93
            $user_id,
94
            $user_type,
95
            $this->getAccessTokenDb($token)
96
        );
97
        $tokenDB->token = $token;
98
        return $tokenDB;
99
    }
100
101
    /**
102
     * Удалить токен по ID токена
103
     * @param int $token_id - ID токена
104
     * @return bool
105
     */
106
    public function deleteAccessTokenById(int $token_id): bool
107
    {
108
        return $this->accessTokenRepository->deleteAccessTokenById($token_id);
109
    }
110
111
    /**
112
     * Удалить токен
113
     * @param string $token
114
     * @return bool
115
     */
116
    public function deleteAccessToken(string $token): bool
117
    {
118
        return $this->accessTokenRepository->deleteAccessToken($token);
119
    }
120
121
    /**
122
     * Удалить все токены пользователя по id пользователя
123
     *
124
     * @param int    $user_id
125
     * @param string $user_type
126
     *
127
     * @return bool
128
     */
129
    public function deleteAccessTokenByUser(int $user_id, string $user_type): bool
130
    {
131
        return $this->accessTokenRepository->deleteAccessTokenByUser($user_id, $user_type);
132
    }
133
134
    /**
135
     * Очистить таблицу токенов
136
     * @return bool
137
     */
138
    public function deleteAllTokens(): bool
139
    {
140
        return $this->accessTokenRepository->deleteAllAccessToken();
141
    }
142
143
    /**
144
     * Деактивировать токен (прекратить срок действия токена) по ID токена
145
     * @param int $token_id - ID токена
146
     * @return bool
147
     */
148
    public function deactivationAccessTokenById(int $token_id): bool
149
    {
150
        return $this->accessTokenRepository->deactivationAccessTokenById($token_id);
151
    }
152
153
    /**
154
     * Деактивировать токен (прекратить срок действия токена) по токену
155
     * @param string $token
156
     * @return bool
157
     */
158
    public function deactivationAccessToken(string $token): bool
159
    {
160
        return $this->accessTokenRepository->deactivationAccessToken($token);
161
    }
162
163
    /**
164
     * Деактивировать токен (прекратить срок действия токена) по id пользователя
165
     *
166
     * @param int    $user_id
167
     * @param string $user_type
168
     *
169
     * @return bool
170
     */
171
    public function deactivationAccessTokenByUser(int $user_id, string $user_type): bool
172
    {
173
        return $this->accessTokenRepository->deactivationAccessTokenByUser($user_id, $user_type);
174
    }
175
176
    /**
177
     * Продлить срок действия токена по id токена
178
     * @param int $token_id
179
     * @param DateTime $expiration
180
     * @return bool
181
     */
182
    public function prolongationAccessTokenById(int $token_id, DateTime $expiration): bool
183
    {
184
        return $this->accessTokenRepository->prolongationAccessTokenById($token_id, $expiration);
185
    }
186
187
    /**
188
     * Продлить срок действия всех токенов по id пользователя
189
     *
190
     * @param int      $user_id
191
     * @param string   $user_type
192
     * @param DateTime $expiration
193
     *
194
     * @return bool
195
     */
196
    public function prolongationAccessTokenByUser(int $user_id, string $user_type, DateTime $expiration): bool
197
    {
198
        return $this->accessTokenRepository->prolongationAccessTokenByUser($user_id, $user_type, $expiration);
199
    }
200
201
    /**
202
     * Продлить срок действия токена по токену
203
     * @param string $token
204
     * @param DateTime $expiration
205
     * @return bool
206
     */
207
    public function prolongationAccessToken(string $token, DateTime $expiration): bool
208
    {
209
        return $this->accessTokenRepository->prolongationAccessToken($token, $expiration);
210
    }
211
212
    /**
213
     * Генерация случайного токена на основе даты и случайной строки
214
     * @return string
215
     */
216
    public function generateAccessToken(): string
217
    {
218
        return sha1(time() . Str::random());
219
    }
220
221
    /**
222
     * Преобразование токена для БД в зависимости от настройки Encryption
223
     * @param string $token
224
     * @return string
225
     */
226
    public function getAccessTokenDb(string $token): string
227
    {
228
        return $this->config->isEncryption() ? $this->getHash($token) : $token;
229
    }
230
231
    /**
232
     * Получение хэша
233
     * @param string $string
234
     * @return string
235
     */
236
    public function getHash(string $string): string
237
    {
238
        return hash('sha256', $string);
239
    }
240
241
    /**
242
     * Сравнение токена
243
     * @param string $token
244
     * @param string $hash
245
     * @return bool
246
     */
247
    public function isVerify(string $token, string $hash): bool
248
    {
249
        return strcmp($this->getAccessTokenDb($token), $hash) !== 0;
250
    }
251
252
    /**
253
     * Получить deault Morph
254
     * @return string
255
     */
256
    public function getDefaultMorph(): string
257
    {
258
        return 'App\Models\User';
259
    }
260
}
261