Configurable refresh token lifetimes.
This commit is contained in:
parent
dd968eae44
commit
61dad487f6
5 changed files with 39 additions and 23 deletions
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
use Index\Data\IDbConnection;
|
||||
use Index\Data\Migration\IDbMigration;
|
||||
|
||||
final class ConfigurableRefreshLifetime_20240727_025524 implements IDbMigration {
|
||||
public function migrate(IDbConnection $conn): void {
|
||||
$conn->execute('ALTER TABLE hau_apps ADD COLUMN app_refresh_lifetime INT UNSIGNED NULL DEFAULT NULL AFTER app_type');
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ class AppInfo {
|
|||
private string $website,
|
||||
private bool $trusted,
|
||||
private string $type,
|
||||
private ?int $refreshLifetime,
|
||||
private string $clientId,
|
||||
private string $clientSecret,
|
||||
private int $created,
|
||||
|
@ -26,11 +27,12 @@ class AppInfo {
|
|||
website: $result->getString(3),
|
||||
trusted: $result->getBoolean(4),
|
||||
type: $result->getString(5),
|
||||
clientId: $result->getString(6),
|
||||
clientSecret: $result->getString(7),
|
||||
created: $result->getInteger(8),
|
||||
updated: $result->getInteger(9),
|
||||
deleted: $result->getIntegerOrNull(10),
|
||||
refreshLifetime: $result->getIntegerOrNull(6),
|
||||
clientId: $result->getString(7),
|
||||
clientSecret: $result->getString(8),
|
||||
created: $result->getInteger(9),
|
||||
updated: $result->getInteger(10),
|
||||
deleted: $result->getIntegerOrNull(11),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -71,6 +73,16 @@ class AppInfo {
|
|||
return strcasecmp($this->type, 'confidential') === 0;
|
||||
}
|
||||
|
||||
public function getRefreshTokenLifetime(): ?int {
|
||||
return $this->refreshLifetime;
|
||||
}
|
||||
public function shouldIssueRefreshToken(): bool {
|
||||
if($this->refreshLifetime === null)
|
||||
return $this->isConfidential();
|
||||
|
||||
return $this->refreshLifetime > 0;
|
||||
}
|
||||
|
||||
public function getClientId(): string {
|
||||
return $this->clientId;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class AppsData {
|
|||
throw new InvalidArgumentException('you must specify either $appId or $clientId');
|
||||
|
||||
$values = [];
|
||||
$query = 'SELECT app_id, app_name, app_summary, app_website, app_trusted, app_type, app_client_id, app_client_secret, UNIX_TIMESTAMP(app_created), UNIX_TIMESTAMP(app_updated), UNIX_TIMESTAMP(app_deleted) FROM hau_apps';
|
||||
$query = 'SELECT app_id, app_name, app_summary, app_website, app_trusted, app_type, app_refresh_lifetime, app_client_id, app_client_secret, UNIX_TIMESTAMP(app_created), UNIX_TIMESTAMP(app_updated), UNIX_TIMESTAMP(app_deleted) FROM hau_apps';
|
||||
$query .= sprintf(' WHERE %s = ?', $hasAppId ? 'app_id' : 'app_client_id');
|
||||
if($hasDeleted)
|
||||
$query .= sprintf(' AND app_deleted %s NULL', $deleted ? 'IS NOT' : 'IS');
|
||||
|
|
|
@ -27,18 +27,16 @@ class OAuth2Context {
|
|||
return $this->devices;
|
||||
}
|
||||
|
||||
public function createRefreshFromAccessInfo(
|
||||
OAuth2AccessInfo $accessInfo,
|
||||
?string $token = null,
|
||||
?int $lifetime = null
|
||||
public function createRefresh(
|
||||
AppInfo $appInfo,
|
||||
OAuth2AccessInfo $accessInfo
|
||||
): OAuth2RefreshInfo {
|
||||
return $this->tokens->createRefresh(
|
||||
$accessInfo->getAppId(),
|
||||
$accessInfo,
|
||||
$accessInfo->getUserId(),
|
||||
$token,
|
||||
$accessInfo->getScope(),
|
||||
$lifetime
|
||||
userId: $accessInfo->getUserId(),
|
||||
scope: $accessInfo->getScope(),
|
||||
lifetime: $appInfo->getRefreshTokenLifetime()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -595,9 +595,8 @@ final class OAuth2Routes extends RouteHandler {
|
|||
if($scope === $authoriseInfo->getScope())
|
||||
unset($scope);
|
||||
|
||||
// this should probably check something else
|
||||
if($appInfo->isConfidential())
|
||||
$refreshInfo = $this->oauth2Ctx->createRefreshFromAccessInfo($accessInfo);
|
||||
if($appInfo->shouldIssueRefreshToken())
|
||||
$refreshInfo = $this->oauth2Ctx->createRefresh($appInfo, $accessInfo);
|
||||
} elseif($type === 'refresh_token') {
|
||||
$tokensData = $this->oauth2Ctx->getTokensData();
|
||||
try {
|
||||
|
@ -639,9 +638,8 @@ final class OAuth2Routes extends RouteHandler {
|
|||
|
||||
unset($refreshInfo);
|
||||
|
||||
// this should probably check something else
|
||||
if($appInfo->isConfidential())
|
||||
$refreshInfo = $this->oauth2Ctx->createRefreshFromAccessInfo($accessInfo);
|
||||
if($appInfo->shouldIssueRefreshToken())
|
||||
$refreshInfo = $this->oauth2Ctx->createRefresh($appInfo, $accessInfo);
|
||||
} elseif($type === 'client_credentials') {
|
||||
if(!$appInfo->isConfidential()) {
|
||||
$response->setStatusCode(400);
|
||||
|
@ -723,9 +721,8 @@ final class OAuth2Routes extends RouteHandler {
|
|||
if($scope === $deviceInfo->getScope())
|
||||
unset($scope);
|
||||
|
||||
// this should probably check something else
|
||||
if($appInfo->isConfidential())
|
||||
$refreshInfo = $this->oauth2Ctx->createRefreshFromAccessInfo($accessInfo);
|
||||
if($appInfo->shouldIssueRefreshToken())
|
||||
$refreshInfo = $this->oauth2Ctx->createRefresh($appInfo, $accessInfo);
|
||||
} else {
|
||||
$response->setStatusCode(400);
|
||||
return self::error('unsupported_grant_type', 'Requested grant type is not supported by this server.');
|
||||
|
|
Loading…
Reference in a new issue