diff --git a/api/components/OAuth2/Component.php b/api/components/OAuth2/Component.php index 3712109..fc65b5b 100644 --- a/api/components/OAuth2/Component.php +++ b/api/components/OAuth2/Component.php @@ -25,7 +25,7 @@ class Component extends BaseComponent { $authCodesRepo = new Repositories\AuthCodeRepository(); $refreshTokensRepo = new Repositories\RefreshTokenRepository(); - $accessTokenTTL = CarbonInterval::day(); + $accessTokenTTL = CarbonInterval::days(2); $authServer = new AuthorizationServer( $clientsRepo, diff --git a/api/components/OAuth2/Entities/AccessTokenEntity.php b/api/components/OAuth2/Entities/AccessTokenEntity.php index 5d352e5..a3c0f78 100644 --- a/api/components/OAuth2/Entities/AccessTokenEntity.php +++ b/api/components/OAuth2/Entities/AccessTokenEntity.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace api\components\OAuth2\Entities; use api\components\OAuth2\Repositories\PublicScopeRepository; +use api\rbac\Permissions; +use Carbon\CarbonImmutable; use DateTimeImmutable; use League\OAuth2\Server\CryptKeyInterface; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; @@ -43,8 +45,22 @@ class AccessTokenEntity implements AccessTokenEntityInterface { } public function getExpiryDateTime(): DateTimeImmutable { - // TODO: extend token life depending on scopes list - return $this->parentGetExpiryDateTime(); + $expiryTime = $this->parentGetExpiryDateTime(); + if ($this->hasScope(PublicScopeRepository::CHANGE_SKIN) || $this->hasScope(Permissions::OBTAIN_ACCOUNT_EMAIL)) { + $expiryTime = min($expiryTime, CarbonImmutable::now()->addHour()); + } + + return $expiryTime; + } + + private function hasScope(string $scopeIdentifier): bool { + foreach ($this->getScopes() as $scope) { + if ($scope->getIdentifier() === $scopeIdentifier) { + return true; + } + } + + return false; } } diff --git a/api/components/OAuth2/Repositories/PublicScopeRepository.php b/api/components/OAuth2/Repositories/PublicScopeRepository.php index 60335e6..16991fb 100644 --- a/api/components/OAuth2/Repositories/PublicScopeRepository.php +++ b/api/components/OAuth2/Repositories/PublicScopeRepository.php @@ -12,8 +12,8 @@ use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; class PublicScopeRepository implements ScopeRepositoryInterface { public const OFFLINE_ACCESS = 'offline_access'; + public const CHANGE_SKIN = 'change_skin'; - private const CHANGE_SKIN = 'change_skin'; private const ACCOUNT_INFO = 'account_info'; private const ACCOUNT_EMAIL = 'account_email'; diff --git a/api/tests/unit/components/OAuth2/Entities/AccessTokenEntityTest.php b/api/tests/unit/components/OAuth2/Entities/AccessTokenEntityTest.php index 959c52e..a43a664 100644 --- a/api/tests/unit/components/OAuth2/Entities/AccessTokenEntityTest.php +++ b/api/tests/unit/components/OAuth2/Entities/AccessTokenEntityTest.php @@ -5,6 +5,8 @@ namespace api\tests\unit\components\OAuth2\Entities; use api\components\OAuth2\Entities\AccessTokenEntity; use api\tests\unit\TestCase; +use DateInterval; +use DateTimeImmutable; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; @@ -17,7 +19,7 @@ class AccessTokenEntityTest extends TestCase { $entity = new AccessTokenEntity(); $entity->setClient($client); - $entity->setExpiryDateTime(new \DateTimeImmutable()); + $entity->setExpiryDateTime(new DateTimeImmutable()); $entity->addScope($this->createScopeEntity('first')); $entity->addScope($this->createScopeEntity('second')); $entity->addScope($this->createScopeEntity('offline_access')); @@ -33,6 +35,24 @@ class AccessTokenEntityTest extends TestCase { $this->assertSame('offline_access', $scopes[2]->getIdentifier()); } + public function testGetExpiryDateTime() { + $initialExpiry = (new DateTimeImmutable())->add(new DateInterval('P1D')); + + $entity = new AccessTokenEntity(); + $entity->setExpiryDateTime($initialExpiry); + $this->assertSame($initialExpiry, $entity->getExpiryDateTime()); + + $entity = new AccessTokenEntity(); + $entity->setExpiryDateTime($initialExpiry); + $entity->addScope($this->createScopeEntity('change_skin')); + $this->assertEqualsWithDelta(time() + 60 * 60, $entity->getExpiryDateTime()->getTimestamp(), 5); + + $entity = new AccessTokenEntity(); + $entity->setExpiryDateTime($initialExpiry); + $entity->addScope($this->createScopeEntity('obtain_account_email')); + $this->assertEqualsWithDelta(time() + 60 * 60, $entity->getExpiryDateTime()->getTimestamp(), 5); + } + private function createScopeEntity(string $id): ScopeEntityInterface { /** @var ScopeEntityInterface|\PHPUnit\Framework\MockObject\MockObject $entity */ $entity = $this->createMock(ScopeEntityInterface::class);