AuthorizationCodeStorage::store()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

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