diff options
Diffstat (limited to 'apps/oauth2/tests/Controller/SettingsControllerTest.php')
-rw-r--r-- | apps/oauth2/tests/Controller/SettingsControllerTest.php | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/apps/oauth2/tests/Controller/SettingsControllerTest.php b/apps/oauth2/tests/Controller/SettingsControllerTest.php new file mode 100644 index 00000000000..030a220e3d7 --- /dev/null +++ b/apps/oauth2/tests/Controller/SettingsControllerTest.php @@ -0,0 +1,188 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\OAuth2\Tests\Controller; + +use OCA\OAuth2\Controller\SettingsController; +use OCA\OAuth2\Db\AccessTokenMapper; +use OCA\OAuth2\Db\Client; +use OCA\OAuth2\Db\ClientMapper; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\JSONResponse; +use OCP\Authentication\Token\IProvider as IAuthTokenProvider; +use OCP\IL10N; +use OCP\IRequest; +use OCP\IUser; +use OCP\IUserManager; +use OCP\Security\ICrypto; +use OCP\Security\ISecureRandom; +use OCP\Server; +use Test\TestCase; + +/** + * @group DB + */ +class SettingsControllerTest extends TestCase { + /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ + private $request; + /** @var ClientMapper|\PHPUnit\Framework\MockObject\MockObject */ + private $clientMapper; + /** @var ISecureRandom|\PHPUnit\Framework\MockObject\MockObject */ + private $secureRandom; + /** @var AccessTokenMapper|\PHPUnit\Framework\MockObject\MockObject */ + private $accessTokenMapper; + /** @var IAuthTokenProvider|\PHPUnit\Framework\MockObject\MockObject */ + private $authTokenProvider; + /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ + private $userManager; + /** @var SettingsController */ + private $settingsController; + /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ + private $l; + /** @var ICrypto|\PHPUnit\Framework\MockObject\MockObject */ + private $crypto; + + protected function setUp(): void { + parent::setUp(); + + $this->request = $this->createMock(IRequest::class); + $this->clientMapper = $this->createMock(ClientMapper::class); + $this->secureRandom = $this->createMock(ISecureRandom::class); + $this->accessTokenMapper = $this->createMock(AccessTokenMapper::class); + $this->authTokenProvider = $this->createMock(IAuthTokenProvider::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->crypto = $this->createMock(ICrypto::class); + $this->l = $this->createMock(IL10N::class); + $this->l->method('t') + ->willReturnArgument(0); + $this->settingsController = new SettingsController( + 'oauth2', + $this->request, + $this->clientMapper, + $this->secureRandom, + $this->accessTokenMapper, + $this->l, + $this->authTokenProvider, + $this->userManager, + $this->crypto + ); + + } + + public function testAddClient(): void { + $this->secureRandom + ->expects($this->exactly(2)) + ->method('generate') + ->with(64, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') + ->willReturnOnConsecutiveCalls( + 'MySecret', + 'MyClientIdentifier'); + + $this->crypto + ->expects($this->once()) + ->method('calculateHMAC') + ->willReturn('MyHashedSecret'); + + $client = new Client(); + $client->setName('My Client Name'); + $client->setRedirectUri('https://example.com/'); + $client->setSecret(bin2hex('MyHashedSecret')); + $client->setClientIdentifier('MyClientIdentifier'); + + $this->clientMapper + ->expects($this->once()) + ->method('insert') + ->with($this->callback(function (Client $c) { + return $c->getName() === 'My Client Name' + && $c->getRedirectUri() === 'https://example.com/' + && $c->getSecret() === bin2hex('MyHashedSecret') + && $c->getClientIdentifier() === 'MyClientIdentifier'; + }))->willReturnCallback(function (Client $c) { + $c->setId(42); + return $c; + }); + + $result = $this->settingsController->addClient('My Client Name', 'https://example.com/'); + $this->assertInstanceOf(JSONResponse::class, $result); + + $data = $result->getData(); + + $this->assertEquals([ + 'id' => 42, + 'name' => 'My Client Name', + 'redirectUri' => 'https://example.com/', + 'clientId' => 'MyClientIdentifier', + 'clientSecret' => 'MySecret', + ], $data); + } + + public function testDeleteClient(): void { + + $userManager = Server::get(IUserManager::class); + // count other users in the db before adding our own + $count = 0; + $function = function (IUser $user) use (&$count): void { + if ($user->getLastLogin() > 0) { + $count++; + } + }; + $userManager->callForAllUsers($function); + $user1 = $userManager->createUser('test101', 'test101'); + $user1->updateLastLoginTimestamp(); + $tokenProviderMock = $this->getMockBuilder(IAuthTokenProvider::class)->getMock(); + + // expect one call per user and ensure the correct client name + $tokenProviderMock + ->expects($this->exactly($count + 1)) + ->method('invalidateTokensOfUser') + ->with($this->isType('string'), 'My Client Name'); + + $client = new Client(); + $client->setId(123); + $client->setName('My Client Name'); + $client->setRedirectUri('https://example.com/'); + $client->setSecret(bin2hex('MyHashedSecret')); + $client->setClientIdentifier('MyClientIdentifier'); + + $this->clientMapper + ->method('getByUid') + ->with(123) + ->willReturn($client); + $this->accessTokenMapper + ->expects($this->once()) + ->method('deleteByClientId') + ->with(123); + $this->clientMapper + ->expects($this->once()) + ->method('delete') + ->with($client); + + $settingsController = new SettingsController( + 'oauth2', + $this->request, + $this->clientMapper, + $this->secureRandom, + $this->accessTokenMapper, + $this->l, + $tokenProviderMock, + $userManager, + $this->crypto + ); + + $result = $settingsController->deleteClient(123); + $this->assertInstanceOf(JSONResponse::class, $result); + $this->assertEquals([], $result->getData()); + + $user1->delete(); + } + + public function testInvalidRedirectUri(): void { + $result = $this->settingsController->addClient('test', 'invalidurl'); + + $this->assertEquals(Http::STATUS_BAD_REQUEST, $result->getStatus()); + $this->assertSame(['message' => 'Your redirect URL needs to be a full URL for example: https://yourdomain.com/path'], $result->getData()); + } +} |