Skip to content

Commit

Permalink
Merge pull request #45063 from nextcloud/backport/44670/stable28
Browse files Browse the repository at this point in the history
[stable28] fix(session): Do not update authtoken last_check for passwordless
  • Loading branch information
kesselb authored May 29, 2024
2 parents d125aa3 + 3534f3d commit 82a53ae
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 2 deletions.
2 changes: 0 additions & 2 deletions lib/private/User/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -757,8 +757,6 @@ private function checkTokenCredentials(IToken $dbToken, $token) {
return false;
}

$dbToken->setLastCheck($now);
$this->tokenProvider->updateToken($dbToken);
return true;
}

Expand Down
78 changes: 78 additions & 0 deletions tests/lib/User/SessionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
use OC\AppFramework\Http\Request;
use OC\Authentication\Events\LoginFailed;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OC\Authentication\Exceptions\PasswordLoginForbiddenException;
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken;
use OC\Authentication\Token\PublicKeyToken;
use OC\Security\CSRF\CsrfTokenManager;
use OC\Session\Memory;
use OC\User\LoginException;
Expand All @@ -35,6 +37,8 @@
use OCP\User\Events\PostLoginEvent;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use function array_diff;
use function get_class_methods;

/**
* @group DB
Expand Down Expand Up @@ -309,6 +313,80 @@ public function testLoginInvalidPassword() {
$userSession->login('foo', 'bar');
}

public function testPasswordlessLoginNoLastCheckUpdate(): void {
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$managerMethods = get_class_methods(Manager::class);
// Keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([
$this->config,
$this->createMock(ICacheFactory::class),
$this->createMock(IEventDispatcher::class),
])
->getMock();
$userSession = new Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);

$session->expects($this->never())
->method('set');
$session->expects($this->once())
->method('regenerateId');
$token = new PublicKeyToken();
$token->setLoginName('foo');
$token->setLastCheck(0); // Never
$token->setUid('foo');
$this->tokenProvider
->method('getPassword')
->with($token)
->willThrowException(new PasswordlessTokenException());
$this->tokenProvider
->method('getToken')
->with('app-password')
->willReturn($token);
$this->tokenProvider->expects(self::never())
->method('updateToken');

$userSession->login('foo', 'app-password');
}

public function testLoginLastCheckUpdate(): void {
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$managerMethods = get_class_methods(Manager::class);
// Keep following methods intact in order to ensure hooks are working
$mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
$manager = $this->getMockBuilder(Manager::class)
->setMethods($mockedManagerMethods)
->setConstructorArgs([
$this->config,
$this->createMock(ICacheFactory::class),
$this->createMock(IEventDispatcher::class),
])
->getMock();
$userSession = new Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);

$session->expects($this->never())
->method('set');
$session->expects($this->once())
->method('regenerateId');
$token = new PublicKeyToken();
$token->setLoginName('foo');
$token->setLastCheck(0); // Never
$token->setUid('foo');
$this->tokenProvider
->method('getPassword')
->with($token)
->willReturn('secret');
$this->tokenProvider
->method('getToken')
->with('app-password')
->willReturn($token);
$this->tokenProvider->expects(self::once())
->method('updateToken');

$userSession->login('foo', 'app-password');
}

public function testLoginNonExisting() {
$session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
$manager = $this->createMock(Manager::class);
Expand Down

0 comments on commit 82a53ae

Please sign in to comment.