diff options
author | Arthur Schiwon <blizzz@arthur-schiwon.de> | 2021-08-13 15:53:17 +0200 |
---|---|---|
committer | Arthur Schiwon <blizzz@arthur-schiwon.de> | 2021-09-09 14:03:29 +0200 |
commit | 19cc757531959a14df40a79d550c82b39e4bc5a2 (patch) | |
tree | ff8742a5038b7999898b62d68eb8716cbbed9d4b /tests/Core | |
parent | 9be939300ae0e426d9818756f83f6f09733307fe (diff) | |
download | nextcloud-server-19cc757531959a14df40a79d550c82b39e4bc5a2.tar.gz nextcloud-server-19cc757531959a14df40a79d550c82b39e4bc5a2.zip |
move verification token logic out of lost password controller
- to make it reusable
- needed for local email verification
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Diffstat (limited to 'tests/Core')
-rw-r--r-- | tests/Core/Controller/LostControllerTest.php | 301 |
1 files changed, 43 insertions, 258 deletions
diff --git a/tests/Core/Controller/LostControllerTest.php b/tests/Core/Controller/LostControllerTest.php index fd4e27d47f1..a9dd4c1797b 100644 --- a/tests/Core/Controller/LostControllerTest.php +++ b/tests/Core/Controller/LostControllerTest.php @@ -26,7 +26,6 @@ use OC\Core\Controller\LostController; use OC\Mail\Message; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; -use OCP\AppFramework\Utility\ITimeFactory; use OCP\Defaults; use OCP\Encryption\IEncryptionModule; use OCP\Encryption\IManager; @@ -40,8 +39,8 @@ use OCP\IUser; use OCP\IUserManager; use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; -use OCP\Security\ICrypto; -use OCP\Security\ISecureRandom; +use OCP\Security\VerificationToken\InvalidTokenException; +use OCP\Security\VerificationToken\IVerificationToken; /** * Class LostControllerTest @@ -66,22 +65,18 @@ class LostControllerTest extends \Test\TestCase { private $config; /** @var IMailer | \PHPUnit\Framework\MockObject\MockObject */ private $mailer; - /** @var ISecureRandom | \PHPUnit\Framework\MockObject\MockObject */ - private $secureRandom; /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ private $encryptionManager; - /** @var ITimeFactory | \PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ private $request; - /** @var ICrypto|\PHPUnit\Framework\MockObject\MockObject */ - private $crypto; /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */ private $logger; /** @var Manager|\PHPUnit\Framework\MockObject\MockObject */ private $twofactorManager; /** @var IInitialStateService|\PHPUnit\Framework\MockObject\MockObject */ private $initialStateService; + /** @var IVerificationToken|\PHPUnit\Framework\MockObject\MockObject */ + private $verificationToken; protected function setUp(): void { parent::setUp(); @@ -123,10 +118,6 @@ class LostControllerTest extends \Test\TestCase { ->disableOriginalConstructor()->getMock(); $this->mailer = $this->getMockBuilder('\OCP\Mail\IMailer') ->disableOriginalConstructor()->getMock(); - $this->secureRandom = $this->getMockBuilder('\OCP\Security\ISecureRandom') - ->disableOriginalConstructor()->getMock(); - $this->timeFactory = $this->getMockBuilder('\OCP\AppFramework\Utility\ITimeFactory') - ->disableOriginalConstructor()->getMock(); $this->request = $this->getMockBuilder(IRequest::class) ->disableOriginalConstructor()->getMock(); $this->encryptionManager = $this->getMockBuilder(IManager::class) @@ -134,10 +125,10 @@ class LostControllerTest extends \Test\TestCase { $this->encryptionManager->expects($this->any()) ->method('isEnabled') ->willReturn(true); - $this->crypto = $this->createMock(ICrypto::class); $this->logger = $this->createMock(ILogger::class); $this->twofactorManager = $this->createMock(Manager::class); $this->initialStateService = $this->createMock(IInitialStateService::class); + $this->verificationToken = $this->createMock(IVerificationToken::class); $this->lostController = new LostController( 'Core', $this->request, @@ -146,89 +137,31 @@ class LostControllerTest extends \Test\TestCase { $this->defaults, $this->l10n, $this->config, - $this->secureRandom, 'lostpassword-noreply@localhost', $this->encryptionManager, $this->mailer, - $this->timeFactory, - $this->crypto, $this->logger, $this->twofactorManager, - $this->initialStateService + $this->initialStateService, + $this->verificationToken ); } - public function testResetFormWithNotExistingUser() { - $this->userManager->method('get') - ->with('NotExistingUser') - ->willReturn(null); - - $expectedResponse = new TemplateResponse( - 'core', - 'error', - [ - 'errors' => [ - ['error' => 'Couldn\'t reset password because the token is invalid'], - ] - ], - 'guest' - ); - $this->assertEquals($expectedResponse, $this->lostController->resetform('MySecretToken', 'NotExistingUser')); - } - - public function testResetFormInvalidTokenMatch() { - $this->config->method('getUserValue') - ->with('ValidTokenUser', 'core', 'lostpassword', null) - ->willReturn('encryptedToken'); - $this->existingUser->method('getLastLogin') - ->willReturn(12344); + public function testResetFormTokenError() { $this->userManager->method('get') ->with('ValidTokenUser') ->willReturn($this->existingUser); - $this->crypto->method('decrypt') - ->with( - $this->equalTo('encryptedToken'), - $this->equalTo('test@example.comSECRET') - )->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword'); + $this->verificationToken->expects($this->once()) + ->method('check') + ->with('12345:MySecretToken', $this->existingUser, 'lostpassword') + ->willThrowException(new InvalidTokenException(InvalidTokenException::TOKEN_DECRYPTION_ERROR)); $response = $this->lostController->resetform('12345:MySecretToken', 'ValidTokenUser'); $expectedResponse = new TemplateResponse('core', 'error', [ 'errors' => [ - ['error' => 'Couldn\'t reset password because the token is invalid'], - ] - ], - 'guest'); - $this->assertEquals($expectedResponse, $response); - } - - - public function testResetFormExpiredToken() { - $this->userManager->method('get') - ->with('ValidTokenUser') - ->willReturn($this->existingUser); - $this->config - ->expects($this->once()) - ->method('getUserValue') - ->with('ValidTokenUser', 'core', 'lostpassword', null) - ->willReturn('encryptedToken'); - $this->crypto->method('decrypt') - ->with( - $this->equalTo('encryptedToken'), - $this->equalTo('test@example.comSECRET') - )->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword'); - $this->timeFactory - ->expects($this->once()) - ->method('getTime') - ->willReturn(999999); - - $response = $this->lostController->resetform('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser'); - $expectedResponse = new TemplateResponse('core', - 'error', - [ - 'errors' => [ - ['error' => 'Couldn\'t reset password because the token is expired'], + ['error' => 'Could not reset password because the token is invalid'], ] ], 'guest'); @@ -236,39 +169,14 @@ class LostControllerTest extends \Test\TestCase { } public function testResetFormValidToken() { - $this->existingUser->method('getLastLogin') - ->willReturn(12344); $this->userManager->method('get') ->with('ValidTokenUser') ->willReturn($this->existingUser); - $this->timeFactory - ->expects($this->once()) - ->method('getTime') - ->willReturn(12348); + $this->verificationToken->expects($this->once()) + ->method('check') + ->with('MySecretToken', $this->existingUser, 'lostpassword'); - $this->config->method('getUserValue') - ->with('ValidTokenUser', 'core', 'lostpassword', null) - ->willReturn('encryptedToken'); - - $this->crypto->method('decrypt') - ->with( - $this->equalTo('encryptedToken'), - $this->equalTo('test@example.comSECRET') - )->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword'); - $this->urlGenerator - ->expects($this->once()) - ->method('linkToRouteAbsolute') - ->with('core.lost.setPassword', ['userId' => 'ValidTokenUser', 'token' => 'TheOnlyAndOnlyOneTokenToResetThePassword']) - ->willReturn('https://example.tld/index.php/lostpassword/'); - - $this->initialStateService->expects($this->at(0)) - ->method('provideInitialState') - ->with('core', 'resetPasswordUser', 'ValidTokenUser'); - $this->initialStateService->expects($this->at(1)) - ->method('provideInitialState') - ->with('core', 'resetPasswordTarget', 'https://example.tld/index.php/lostpassword/'); - - $response = $this->lostController->resetform('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser'); + $response = $this->lostController->resetform('MySecretToken', 'ValidTokenUser'); $expectedResponse = new TemplateResponse('core', 'login', [], @@ -319,24 +227,14 @@ class LostControllerTest extends \Test\TestCase { } public function testEmailSuccessful() { - $this->secureRandom - ->expects($this->once()) - ->method('generate') - ->with('21') - ->willReturn('ThisIsMaybeANotSoSecretToken!'); $this->userManager ->expects($this->any()) ->method('get') ->with('ExistingUser') ->willReturn($this->existingUser); - $this->timeFactory - ->expects($this->once()) - ->method('getTime') - ->willReturn(12348); - $this->config - ->expects($this->once()) - ->method('setUserValue') - ->with('ExistingUser', 'core', 'lostpassword', 'encryptedToken'); + $this->verificationToken->expects($this->once()) + ->method('create') + ->willReturn('ThisIsMaybeANotSoSecretToken!'); $this->urlGenerator ->expects($this->once()) ->method('linkToRouteAbsolute') @@ -379,12 +277,6 @@ class LostControllerTest extends \Test\TestCase { ->method('send') ->with($message); - $this->crypto->method('encrypt') - ->with( - $this->equalTo('12348:ThisIsMaybeANotSoSecretToken!'), - $this->equalTo('test@example.comSECRET') - )->willReturn('encryptedToken'); - $response = $this->lostController->email('ExistingUser'); $expectedResponse = new JSONResponse(['status' => 'success']); $expectedResponse->throttle(); @@ -392,11 +284,6 @@ class LostControllerTest extends \Test\TestCase { } public function testEmailWithMailSuccessful() { - $this->secureRandom - ->expects($this->once()) - ->method('generate') - ->with('21') - ->willReturn('ThisIsMaybeANotSoSecretToken!'); $this->userManager ->expects($this->any()) ->method('get') @@ -407,14 +294,9 @@ class LostControllerTest extends \Test\TestCase { ->method('getByEmail') ->with('test@example.com') ->willReturn([$this->existingUser]); - $this->timeFactory - ->expects($this->once()) - ->method('getTime') - ->willReturn(12348); - $this->config - ->expects($this->once()) - ->method('setUserValue') - ->with('ExistingUser', 'core', 'lostpassword', 'encryptedToken'); + $this->verificationToken->expects($this->once()) + ->method('create') + ->willReturn('ThisIsMaybeANotSoSecretToken!'); $this->urlGenerator ->expects($this->once()) ->method('linkToRouteAbsolute') @@ -457,12 +339,6 @@ class LostControllerTest extends \Test\TestCase { ->method('send') ->with($message); - $this->crypto->method('encrypt') - ->with( - $this->equalTo('12348:ThisIsMaybeANotSoSecretToken!'), - $this->equalTo('test@example.comSECRET') - )->willReturn('encryptedToken'); - $response = $this->lostController->email('test@example.com'); $expectedResponse = new JSONResponse(['status' => 'success']); $expectedResponse->throttle(); @@ -470,24 +346,14 @@ class LostControllerTest extends \Test\TestCase { } public function testEmailCantSendException() { - $this->secureRandom - ->expects($this->once()) - ->method('generate') - ->with('21') - ->willReturn('ThisIsMaybeANotSoSecretToken!'); $this->userManager ->expects($this->any()) ->method('get') ->with('ExistingUser') ->willReturn($this->existingUser); - $this->config - ->expects($this->once()) - ->method('setUserValue') - ->with('ExistingUser', 'core', 'lostpassword', 'encryptedToken'); - $this->timeFactory - ->expects($this->once()) - ->method('getTime') - ->willReturn(12348); + $this->verificationToken->expects($this->once()) + ->method('create') + ->willReturn('ThisIsMaybeANotSoSecretToken!'); $this->urlGenerator ->expects($this->once()) ->method('linkToRouteAbsolute') @@ -530,12 +396,6 @@ class LostControllerTest extends \Test\TestCase { ->with($message) ->will($this->throwException(new \Exception())); - $this->crypto->method('encrypt') - ->with( - $this->equalTo('12348:ThisIsMaybeANotSoSecretToken!'), - $this->equalTo('test@example.comSECRET') - )->willReturn('encryptedToken'); - $this->logger->expects($this->exactly(1)) ->method('logException'); @@ -560,14 +420,6 @@ class LostControllerTest extends \Test\TestCase { ->willReturn($this->existingUser); $this->config->expects($this->never()) ->method('deleteUserValue'); - $this->timeFactory->method('getTime') - ->willReturn(12348); - - $this->crypto->method('decrypt') - ->with( - $this->equalTo('encryptedData'), - $this->equalTo('test@example.comSECRET') - )->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword'); $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true); $expectedResponse = ['status' => 'error', 'msg' => '']; @@ -590,14 +442,6 @@ class LostControllerTest extends \Test\TestCase { $this->config->expects($this->once()) ->method('deleteUserValue') ->with('ValidTokenUser', 'core', 'lostpassword'); - $this->timeFactory->method('getTime') - ->willReturn(12348); - - $this->crypto->method('decrypt') - ->with( - $this->equalTo('encryptedData'), - $this->equalTo('test@example.comSECRET') - )->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword'); $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true); $expectedResponse = ['user' => 'ValidTokenUser', 'status' => 'success']; @@ -611,19 +455,14 @@ class LostControllerTest extends \Test\TestCase { $this->userManager->method('get') ->with('ValidTokenUser') ->willReturn($this->existingUser); - $this->timeFactory->method('getTime') - ->willReturn(617146); - - $this->crypto->method('decrypt') - ->with( - $this->equalTo('encryptedData'), - $this->equalTo('test@example.comSECRET') - )->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword'); + $this->verificationToken->expects($this->atLeastOnce()) + ->method('check') + ->willThrowException(new InvalidTokenException(InvalidTokenException::TOKEN_EXPIRED)); $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true); $expectedResponse = [ 'status' => 'error', - 'msg' => 'Couldn\'t reset password because the token is expired', + 'msg' => 'Could not reset password because the token is expired', ]; $this->assertSame($expectedResponse, $response); } @@ -636,45 +475,14 @@ class LostControllerTest extends \Test\TestCase { ->method('get') ->with('ValidTokenUser') ->willReturn($this->existingUser); - - $this->crypto->method('decrypt') - ->with( - $this->equalTo('invalidEncryptedData'), - $this->equalTo('test@example.comSECRET') - )->willReturn('TheOnlyAndOnlyOneTokenToResetThePassword'); + $this->verificationToken->expects($this->atLeastOnce()) + ->method('check') + ->willThrowException(new InvalidTokenException(InvalidTokenException::TOKEN_INVALID_FORMAT)); $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true); $expectedResponse = [ 'status' => 'error', - 'msg' => 'Couldn\'t reset password because the token is invalid', - ]; - $this->assertSame($expectedResponse, $response); - } - - public function testSetPasswordExpiredTokenDueToLogin() { - $this->config->method('getUserValue') - ->with('ValidTokenUser', 'core', 'lostpassword', null) - ->willReturn('encryptedData'); - $this->existingUser->method('getLastLogin') - ->willReturn(12346); - $this->userManager - ->method('get') - ->with('ValidTokenUser') - ->willReturn($this->existingUser); - $this->timeFactory - ->method('getTime') - ->willReturn(12345); - - $this->crypto->method('decrypt') - ->with( - $this->equalTo('encryptedData'), - $this->equalTo('test@example.comSECRET') - )->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword'); - - $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true); - $expectedResponse = [ - 'status' => 'error', - 'msg' => 'Couldn\'t reset password because the token is expired', + 'msg' => 'Could not reset password because the token is invalid', ]; $this->assertSame($expectedResponse, $response); } @@ -686,33 +494,14 @@ class LostControllerTest extends \Test\TestCase { $this->userManager->method('get') ->with('ValidTokenUser') ->willReturn($this->existingUser); - - $this->crypto->method('decrypt') - ->with( - $this->equalTo('aValidtoken'), - $this->equalTo('test@example.comSECRET') - )->willThrowException(new \Exception()); - - $response = $this->lostController->setPassword('', 'ValidTokenUser', 'NewPassword', true); - $expectedResponse = [ - 'status' => 'error', - 'msg' => 'Couldn\'t reset password because the token is invalid' - ]; - $this->assertSame($expectedResponse, $response); - } - - public function testIsSetPasswordTokenNullFailing() { - $this->config->method('getUserValue') - ->with('ValidTokenUser', 'core', 'lostpassword', null) - ->willReturn(null); - $this->userManager->method('get') - ->with('ValidTokenUser') - ->willReturn($this->existingUser); + $this->verificationToken->expects($this->atLeastOnce()) + ->method('check') + ->willThrowException(new InvalidTokenException(InvalidTokenException::TOKEN_MISMATCH)); $response = $this->lostController->setPassword('', 'ValidTokenUser', 'NewPassword', true); $expectedResponse = [ 'status' => 'error', - 'msg' => 'Couldn\'t reset password because the token is invalid' + 'msg' => 'Could not reset password because the token is invalid' ]; $this->assertSame($expectedResponse, $response); } @@ -732,10 +521,14 @@ class LostControllerTest extends \Test\TestCase { ->with('DisabledUser') ->willReturn($user); + $this->verificationToken->expects($this->atLeastOnce()) + ->method('check') + ->willThrowException(new InvalidTokenException(InvalidTokenException::USER_UNKNOWN)); + $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'DisabledUser', 'NewPassword', true); $expectedResponse = [ 'status' => 'error', - 'msg' => 'Couldn\'t reset password because the token is invalid' + 'msg' => 'Could not reset password because the token is invalid' ]; $this->assertSame($expectedResponse, $response); } @@ -798,14 +591,6 @@ class LostControllerTest extends \Test\TestCase { $this->config->expects($this->once()) ->method('deleteUserValue') ->with('ValidTokenUser', 'core', 'lostpassword'); - $this->timeFactory->method('getTime') - ->willReturn(12348); - - $this->crypto->method('decrypt') - ->with( - $this->equalTo('encryptedData'), - $this->equalTo('test@example.comSECRET') - )->willReturn('12345:TheOnlyAndOnlyOneTokenToResetThePassword'); $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', false); $expectedResponse = ['user' => 'ValidTokenUser', 'status' => 'success']; |