From c6d8aff39340f29878ffa6b682f0b9a6ed091b1b Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 29 Jul 2024 13:45:23 +0200 Subject: [PATCH] fix(Token): take over scope in token refresh with login by cookie Signed-off-by: Arthur Schiwon --- .../Authentication/Token/IProvider.php | 17 +++++++----- lib/private/Authentication/Token/Manager.php | 20 ++++++++------ .../Token/PublicKeyTokenProvider.php | 27 ++++++++++++------- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index b5af3f3a5ee9b..59fcac4752127 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -48,13 +48,16 @@ interface IProvider { * @return IToken * @throws \RuntimeException when OpenSSL reports a problem */ - public function generateToken(string $token, - string $uid, - string $loginName, - ?string $password, - string $name, - int $type = IToken::TEMPORARY_TOKEN, - int $remember = IToken::DO_NOT_REMEMBER): IToken; + public function generateToken( + string $token, + string $uid, + string $loginName, + ?string $password, + string $name, + int $type = IToken::TEMPORARY_TOKEN, + int $remember = IToken::DO_NOT_REMEMBER, + ?array $scope = null, + ): IToken; /** * Get a token by token id diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php index 761e799d29835..98b04d2fcdaa8 100644 --- a/lib/private/Authentication/Token/Manager.php +++ b/lib/private/Authentication/Token/Manager.php @@ -54,13 +54,16 @@ public function __construct(PublicKeyTokenProvider $publicKeyTokenProvider) { * @param int $remember whether the session token should be used for remember-me * @return IToken */ - public function generateToken(string $token, - string $uid, - string $loginName, - $password, - string $name, - int $type = IToken::TEMPORARY_TOKEN, - int $remember = IToken::DO_NOT_REMEMBER): IToken { + public function generateToken( + string $token, + string $uid, + string $loginName, + $password, + string $name, + int $type = IToken::TEMPORARY_TOKEN, + int $remember = IToken::DO_NOT_REMEMBER, + ?array $scope = null, + ): IToken { if (mb_strlen($name) > 128) { $name = mb_substr($name, 0, 120) . '…'; } @@ -73,7 +76,8 @@ public function generateToken(string $token, $password, $name, $type, - $remember + $remember, + $scope, ); } catch (UniqueConstraintViolationException $e) { // It's rare, but if two requests of the same session (e.g. env-based SAML) diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php index 726892bc4c593..be665d1460e89 100644 --- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php +++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php @@ -93,13 +93,16 @@ public function __construct(PublicKeyTokenMapper $mapper, /** * {@inheritDoc} */ - public function generateToken(string $token, - string $uid, - string $loginName, - ?string $password, - string $name, - int $type = IToken::TEMPORARY_TOKEN, - int $remember = IToken::DO_NOT_REMEMBER): IToken { + public function generateToken( + string $token, + string $uid, + string $loginName, + ?string $password, + string $name, + int $type = IToken::TEMPORARY_TOKEN, + int $remember = IToken::DO_NOT_REMEMBER, + ?array $scope = null, + ): IToken { if (strlen($token) < self::TOKEN_MIN_LENGTH) { $exception = new InvalidTokenException('Token is too short, minimum of ' . self::TOKEN_MIN_LENGTH . ' characters is required, ' . strlen($token) . ' characters given'); $this->logger->error('Invalid token provided when generating new token', ['exception' => $exception]); @@ -121,6 +124,10 @@ public function generateToken(string $token, $dbToken->setPasswordHash($randomOldToken->getPasswordHash()); } + if ($scope !== null) { + $dbToken->setScope($scope); + } + $this->mapper->insert($dbToken); if (!$oldTokenMatches && $password !== null) { @@ -233,6 +240,8 @@ public function renewSessionToken(string $oldSessionId, string $sessionId): ITok $privateKey = $this->decrypt($token->getPrivateKey(), $oldSessionId); $password = $this->decryptPassword($token->getPassword(), $privateKey); } + + $scope = $token->getScope() === '' ? null : $token->getScopeAsArray(); $newToken = $this->generateToken( $sessionId, $token->getUID(), @@ -240,9 +249,9 @@ public function renewSessionToken(string $oldSessionId, string $sessionId): ITok $password, $token->getName(), IToken::TEMPORARY_TOKEN, - $token->getRemember() + $token->getRemember(), + $scope, ); - $newToken->setScope($token->getScopeAsArray()); $this->mapper->delete($token);