Skip to content

Commit 694aeb0

Browse files
committed
feat(oauth): rotate the auth token only if the access token rotation was successful
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
1 parent 2475ad5 commit 694aeb0

2 files changed

Lines changed: 19 additions & 36 deletions

File tree

apps/oauth2/lib/Controller/OauthApiController.php

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -184,21 +184,9 @@ public function getToken(
184184
$redeemedThrottleReason = $grant_type === 'authorization_code'
185185
? 'authorization_code_already_redeemed'
186186
: 'refresh_token_already_redeemed';
187-
$tokenRotated = false;
188187

189188
$this->db->beginTransaction();
190189
try {
191-
$appToken = $this->tokenProvider->rotate(
192-
$appToken,
193-
$decryptedToken,
194-
$newToken
195-
);
196-
$tokenRotated = true;
197-
198-
// Expiration is in 1 hour again
199-
$appToken->setExpires($this->time->getTime() + 3600);
200-
$this->tokenProvider->updateToken($appToken);
201-
202190
$updatedRows = $this->accessTokenMapper->rotateToken(
203191
$accessToken->getId(),
204192
$code,
@@ -209,25 +197,31 @@ public function getToken(
209197

210198
if ($updatedRows !== 1) {
211199
$this->db->rollBack();
212-
// tokenProvider->rotate() updates the auth token cache, so we have to clear the new token on rollback
213-
$this->tokenProvider->invalidateToken($newToken);
214200
$response = new JSONResponse([
215201
'error' => 'invalid_request',
216202
], Http::STATUS_BAD_REQUEST);
217203
$response->throttle(['invalid_request' => $redeemedThrottleReason]);
218204
return $response;
219205
}
220206

207+
$appToken = $this->tokenProvider->rotate(
208+
$appToken,
209+
$decryptedToken,
210+
$newToken
211+
);
212+
213+
// Expiration is in 1 hour again
214+
$appToken->setExpires($this->time->getTime() + 3600);
215+
$this->tokenProvider->updateToken($appToken);
216+
221217
$this->db->commit();
222218
} catch (\Throwable $e) {
223219
if ($this->db->inTransaction()) {
224220
$this->db->rollBack();
225221
}
226-
227-
if ($tokenRotated) {
228-
// tokenProvider->rotate() updates the auth token cache, so we have to clear the new token on rollback
229-
$this->tokenProvider->invalidateToken($newToken);
230-
}
222+
// rotate() and updateToken() write the auth token to the cache,
223+
// so if we are past rotate() we must invalidate the new token
224+
$this->tokenProvider->invalidateToken($newToken);
231225

232226
throw $e;
233227
}

apps/oauth2/tests/Controller/OauthApiControllerTest.php

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -696,20 +696,14 @@ public function testRefreshTokenRedeemedConcurrently(): void {
696696
return 'random' . $len;
697697
});
698698

699-
$this->tokenProvider->expects($this->once())
700-
->method('rotate')
701-
->with(
702-
$appToken,
703-
'decryptedToken',
704-
'random72'
705-
)->willReturn($appToken);
699+
$this->tokenProvider->expects($this->never())
700+
->method('rotate');
706701

707702
$this->time->method('getTime')
708703
->willReturn(1000);
709704

710-
$this->tokenProvider->expects($this->once())
711-
->method('updateToken')
712-
->with($this->isInstanceOf(PublicKeyToken::class));
705+
$this->tokenProvider->expects($this->never())
706+
->method('updateToken');
713707

714708
$this->crypto->method('encrypt')
715709
->with('random72', 'random128')
@@ -721,16 +715,11 @@ public function testRefreshTokenRedeemedConcurrently(): void {
721715
$this->db->expects($this->never())
722716
->method('commit');
723717

724-
$this->db->expects($this->exactly(2))
725-
->method('inTransaction')
726-
->willReturnOnConsecutiveCalls(true, false);
727-
728718
$this->db->expects($this->once())
729719
->method('rollBack');
730720

731-
$this->tokenProvider->expects($this->once())
732-
->method('invalidateToken')
733-
->with('random72');
721+
$this->tokenProvider->expects($this->never())
722+
->method('invalidateToken');
734723

735724
$this->accessTokenMapper->expects($this->once())
736725
->method('rotateToken')

0 commit comments

Comments
 (0)