AccessTokenStorage::getScopeTable()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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