From c5444c828ffa6938be4e0f9901fb2f7a970e9aeb Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 13 Jan 2020 10:48:37 +0200 Subject: [PATCH 1/6] Fix for OAuth issues --- app/controllers/auth.php | 2 -- app/controllers/shared/api.php | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/controllers/auth.php b/app/controllers/auth.php index 83afc8e3e..0c8bbab20 100644 --- a/app/controllers/auth.php +++ b/app/controllers/auth.php @@ -433,8 +433,6 @@ $utopia->get('/v1/auth/login/oauth/callback/:provider/:projectId') ->desc('OAuth Callback') ->label('error', __DIR__.'/../views/general/error.phtml') ->label('scope', 'auth') - ->label('abuse-limit', 50) - ->label('abuse-key', 'ip:{ip}') ->label('docs', false) ->param('projectId', '', function () { return new Text(1024); }, 'Project unique ID') ->param('provider', '', function () use ($providers) { return new WhiteList(array_keys($providers)); }, 'OAuth provider') diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 020f8d9ad..fef57029c 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -8,9 +8,9 @@ use Database\Database; global $utopia, $request, $response, $register, $user, $project; $utopia->init(function () use ($utopia, $request, $response, $register, $user, $project) { - if (is_null($project->getUid()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) { - throw new Exception('Missing Project UID', 400); - } + // if (is_null($project->getUid()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) { + // throw new Exception('Missing Project UID', 400); + // } $route = $utopia->match($request); From 2f125196e4de712d50faa8f67caae29f52ae1127 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 13 Jan 2020 14:23:39 +0200 Subject: [PATCH 2/6] Added mock OAuth adapter --- src/Auth/OAuth/Mock.php | 123 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/Auth/OAuth/Mock.php diff --git a/src/Auth/OAuth/Mock.php b/src/Auth/OAuth/Mock.php new file mode 100644 index 000000000..004836e0e --- /dev/null +++ b/src/Auth/OAuth/Mock.php @@ -0,0 +1,123 @@ +version.'/oauth?client_id='.urlencode($this->appID).'&redirect_uri='.urlencode($this->callback).'&scope=email&state='.urlencode(json_encode($this->state)); + } + + /** + * @param string $code + * + * @return string + */ + public function getAccessToken(string $code):string + { + $accessToken = $this->request( + 'GET', + 'http://localhost/'.$this->version.'/oauth/token?'. + 'client_id='.urlencode($this->appID). + '&redirect_uri='.urlencode($this->callback). + '&client_secret='.urlencode($this->appSecret). + '&code='.urlencode($code) + ); + + $accessToken = json_decode($accessToken, true); // + + if (isset($accessToken['access_token'])) { + return $accessToken['access_token']; + } + + return ''; + } + + /** + * @param string $accessToken + * + * @return string + */ + public function getUserID(string $accessToken):string + { + $user = $this->getUser($accessToken); + + if (isset($user['id'])) { + return $user['id']; + } + + return ''; + } + + /** + * @param string $accessToken + * + * @return string + */ + public function getUserEmail(string $accessToken):string + { + $user = $this->getUser($accessToken); + + if (isset($user['email'])) { + return $user['email']; + } + + return ''; + } + + /** + * @param string $accessToken + * + * @return string + */ + public function getUserName(string $accessToken):string + { + $user = $this->getUser($accessToken); + + if (isset($user['name'])) { + return $user['name']; + } + + return ''; + } + + /** + * @param string $accessToken + * + * @return array + */ + protected function getUser(string $accessToken):array + { + if (empty($this->user)) { + $user = $this->request('GET', 'http://localhost/'.$this->version.'/oauth/user?token='.urlencode($accessToken)); + + $this->user = json_decode($user, true); + } + + return $this->user; + } +} \ No newline at end of file From 8b8d31113579223cfd04a7c62ac64284ed158083 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 13 Jan 2020 14:23:45 +0200 Subject: [PATCH 3/6] Added mock OAuth server --- app/controllers/mock.php | 68 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/app/controllers/mock.php b/app/controllers/mock.php index 9fbcbc1dd..b9e9c5a06 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\Validator\Host; $result = []; @@ -218,6 +219,73 @@ $utopia->get('/v1/mock/tests/general/empty') } ); + $utopia->get('/v1/mock/tests/general/oauth/login') + ->desc('Mock an OAuth login route') + ->label('scope', 'public') + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'empty') + ->label('sdk.description', 'Mock an OAuth login route') + ->param('client_id', '', function () { return new Text(100); }, 'OAuth Client ID.') + ->param('redirect_uri', '', function () { return new Host(['http://localhost']); }, 'OAuth Redirect URI.') + ->param('scope', '', function () { return new Text(100); }, 'OAuth scope list.') + ->param('state', '', function () { return new Text(100); }, 'OAuth state.') + ->action( + function ($clientId, $redirectURI, $scope, $state) use ($response) { + var_dump($clientId, $redirectURI, $scope, $state); + exit(); + $response->redirect(''); + } + ); + +$utopia->get('/v1/mock/tests/general/oauth/token') + ->desc('Mock an OAuth login route') + ->label('scope', 'public') + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'empty') + ->label('sdk.description', 'Mock an OAuth login route') + ->param('client_id', '', function () { return new Text(100); }, 'OAuth Client ID.') + ->param('redirect_uri', '', function () { return new Host(['http://localhost']); }, 'OAuth Redirect URI.') + ->param('client_secret', '', function () { return new Text(100); }, 'OAuth scope list.') + ->param('code', '', function () { return new Text(100); }, 'OAuth state.') + ->action( + function ($clientId, $redirectURI, $clientSecret, $code) use ($response) { + if($clientId != '1') { + throw new Exception('Invalid client ID'); + } + + if($clientSecret != 'secret') { + throw new Exception('Invalid client secret'); + } + + if($code != 'abcdef') { + throw new Exception('Invalid token'); + } + + $response->json(['access_token' => '123456']); + } + ); + +$utopia->get('/v1/mock/tests/general/oauth/user') + ->desc('Mock an OAuth user route') + ->label('scope', 'public') + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'empty') + ->label('sdk.description', 'Mock an OAuth user route') + ->param('token', '', function () { return new Text(100); }, 'OAuth Access Token.') + ->action( + function ($token) use ($response) { + if($token != '123456') { + throw new Exception('Invalid token'); + } + + $response->json([ + 'id' => 1, + 'name' => 'User Name', + 'email' => 'user@localhost', + ]); + } + ); + $utopia->shutdown(function() use ($response, $request, &$result, $utopia) { $route = $utopia->match($request); From 127a29879f55ab41a7c5b27fece3b265ca1b75d8 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 13 Jan 2020 14:31:23 +0200 Subject: [PATCH 4/6] Updated OAuth providers list --- app/config/providers.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/app/config/providers.php b/app/config/providers.php index 62b8c0a8d..85d2326d5 100644 --- a/app/config/providers.php +++ b/app/config/providers.php @@ -5,70 +5,92 @@ return [ 'developers' => 'https://developer.atlassian.com/bitbucket', 'icon' => 'icon-bitbucket', 'enabled' => true, + 'mock' => false, ], 'facebook' => [ 'developers' => 'https://developers.facebook.com/', 'icon' => 'icon-facebook', 'enabled' => true, + 'mock' => false, ], 'github' => [ 'developers' => 'https://developer.github.com/', 'icon' => 'icon-github-circled', 'enabled' => true, + 'mock' => false, ], 'gitlab' => [ 'developers' => 'https://docs.gitlab.com/ee/api/', 'icon' => 'icon-gitlab', 'enabled' => true, + 'mock' => false, ], 'google' => [ 'developers' => 'https://developers.google.com/', 'icon' => 'icon-google', 'enabled' => true, + 'mock' => false, ], // 'instagram' => [ // 'developers' => 'https://www.instagram.com/developer/', // 'icon' => 'icon-instagram', // 'enabled' => false, + // 'mock' => false, // ], 'microsoft' => [ 'developers' => 'https://developer.microsoft.com/en-us/', 'icon' => 'icon-windows', 'enabled' => true, + 'mock' => false, ], // 'twitter' => [ // 'developers' => 'https://developer.twitter.com/', // 'icon' => 'icon-twitter', // 'enabled' => false, + // 'mock' => false, // ], 'linkedin' => [ 'developers' => 'https://developer.linkedin.com/', 'icon' => 'icon-linkedin', 'enabled' => true, + 'mock' => false, ], 'slack' => [ 'developers' => 'https://api.slack.com/', 'icon' => 'icon-slack', 'enabled' => true, + 'mock' => false, ], 'dropbox' => [ 'developers' => 'https://www.dropbox.com/developers/documentation', 'icon' => 'icon-dropbox', 'enabled' => true, + 'mock' => false, ], // 'apple' => [ // 'developers' => 'https://developer.apple.com/', // 'icon' => 'icon-apple', // 'enabled' => false, + // 'mock' => false, // ], 'amazon' => [ 'developers' => 'https://developer.amazon.com/apps-and-games/services-and-apis', 'icon' => 'icon-amazon', 'enabled' => true, + 'mock' => false, ], 'vk' => [ 'developers' => 'https://vk.com/dev', 'icon' => 'icon-vk', 'enabled' => true, + 'mock' => false, + ], + + // Keep Last + 'mock' => [ + 'developers' => 'https://appwrite.io', + 'icon' => 'icon-appwrite', + 'enabled' => true, + 'mock' => true, ], ]; From 00e18551b172d587693d9b49b29b72a16ad0e04b Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 13 Jan 2020 14:40:10 +0200 Subject: [PATCH 5/6] Updated OAuth mock server --- app/controllers/mock.php | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/app/controllers/mock.php b/app/controllers/mock.php index b9e9c5a06..0ee8b5401 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -219,30 +219,24 @@ $utopia->get('/v1/mock/tests/general/empty') } ); - $utopia->get('/v1/mock/tests/general/oauth/login') +$utopia->get('/v1/mock/tests/general/oauth/login') ->desc('Mock an OAuth login route') ->label('scope', 'public') - ->label('sdk.namespace', 'general') - ->label('sdk.method', 'empty') - ->label('sdk.description', 'Mock an OAuth login route') + ->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.') + ->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.') ->action( function ($clientId, $redirectURI, $scope, $state) use ($response) { - var_dump($clientId, $redirectURI, $scope, $state); - exit(); - $response->redirect(''); + $response->redirect($redirectURI); } ); $utopia->get('/v1/mock/tests/general/oauth/token') ->desc('Mock an OAuth login route') ->label('scope', 'public') - ->label('sdk.namespace', 'general') - ->label('sdk.method', 'empty') - ->label('sdk.description', 'Mock an OAuth login route') + ->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.') ->param('client_secret', '', function () { return new Text(100); }, 'OAuth scope list.') @@ -268,9 +262,7 @@ $utopia->get('/v1/mock/tests/general/oauth/token') $utopia->get('/v1/mock/tests/general/oauth/user') ->desc('Mock an OAuth user route') ->label('scope', 'public') - ->label('sdk.namespace', 'general') - ->label('sdk.method', 'empty') - ->label('sdk.description', 'Mock an OAuth user route') + ->label('docs', false) ->param('token', '', function () { return new Text(100); }, 'OAuth Access Token.') ->action( function ($token) use ($response) { From 0a7889ac84d9e1122c24ad611b3d859f74a78bb4 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Mon, 13 Jan 2020 14:43:00 +0200 Subject: [PATCH 6/6] Hide mock OAuth server from the UI --- app/views/console/users/index.phtml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/console/users/index.phtml b/app/views/console/users/index.phtml index f16b9df45..0ed2630e9 100644 --- a/app/views/console/users/index.phtml +++ b/app/views/console/users/index.phtml @@ -318,7 +318,10 @@ $providers = $this->getParam('providers', []); data-param-project-id="{{router.params.project}}" data-scope="console">
    - $data): if (isset($data['enabled']) && !$data['enabled']) { continue; } ?> + $data): + if (isset($data['enabled']) && !$data['enabled']) { continue; } + if (isset($data['mock']) && $data['mock']) { continue; } + ?>