Skip to content

Commit 8a8e1c8

Browse files
authored
Merge pull request nextcloud#54545 from nextcloud/enh/noid/add-token-invalidated-event
Dispatch new event when invalidating an authentication token
2 parents d5417d6 + 3d36834 commit 8a8e1c8

File tree

5 files changed

+62
-2
lines changed

5 files changed

+62
-2
lines changed

lib/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157
'OCP\\App\\ManagerEvent' => $baseDir . '/lib/public/App/ManagerEvent.php',
158158
'OCP\\Authentication\\Events\\AnyLoginFailedEvent' => $baseDir . '/lib/public/Authentication/Events/AnyLoginFailedEvent.php',
159159
'OCP\\Authentication\\Events\\LoginFailedEvent' => $baseDir . '/lib/public/Authentication/Events/LoginFailedEvent.php',
160+
'OCP\\Authentication\\Events\\TokenInvalidatedEvent' => $baseDir . '/lib/public/Authentication/Events/TokenInvalidatedEvent.php',
160161
'OCP\\Authentication\\Exceptions\\CredentialsUnavailableException' => $baseDir . '/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php',
161162
'OCP\\Authentication\\Exceptions\\ExpiredTokenException' => $baseDir . '/lib/public/Authentication/Exceptions/ExpiredTokenException.php',
162163
'OCP\\Authentication\\Exceptions\\InvalidTokenException' => $baseDir . '/lib/public/Authentication/Exceptions/InvalidTokenException.php',

lib/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
198198
'OCP\\App\\ManagerEvent' => __DIR__ . '/../../..' . '/lib/public/App/ManagerEvent.php',
199199
'OCP\\Authentication\\Events\\AnyLoginFailedEvent' => __DIR__ . '/../../..' . '/lib/public/Authentication/Events/AnyLoginFailedEvent.php',
200200
'OCP\\Authentication\\Events\\LoginFailedEvent' => __DIR__ . '/../../..' . '/lib/public/Authentication/Events/LoginFailedEvent.php',
201+
'OCP\\Authentication\\Events\\TokenInvalidatedEvent' => __DIR__ . '/../../..' . '/lib/public/Authentication/Events/TokenInvalidatedEvent.php',
201202
'OCP\\Authentication\\Exceptions\\CredentialsUnavailableException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php',
202203
'OCP\\Authentication\\Exceptions\\ExpiredTokenException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/ExpiredTokenException.php',
203204
'OCP\\Authentication\\Exceptions\\InvalidTokenException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/InvalidTokenException.php',

lib/private/Authentication/Token/PublicKeyTokenProvider.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
use OCP\AppFramework\Db\DoesNotExistException;
1616
use OCP\AppFramework\Db\TTransactional;
1717
use OCP\AppFramework\Utility\ITimeFactory;
18+
use OCP\Authentication\Events\TokenInvalidatedEvent;
1819
use OCP\Authentication\Token\IToken as OCPIToken;
20+
use OCP\EventDispatcher\IEventDispatcher;
1921
use OCP\ICache;
2022
use OCP\ICacheFactory;
2123
use OCP\IConfig;
@@ -55,14 +57,18 @@ class PublicKeyTokenProvider implements IProvider {
5557
/** @var IHasher */
5658
private $hasher;
5759

60+
private IEventDispatcher $eventDispatcher;
61+
5862
public function __construct(PublicKeyTokenMapper $mapper,
5963
ICrypto $crypto,
6064
IConfig $config,
6165
IDBConnection $db,
6266
LoggerInterface $logger,
6367
ITimeFactory $time,
6468
IHasher $hasher,
65-
ICacheFactory $cacheFactory) {
69+
ICacheFactory $cacheFactory,
70+
IEventDispatcher $eventDispatcher,
71+
) {
6672
$this->mapper = $mapper;
6773
$this->crypto = $crypto;
6874
$this->config = $config;
@@ -74,6 +80,7 @@ public function __construct(PublicKeyTokenMapper $mapper,
7480
? $cacheFactory->createLocal('authtoken_')
7581
: $cacheFactory->createInMemory();
7682
$this->hasher = $hasher;
83+
$this->eventDispatcher = $eventDispatcher;
7784
}
7885

7986
/**
@@ -263,9 +270,17 @@ public function renewSessionToken(string $oldSessionId, string $sessionId): OCPI
263270

264271
public function invalidateToken(string $token) {
265272
$tokenHash = $this->hashToken($token);
273+
$tokenEntry = null;
274+
try {
275+
$tokenEntry = $this->mapper->getToken($tokenHash);
276+
} catch (DoesNotExistException) {
277+
}
266278
$this->mapper->invalidate($this->hashToken($token));
267279
$this->mapper->invalidate($this->hashTokenWithEmptySecret($token));
268280
$this->cacheInvalidHash($tokenHash);
281+
if ($tokenEntry !== null) {
282+
$this->eventDispatcher->dispatchTyped(new TokenInvalidatedEvent($tokenEntry));
283+
}
269284
}
270285

271286
public function invalidateTokenById(string $uid, int $id) {
@@ -275,7 +290,7 @@ public function invalidateTokenById(string $uid, int $id) {
275290
}
276291
$this->mapper->invalidate($token->getToken());
277292
$this->cacheInvalidHash($token->getToken());
278-
293+
$this->eventDispatcher->dispatchTyped(new TokenInvalidatedEvent($token));
279294
}
280295

281296
public function invalidateOldTokens() {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
namespace OCP\Authentication\Events;
10+
11+
use OCP\Authentication\Token\IToken;
12+
use OCP\EventDispatcher\Event;
13+
14+
/**
15+
* Emitted when an authentication token is invalidated
16+
*
17+
* @since 32.0.0
18+
*/
19+
class TokenInvalidatedEvent extends Event {
20+
21+
/**
22+
* @since 32.0.0
23+
*/
24+
public function __construct(
25+
private IToken $token,
26+
) {
27+
parent::__construct();
28+
}
29+
30+
/**
31+
* returns the token that has been invalidated
32+
*
33+
* @since 32.0.0
34+
*/
35+
public function getToken(): IToken {
36+
return $this->token;
37+
}
38+
}

tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use OCP\AppFramework\Db\DoesNotExistException;
1919
use OCP\AppFramework\Utility\ITimeFactory;
2020
use OCP\Authentication\Token\IToken;
21+
use OCP\EventDispatcher\IEventDispatcher;
2122
use OCP\ICacheFactory;
2223
use OCP\IConfig;
2324
use OCP\IDBConnection;
@@ -49,6 +50,8 @@ class PublicKeyTokenProviderTest extends TestCase {
4950
private $cacheFactory;
5051
/** @var int */
5152
private $time;
53+
/** @var IEventDispatcher */
54+
private $eventDispatcher;
5255

5356
protected function setUp(): void {
5457
parent::setUp();
@@ -72,6 +75,7 @@ protected function setUp(): void {
7275
$this->timeFactory->method('getTime')
7376
->willReturn($this->time);
7477
$this->cacheFactory = $this->createMock(ICacheFactory::class);
78+
$this->eventDispatcher = Server::get(IEventDispatcher::class);
7579

7680
$this->tokenProvider = new PublicKeyTokenProvider(
7781
$this->mapper,
@@ -82,6 +86,7 @@ protected function setUp(): void {
8286
$this->timeFactory,
8387
$this->hasher,
8488
$this->cacheFactory,
89+
$this->eventDispatcher,
8590
);
8691
}
8792

0 commit comments

Comments
 (0)