Passed
Push — develop ( 641a70...483548 )
by nguereza
01:41
created

BaseTokenService::cleanExpired()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * Platine OAuth2
5
 *
6
 * Platine OAuth2 is a library that implements the OAuth2 specification
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine OAuth2
11
 *
12
 * Permission is hereby granted, free of charge, to any person obtaining a copy
13
 * of this software and associated documentation files (the "Software"), to deal
14
 * in the Software without restriction, including without limitation the rights
15
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
 * copies of the Software, and to permit persons to whom the Software is
17
 * furnished to do so, subject to the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be included in all
20
 * copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
 * SOFTWARE.
29
 */
30
31
declare(strict_types=1);
32
33
namespace Platine\OAuth2\Service;
34
35
use Platine\OAuth2\Configuration;
36
use Platine\OAuth2\Entity\BaseToken;
37
use Platine\OAuth2\Entity\Client;
38
use Platine\OAuth2\Exception\OAuth2Exception;
39
use Platine\OAuth2\Repository\TokenRepositoryInterface;
40
41
/**
42
 * @class BaseTokenService
43
 * @package Platine\OAuth2\Service
44
 */
45
class BaseTokenService
46
{
47
    /**
48
     * The TokenRepository instance
49
     * @var TokenRepositoryInterface
50
     */
51
    protected $tokenRepository;
52
53
    /**
54
     * The ScopeService instance
55
     * @var ScopeService
56
     */
57
    protected ScopeService $scopeService;
58
59
    /**
60
     * The Configuration instance
61
     * @var Configuration
62
     */
63
    protected Configuration $configuration;
64
65
    /**
66
     * Create new instance
67
     * @param TokenRepositoryInterface $tokenRepository
68
     * @param ScopeService $scopeService
69
     * @param Configuration $configuration
70
     */
71
    public function __construct(
72
        TokenRepositoryInterface $tokenRepository,
73
        ScopeService $scopeService,
74
        Configuration $configuration
75
    ) {
76
        $this->tokenRepository = $tokenRepository;
77
        $this->scopeService = $scopeService;
78
        $this->configuration = $configuration;
79
    }
80
81
    /**
82
     * Return the token entity of given token value
83
     * @param string $tokenValue
84
     * @return BaseToken|null
85
     */
86
    public function getToken(string $tokenValue): ?BaseToken
87
    {
88
        $token = $this->tokenRepository->getByToken($tokenValue);
89
        // Because the collation is most often case insensitive, we need to add a
90
        // check here to ensure that the token matches case
91
        if ($token === null || hash_equals($token->getToken(), $tokenValue) === false) {
92
            return null;
93
        }
94
95
96
        return $token;
97
    }
98
99
    /**
100
     * Delete the given token
101
     * @param BaseToken $token
102
     * @return void
103
     */
104
    public function delete(BaseToken $token): void
105
    {
106
        $this->tokenRepository->delete($token);
107
    }
108
109
    /**
110
     * Clean the expired tokens
111
     * @return void
112
     */
113
    public function cleanExpired(): void
114
    {
115
        $this->tokenRepository->cleanExpired();
116
    }
117
118
    /**
119
     *
120
     * @param array<string>|array<Scope> $scopes
121
     * @param Client|null $client
122
     * @return void
123
     */
124
    public function validateTokenScopes(array $scopes, ?Client $client = null): void
125
    {
126
        $scopeList = array_map(fn($scope) => (string) $scope, $scopes);
127
128
        $persistentScopes = $this->scopeService->all();
129
        $persistentList = array_map(fn($scope) => (string) $scope, $persistentScopes);
130
131
        $diff = array_diff($scopeList, $persistentList);
132
        if (count($diff) > 0) {
133
            throw OAuth2Exception::invalidScope(sprintf(
134
                'Some scope(s) do not exist: [%s]',
135
                implode(', ', $diff)
136
            ));
137
        }
138
139
        if ($client === null) {
140
            return;
141
        }
142
143
        $clientScopes = $client->getScopes();
144
        $diffClient = array_diff($scopeList, $clientScopes);
145
        if (count($diffClient) > 0) {
146
            throw OAuth2Exception::invalidScope(sprintf(
147
                'Some scope(s) are not assigned to client: %s',
148
                implode(', ', $diff)
149
            ));
150
        }
151
    }
152
}
153