AuthorizationCodeStorage::store()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4.0039

Importance

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