]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add tests for ClientFlowLoginController
authorLukas Reschke <lukas@statuscode.ch>
Thu, 18 May 2017 14:31:14 +0000 (16:31 +0200)
committerLukas Reschke <lukas@statuscode.ch>
Thu, 18 May 2017 18:49:08 +0000 (20:49 +0200)
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
core/Controller/ClientFlowLoginController.php
tests/Core/Controller/ClientFlowLoginControllerTest.php

index cafcc16442a049d53197cccf27acdf1e075bc58b..bec81a89d53e06486e528d52d97297619e74b556 100644 (file)
@@ -109,7 +109,8 @@ class ClientFlowLoginController extends Controller {
         * @return string
         */
        private function getClientName() {
-               return $this->request->getHeader('USER_AGENT') !== null ? $this->request->getHeader('USER_AGENT') : 'unknown';
+               $userAgent = $this->request->getHeader('USER_AGENT');
+               return $userAgent !== null ? $userAgent : 'unknown';
        }
 
        /**
@@ -265,11 +266,10 @@ class ClientFlowLoginController extends Controller {
                }
 
                $clientName = $this->getClientName();
-               $oAuthClient = false;
+               $client = false;
                if($clientIdentifier !== '') {
                        $client = $this->clientMapper->getByIdentifier($clientIdentifier);
                        $clientName = $client->getName();
-                       $oAuthClient = true;
                }
 
                $token = $this->random->generate(72, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
@@ -284,9 +284,7 @@ class ClientFlowLoginController extends Controller {
                        IToken::DO_NOT_REMEMBER
                );
 
-               if($oAuthClient) {
-                       $client = $this->clientMapper->getByIdentifier($clientIdentifier);
-
+               if($client) {
                        $code = $this->random->generate(128);
                        $accessToken = new AccessToken();
                        $accessToken->setClientId($client->getId());
index 7a98e5c26c6a293f24b85bc9d29e36948827c9d3..1132c0f540cd519159c15198c5a2563678ec39fd 100644 (file)
@@ -26,6 +26,9 @@ use OC\Authentication\Exceptions\PasswordlessTokenException;
 use OC\Authentication\Token\IProvider;
 use OC\Authentication\Token\IToken;
 use OC\Core\Controller\ClientFlowLoginController;
+use OCA\OAuth2\Db\AccessTokenMapper;
+use OCA\OAuth2\Db\Client;
+use OCA\OAuth2\Db\ClientMapper;
 use OCP\AppFramework\Http;
 use OCP\AppFramework\Http\TemplateResponse;
 use OCP\Defaults;
@@ -35,6 +38,7 @@ use OCP\ISession;
 use OCP\IURLGenerator;
 use OCP\IUser;
 use OCP\IUserSession;
+use OCP\Security\ICrypto;
 use OCP\Security\ISecureRandom;
 use OCP\Session\Exceptions\SessionNotAvailableException;
 use Test\TestCase;
@@ -56,6 +60,13 @@ class ClientFlowLoginControllerTest extends TestCase {
        private $random;
        /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
        private $urlGenerator;
+       /** @var ClientMapper|\PHPUnit_Framework_MockObject_MockObject */
+       private $clientMapper;
+       /** @var AccessTokenMapper|\PHPUnit_Framework_MockObject_MockObject */
+       private $accessTokenMapper;
+       /** @var ICrypto|\PHPUnit_Framework_MockObject_MockObject */
+       private $crypto;
+
        /** @var ClientFlowLoginController */
        private $clientFlowLoginController;
 
@@ -76,6 +87,9 @@ class ClientFlowLoginControllerTest extends TestCase {
                $this->tokenProvider = $this->createMock(IProvider::class);
                $this->random = $this->createMock(ISecureRandom::class);
                $this->urlGenerator = $this->createMock(IURLGenerator::class);
+               $this->clientMapper = $this->createMock(ClientMapper::class);
+               $this->accessTokenMapper = $this->createMock(AccessTokenMapper::class);
+               $this->crypto = $this->createMock(ICrypto::class);
 
                $this->clientFlowLoginController = new ClientFlowLoginController(
                        'core',
@@ -86,32 +100,43 @@ class ClientFlowLoginControllerTest extends TestCase {
                        $this->session,
                        $this->tokenProvider,
                        $this->random,
-                       $this->urlGenerator
+                       $this->urlGenerator,
+                       $this->clientMapper,
+                       $this->accessTokenMapper,
+                       $this->crypto
                );
        }
 
-       public function testShowAuthPickerPageNotAuthenticated() {
-               $this->userSession
-                       ->expects($this->once())
-                       ->method('isLoggedIn')
-                       ->willReturn(true);
-
+       public function testShowAuthPickerPageNoClientOrOauthRequest() {
                $expected = new TemplateResponse(
                        'core',
-                       '403',
+                       'error',
                        [
-                               'file' => 'Auth flow can only be started unauthenticated.',
+                               'errors' =>
+                                       [
+                                               [
+                                                       'error' => 'Access Forbidden',
+                                                       'hint' => 'Invalid request',
+                                               ],
+                                       ],
                        ],
                        'guest'
                );
+
                $this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage());
        }
 
-       public function testShowAuthPickerPage() {
-               $this->userSession
-                       ->expects($this->once())
-                       ->method('isLoggedIn')
-                       ->willReturn(false);
+       public function testShowAuthPickerPageWithOcsHeader() {
+               $this->request
+                       ->expects($this->at(0))
+                       ->method('getHeader')
+                       ->with('USER_AGENT')
+                       ->willReturn('Mac OS X Sync Client');
+               $this->request
+                       ->expects($this->at(1))
+                       ->method('getHeader')
+                       ->with('OCS-APIREQUEST')
+                       ->willReturn('true');
                $this->random
                        ->expects($this->once())
                        ->method('generate')
@@ -124,11 +149,56 @@ class ClientFlowLoginControllerTest extends TestCase {
                        ->expects($this->once())
                        ->method('set')
                        ->with('client.flow.state.token', 'StateToken');
+               $this->defaults
+                       ->expects($this->once())
+                       ->method('getName')
+                       ->willReturn('ExampleCloud');
+               $this->request
+                       ->expects($this->once())
+                       ->method('getServerHost')
+                       ->willReturn('example.com');
+
+               $expected = new TemplateResponse(
+                       'core',
+                       'loginflow/authpicker',
+                       [
+                               'client' => 'Mac OS X Sync Client',
+                               'clientIdentifier' => '',
+                               'instanceName' => 'ExampleCloud',
+                               'urlGenerator' => $this->urlGenerator,
+                               'stateToken' => 'StateToken',
+                               'serverHost' => 'example.com',
+                       ],
+                       'guest'
+               );
+               $this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage());
+       }
+
+       public function testShowAuthPickerPageWithOauth() {
                $this->request
-                       ->expects($this->exactly(2))
+                       ->expects($this->at(0))
                        ->method('getHeader')
                        ->with('USER_AGENT')
                        ->willReturn('Mac OS X Sync Client');
+               $client = new Client();
+               $client->setName('My external service');
+               $this->clientMapper
+                       ->expects($this->once())
+                       ->method('getByIdentifier')
+                       ->with('MyClientIdentifier')
+                       ->willReturn($client);
+               $this->random
+                       ->expects($this->once())
+                       ->method('generate')
+                       ->with(
+                               64,
+                               ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS
+                       )
+                       ->willReturn('StateToken');
+               $this->session
+                       ->expects($this->once())
+                       ->method('set')
+                       ->with('client.flow.state.token', 'StateToken');
                $this->defaults
                        ->expects($this->once())
                        ->method('getName')
@@ -142,7 +212,8 @@ class ClientFlowLoginControllerTest extends TestCase {
                        'core',
                        'loginflow/authpicker',
                        [
-                               'client' => 'Mac OS X Sync Client',
+                               'client' => 'My external service',
+                               'clientIdentifier' => 'MyClientIdentifier',
                                'instanceName' => 'ExampleCloud',
                                'urlGenerator' => $this->urlGenerator,
                                'stateToken' => 'StateToken',
@@ -150,7 +221,7 @@ class ClientFlowLoginControllerTest extends TestCase {
                        ],
                        'guest'
                );
-               $this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage());
+               $this->assertEquals($expected, $this->clientFlowLoginController->showAuthPickerPage('MyClientIdentifier'));
        }
 
        public function testRedirectPageWithInvalidToken() {
@@ -193,10 +264,15 @@ class ClientFlowLoginControllerTest extends TestCase {
 
        public function testRedirectPage() {
                $this->session
-                       ->expects($this->once())
+                       ->expects($this->at(0))
                        ->method('get')
                        ->with('client.flow.state.token')
                        ->willReturn('MyStateToken');
+               $this->session
+                       ->expects($this->at(1))
+                       ->method('get')
+                       ->with('oauth.state')
+                       ->willReturn('MyOauthStateToken');
 
                $expected = new TemplateResponse(
                        'core',
@@ -204,10 +280,12 @@ class ClientFlowLoginControllerTest extends TestCase {
                        [
                                'urlGenerator' => $this->urlGenerator,
                                'stateToken' => 'MyStateToken',
+                               'clientIdentifier' => 'Identifier',
+                               'oauthState' => 'MyOauthStateToken',
                        ],
                        'empty'
                );
-               $this->assertEquals($expected, $this->clientFlowLoginController->redirectPage('MyStateToken'));
+               $this->assertEquals($expected, $this->clientFlowLoginController->redirectPage('MyStateToken', 'Identifier'));
        }
 
        public function testGenerateAppPasswordWithInvalidToken() {
@@ -342,6 +420,90 @@ class ClientFlowLoginControllerTest extends TestCase {
                $this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken'));
        }
 
+       public function testGeneratePasswordWithPasswordForOauthClient() {
+               $this->session
+                       ->expects($this->at(0))
+                       ->method('get')
+                       ->with('client.flow.state.token')
+                       ->willReturn('MyStateToken');
+               $this->session
+                       ->expects($this->at(1))
+                       ->method('remove')
+                       ->with('client.flow.state.token');
+               $this->session
+                       ->expects($this->at(3))
+                       ->method('get')
+                       ->with('oauth.state')
+                       ->willReturn('MyOauthState');
+               $this->session
+                       ->expects($this->at(4))
+                       ->method('remove')
+                       ->with('oauth.state');
+               $this->session
+                       ->expects($this->once())
+                       ->method('getId')
+                       ->willReturn('SessionId');
+               $myToken = $this->createMock(IToken::class);
+               $myToken
+                       ->expects($this->once())
+                       ->method('getLoginName')
+                       ->willReturn('MyLoginName');
+               $this->tokenProvider
+                       ->expects($this->once())
+                       ->method('getToken')
+                       ->with('SessionId')
+                       ->willReturn($myToken);
+               $this->tokenProvider
+                       ->expects($this->once())
+                       ->method('getPassword')
+                       ->with($myToken, 'SessionId')
+                       ->willReturn('MyPassword');
+               $this->random
+                       ->expects($this->at(0))
+                       ->method('generate')
+                       ->with(72)
+                       ->willReturn('MyGeneratedToken');
+               $this->random
+                       ->expects($this->at(1))
+                       ->method('generate')
+                       ->with(128)
+                       ->willReturn('MyAccessCode');
+               $user = $this->createMock(IUser::class);
+               $user
+                       ->expects($this->once())
+                       ->method('getUID')
+                       ->willReturn('MyUid');
+               $this->userSession
+                       ->expects($this->once())
+                       ->method('getUser')
+                       ->willReturn($user);
+               $token = $this->createMock(IToken::class);
+               $this->tokenProvider
+                       ->expects($this->once())
+                       ->method('generateToken')
+                       ->with(
+                               'MyGeneratedToken',
+                               'MyUid',
+                               'MyLoginName',
+                               'MyPassword',
+                               'My OAuth client',
+                               IToken::PERMANENT_TOKEN,
+                               IToken::DO_NOT_REMEMBER
+                       )
+                       ->willReturn($token);
+               $client = new Client();
+               $client->setName('My OAuth client');
+               $client->setRedirectUri('https://example.com/redirect.php');
+               $this->clientMapper
+                       ->expects($this->once())
+                       ->method('getByIdentifier')
+                       ->with('MyClientIdentifier')
+                       ->willReturn($client);
+
+               $expected = new Http\RedirectResponse('https://example.com/redirect.php?state=MyOauthState&code=MyAccessCode');
+               $this->assertEquals($expected, $this->clientFlowLoginController->generateAppPassword('MyStateToken', 'MyClientIdentifier'));
+       }
+
        public function testGeneratePasswordWithoutPassword() {
                $this->session
                        ->expects($this->once())