Skip to content

Commit 7096ef2

Browse files
authored
Merge pull request #46436 from nextcloud/backport/46398/stable28
[stable28] fix(Session): avoid race conditions on clustered setups
2 parents 3f06411 + a794756 commit 7096ef2

File tree

4 files changed

+22
-46
lines changed

4 files changed

+22
-46
lines changed

build/psalm-baseline.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3433,6 +3433,9 @@
34333433
<code><![CDATA[$request->server]]></code>
34343434
<code><![CDATA[$request->server]]></code>
34353435
</NoInterfaceProperties>
3436+
<RedundantCondition>
3437+
<code><![CDATA[$this->manager instanceof PublicEmitter]]></code>
3438+
</RedundantCondition>
34363439
</file>
34373440
<file src="lib/private/User/User.php">
34383441
<UndefinedInterfaceMethod>

lib/private/Authentication/Token/PublicKeyTokenProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public function getToken(string $tokenId): OCPIToken {
193193
private function getTokenFromCache(string $tokenHash): ?PublicKeyToken {
194194
$serializedToken = $this->cache->get($tokenHash);
195195
if ($serializedToken === false) {
196-
throw new InvalidTokenException('Token does not exist: ' . $tokenHash);
196+
return null;
197197
}
198198

199199
if ($serializedToken === null) {

lib/private/Server.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ public function __construct($webRoot, \OC\Config $config) {
539539
$c->get(ISecureRandom::class),
540540
$c->getLockdownManager(),
541541
$c->get(LoggerInterface::class),
542-
$c->get(IEventDispatcher::class)
542+
$c->get(IEventDispatcher::class),
543543
);
544544
/** @deprecated 21.0.0 use BeforeUserCreatedEvent event with the IEventDispatcher instead */
545545
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {

lib/private/User/Session.php

Lines changed: 17 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@
4949
use OC_User;
5050
use OC_Util;
5151
use OCA\DAV\Connector\Sabre\Auth;
52+
use OCP\AppFramework\Db\TTransactional;
5253
use OCP\AppFramework\Utility\ITimeFactory;
5354
use OCP\Authentication\Exceptions\ExpiredTokenException;
5455
use OCP\Authentication\Exceptions\InvalidTokenException;
5556
use OCP\EventDispatcher\GenericEvent;
5657
use OCP\EventDispatcher\IEventDispatcher;
5758
use OCP\Files\NotPermittedException;
5859
use OCP\IConfig;
60+
use OCP\IDBConnection;
5961
use OCP\IRequest;
6062
use OCP\ISession;
6163
use OCP\IUser;
@@ -92,53 +94,22 @@
9294
* @package OC\User
9395
*/
9496
class Session implements IUserSession, Emitter {
95-
/** @var Manager $manager */
96-
private $manager;
97-
98-
/** @var ISession $session */
99-
private $session;
100-
101-
/** @var ITimeFactory */
102-
private $timeFactory;
103-
104-
/** @var IProvider */
105-
private $tokenProvider;
106-
107-
/** @var IConfig */
108-
private $config;
97+
use TTransactional;
10998

11099
/** @var User $activeUser */
111100
protected $activeUser;
112101

113-
/** @var ISecureRandom */
114-
private $random;
115-
116-
/** @var ILockdownManager */
117-
private $lockdownManager;
118-
119-
private LoggerInterface $logger;
120-
/** @var IEventDispatcher */
121-
private $dispatcher;
122-
123-
public function __construct(Manager $manager,
124-
ISession $session,
125-
ITimeFactory $timeFactory,
126-
?IProvider $tokenProvider,
127-
IConfig $config,
128-
ISecureRandom $random,
129-
ILockdownManager $lockdownManager,
130-
LoggerInterface $logger,
131-
IEventDispatcher $dispatcher
102+
public function __construct(
103+
private Manager $manager,
104+
private ISession $session,
105+
private ITimeFactory $timeFactory,
106+
private ?IProvider $tokenProvider,
107+
private IConfig $config,
108+
private ISecureRandom $random,
109+
private ILockdownManager $lockdownManager,
110+
private LoggerInterface $logger,
111+
private IEventDispatcher $dispatcher,
132112
) {
133-
$this->manager = $manager;
134-
$this->session = $session;
135-
$this->timeFactory = $timeFactory;
136-
$this->tokenProvider = $tokenProvider;
137-
$this->config = $config;
138-
$this->random = $random;
139-
$this->lockdownManager = $lockdownManager;
140-
$this->logger = $logger;
141-
$this->dispatcher = $dispatcher;
142113
}
143114

144115
/**
@@ -695,8 +666,10 @@ public function createSessionToken(IRequest $request, $uid, $loginName, $passwor
695666
$sessionId = $this->session->getId();
696667
$pwd = $this->getPassword($password);
697668
// Make sure the current sessionId has no leftover tokens
698-
$this->tokenProvider->invalidateToken($sessionId);
699-
$this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name, IToken::TEMPORARY_TOKEN, $remember);
669+
$this->atomic(function () use ($sessionId, $uid, $loginName, $pwd, $name, $remember) {
670+
$this->tokenProvider->invalidateToken($sessionId);
671+
$this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name, IToken::TEMPORARY_TOKEN, $remember);
672+
}, \OCP\Server::get(IDBConnection::class));
700673
return true;
701674
} catch (SessionNotAvailableException $ex) {
702675
// This can happen with OCC, where a memory session is used

0 commit comments

Comments
 (0)