aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Authentication/Token/ManagerTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Authentication/Token/ManagerTest.php')
-rw-r--r--tests/lib/Authentication/Token/ManagerTest.php406
1 files changed, 406 insertions, 0 deletions
diff --git a/tests/lib/Authentication/Token/ManagerTest.php b/tests/lib/Authentication/Token/ManagerTest.php
new file mode 100644
index 00000000000..58bbe236248
--- /dev/null
+++ b/tests/lib/Authentication/Token/ManagerTest.php
@@ -0,0 +1,406 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Authentication\Token;
+
+use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
+use OC\Authentication\Exceptions\InvalidTokenException;
+use OC\Authentication\Token\IToken;
+use OC\Authentication\Token\Manager;
+use OC\Authentication\Token\PublicKeyToken;
+use OC\Authentication\Token\PublicKeyTokenProvider;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class ManagerTest extends TestCase {
+ /** @var PublicKeyTokenProvider|MockObject */
+ private $publicKeyTokenProvider;
+ /** @var Manager */
+ private $manager;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->publicKeyTokenProvider = $this->createMock(PublicKeyTokenProvider::class);
+ $this->manager = new Manager(
+ $this->publicKeyTokenProvider
+ );
+ }
+
+ public function testGenerateToken(): void {
+ $token = new PublicKeyToken();
+
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('generateToken')
+ ->with(
+ 'token',
+ 'uid',
+ 'loginName',
+ 'password',
+ 'name',
+ IToken::TEMPORARY_TOKEN,
+ IToken::REMEMBER
+ )->willReturn($token);
+
+ $actual = $this->manager->generateToken(
+ 'token',
+ 'uid',
+ 'loginName',
+ 'password',
+ 'name',
+ IToken::TEMPORARY_TOKEN,
+ IToken::REMEMBER
+ );
+
+ $this->assertSame($token, $actual);
+ }
+
+ public function testGenerateConflictingToken(): void {
+ /** @var MockObject|UniqueConstraintViolationException $exception */
+ $exception = $this->createMock(UniqueConstraintViolationException::class);
+
+ $token = new PublicKeyToken();
+ $token->setUid('uid');
+
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('generateToken')
+ ->with(
+ 'token',
+ 'uid',
+ 'loginName',
+ 'password',
+ 'name',
+ IToken::TEMPORARY_TOKEN,
+ IToken::REMEMBER
+ )->willThrowException($exception);
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('getToken')
+ ->with('token')
+ ->willReturn($token);
+
+ $actual = $this->manager->generateToken(
+ 'token',
+ 'uid',
+ 'loginName',
+ 'password',
+ 'name',
+ IToken::TEMPORARY_TOKEN,
+ IToken::REMEMBER
+ );
+
+ $this->assertSame($token, $actual);
+ }
+
+ public function testGenerateTokenTooLongName(): void {
+ $token = $this->createMock(IToken::class);
+ $token->method('getName')
+ ->willReturn(str_repeat('a', 120) . '…');
+
+
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('generateToken')
+ ->with(
+ 'token',
+ 'uid',
+ 'loginName',
+ 'password',
+ str_repeat('a', 120) . '…',
+ IToken::TEMPORARY_TOKEN,
+ IToken::REMEMBER
+ )->willReturn($token);
+
+ $actual = $this->manager->generateToken(
+ 'token',
+ 'uid',
+ 'loginName',
+ 'password',
+ str_repeat('a', 200),
+ IToken::TEMPORARY_TOKEN,
+ IToken::REMEMBER
+ );
+
+ $this->assertSame(121, mb_strlen($actual->getName()));
+ }
+
+ public static function tokenData(): array {
+ return [
+ [new PublicKeyToken()],
+ [IToken::class],
+ ];
+ }
+
+ protected function setNoCall(IToken $token) {
+ if (!($token instanceof PublicKeyToken)) {
+ $this->publicKeyTokenProvider->expects($this->never())
+ ->method($this->anything());
+ }
+ }
+
+ protected function setCall(IToken $token, string $function, $return = null) {
+ if ($token instanceof PublicKeyToken) {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method($function)
+ ->with($token)
+ ->willReturn($return);
+ }
+ }
+
+ protected function setException(IToken $token) {
+ if (!($token instanceof PublicKeyToken)) {
+ $this->expectException(InvalidTokenException::class);
+ }
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('tokenData')]
+ public function testUpdateToken(IToken|string $token): void {
+ if (is_string($token)) {
+ $token = $this->createMock($token);
+ }
+
+ $this->setNoCall($token);
+ $this->setCall($token, 'updateToken');
+ $this->setException($token);
+
+ $this->manager->updateToken($token);
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('tokenData')]
+ public function testUpdateTokenActivity(IToken|string $token): void {
+ if (is_string($token)) {
+ $token = $this->createMock($token);
+ }
+
+ $this->setNoCall($token);
+ $this->setCall($token, 'updateTokenActivity');
+ $this->setException($token);
+
+ $this->manager->updateTokenActivity($token);
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('tokenData')]
+ public function testGetPassword(IToken|string $token): void {
+ if (is_string($token)) {
+ $token = $this->createMock($token);
+ }
+
+ $this->setNoCall($token);
+ $this->setCall($token, 'getPassword', 'password');
+ $this->setException($token);
+
+ $result = $this->manager->getPassword($token, 'tokenId', 'password');
+
+ $this->assertSame('password', $result);
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('tokenData')]
+ public function testSetPassword(IToken|string $token): void {
+ if (is_string($token)) {
+ $token = $this->createMock($token);
+ }
+
+ $this->setNoCall($token);
+ $this->setCall($token, 'setPassword');
+ $this->setException($token);
+
+ $this->manager->setPassword($token, 'tokenId', 'password');
+ }
+
+ public function testInvalidateTokens(): void {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('invalidateToken')
+ ->with('token');
+
+ $this->manager->invalidateToken('token');
+ }
+
+ public function testInvalidateTokenById(): void {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('invalidateTokenById')
+ ->with('uid', 42);
+
+ $this->manager->invalidateTokenById('uid', 42);
+ }
+
+ public function testInvalidateOldTokens(): void {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('invalidateOldTokens');
+
+ $this->manager->invalidateOldTokens();
+ }
+
+ public function testInvalidateLastUsedBefore(): void {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('invalidateLastUsedBefore')
+ ->with('user', 946684800);
+
+ $this->manager->invalidateLastUsedBefore('user', 946684800);
+ }
+
+ public function testGetTokenByUser(): void {
+ $t1 = new PublicKeyToken();
+ $t2 = new PublicKeyToken();
+
+ $this->publicKeyTokenProvider
+ ->method('getTokenByUser')
+ ->willReturn([$t1, $t2]);
+
+ $result = $this->manager->getTokenByUser('uid');
+
+ $this->assertEquals([$t1, $t2], $result);
+ }
+
+ public function testRenewSessionTokenPublicKey(): void {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('renewSessionToken')
+ ->with('oldId', 'newId');
+
+ $this->manager->renewSessionToken('oldId', 'newId');
+ }
+
+ public function testRenewSessionInvalid(): void {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('renewSessionToken')
+ ->with('oldId', 'newId')
+ ->willThrowException(new InvalidTokenException());
+
+ $this->expectException(InvalidTokenException::class);
+ $this->manager->renewSessionToken('oldId', 'newId');
+ }
+
+ public function testGetTokenByIdPublicKey(): void {
+ $token = $this->createMock(IToken::class);
+
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('getTokenById')
+ ->with(42)
+ ->willReturn($token);
+
+ $this->assertSame($token, $this->manager->getTokenById(42));
+ }
+
+ public function testGetTokenByIdInvalid(): void {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('getTokenById')
+ ->with(42)
+ ->willThrowException(new InvalidTokenException());
+
+ $this->expectException(InvalidTokenException::class);
+ $this->manager->getTokenById(42);
+ }
+
+ public function testGetTokenPublicKey(): void {
+ $token = new PublicKeyToken();
+
+ $this->publicKeyTokenProvider
+ ->method('getToken')
+ ->with('tokenId')
+ ->willReturn($token);
+
+ $this->assertSame($token, $this->manager->getToken('tokenId'));
+ }
+
+ public function testGetTokenInvalid(): void {
+ $this->publicKeyTokenProvider
+ ->method('getToken')
+ ->with('tokenId')
+ ->willThrowException(new InvalidTokenException());
+
+ $this->expectException(InvalidTokenException::class);
+ $this->manager->getToken('tokenId');
+ }
+
+ public function testRotateInvalid(): void {
+ $this->expectException(InvalidTokenException::class);
+ $this->manager->rotate($this->createMock(IToken::class), 'oldId', 'newId');
+ }
+
+ public function testRotatePublicKey(): void {
+ $token = new PublicKeyToken();
+
+ $this->publicKeyTokenProvider
+ ->method('rotate')
+ ->with($token, 'oldId', 'newId')
+ ->willReturn($token);
+
+ $this->assertSame($token, $this->manager->rotate($token, 'oldId', 'newId'));
+ }
+
+ public function testMarkPasswordInvalidPublicKey(): void {
+ $token = $this->createMock(PublicKeyToken::class);
+
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('markPasswordInvalid')
+ ->with($token, 'tokenId');
+
+ $this->manager->markPasswordInvalid($token, 'tokenId');
+ }
+
+ public function testMarkPasswordInvalidInvalidToken(): void {
+ $this->expectException(InvalidTokenException::class);
+
+ $this->manager->markPasswordInvalid($this->createMock(IToken::class), 'tokenId');
+ }
+
+ public function testUpdatePasswords(): void {
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('updatePasswords')
+ ->with('uid', 'pass');
+
+ $this->manager->updatePasswords('uid', 'pass');
+ }
+
+ public function testInvalidateTokensOfUserNoClientName(): void {
+ $t1 = new PublicKeyToken();
+ $t2 = new PublicKeyToken();
+ $t1->setId(123);
+ $t2->setId(456);
+
+ $this->publicKeyTokenProvider
+ ->expects($this->once())
+ ->method('getTokenByUser')
+ ->with('theUser')
+ ->willReturn([$t1, $t2]);
+
+ $calls = [
+ ['theUser', 123],
+ ['theUser', 456],
+ ];
+ $this->publicKeyTokenProvider
+ ->expects($this->exactly(2))
+ ->method('invalidateTokenById')
+ ->willReturnCallback(function () use (&$calls): void {
+ $expected = array_shift($calls);
+ $this->assertEquals($expected, func_get_args());
+ });
+ $this->manager->invalidateTokensOfUser('theUser', null);
+ }
+
+ public function testInvalidateTokensOfUserClientNameGiven(): void {
+ $t1 = new PublicKeyToken();
+ $t2 = new PublicKeyToken();
+ $t3 = new PublicKeyToken();
+ $t1->setId(123);
+ $t1->setName('Firefox session');
+ $t2->setId(456);
+ $t2->setName('My Client Name');
+ $t3->setId(789);
+ $t3->setName('mobile client');
+
+ $this->publicKeyTokenProvider
+ ->expects($this->once())
+ ->method('getTokenByUser')
+ ->with('theUser')
+ ->willReturn([$t1, $t2, $t3]);
+ $this->publicKeyTokenProvider
+ ->expects($this->once())
+ ->method('invalidateTokenById')
+ ->with('theUser', 456);
+ $this->manager->invalidateTokensOfUser('theUser', 'My Client Name');
+ }
+}