1
0
Fork 0
mirror of synced 2024-07-07 23:46:11 +12:00

Merge remote-tracking branch 'origin/master' into feat-graphql-support

This commit is contained in:
Jake Barnby 2022-05-02 21:34:25 +12:00
commit 0c497f2600
No known key found for this signature in database
GPG key ID: A4674EBC0E404657
10 changed files with 502 additions and 27 deletions

View file

@ -21,6 +21,16 @@ return [ // Ordered by ABC.
'beta' => true,
'mock' => false,
],
'auth0' => [
'name' => 'Auth0',
'developers' => 'https://auth0.com/developers',
'icon' => 'icon-auth0',
'enabled' => true,
'sandbox' => false,
'form' => 'auth0.phtml',
'beta' => false,
'mock' => false,
],
'bitbucket' => [
'name' => 'BitBucket',
'developers' => 'https://developer.atlassian.com/bitbucket',
@ -141,6 +151,16 @@ return [ // Ordered by ABC.
'beta' => false,
'mock' => false,
],
'okta' => [
'name' => 'Okta',
'developers' => 'https://developer.okta.com/',
'icon' => 'icon-okta',
'enabled' => true,
'sandbox' => false,
'form' => 'okta.phtml',
'beta' => false,
'mock' => false,
],
'paypal' => [
'name' => 'PayPal',
'developers' => 'https://developer.paypal.com/docs/api/overview/',

View file

@ -1,9 +1,12 @@
<?php
use Utopia\Database\Document;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Request;
use MaxMind\Db\Reader;
use Utopia\App;
use Utopia\Config\Config;
use Utopia\Database\Document;
use Utopia\Locale\Locale;
App::get('/v1/locale')
->desc('Get User Locale')
@ -20,12 +23,8 @@ App::get('/v1/locale')
->inject('response')
->inject('locale')
->inject('geodb')
->action(function ($request, $response, $locale, $geodb) {
/** @var Appwrite\Utopia\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
->action(function (Request $request, Response $response, Locale $locale, Reader $geodb) {
$eu = Config::getParam('locale-eu');
$currencies = Config::getParam('locale-currencies');
$output = [];
@ -82,10 +81,8 @@ App::get('/v1/locale/countries')
->label('sdk.response.model', Response::MODEL_COUNTRY_LIST)
->inject('response')
->inject('locale')
->action(function ($response, $locale) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */
->action(function (Response $response, Locale $locale) {
$list = Config::getParam('locale-countries'); /* @var $list array */
$output = [];
@ -116,9 +113,7 @@ App::get('/v1/locale/countries/eu')
->label('sdk.response.model', Response::MODEL_COUNTRY_LIST)
->inject('response')
->inject('locale')
->action(function ($response, $locale) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */
->action(function (Response $response, Locale $locale) {
$eu = Config::getParam('locale-eu');
$output = [];
@ -152,10 +147,8 @@ App::get('/v1/locale/countries/phones')
->label('sdk.response.model', Response::MODEL_PHONE_LIST)
->inject('response')
->inject('locale')
->action(function ($response, $locale) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */
->action(function (Response $response, Locale $locale) {
$list = Config::getParam('locale-phones'); /* @var $list array */
$output = [];
@ -187,9 +180,7 @@ App::get('/v1/locale/continents')
->label('sdk.response.model', Response::MODEL_CONTINENT_LIST)
->inject('response')
->inject('locale')
->action(function ($response, $locale) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */
->action(function (Response $response, Locale $locale) {
$list = Config::getParam('locale-continents'); /* @var $list array */
@ -219,8 +210,7 @@ App::get('/v1/locale/currencies')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_CURRENCY_LIST)
->inject('response')
->action(function ($response) {
/** @var Appwrite\Utopia\Response $response */
->action(function (Response $response) {
$list = Config::getParam('locale-currencies');
@ -242,8 +232,7 @@ App::get('/v1/locale/languages')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_LANGUAGE_LIST)
->inject('response')
->action(function ($response) {
/** @var Appwrite\Utopia\Response $response */
->action(function (Response $response) {
$list = Config::getParam('locale-languages');

View file

@ -0,0 +1,12 @@
<?php
$provider = $this->getParam('provider', '');
?>
<label for="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Appid">Client ID<span class="tooltip" data-tooltip="Provided by Auth0"><i class="icon-info-circled"></i></span></label>
<input name="appId" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Appid" type="text" autocomplete="off" data-ls-bind="{{console-project.provider<?php echo $this->escape(ucfirst($provider)); ?>Appid}}" placeholder="Client ID" />
<label for="oauth2<?php echo $this->escape(ucfirst($provider)); ?>ClientSecret">Client Secret <span class="tooltip" data-tooltip="Provided in the Application you created in Auth0"><i class="icon-info-circled"></i></span></label>
<input name="clientSecret" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>ClientSecret" type="password" autocomplete="off" placeholder="Client Secret" />
<label for="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Domain">Auth0 Domain<span class="tooltip" data-tooltip="Your Auth0 Domain (without 'https://')"><i class="icon-info-circled"></i></span></label>
<input name="auth0Domain" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Domain" type="text" autocomplete="off" placeholder="YOUR_DOMAIN" />
<?php /*Hidden input for the final secret. Gets filled with a JSON via JS. */ ?>
<input name="secret" data-forms-oauth-custom="<?php echo $this->escape(ucfirst($provider)); ?>" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Secret" type="hidden" autocomplete="off" data-ls-bind="{{console-project.provider<?php echo $this->escape(ucfirst($provider)); ?>Secret}}" />

View file

@ -0,0 +1,14 @@
<?php
$provider = $this->getParam('provider', '');
?>
<label for="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Appid">Client ID<span class="tooltip" data-tooltip="Provided by Okta"><i class="icon-info-circled"></i></span></label>
<input name="appId" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Appid" type="text" autocomplete="off" data-ls-bind="{{console-project.provider<?php echo $this->escape(ucfirst($provider)); ?>Appid}}" placeholder="Client ID" />
<label for="oauth2<?php echo $this->escape(ucfirst($provider)); ?>ClientSecret">Client Secret <span class="tooltip" data-tooltip="Provided in the Application you created in Okta"><i class="icon-info-circled"></i></span></label>
<input name="clientSecret" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>ClientSecret" type="password" autocomplete="off" placeholder="Client Secret" />
<label for="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Domain">Okta Domain<span class="tooltip" data-tooltip="Your Okta Domain (without 'https://')"><i class="icon-info-circled"></i></span></label>
<input name="oktaDomain" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Domain" type="text" autocomplete="off" placeholder="dev-1337.okta.com" />
<label for="oauth2<?php echo $this->escape(ucfirst($provider)); ?>AuthorizationServerId">Authorization Server ID<span class="tooltip" data-tooltip="Authorization Server ID for custom authorization servers"><i class="icon-info-circled"></i></span></label>
<input name="authorizationServerId" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>AuthorizationServerId" type="text" autocomplete="off" placeholder="default" />
<?php /*Hidden input for the final secret. Gets filled with a JSON via JS. */ ?>
<input name="secret" data-forms-oauth-custom="<?php echo $this->escape(ucfirst($provider)); ?>" id="oauth2<?php echo $this->escape(ucfirst($provider)); ?>Secret" type="hidden" autocomplete="off" data-ls-bind="{{console-project.provider<?php echo $this->escape(ucfirst($provider)); ?>Secret}}" />

View file

@ -1,7 +1,7 @@
## Getting Started
### Init your SDK
Initialize your SDK with your Appwrite server API endpoint and project ID which can be found in your project settings page and your new API secret Key from project's API keys section.
Initialize your SDK with your Appwrite server API endpoint and project ID which can be found on your project settings page and your new API secret Key from project's API keys section.
```python
from appwrite.client import Client

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View file

@ -16,10 +16,19 @@
"keyID": "oauth2AppleKeyId",
"teamID": "oauth2AppleTeamId",
"p8": "oauth2AppleP8"
},
"Okta": {
"clientSecret": "oauth2OktaClientSecret",
"oktaDomain": "oauth2OktaDomain",
"authorizationServerId": "oauth2OktaAuthorizationServerId"
},
"Auth0": {
"clientSecret": "oauth2Auth0ClientSecret",
"auth0Domain": "oauth2Auth0Domain"
}
}
let provider = element.getAttribute("data-forms-oauth-custom");
if (!provider || !providers.hasOwnProperty(provider)) { console.error("Provider for custom form not set or unkown") }
if (!provider || !providers.hasOwnProperty(provider)) { console.error("Provider for custom form not set or unknown") }
let config = providers[provider];
// Add Change Listeners for element

View file

@ -0,0 +1,210 @@
<?php
namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2;
// Reference Material
// https://auth0.com/docs/api/authentication
class Auth0 extends OAuth2
{
/**
* @var array
*/
protected $scopes = [
'openid',
'profile',
'email',
'offline_access'
];
/**
* @var array
*/
protected $user = [];
/**
* @var array
*/
protected $tokens = [];
/**
* @return string
*/
public function getName(): string
{
return 'auth0';
}
/**
* @return string
*/
public function getLoginURL(): string
{
return 'https://'.$this->getAuth0Domain().'/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state'=> \json_encode($this->state),
'scope'=> \implode(' ', $this->getScopes()),
'response_type' => 'code'
]);
}
/**
* @param string $code
*
* @return array
*/
protected function getTokens(string $code): array
{
if(empty($this->tokens)) {
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://'.$this->getAuth0Domain().'/oauth/token',
$headers,
\http_build_query([
'code' => $code,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'grant_type' => 'authorization_code'
])
), true);
}
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://'.$this->getAuth0Domain().'/oauth/token',
$headers,
\http_build_query([
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'grant_type' => 'refresh_token'
])
), true);
if(empty($this->tokens['refresh_token'])) {
$this->tokens['refresh_token'] = $refreshToken;
}
return $this->tokens;
}
/**
* @param string $accessToken
*
* @return string
*/
public function getUserID(string $accessToken): string
{
$user = $this->getUser($accessToken);
if (isset($user['sub'])) {
return $user['sub'];
}
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)) {
$headers = ['Authorization: Bearer '. \urlencode($accessToken)];
$user = $this->request('GET', 'https://'.$this->getAuth0Domain().'/userinfo', $headers);
$this->user = \json_decode($user, true);
}
return $this->user;
}
/**
* Extracts the Client Secret from the JSON stored in appSecret
*
* @return string
*/
protected function getClientSecret(): string
{
$secret = $this->getAppSecret();
return (isset($secret['clientSecret'])) ? $secret['clientSecret'] : '';
}
/**
* Extracts the Auth0 Domain from the JSON stored in appSecret
*
* @return string
*/
protected function getAuth0Domain(): string
{
$secret = $this->getAppSecret();
return (isset($secret['auth0Domain'])) ? $secret['auth0Domain'] : '';
}
/**
* Decode the JSON stored in appSecret
*
* @return array
*/
protected function getAppSecret(): array
{
try {
$secret = \json_decode($this->appSecret, true, 512, JSON_THROW_ON_ERROR);
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
}

View file

@ -0,0 +1,221 @@
<?php
namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2;
// Reference Material
// https://developer.okta.com/docs/guides/sign-into-web-app-redirect/php/main/
class Okta extends OAuth2
{
/**
* @var array
*/
protected $scopes = [
'openid',
'profile',
'email',
'offline_access'
];
/**
* @var array
*/
protected $user = [];
/**
* @var array
*/
protected $tokens = [];
/**
* @return string
*/
public function getName(): string
{
return 'okta';
}
/**
* @return string
*/
public function getLoginURL(): string
{
return 'https://'.$this->getOktaDomain().'/oauth2/'.$this->getAuthorizationServerId().'/v1/authorize?'.\http_build_query([
'client_id' => $this->appID,
'redirect_uri' => $this->callback,
'state'=> \json_encode($this->state),
'scope'=> \implode(' ', $this->getScopes()),
'response_type' => 'code'
]);
}
/**
* @param string $code
*
* @return array
*/
protected function getTokens(string $code): array
{
if(empty($this->tokens)) {
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://'.$this->getOktaDomain().'/oauth2/'.$this->getAuthorizationServerId().'/v1/token',
$headers,
\http_build_query([
'code' => $code,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'redirect_uri' => $this->callback,
'scope' => \implode(' ', $this->getScopes()),
'grant_type' => 'authorization_code'
])
), true);
}
return $this->tokens;
}
/**
* @param string $refreshToken
*
* @return array
*/
public function refreshTokens(string $refreshToken): array
{
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$this->tokens = \json_decode($this->request(
'POST',
'https://'.$this->getOktaDomain().'/oauth2/'.$this->getAuthorizationServerId().'/v1/token',
$headers,
\http_build_query([
'refresh_token' => $refreshToken,
'client_id' => $this->appID,
'client_secret' => $this->getClientSecret(),
'grant_type' => 'refresh_token'
])
), true);
if(empty($this->tokens['refresh_token'])) {
$this->tokens['refresh_token'] = $refreshToken;
}
return $this->tokens;
}
/**
* @param string $accessToken
*
* @return string
*/
public function getUserID(string $accessToken): string
{
$user = $this->getUser($accessToken);
if (isset($user['sub'])) {
return $user['sub'];
}
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)) {
$headers = ['Authorization: Bearer '. \urlencode($accessToken)];
$user = $this->request('GET', 'https://'.$this->getOktaDomain().'/oauth2/'.$this->getAuthorizationServerId().'/v1/userinfo', $headers);
$this->user = \json_decode($user, true);
}
return $this->user;
}
/**
* Extracts the Client Secret from the JSON stored in appSecret
*
* @return string
*/
protected function getClientSecret(): string
{
$secret = $this->getAppSecret();
return (isset($secret['clientSecret'])) ? $secret['clientSecret'] : '';
}
/**
* Extracts the Okta Domain from the JSON stored in appSecret
*
* @return string
*/
protected function getOktaDomain(): string
{
$secret = $this->getAppSecret();
return (isset($secret['oktaDomain'])) ? $secret['oktaDomain'] : '';
}
/**
* Extracts the Okta Authorization Server ID from the JSON stored in appSecret
*
* @return string
*/
protected function getAuthorizationServerId(): string
{
$secret = $this->getAppSecret();
return (isset($secret['authorizationServerId'])) ? $secret['authorizationServerId'] : 'default';
}
/**
* Decode the JSON stored in appSecret
*
* @return array
*/
protected function getAppSecret(): array
{
try {
$secret = \json_decode($this->appSecret, true, 512, JSON_THROW_ON_ERROR);
} catch (\Throwable $th) {
throw new \Exception('Invalid secret');
}
return $secret;
}
}