fix(Session): avoid race conditions on clustered setups

- re-stablishes old behaviour with cache to return null instead of throwing
  an InvalidTokenException when the token is cached as non-existing
- token invalidation and re-generation are bundled in a DB transaction now

Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
This commit is contained in:
Arthur Schiwon 2024-07-10 18:54:25 +02:00
parent 43fa5b6c54
commit 7335c064fc
No known key found for this signature in database
GPG key ID: 7424F1874854DF23

View file

@ -50,10 +50,12 @@ use OC\Hooks\PublicEmitter;
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;
@ -90,6 +92,8 @@ use Symfony\Component\EventDispatcher\GenericEvent;
* @package OC\User
*/
class Session implements IUserSession, Emitter {
use TTransactional;
/** @var Manager $manager */
private $manager;
@ -692,8 +696,10 @@ class Session implements IUserSession, Emitter {
$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