mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #34952 from nextcloud/backport/34379/stable24
[stable24] Run session token renewals in a database transaction
This commit is contained in:
commit
719d88c3ac
2 changed files with 48 additions and 23 deletions
|
|
@ -36,12 +36,16 @@ use OC\Authentication\Exceptions\PasswordlessTokenException;
|
|||
use OC\Authentication\Exceptions\WipeTokenException;
|
||||
use OC\Cache\CappedMemoryCache;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\TTransactional;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Security\ICrypto;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class PublicKeyTokenProvider implements IProvider {
|
||||
use TTransactional;
|
||||
|
||||
/** @var PublicKeyTokenMapper */
|
||||
private $mapper;
|
||||
|
||||
|
|
@ -51,6 +55,8 @@ class PublicKeyTokenProvider implements IProvider {
|
|||
/** @var IConfig */
|
||||
private $config;
|
||||
|
||||
private IDBConnection $db;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
|
|
@ -63,11 +69,13 @@ class PublicKeyTokenProvider implements IProvider {
|
|||
public function __construct(PublicKeyTokenMapper $mapper,
|
||||
ICrypto $crypto,
|
||||
IConfig $config,
|
||||
IDBConnection $db,
|
||||
LoggerInterface $logger,
|
||||
ITimeFactory $time) {
|
||||
$this->mapper = $mapper;
|
||||
$this->crypto = $crypto;
|
||||
$this->config = $config;
|
||||
$this->db = $db;
|
||||
$this->logger = $logger;
|
||||
$this->time = $time;
|
||||
|
||||
|
|
@ -158,31 +166,32 @@ class PublicKeyTokenProvider implements IProvider {
|
|||
public function renewSessionToken(string $oldSessionId, string $sessionId): IToken {
|
||||
$this->cache->clear();
|
||||
|
||||
$token = $this->getToken($oldSessionId);
|
||||
return $this->atomic(function () use ($oldSessionId, $sessionId) {
|
||||
$token = $this->getToken($oldSessionId);
|
||||
|
||||
if (!($token instanceof PublicKeyToken)) {
|
||||
throw new InvalidTokenException("Invalid token type");
|
||||
}
|
||||
if (!($token instanceof PublicKeyToken)) {
|
||||
throw new InvalidTokenException("Invalid token type");
|
||||
}
|
||||
|
||||
$password = null;
|
||||
if (!is_null($token->getPassword())) {
|
||||
$privateKey = $this->decrypt($token->getPrivateKey(), $oldSessionId);
|
||||
$password = $this->decryptPassword($token->getPassword(), $privateKey);
|
||||
}
|
||||
$password = null;
|
||||
if (!is_null($token->getPassword())) {
|
||||
$privateKey = $this->decrypt($token->getPrivateKey(), $oldSessionId);
|
||||
$password = $this->decryptPassword($token->getPassword(), $privateKey);
|
||||
}
|
||||
$newToken = $this->generateToken(
|
||||
$sessionId,
|
||||
$token->getUID(),
|
||||
$token->getLoginName(),
|
||||
$password,
|
||||
$token->getName(),
|
||||
IToken::TEMPORARY_TOKEN,
|
||||
$token->getRemember()
|
||||
);
|
||||
|
||||
$newToken = $this->generateToken(
|
||||
$sessionId,
|
||||
$token->getUID(),
|
||||
$token->getLoginName(),
|
||||
$password,
|
||||
$token->getName(),
|
||||
IToken::TEMPORARY_TOKEN,
|
||||
$token->getRemember()
|
||||
);
|
||||
$this->mapper->delete($token);
|
||||
|
||||
$this->mapper->delete($token);
|
||||
|
||||
return $newToken;
|
||||
return $newToken;
|
||||
}, $this->db);
|
||||
}
|
||||
|
||||
public function invalidateToken(string $token) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
|
|
@ -34,6 +37,7 @@ use OCP\AppFramework\Db\DoesNotExistException;
|
|||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\Security\ICrypto;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
|
|
@ -46,6 +50,8 @@ class PublicKeyTokenProviderTest extends TestCase {
|
|||
private $crypto;
|
||||
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $config;
|
||||
/** @var IDBConnection|IDBConnection|MockObject */
|
||||
private IDBConnection $db;
|
||||
/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
|
||||
private $logger;
|
||||
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
|
||||
|
|
@ -66,14 +72,24 @@ class PublicKeyTokenProviderTest extends TestCase {
|
|||
['secret', '', '1f4h9s'],
|
||||
['openssl', [], []],
|
||||
]);
|
||||
$this->db = $this->createMock(IDBConnection::class);
|
||||
$this->db->method('atomic')->willReturnCallback(function ($cb) {
|
||||
return $cb();
|
||||
});
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->time = 1313131;
|
||||
$this->timeFactory->method('getTime')
|
||||
->willReturn($this->time);
|
||||
|
||||
$this->tokenProvider = new PublicKeyTokenProvider($this->mapper, $this->crypto, $this->config, $this->logger,
|
||||
$this->timeFactory);
|
||||
$this->tokenProvider = new PublicKeyTokenProvider(
|
||||
$this->mapper,
|
||||
$this->crypto,
|
||||
$this->config,
|
||||
$this->db,
|
||||
$this->logger,
|
||||
$this->timeFactory,
|
||||
);
|
||||
}
|
||||
|
||||
public function testGenerateToken() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue