Skip to content

Commit

Permalink
Merge pull request #46435 from nextcloud/backport/46398/stable27
Browse files Browse the repository at this point in the history
[stable27] fix(Session): avoid race conditions on clustered setups
  • Loading branch information
blizzz authored Jul 11, 2024
2 parents 6268273 + e39be84 commit 38a6c50
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 46 deletions.
3 changes: 3 additions & 0 deletions build/psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3587,6 +3587,9 @@
<code><![CDATA[$request->server]]></code>
<code><![CDATA[$request->server]]></code>
</NoInterfaceProperties>
<RedundantCondition>
<code><![CDATA[$this->manager instanceof PublicEmitter]]></code>
</RedundantCondition>
<TooManyArguments>
<code>dispatch</code>
</TooManyArguments>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public function getToken(string $tokenId): IToken {
private function getTokenFromCache(string $tokenHash): ?PublicKeyToken {
$serializedToken = $this->cache->get($tokenHash);
if ($serializedToken === false) {
throw new InvalidTokenException('Token does not exist: ' . $tokenHash);
return null;
}

if ($serializedToken === null) {
Expand Down
2 changes: 1 addition & 1 deletion lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ public function __construct($webRoot, \OC\Config $config) {
$c->get(ISecureRandom::class),
$c->getLockdownManager(),
$c->get(LoggerInterface::class),
$c->get(IEventDispatcher::class)
$c->get(IEventDispatcher::class),
);
/** @deprecated 21.0.0 use BeforeUserCreatedEvent event with the IEventDispatcher instead */
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
Expand Down
61 changes: 17 additions & 44 deletions lib/private/User/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@
use OC_User;
use OC_Util;
use OCA\DAV\Connector\Sabre\Auth;
use OCP\AppFramework\Db\TTransactional;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\NotPermittedException;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IRequest;
use OCP\ISession;
use OCP\IUser;
Expand Down Expand Up @@ -91,53 +93,22 @@
* @package OC\User
*/
class Session implements IUserSession, Emitter {
/** @var Manager $manager */
private $manager;

/** @var ISession $session */
private $session;

/** @var ITimeFactory */
private $timeFactory;

/** @var IProvider */
private $tokenProvider;

/** @var IConfig */
private $config;
use TTransactional;

/** @var User $activeUser */
protected $activeUser;

/** @var ISecureRandom */
private $random;

/** @var ILockdownManager */
private $lockdownManager;

private LoggerInterface $logger;
/** @var IEventDispatcher */
private $dispatcher;

public function __construct(Manager $manager,
ISession $session,
ITimeFactory $timeFactory,
?IProvider $tokenProvider,
IConfig $config,
ISecureRandom $random,
ILockdownManager $lockdownManager,
LoggerInterface $logger,
IEventDispatcher $dispatcher
public function __construct(
private Manager $manager,
private ISession $session,
private ITimeFactory $timeFactory,
private ?IProvider $tokenProvider,
private IConfig $config,
private ISecureRandom $random,
private ILockdownManager $lockdownManager,
private LoggerInterface $logger,
private IEventDispatcher $dispatcher
) {
$this->manager = $manager;
$this->session = $session;
$this->timeFactory = $timeFactory;
$this->tokenProvider = $tokenProvider;
$this->config = $config;
$this->random = $random;
$this->lockdownManager = $lockdownManager;
$this->logger = $logger;
$this->dispatcher = $dispatcher;
}

/**
Expand Down Expand Up @@ -693,8 +664,10 @@ public function createSessionToken(IRequest $request, $uid, $loginName, $passwor
$sessionId = $this->session->getId();
$pwd = $this->getPassword($password);
// Make sure the current sessionId has no leftover tokens
$this->tokenProvider->invalidateToken($sessionId);
$this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name, IToken::TEMPORARY_TOKEN, $remember);
$this->atomic(function () use ($sessionId, $uid, $loginName, $pwd, $name, $remember) {
$this->tokenProvider->invalidateToken($sessionId);
$this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name, IToken::TEMPORARY_TOKEN, $remember);
}, \OCP\Server::get(IDBConnection::class));
return true;
} catch (SessionNotAvailableException $ex) {
// This can happen with OCC, where a memory session is used
Expand Down

0 comments on commit 38a6c50

Please sign in to comment.