AccessTokenStorage   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Test Coverage

Coverage 97.44%

Importance

Changes 0
Metric Value
wmc 12
eloc 36
dl 0
loc 95
ccs 38
cts 39
cp 0.9744
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getScopeTable() 0 3 1
A __construct() 0 4 1
A remove() 0 3 1
A getTable() 0 3 1
A getValidAccessToken() 0 21 4
A store() 0 26 4
1
<?php
2
3
namespace kalanis\OAuth2\Storage\NDB;
4
5
6
use DateTime;
7
use kalanis\OAuth2\Exceptions\InvalidScopeException;
8
use kalanis\OAuth2\Storage\AccessTokens\AccessToken;
9
use kalanis\OAuth2\Storage\AccessTokens\IAccessToken;
10
use kalanis\OAuth2\Storage\AccessTokens\IAccessTokenStorage;
11
use Nette\Database\Explorer;
12
use Nette\Database\SqlLiteral;
13
use Nette\Database\Table\ActiveRow;
14
use Nette\Database\Table\Selection;
15
use PDOException;
16
17
18
/**
19
 * AccessTokenStorage
20
 * @package kalanis\OAuth2\Storage\NDB
21
 */
22 1
class AccessTokenStorage implements IAccessTokenStorage
23
{
24
25 1
    public function __construct(
26
        private readonly Explorer $context,
27
    )
28
    {
29 1
    }
30
31
    /**
32
     * Store access token
33
     * @throws InvalidScopeException
34
     */
35
    public function store(IAccessToken $accessToken): void
36
    {
37 1
        $connection = $this->context->getConnection();
38 1
        $connection->beginTransaction();
39 1
        $this->getTable()->insert([
40 1
            'access_token' => $accessToken->getAccessToken(),
41 1
            'client_id' => $accessToken->getClientId(),
42 1
            'user_id' => $accessToken->getUserId(),
43 1
            'expires_at' => $accessToken->getExpires(),
44
        ]);
45
46
        try {
47 1
            foreach ($accessToken->getScope() as $scope) {
48 1
                $this->getScopeTable()->insert([
49 1
                    'access_token' => $accessToken->getAccessToken(),
50 1
                    'scope_name' => $scope,
51
                ]);
52
            }
53 1
        } catch (PDOException $e) {
54
            // MySQL error 1452 - Cannot add or update a child row: a foreign key constraint fails
55 1
            if (in_array(1452, (array) $e->errorInfo)) {
56 1
                throw new InvalidScopeException;
57
            }
58
            throw $e;
59
        }
60 1
        $connection->commit();
61 1
    }
62
63
    /**
64
     * Get authorization code table
65
     * @return Selection<ActiveRow>
66
     */
67
    protected function getTable(): Selection
68
    {
69 1
        return $this->context->table('oauth_access_token');
70
    }
71
72
    /**
73
     * Get scope table
74
     * @return Selection<ActiveRow>
75
     */
76
    protected function getScopeTable(): Selection
77
    {
78 1
        return $this->context->table('oauth_access_token_scope');
79
    }
80
81
    /**
82
     * Remove access token
83
     * @param string $token
84
     */
85
    public function remove(string $token): void
86
    {
87 1
        $this->getTable()->where(['access_token' => $token])->delete();
88 1
    }
89
90
    /**
91
     * Get valid access token
92
     * @param string $accessToken
93
     * @throws \Exception
94
     * @return IAccessToken|null
95
     */
96
    public function getValidAccessToken(string $accessToken): ?IAccessToken
97
    {
98 1
        $row = $this->getTable()
99 1
            ->where(['access_token' => $accessToken])
100 1
            ->where(new SqlLiteral('TIMEDIFF(expires_at, NOW()) >= 0'))
101 1
            ->fetch();
102
103 1
        if (!$row) {
104 1
            return null;
105
        }
106
107 1
        $scopes = $this->getScopeTable()
108 1
            ->where(['access_token' => $accessToken])
109 1
            ->fetchPairs('scope_name');
110
111 1
        return new AccessToken(
112 1
            strval($row['access_token']),
113 1
            new DateTime(strval($row['expires_at'])),
114 1
            is_numeric($row['client_id'])? intval($row['client_id']) : strval($row['client_id']),
115 1
            is_null($row['user_id']) ? null : strval($row['user_id']),
116 1
            array_map('strval', array_keys($scopes))
117
        );
118
    }
119
}
120