Skip to content

Commit 66bbc3b

Browse files
committed
add refresh token repository
1 parent ae8b2bb commit 66bbc3b

File tree

3 files changed

+127
-1
lines changed

3 files changed

+127
-1
lines changed

init.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ function initDatabase() {
4545
type VARCHAR(255) NOT NULL,
4646
expires TEXT NOT NULL
4747
)',
48+
'CREATE TABLE IF NOT EXISTS oauth2Repository (
49+
type VARCHAR(255) NOT NULL,
50+
key VARCHAR(255) NOT NULL,
51+
value TEXT NOT NULL,
52+
expires TEXT NOT NULL
53+
)',
4854
];
4955

5056
try {
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
namespace Pdsinterop\PhpSolid\Repository;
3+
4+
use Pdsinterop\PhpSolid\Db;
5+
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
6+
use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException;
7+
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
8+
use Pdsinterop\Solid\Auth\Entity\RefreshToken as RefreshTokenEntity;
9+
10+
class RefreshToken implements RefreshTokenRepositoryInterface
11+
{
12+
/**
13+
* Creates a new refresh token
14+
*
15+
* @return RefreshTokenEntityInterface|null
16+
*/
17+
public function getNewRefreshToken() : ?RefreshTokenEntityInterface
18+
{
19+
return new RefreshTokenEntity();
20+
}
21+
22+
/**
23+
* Called when a new refresh token is created
24+
*
25+
* @param RefreshTokenEntityInterface $refreshTokenEntity
26+
*
27+
* @throws UniqueTokenIdentifierConstraintViolationException
28+
*/
29+
public function persistNewRefreshToken(RefreshTokenEntityInterface $refreshTokenEntity) : void
30+
{
31+
// throw new UniqueTokenIdentifierConstraintViolationException;
32+
/*/
33+
When a new refresh token is created this method will be called. You don’t have to do anything here but for
34+
auditing you might want to.
35+
36+
The refresh token entity passed in has a number of methods you can call which contain data worth saving to
37+
a database:
38+
39+
getIdentifier() : string this is randomly generated unique identifier (of 80+ characters in length) for the refresh token.
40+
getExpiryDateTime() : \DateTime the expiry date and time of the refresh token.
41+
getAccessToken()->getIdentifier() : string the linked access token’s identifier.
42+
43+
JWT access tokens contain an expiry date and so will be rejected automatically when used. You can safely
44+
clean up expired access tokens from your database.
45+
/*/
46+
Db::connect();
47+
$query = Db::$pdo->prepare(
48+
'INSERT INTO oauth2Repository VALUES(:type, :key, :value, :expiry)'
49+
);
50+
$query->execute([
51+
':type' => 'refreshToken',
52+
':key' => $refreshTokenEntity->getIdentifier(),
53+
':value' => $refreshTokenEntity,
54+
':expires' => $refreshTokenEntit->getExpiryDateTime()
55+
]);
56+
}
57+
58+
/**
59+
* Revoke the refresh token.
60+
*
61+
* @param string $tokenId
62+
*/
63+
public function revokeRefreshToken($tokenId) : void
64+
{
65+
/*/
66+
This method is called when a refresh token is used to reissue an access token.
67+
68+
The original refresh token is revoked a new refresh token is issued.
69+
/*/
70+
Db::connect();
71+
$now = new \DateTime();
72+
$query = Db::$pdo->prepare(
73+
'DELETE FROM oauth2Repository WHERE type=:type AND key = :key'
74+
);
75+
$query->execute([
76+
':type' => 'refreshToken',
77+
':key' => $tokenId
78+
]);
79+
}
80+
81+
/**
82+
* Check if the refresh token has been revoked.
83+
*
84+
* @param string $tokenId
85+
*
86+
* @return bool Return true if this token has been revoked
87+
*/
88+
public function isRefreshTokenRevoked($tokenId) : bool
89+
{
90+
/*/
91+
This method is called when an refresh token is used to issue a new access token.
92+
93+
Return true if the refresh token has been manually revoked before it expired.
94+
If the token is still valid return false.
95+
/*/
96+
return false;
97+
}
98+
99+
public static function cleanup() {
100+
Db::connect();
101+
$now = new \DateTime();
102+
$query = Db::$pdo->prepare(
103+
'DELETE FROM oauth2Repository WHERE type=:type AND expires < :now'
104+
);
105+
$query->execute([
106+
':type' => 'refreshToken',
107+
':now' => $now->getTimestamp()
108+
]);
109+
}
110+
}

lib/Server.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
namespace Pdsinterop\PhpSolid;
33

44
use Pdsinterop\Solid\Auth\Factory\AuthorizationServerFactory;
5+
use Pdsinterop\Solid\Auth\Factory\RepositoryFactory;
56
use Laminas\Diactoros\Response;
67
use Pdsinterop\Solid\Auth\Server as SolidAuthServer;
78
use Pdsinterop\Solid\Auth\Factory\ConfigFactory;
@@ -13,6 +14,7 @@
1314
use Pdsinterop\Solid\Auth\TokenGenerator;
1415
use Pdsinterop\PhpSolid\ClientRegistration;
1516
use Pdsinterop\PhpSolid\JtiStore;
17+
use Pdsinterop\Solid\Auth\Enum\Repository;
1618

1719
class Server {
1820
public static function generateKeySet() {
@@ -40,6 +42,8 @@ public static function generateKeySet() {
4042
public static function getAuthServer() {
4143
$authServerConfig = self::getAuthServerConfig();
4244
$authServerFactory = new AuthorizationServerFactory($authServerConfig);
45+
$repositoryFactory = self::getAuthServerRepositoryFactory();
46+
$authServerFactory->setRepositoryFactory($repositoryFactory);
4347
$authServer = $authServerFactory->create();
4448
$response = new Response();
4549
$server = new SolidAuthServer($authServer, $authServerConfig, $response);
@@ -60,7 +64,13 @@ public static function getAuthServerConfig() {
6064
$authServerConfig = $authServerConfigFactory->create();
6165
return $authServerConfig;
6266
}
63-
67+
68+
public static function getAuthServerRepositoryFactory() {
69+
return new RepositoryFactory([
70+
Repository::REFRESH_TOKEN => new RefreshTokenRepository()
71+
]);
72+
}
73+
6474
public static function getConfigClient() {
6575
$clientId = $_GET['client_id'] ?? $_POST['client_id'] ?? null;
6676
if ($clientId) {

0 commit comments

Comments
 (0)