Skip to content

Commit dbc976b

Browse files
committed
fix(oauth): rotate the auth token only if the access token rotation was successful
fix(oauth): rotate the auth token only if the access token rotation was successful Signed-off-by: Julien Veyssier <julien-nc@posteo.net> [skip ci]
1 parent 2c78a35 commit dbc976b

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
@@ -692,20 +692,14 @@ public function testRefreshTokenRedeemedConcurrently(): void {
692692
return 'random' . $len;
693693
});
694694

695-
$this->tokenProvider->expects($this->once())
696-
->method('rotate')
697-
->with(
698-
$appToken,
699-
'decryptedToken',
700-
'random72'
701-
)->willReturn($appToken);
695+
$this->tokenProvider->expects($this->never())
696+
->method('rotate');
702697

703698
$this->time->method('getTime')
704699
->willReturn(1000);
705700

706-
$this->tokenProvider->expects($this->once())
707-
->method('updateToken')
708-
->with($this->isInstanceOf(PublicKeyToken::class));
701+
$this->tokenProvider->expects($this->never())
702+
->method('updateToken');
709703

710704
$this->crypto->method('encrypt')
711705
->with('random72', 'random128')
@@ -717,16 +711,11 @@ public function testRefreshTokenRedeemedConcurrently(): void {
717711
$this->db->expects($this->never())
718712
->method('commit');
719713

720-
$this->db->expects($this->exactly(2))
721-
->method('inTransaction')
722-
->willReturnOnConsecutiveCalls(true, false);
723-
724714
$this->db->expects($this->once())
725715
->method('rollBack');
726716

727-
$this->tokenProvider->expects($this->once())
728-
->method('invalidateToken')
729-
->with('random72');
717+
$this->tokenProvider->expects($this->never())
718+
->method('invalidateToken');
730719

731720
$this->accessTokenMapper->expects($this->once())
732721
->method('rotateToken')

0 commit comments

Comments
 (0)