GrantType::verifyGrantType()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 9
ccs 0
cts 5
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace kalanis\OAuth2\Grant;
4
5
6
use kalanis\OAuth2\Exceptions\UnauthorizedClientException;
7
use kalanis\OAuth2\Grant\Exceptions\InvalidGrantTypeException;
8
use kalanis\OAuth2\Http\IInput;
9
use kalanis\OAuth2\Storage\Clients\IClient;
10
use kalanis\OAuth2\Storage\Clients\IClientStorage;
11
use kalanis\OAuth2\Storage\TokenContext;
12
use Nette\Security\User;
13
14
15
/**
16
 * GrantType
17
 * @package kalanis\OAuth2\Grant
18
 *
19
 * @property-read string $identifier
20
 */
21 1
abstract class GrantType implements IGrant
22
{
23
24
    public const SCOPE_KEY = 'scope';
25
    public const CLIENT_ID_KEY = 'client_id';
26
    public const CLIENT_SECRET_KEY = 'client_secret';
27
    public const GRANT_TYPE_KEY = 'grant_type';
28
29
    private ?IClient $client = null;
30
31 1
    public function __construct(
32
        protected IInput $input,
33
        protected TokenContext $token,
34
        protected IClientStorage $clientStorage,
35
        protected User $user,
36
    )
37
    {
38 1
    }
39
40
    /**
41
     * Get access token
42
     * @throws UnauthorizedClientException
43
     * @throws InvalidGrantTypeException
44
     * @return array<string, string|int>
45
     */
46
    public final function getAccessToken(): array
47
    {
48
        if (!$client = $this->getClient()) {
49
            throw new UnauthorizedClientException('Client is not found');
50
        }
51
52
        $this->verifyGrantType($client);
53
        $this->verifyRequest();
54
        return $this->generateAccessToken($client);
55
    }
56
57
    /**
58
     * Get client
59
     * @return IClient|null
60
     */
61
    private function getClient(): ?IClient
62
    {
63
        if (!$this->client) {
64
            $clientId = $this->input->getParameter(self::CLIENT_ID_KEY);
65
            $clientSecret = $this->input->getParameter(self::CLIENT_SECRET_KEY);
66
            $this->client = $this->clientStorage->getClient(
67
                is_numeric($clientId) ? intval($clientId) : strval($clientId),
68
                is_null($clientSecret) ? null : strval($clientSecret)
69
            );
70
        }
71
        return $this->client;
72
    }
73
74
    /**
75
     * Verify grant type
76
     * @param IClient $client
77
     * @throws UnauthorizedClientException
78
     * @throws InvalidGrantTypeException
79
     */
80
    protected function verifyGrantType(IClient $client): void
81
    {
82
        $grantType = $this->input->getParameter(self::GRANT_TYPE_KEY);
83
        if (!$grantType) {
84
            throw new InvalidGrantTypeException;
85
        }
86
87
        if (!$this->clientStorage->canUseGrantType($client->getId(), strval($grantType))) {
88
            throw new UnauthorizedClientException;
89
        }
90
    }
91
92
    /**
93
     * Verify request
94
     * @return void
95
     */
96
    protected abstract function verifyRequest(): void;
97
98
    /**
99
     * Generate access token
100
     * @param IClient $client
101
     * @return array<string, string|int>
102
     */
103
    protected abstract function generateAccessToken(IClient $client): array;
104
105
    /**
106
     * Get scope as array - allowed separators: ',' AND ' '
107
     * @return array<string>
108
     */
109
    protected function getScope(): array
110
    {
111 1
        $scope = $this->input->getParameter(self::SCOPE_KEY);
112 1
        return !is_array($scope) ?
113 1
            array_filter(explode(',', str_replace(' ', ',', strval($scope)))) :
114 1
            array_filter(array_map('strval', $scope));
115
    }
116
}
117