Lines 100.00% 41 / 41
Methods 100.00% 7 / 7
Classes 100.00% 1 / 1
Covered by tests of size
Name Lines Methods CRAP
 getNewAuthCode 100.00% 1 / 1 100.00% 1 / 1 1
 persistNewAuthCode 100.00% 21 / 21 100.00% 1 / 1 5
 revokeAuthCode 100.00% 5 / 5 100.00% 1 / 1 1
 isAuthCodeRevoked 100.00% 11 / 11 100.00% 1 / 1 3
 [phpMyFAQ\Auth\OAuth2\Repository\AbstractRepository] __construct 100.00% 1 / 1 100.00% 1 / 1 1
 [phpMyFAQ\Auth\OAuth2\Repository\AbstractRepository] db 100.00% 1 / 1 100.00% 1 / 1 1
 [phpMyFAQ\Auth\OAuth2\Repository\AbstractRepository] table 100.00% 1 / 1 100.00% 1 / 1 1
28final class AuthCodeRepository extends AbstractRepository implements AuthCodeRepositoryInterface
29{
30    public function getNewAuthCode(): AuthCodeEntityInterface
31    {
32        return new AuthCodeEntity();
33    }
34
35    public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity): void
36    {
37        $scopes = array_map(
38            static fn(ScopeEntityInterface $scope): string => $scope->getIdentifier(),
39            $authCodeEntity->getScopes(),
40        );
41
42        $userIdentifier = $authCodeEntity->getUserIdentifier();
43
44        $userIdentifier = $userIdentifier === null ? null : (string) $userIdentifier;
45
46        $redirectUri = $authCodeEntity->getRedirectUri();
47
48        $insert = sprintf(
49            "INSERT INTO %s (identifier, client_id, user_id, redirect_uri, scopes, revoked, expires_at, created)
50             VALUES ('%s', '%s', %s, %s, '%s', 0, '%s', %s)",
51            $this->table('faqoauth_auth_codes'),
52            $this->db()->escape($authCodeEntity->getIdentifier()),
53            $this->db()->escape($authCodeEntity->getClient()->getIdentifier()),
54            $userIdentifier === null ? 'NULL' : "'" . $this->db()->escape($userIdentifier) . "'",
55            $redirectUri === null ? 'NULL' : "'" . $this->db()->escape($redirectUri) . "'",
56            $this->db()->escape((string) json_encode($scopes)),
57            $authCodeEntity->getExpiryDateTime()->format('Y-m-d H:i:s'),
58            $this->db()->now(),
59        );
60
61        if ($this->db()->query($insert) === false) {
62            throw UniqueTokenIdentifierConstraintViolationException::create();
63        }
64    }
65
66    public function revokeAuthCode(string $codeId): void
67    {
68        $this->db()->query(sprintf(
69            "UPDATE %s SET revoked = 1 WHERE identifier = '%s'",
70            $this->table('faqoauth_auth_codes'),
71            $this->db()->escape($codeId),
72        ));
73    }
74
75    public function isAuthCodeRevoked(string $codeId): bool
76    {
77        $result = $this->db()->query(sprintf(
78            "SELECT revoked FROM %s WHERE identifier = '%s'",
79            $this->table('faqoauth_auth_codes'),
80            $this->db()->escape($codeId),
81        ));
82
83        if ($result === false) {
84            return true;
85        }
86
87        $row = $this->db()->fetchObject($result);
88        if (!is_object($row)) {
89            return true;
90        }
91
92        return (int) ($row->revoked ?? 1) === 1;
93    }
94}

Inherited from phpMyFAQ\Auth\OAuth2\Repository\AbstractRepository

28    public function __construct(
29        protected readonly Configuration $configuration,
30    ) {
31    }
33    protected function db(): DatabaseDriver
34    {
35        return $this->configuration->getDb();
36    }
38    protected function table(string $tableName): string
39    {
40        return Database::getTablePrefix() . $tableName;
41    }