From 178d45cabfa55cd3dd31e66e3d937ecc4949b627 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 13 Jan 2020 17:15:52 +0200 Subject: [PATCH] New OAuth e2e test --- app/controllers/api/account.php | 4 +- app/controllers/mock.php | 35 ++++++++++++++--- src/Auth/OAuth/Mock.php | 8 ++-- tests/e2e/Client.php | 1 + .../Account/AccountCustomClientTest.php | 38 +++++++++++++++++++ tests/e2e/Services/Health/HealthBase.php | 2 +- 6 files changed, 77 insertions(+), 11 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ea5597037..81936f730 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -500,7 +500,7 @@ $utopia->get('/v1/account/sessions/oauth/:provider/redirect') if (!empty($state['failure']) && !$validateURL->isValid($state['failure'])) { throw new Exception('Invalid redirect URL for failure login', 400); } - + $state['failure'] = null; $accessToken = $oauth->getAccessToken($code); if (empty($accessToken)) { @@ -512,7 +512,7 @@ $utopia->get('/v1/account/sessions/oauth/:provider/redirect') } $oauthID = $oauth->getUserID($accessToken); - + if (empty($oauthID)) { if (!empty($state['failure'])) { $response->redirect($state['failure'], 301, 0); diff --git a/app/controllers/mock.php b/app/controllers/mock.php index 0ee8b5401..89d1d448d 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -6,6 +6,7 @@ use Utopia\Validator\Numeric; use Utopia\Validator\Text; use Utopia\Validator\ArrayList; use Storage\Validators\File; +use Utopia\Response; use Utopia\Validator\Host; $result = []; @@ -219,17 +220,17 @@ $utopia->get('/v1/mock/tests/general/empty') } ); -$utopia->get('/v1/mock/tests/general/oauth/login') +$utopia->get('/v1/mock/tests/general/oauth') ->desc('Mock an OAuth login route') ->label('scope', 'public') ->label('docs', false) ->param('client_id', '', function () { return new Text(100); }, 'OAuth Client ID.') ->param('redirect_uri', '', function () { return new Host(['http://localhost']); }, 'OAuth Redirect URI.') // Important to deny an open redirect attack ->param('scope', '', function () { return new Text(100); }, 'OAuth scope list.') - ->param('state', '', function () { return new Text(100); }, 'OAuth state.') + ->param('state', '', function () { return new Text(1024); }, 'OAuth state.') ->action( function ($clientId, $redirectURI, $scope, $state) use ($response) { - $response->redirect($redirectURI); + $response->redirect($redirectURI.'?'.http_build_query(['code' => 'abcdef', 'state' => $state])); } ); @@ -247,7 +248,7 @@ $utopia->get('/v1/mock/tests/general/oauth/token') throw new Exception('Invalid client ID'); } - if($clientSecret != 'secret') { + if($clientSecret != '123456') { throw new Exception('Invalid client secret'); } @@ -273,11 +274,35 @@ $utopia->get('/v1/mock/tests/general/oauth/user') $response->json([ 'id' => 1, 'name' => 'User Name', - 'email' => 'user@localhost', + 'email' => 'user@localhost.test', ]); } ); +$utopia->get('/v1/mock/tests/general/oauth/success') + ->label('scope', 'public') + ->label('docs', false) + ->action( + function () use ($response) { + $response->json([ + 'result' => 'success', + ]); + } + ); + +$utopia->get('/v1/mock/tests/general/oauth/failure') + ->label('scope', 'public') + ->label('docs', false) + ->action( + function () use ($response) { + $response + ->setStatusCode(Response::STATUS_CODE_BAD_REQUEST) + ->json([ + 'result' => 'failure', + ]); + } + ); + $utopia->shutdown(function() use ($response, $request, &$result, $utopia) { $route = $utopia->match($request); diff --git a/src/Auth/OAuth/Mock.php b/src/Auth/OAuth/Mock.php index 004836e0e..e374694df 100644 --- a/src/Auth/OAuth/Mock.php +++ b/src/Auth/OAuth/Mock.php @@ -29,7 +29,7 @@ class Mock extends OAuth */ public function getLoginURL():string { - return 'http://localhost/'.$this->version.'/oauth?client_id='.urlencode($this->appID).'&redirect_uri='.urlencode($this->callback).'&scope=email&state='.urlencode(json_encode($this->state)); + return 'http://localhost/'.$this->version.'/mock/tests/general/oauth?client_id='.urlencode($this->appID).'&redirect_uri='.urlencode($this->callback).'&scope=email&state='.urlencode(json_encode($this->state)); } /** @@ -41,13 +41,15 @@ class Mock extends OAuth { $accessToken = $this->request( 'GET', - 'http://localhost/'.$this->version.'/oauth/token?'. + 'http://localhost/'.$this->version.'/mock/tests/general/oauth/token?'. 'client_id='.urlencode($this->appID). '&redirect_uri='.urlencode($this->callback). '&client_secret='.urlencode($this->appSecret). '&code='.urlencode($code) ); + var_dump($this->appSecret); + var_dump($accessToken); $accessToken = json_decode($accessToken, true); // if (isset($accessToken['access_token'])) { @@ -113,7 +115,7 @@ class Mock extends OAuth protected function getUser(string $accessToken):array { if (empty($this->user)) { - $user = $this->request('GET', 'http://localhost/'.$this->version.'/oauth/user?token='.urlencode($accessToken)); + $user = $this->request('GET', 'http://localhost/'.$this->version.'/mock/tests/general/oauth/user?token='.urlencode($accessToken)); $this->user = json_decode($user, true); } diff --git a/tests/e2e/Client.php b/tests/e2e/Client.php index 4511f78c9..5a84716b5 100644 --- a/tests/e2e/Client.php +++ b/tests/e2e/Client.php @@ -184,6 +184,7 @@ class Client curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) { diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index a2f615a16..a0e600e90 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -2,6 +2,7 @@ namespace Tests\E2E\Services\Account; +use Tests\E2E\Client; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\SideClient; @@ -11,4 +12,41 @@ class AccountCustomClientTest extends Scope use AccountBase; use ProjectCustom; use SideClient; + + public function testCreateOAuthAccountSession():array + { + $provider = 'mock'; + $appId = '1'; + $secret = '123456'; + + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/'.$this->getProject()['$uid'].'/oauth', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => 'console', + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'provider' => $provider, + 'appId' => $appId, + 'secret' => $secret, + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + + $response = $this->client->call(Client::METHOD_GET, '/account/sessions/oauth/'.$provider, array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$uid'], + ]), [ + 'success' => 'http://localhost/v1/mock/tests/general/oauth/success', + 'failure' => 'http://localhost/v1/mock/tests/general/oauth/failure', + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('success', $response['body']['result']); + + return []; + } } \ No newline at end of file diff --git a/tests/e2e/Services/Health/HealthBase.php b/tests/e2e/Services/Health/HealthBase.php index e579f4680..c4b730745 100644 --- a/tests/e2e/Services/Health/HealthBase.php +++ b/tests/e2e/Services/Health/HealthBase.php @@ -102,7 +102,7 @@ trait HealthBase $this->assertEquals(200, $response['headers']['status-code']); $this->assertIsInt($response['body']['size']); - $this->assertLessThan(10, $response['body']['size']); + $this->assertLessThan(50, $response['body']['size']); /** * Test for FAILURE