mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
abstract oauth adapters
This commit is contained in:
@@ -50,13 +50,6 @@ abstract class OAuth2
|
||||
$this->addScope($scope);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the OAuth credentials are valid
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
abstract public function verifyCredentials(): void;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
|
||||
@@ -184,8 +184,4 @@ class Discord extends OAuth2
|
||||
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function verifyCredentials(): void {
|
||||
// TODO: Implement, eventuelly. Refer to GitHub.php in this directory for inspiration
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,8 +175,4 @@ class Figma extends OAuth2
|
||||
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function verifyCredentials(): void {
|
||||
// TODO: Implement, eventuelly. Refer to GitHub.php in this directory for inspiration
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\OAuth2;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
abstract class Base extends Action
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
/**
|
||||
* Provider ID used in paths, database keys and event labels.
|
||||
*
|
||||
* @return string e.g. 'github', 'discord', 'figma'
|
||||
*/
|
||||
abstract public static function getProviderId(): string;
|
||||
|
||||
/**
|
||||
* Provider OAuth2 implementation class. Must implement verifyCredentials().
|
||||
*
|
||||
* @return class-string e.g. Github::class
|
||||
*/
|
||||
abstract public static function getProviderClass(): string;
|
||||
|
||||
/**
|
||||
* Provider display label used in descriptions, SDK method name and action name.
|
||||
*
|
||||
* @return string e.g. 'GitHub', 'Discord', 'Figma'
|
||||
*/
|
||||
abstract public static function getProviderLabel(): string;
|
||||
|
||||
/**
|
||||
* Response model constant for this provider.
|
||||
*
|
||||
* @return string e.g. Response::MODEL_OAUTH2_GITHUB
|
||||
*/
|
||||
abstract public static function getResponseModel(): string;
|
||||
|
||||
/**
|
||||
* Description of the clientId param, including an example value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public static function getClientIdDescription(): string;
|
||||
|
||||
/**
|
||||
* Description of the clientSecret param, including an example value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public static function getClientSecretDescription(): string;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'updateProjectOAuth2' . static::getProviderLabel();
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$providerId = static::getProviderId();
|
||||
$providerLabel = static::getProviderLabel();
|
||||
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/project/oauth2/' . $providerId)
|
||||
->desc('Update project OAuth2 ' . $providerLabel)
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'oauth2.write')
|
||||
->label('event', 'oauth2.' . $providerId . '.update')
|
||||
->label('audits.event', 'project.oauth2.' . $providerId . '.update')
|
||||
->label('audits.resource', 'project.oauth2/{response.$id}')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: 'oauth2',
|
||||
name: 'updateOAuth2' . $providerLabel,
|
||||
description: 'Update the project OAuth2 ' . $providerLabel . ' configuration.',
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: static::getResponseModel(),
|
||||
)
|
||||
],
|
||||
))
|
||||
->param('clientId', null, new Nullable(new Text(256, 0)), static::getClientIdDescription(), optional: true)
|
||||
->param('clientSecret', null, new Nullable(new Text(512, 0)), static::getClientSecretDescription(), optional: true)
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(
|
||||
?string $clientId,
|
||||
?string $clientSecret,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
Authorization $authorization
|
||||
): void {
|
||||
$providerId = static::getProviderId();
|
||||
if(!(\in_array($providerId, \array_keys(Config::getParam('oAuthProviders'))))) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Provider ' . $providerId . ' is not supported by server configuration.');
|
||||
}
|
||||
|
||||
$oAuthProviders = $project->getAttribute('oAuthProviders', []);
|
||||
|
||||
$appIdKey = $providerId . 'Appid';
|
||||
$appSecretKey = $providerId . 'Secret';
|
||||
$enabledKey = $providerId . 'Enabled';
|
||||
|
||||
if (!\is_null($clientId)) {
|
||||
$oAuthProviders[$appIdKey] = $clientId;
|
||||
}
|
||||
|
||||
if (!\is_null($clientSecret)) {
|
||||
$oAuthProviders[$appSecretKey] = $clientSecret;
|
||||
}
|
||||
|
||||
if (!\is_null($enabled)) {
|
||||
$oAuthProviders[$enabledKey] = $enabled;
|
||||
}
|
||||
|
||||
if($enabled === true || \is_null($enabled)) {
|
||||
try {
|
||||
if(empty($oAuthProviders[$appIdKey]) || empty($oAuthProviders[$appSecretKey])) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Client ID and Client Secret are required when enabling OAuth2 provider.');
|
||||
}
|
||||
|
||||
$providerClass = static::getProviderClass();
|
||||
$providerInstance = new $providerClass(appId: $oAuthProviders[$appIdKey], appSecret: $oAuthProviders[$appSecretKey], callback: '', state: [], scopes: []);
|
||||
|
||||
// E2E integration check
|
||||
if(\method_exists($providerInstance,'verifyCredentials')) {
|
||||
$providerInstance->verifyCredentials();
|
||||
}
|
||||
|
||||
$oAuthProviders[$enabledKey] = true;
|
||||
} catch(\Throwable $err) {
|
||||
if($enabled === true) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Could not enable OAuth2 provider: ' . $err->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$updates = new Document([
|
||||
'oAuthProviders' => $oAuthProviders
|
||||
]);
|
||||
|
||||
$project = $authorization->skip(fn() => $dbForPlatform->updateDocument('projects', $project->getId(), $updates));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'$id' => $providerId,
|
||||
'enabled' => $oAuthProviders[$enabledKey] ?? false,
|
||||
'clientId' => $oAuthProviders[$appIdKey] ?? '',
|
||||
'clientSecret' => $oAuthProviders[$appSecretKey] ?? '',
|
||||
]), static::getResponseModel());
|
||||
}
|
||||
}
|
||||
@@ -3,142 +3,38 @@
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\OAuth2\Discord;
|
||||
|
||||
use Appwrite\Auth\OAuth2\Discord;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\OAuth2\Base;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Update extends Action
|
||||
class Update extends Base
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'updateProjectOAuth2Discord';
|
||||
}
|
||||
|
||||
public static function getProviderId(): string
|
||||
{
|
||||
return 'discord';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string
|
||||
*/
|
||||
public static function getProviderClass(): string
|
||||
{
|
||||
return Discord::class;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
public static function getProviderLabel(): string
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/project/oauth2/discord')
|
||||
->desc('Update project OAuth2 Discord')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'oauth2.write')
|
||||
->label('event', 'oauth2.discord.update')
|
||||
->label('audits.event', 'project.oauth2.discord.update')
|
||||
->label('audits.resource', 'project.oauth2/{response.$id}')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: 'oauth2',
|
||||
name: 'updateOAuth2Discord',
|
||||
description: <<<EOT
|
||||
Update the project OAuth2 Discord configuration.
|
||||
EOT,
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_OAUTH2_DISCORD,
|
||||
)
|
||||
],
|
||||
))
|
||||
->param('clientId', null, new Nullable(new Text(256, 0)), 'Client ID of Discord OAuth2 app. For example: 950722000000343754', optional: true)
|
||||
->param('clientSecret', null, new Nullable(new Text(512, 0)), 'Client Secret of Discord OAuth2 app. For example: YmPXnM000000000000000000002zFg5D', optional: true)
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
return 'Discord';
|
||||
}
|
||||
|
||||
public function action(
|
||||
?string $clientId,
|
||||
?string $clientSecret,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
Authorization $authorization
|
||||
): void {
|
||||
$providerId = self::getProviderId();
|
||||
if(!(\in_array($providerId, \array_keys(Config::getParam('oAuthProviders'))))) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Provider ' . $providerId . ' is not supported by server configuration.');
|
||||
}
|
||||
public static function getResponseModel(): string
|
||||
{
|
||||
return Response::MODEL_OAUTH2_DISCORD;
|
||||
}
|
||||
|
||||
$oAuthProviders = $project->getAttribute('oAuthProviders', []);
|
||||
public static function getClientIdDescription(): string
|
||||
{
|
||||
return 'Client ID of Discord OAuth2 app. For example: 950722000000343754';
|
||||
}
|
||||
|
||||
$appIdKey = $providerId . 'Appid';
|
||||
$appSecretKey = $providerId . 'Secret';
|
||||
$enabledKey = $providerId . 'Enabled';
|
||||
|
||||
if (!\is_null($clientId)) {
|
||||
$oAuthProviders[$appIdKey] = $clientId;
|
||||
}
|
||||
|
||||
if (!\is_null($clientSecret)) {
|
||||
$oAuthProviders[$appSecretKey] = $clientSecret;
|
||||
}
|
||||
|
||||
if (!\is_null($enabled)) {
|
||||
$oAuthProviders[$enabledKey] = $enabled;
|
||||
}
|
||||
|
||||
if($enabled === true || \is_null($enabled)) {
|
||||
try {
|
||||
if(empty($oAuthProviders[$appIdKey]) || empty($oAuthProviders[$appSecretKey])) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Client ID and Client Secret are required when enabling OAuth2 provider.');
|
||||
}
|
||||
|
||||
$providerClass = self::getProviderClass();
|
||||
$providerInstance = new $providerClass(appId: $oAuthProviders[$appIdKey], appSecret: $oAuthProviders[$appSecretKey], callback: '', state: [], scopes: []);
|
||||
|
||||
$providerInstance->verifyCredentials();
|
||||
|
||||
$oAuthProviders[$enabledKey] = true;
|
||||
} catch(\Throwable $err) {
|
||||
if($enabled === true) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Could not enable OAuth2 provider: ' . $err->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$updates = new Document([
|
||||
'oAuthProviders' => $oAuthProviders
|
||||
]);
|
||||
|
||||
$project = $authorization->skip(fn() => $dbForPlatform->updateDocument('projects', $project->getId(), $updates));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'$id' => $providerId,
|
||||
'enabled' => $oAuthProviders[$enabledKey] ?? false,
|
||||
'clientId' => $oAuthProviders[$appIdKey] ?? '',
|
||||
'clientSecret' => $oAuthProviders[$appSecretKey] ?? '',
|
||||
]), Response::MODEL_OAUTH2_DISCORD);
|
||||
public static function getClientSecretDescription(): string
|
||||
{
|
||||
return 'Client Secret of Discord OAuth2 app. For example: YmPXnM000000000000000000002zFg5D';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,142 +3,38 @@
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\OAuth2\Figma;
|
||||
|
||||
use Appwrite\Auth\OAuth2\Figma;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\OAuth2\Base;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Update extends Action
|
||||
class Update extends Base
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'updateProjectOAuth2Figma';
|
||||
}
|
||||
|
||||
public static function getProviderId(): string
|
||||
{
|
||||
return 'figma';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string
|
||||
*/
|
||||
public static function getProviderClass(): string
|
||||
{
|
||||
return Figma::class;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
public static function getProviderLabel(): string
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/project/oauth2/figma')
|
||||
->desc('Update project OAuth2 Figma')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'oauth2.write')
|
||||
->label('event', 'oauth2.figma.update')
|
||||
->label('audits.event', 'project.oauth2.figma.update')
|
||||
->label('audits.resource', 'project.oauth2/{response.$id}')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: 'oauth2',
|
||||
name: 'updateOAuth2Figma',
|
||||
description: <<<EOT
|
||||
Update the project OAuth2 Figma configuration.
|
||||
EOT,
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_OAUTH2_FIGMA,
|
||||
)
|
||||
],
|
||||
))
|
||||
->param('clientId', null, new Nullable(new Text(256, 0)), 'Client ID of Figma OAuth2 app. For example: byay5H0000000000VtiI40', optional: true)
|
||||
->param('clientSecret', null, new Nullable(new Text(512, 0)), 'Client Secret of Figma OAuth2 app. For example: yEpOYn0000000000000000004iIsU5', optional: true)
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
return 'Figma';
|
||||
}
|
||||
|
||||
public function action(
|
||||
?string $clientId,
|
||||
?string $clientSecret,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
Authorization $authorization
|
||||
): void {
|
||||
$providerId = self::getProviderId();
|
||||
if(!(\in_array($providerId, \array_keys(Config::getParam('oAuthProviders'))))) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Provider ' . $providerId . ' is not supported by server configuration.');
|
||||
}
|
||||
public static function getResponseModel(): string
|
||||
{
|
||||
return Response::MODEL_OAUTH2_FIGMA;
|
||||
}
|
||||
|
||||
$oAuthProviders = $project->getAttribute('oAuthProviders', []);
|
||||
public static function getClientIdDescription(): string
|
||||
{
|
||||
return 'Client ID of Figma OAuth2 app. For example: byay5H0000000000VtiI40';
|
||||
}
|
||||
|
||||
$appIdKey = $providerId . 'Appid';
|
||||
$appSecretKey = $providerId . 'Secret';
|
||||
$enabledKey = $providerId . 'Enabled';
|
||||
|
||||
if (!\is_null($clientId)) {
|
||||
$oAuthProviders[$appIdKey] = $clientId;
|
||||
}
|
||||
|
||||
if (!\is_null($clientSecret)) {
|
||||
$oAuthProviders[$appSecretKey] = $clientSecret;
|
||||
}
|
||||
|
||||
if (!\is_null($enabled)) {
|
||||
$oAuthProviders[$enabledKey] = $enabled;
|
||||
}
|
||||
|
||||
if($enabled === true || \is_null($enabled)) {
|
||||
try {
|
||||
if(empty($oAuthProviders[$appIdKey]) || empty($oAuthProviders[$appSecretKey])) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Client ID and Client Secret are required when enabling OAuth2 provider.');
|
||||
}
|
||||
|
||||
$providerClass = self::getProviderClass();
|
||||
$providerInstance = new $providerClass(appId: $oAuthProviders[$appIdKey], appSecret: $oAuthProviders[$appSecretKey], callback: '', state: [], scopes: []);
|
||||
|
||||
$providerInstance->verifyCredentials();
|
||||
|
||||
$oAuthProviders[$enabledKey] = true;
|
||||
} catch(\Throwable $err) {
|
||||
if($enabled === true) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Could not enable OAuth2 provider: ' . $err->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$updates = new Document([
|
||||
'oAuthProviders' => $oAuthProviders
|
||||
]);
|
||||
|
||||
$project = $authorization->skip(fn() => $dbForPlatform->updateDocument('projects', $project->getId(), $updates));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'$id' => $providerId,
|
||||
'enabled' => $oAuthProviders[$enabledKey] ?? false,
|
||||
'clientId' => $oAuthProviders[$appIdKey] ?? '',
|
||||
'clientSecret' => $oAuthProviders[$appSecretKey] ?? '',
|
||||
]), Response::MODEL_OAUTH2_FIGMA);
|
||||
public static function getClientSecretDescription(): string
|
||||
{
|
||||
return 'Client Secret of Figma OAuth2 app. For example: yEpOYn0000000000000000004iIsU5';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,142 +3,38 @@
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\OAuth2\GitHub;
|
||||
|
||||
use Appwrite\Auth\OAuth2\Github;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\OAuth2\Base;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Update extends Action
|
||||
class Update extends Base
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'updateProjectOAuth2GitHub';
|
||||
}
|
||||
|
||||
public static function getProviderId(): string
|
||||
{
|
||||
return 'github';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string
|
||||
*/
|
||||
|
||||
public static function getProviderClass(): string
|
||||
{
|
||||
return Github::class;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
public static function getProviderLabel(): string
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/project/oauth2/github')
|
||||
->desc('Update project OAuth2 GitHub')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'oauth2.write')
|
||||
->label('event', 'oauth2.github.update')
|
||||
->label('audits.event', 'project.oauth2.github.update')
|
||||
->label('audits.resource', 'project.oauth2/{response.$id}')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: 'oauth2',
|
||||
name: 'updateOAuth2GitHub',
|
||||
description: <<<EOT
|
||||
Update the project OAuth2 GitHub configuration.
|
||||
EOT,
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_OAUTH2_GITHUB,
|
||||
)
|
||||
],
|
||||
))
|
||||
->param('clientId', null, new Nullable(new Text(256, 0)), 'Client ID of GitHub OAuth2 app, or App ID of GitHub generic app. For example: e4d87900000000540733', optional: true)
|
||||
->param('clientSecret', null, new Nullable(new Text(512, 0)), 'Client secret of GitHub OAuth2 app, or GitHub generic app. For example: 5e07c00000000000000000000000000000198bcc', optional: true)
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
return 'GitHub';
|
||||
}
|
||||
|
||||
public function action(
|
||||
?string $clientId,
|
||||
?string $clientSecret,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
Authorization $authorization
|
||||
): void {
|
||||
$providerId = self::getProviderId();
|
||||
if(!(\in_array($providerId, \array_keys(Config::getParam('oAuthProviders'))))) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Provider ' . $providerId . ' is not supported by server configuration.');
|
||||
}
|
||||
|
||||
$oAuthProviders = $project->getAttribute('oAuthProviders', []);
|
||||
|
||||
$appIdKey = $providerId . 'Appid';
|
||||
$appSecretKey = $providerId . 'Secret';
|
||||
$enabledKey = $providerId . 'Enabled';
|
||||
public static function getResponseModel(): string
|
||||
{
|
||||
return Response::MODEL_OAUTH2_GITHUB;
|
||||
}
|
||||
|
||||
if (!\is_null($clientId)) {
|
||||
$oAuthProviders[$appIdKey] = $clientId;
|
||||
}
|
||||
|
||||
if (!\is_null($clientSecret)) {
|
||||
$oAuthProviders[$appSecretKey] = $clientSecret;
|
||||
}
|
||||
public static function getClientIdDescription(): string
|
||||
{
|
||||
return 'Client ID of GitHub OAuth2 app, or App ID of GitHub generic app. For example: e4d87900000000540733';
|
||||
}
|
||||
|
||||
if (!\is_null($enabled)) {
|
||||
$oAuthProviders[$enabledKey] = $enabled;
|
||||
}
|
||||
|
||||
if($enabled === true || \is_null($enabled)) {
|
||||
try {
|
||||
if(empty($oAuthProviders[$appIdKey]) || empty($oAuthProviders[$appSecretKey])) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Client ID and Client Secret are required when enabling OAuth2 provider.');
|
||||
}
|
||||
|
||||
$providerClass = self::getProviderClass();
|
||||
$providerInstance = new $providerClass(appId: $oAuthProviders[$appIdKey], appSecret: $oAuthProviders[$appSecretKey], callback: '', state: [], scopes: []);
|
||||
|
||||
$providerInstance->verifyCredentials();
|
||||
|
||||
$oAuthProviders[$enabledKey] = true;
|
||||
} catch(\Throwable $err) {
|
||||
if($enabled === true) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Could not enable OAuth2 provider: ' . $err->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$updates = new Document([
|
||||
'oAuthProviders' => $oAuthProviders
|
||||
]);
|
||||
|
||||
$project = $authorization->skip(fn() => $dbForPlatform->updateDocument('projects', $project->getId(), $updates));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'$id' => $providerId,
|
||||
'enabled' => $oAuthProviders[$enabledKey] ?? false,
|
||||
'clientId' => $oAuthProviders[$appIdKey] ?? '',
|
||||
'clientSecret' => $oAuthProviders[$appSecretKey] ?? '',
|
||||
]), Response::MODEL_OAUTH2_GITHUB);
|
||||
public static function getClientSecretDescription(): string
|
||||
{
|
||||
return 'Client secret of GitHub OAuth2 app, or GitHub generic app. For example: 5e07c00000000000000000000000000000198bcc';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user