diff --git a/CHANGES.md b/CHANGES.md index c6e74d852..21fcc31b6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,11 @@ +# Version 0.10.0 + +## Features + +- Grouped auth related attributes in project collection. Introduced new attribute `auths` and removed all attributes related to auth methods and `usersAuthLimit` as well, all these are grouped under `auths` attribute +- Grouped oAuth related attributes in project collection. Introduced new attribute `providers` and removed all attributes related to OAuth2 providers. All OAuth2 attributes are grouped under `providers` +- Project model changed, `userAuth` => `auth` example `userAuthEmailPassword` => `authEmailPassword`, also `userOauth2...` => `provider...` example `userOauth2GithubAppid` => `providerGithubAppid` + # Version 0.9.3 ## Bugs diff --git a/app/config/auth.php b/app/config/auth.php index 11b89dd9e..6257c08c2 100644 --- a/app/config/auth.php +++ b/app/config/auth.php @@ -5,35 +5,35 @@ return [ 'email-password' => [ 'name' => 'Email/Password', - 'key' => 'usersAuthEmailPassword', + 'key' => 'emailPassword', 'icon' => '/images/users/email.png', 'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateSession', 'enabled' => true, ], 'anonymous' => [ 'name' => 'Anonymous', - 'key' => 'usersAuthAnonymous', + 'key' => 'anonymous', 'icon' => '/images/users/anonymous.png', 'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateAnonymousSession', 'enabled' => true, ], 'invites' => [ 'name' => 'Invites', - 'key' => 'usersAuthInvites', + 'key' => 'invites', 'icon' => '/images/users/invites.png', 'docs' => 'https://appwrite.io/docs/client/teams?sdk=web#teamsCreateMembership', 'enabled' => true, ], 'jwt' => [ 'name' => 'JWT', - 'key' => 'usersAuthJWT', + 'key' => 'JWT', 'icon' => '/images/users/jwt.png', 'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateJWT', 'enabled' => true, ], 'phone' => [ 'name' => 'Phone', - 'key' => 'usersAuthPhone', + 'key' => 'phone', 'icon' => '/images/users/phone.png', 'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreatePhoneSession', 'docs' => '', diff --git a/app/config/collections2.php b/app/config/collections2.php index 67caddcf9..ae9a4feeb 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -78,17 +78,6 @@ $collections = [ 'array' => false, 'filters' => [], ], - [ - '$id' => 'usersAuthLimit', - 'type' => Database::VAR_INTEGER, - 'format' => '', - 'size' => 0, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], [ '$id' => 'legalName', 'type' => Database::VAR_STRING, @@ -166,6 +155,28 @@ $collections = [ 'array' => false, 'filters' => ['json'], ], + [ + '$id' => 'auths', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['json'], + ], + [ + '$id' => 'providers', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['json'], + ], [ '$id' => 'platforms', 'type' => Database::VAR_STRING, @@ -1394,51 +1405,4 @@ $collections = [ ], ]; -/* - * Add enabled OAuth2 providers to default data rules - */ -foreach ($providers as $index => $provider) { - if (!$provider['enabled']) { - continue; - } - - $collections['projects']['attributes'][] = [ - '$id' => 'usersOauth2' . \ucfirst($index) . 'Appid', - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 16384, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ]; - - $collections['projects']['attributes'][] = [ - '$id' => 'usersOauth2' . \ucfirst($index) . 'Secret', - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 16384, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ]; -} - -foreach ($auth as $index => $method) { - $collections['projects']['attributes'][] = [ - '$id' => $method['key'] ?? '', - 'type' => Database::VAR_BOOLEAN, - 'format' => '', - 'size' => 0, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ]; -} - return $collections; diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 197895203..ef0880511 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -73,7 +73,7 @@ App::post('/v1/account') } } - $limit = $project->getAttribute('usersAuthLimit', 0); + $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { $sum = $dbForInternal->count('users', [], APP_LIMIT_USERS); @@ -257,9 +257,9 @@ App::get('/v1/account/sessions/oauth2/:provider') /** @var Utopia\Database\Document $project */ $protocol = $request->getProtocol(); - $callback = $protocol . '://' . $request->getHostname() . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId(); - $appId = $project->getAttribute('usersOauth2' . \ucfirst($provider) . 'Appid', ''); - $appSecret = $project->getAttribute('usersOauth2' . \ucfirst($provider) . 'Secret', '{}'); + $callback = $protocol.'://'.$request->getHostname().'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId(); + $appId = $project->getAttribute('providers', [])[$provider.'Appid'] ?? ''; + $appSecret = $project->getAttribute('providers', [])[$provider.'Secret'] ?? '{}'; if (!empty($appSecret) && isset($appSecret['version'])) { $key = App::getEnv('_APP_OPENSSL_KEY_V' . $appSecret['version']); @@ -370,9 +370,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $callback = $protocol . '://' . $request->getHostname() . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId(); $defaultState = ['success' => $project->getAttribute('url', ''), 'failure' => '']; $validateURL = new URL(); - - $appId = $project->getAttribute('usersOauth2' . \ucfirst($provider) . 'Appid', ''); - $appSecret = $project->getAttribute('usersOauth2' . \ucfirst($provider) . 'Secret', '{}'); + $appId = $project->getAttribute('providers', [])[$provider.'Appid'] ?? ''; + $appSecret = $project->getAttribute('providers', [])[$provider.'Secret'] ?? '{}'; if (!empty($appSecret) && isset($appSecret['version'])) { $key = App::getEnv('_APP_OPENSSL_KEY_V' . $appSecret['version']); @@ -452,7 +451,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $user = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if ($user === false || $user->isEmpty()) { // Last option -> create the user, generate random password - $limit = $project->getAttribute('usersAuthLimit', 0); + $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); @@ -616,7 +615,7 @@ App::post('/v1/account/sessions/anonymous') throw new Exception('Cannot create an anonymous user when logged in.', 401); } - $limit = $project->getAttribute('usersAuthLimit', 0); + $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { $sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 579333d63..81642da8e 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -32,14 +32,6 @@ App::init(function ($project) { } }, ['project'], 'projects'); -App::init(function ($project) { - /** @var Utopia\Database\Document $project */ - - if($project->getId() !== 'console') { - throw new Exception('Access to this API is forbidden.', 401); - } -}, ['project'], 'projects'); - App::post('/v1/projects') ->desc('Create Project') ->groups(['api', 'projects']) @@ -79,6 +71,12 @@ App::post('/v1/projects') if ($team->isEmpty()) { throw new Exception('Team not found', 404); } + + $auth = Config::getParam('auth', []); + $auths = []; + foreach ($auth as $index => $method) { + $auths[$method['key'] ?? ''] = true; + } $project = $dbForConsole->createDocument('projects', new Document([ '$id' => $projectId == 'unique()' ? $dbForConsole->getId() : $projectId, @@ -102,11 +100,7 @@ App::post('/v1/projects') 'webhooks' => [], 'keys' => [], 'domains' => [], - 'usersAuthEmailPassword' => true, - 'usersAuthAnonymous' => true, - 'usersAuthInvites' => true, - 'usersAuthJWT' => true, - 'usersAuthPhone' => true, + 'auths' => $auths, ])); $collections = Config::getParam('collections2', []); /** @var array $collections */ @@ -515,10 +509,11 @@ App::patch('/v1/projects/:projectId/oauth2') throw new Exception('Project not found', 404); } - $project = $dbForConsole->updateDocument('projects', $project->getId(), $project - ->setAttribute('usersOauth2' . \ucfirst($provider) . 'Appid', $appId) - ->setAttribute('usersOauth2' . \ucfirst($provider) . 'Secret', $secret) - ); + $providers = $project->getAttribute('providers', []); + $providers[$provider . 'Appid'] = $appId; + $providers[$provider . 'Secret'] = $secret; + + $project = $dbForConsole->updateDocument('projects', $project->getId(), $project->setAttribute('providers', $providers)); $response->dynamic($project, Response::MODEL_PROJECT); }); @@ -547,8 +542,11 @@ App::patch('/v1/projects/:projectId/auth/limit') throw new Exception('Project not found', 404); } + $auths = $project->getAttribute('auths', []); + $auths['limit'] = $limit; + $dbForConsole->updateDocument('projects', $project->getId(), $project - ->setAttribute('usersAuthLimit', $limit) + ->setAttribute('auths', $auths) ); $response->dynamic($project, Response::MODEL_PROJECT); @@ -582,9 +580,10 @@ App::patch('/v1/projects/:projectId/auth/:method') throw new Exception('Project not found', 404); } - $dbForConsole->updateDocument('projects', $project->getId(), $project - ->setAttribute($authKey, $status) - ); + $auths = $project->getAttribute('auths', []); + $auths[$authKey] = $status; + + $project = $dbForConsole->updateDocument('projects', $project->getId(), $project->setAttribute('auths', $auths)); $response->dynamic($project, Response::MODEL_PROJECT); }); diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 4de8653a2..01ce3c82f 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -279,7 +279,7 @@ App::post('/v1/teams/:teamId/memberships') if (empty($invitee)) { // Create new user if no user with same email found - $limit = $project->getAttribute('usersAuthLimit', 0); + $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed. $sum = $dbForInternal->count('users', [], APP_LIMIT_USERS); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 35e48ea46..8a9256720 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -129,27 +129,28 @@ App::init(function ($utopia, $request, $project) { return; } + $auths = $project->getAttribute('auths', []); switch ($route->getLabel('auth.type', '')) { case 'emailPassword': - if($project->getAttribute('usersAuthEmailPassword', true) === false) { + if(($auths['emailPassword'] ?? true) === false) { throw new Exception('Email / Password authentication is disabled for this project', 501); } break; case 'anonymous': - if($project->getAttribute('usersAuthAnonymous', true) === false) { + if(($auths['anonymous'] ?? true) === false) { throw new Exception('Anonymous authentication is disabled for this project', 501); } break; case 'invites': - if($project->getAttribute('usersAuthInvites', true) === false) { + if(($auths['invites'] ?? true) === false) { throw new Exception('Invites authentication is disabled for this project', 501); } break; case 'jwt': - if($project->getAttribute('usersAuthJWT', true) === false) { + if(($auths['JWT'] ?? true) === false) { throw new Exception('JWT authentication is disabled for this project', 501); } break; diff --git a/app/init.php b/app/init.php index ce0b6219a..72b3dedc7 100644 --- a/app/init.php +++ b/app/init.php @@ -613,9 +613,11 @@ App::setResource('console', function() { 'legalCity' => '', 'legalAddress' => '', 'legalTaxId' => '', + 'auths' => [ + 'limit' => (App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled') === 'enabled') ? 1 : 0, // limit signup to 1 user + ], 'authWhitelistEmails' => (!empty(App::getEnv('_APP_CONSOLE_WHITELIST_EMAILS', null))) ? \explode(',', App::getEnv('_APP_CONSOLE_WHITELIST_EMAILS', null)) : [], 'authWhitelistIPs' => (!empty(App::getEnv('_APP_CONSOLE_WHITELIST_IPS', null))) ? \explode(',', App::getEnv('_APP_CONSOLE_WHITELIST_IPS', null)) : [], - 'usersAuthLimit' => (App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled') === 'enabled') ? 1 : 0, // limit signup to 1 user ]); }, []); diff --git a/app/views/console/users/index.phtml b/app/views/console/users/index.phtml index fdb496c77..d5061edb6 100644 --- a/app/views/console/users/index.phtml +++ b/app/views/console/users/index.phtml @@ -324,9 +324,9 @@ $auth = $this->getParam('auth', []);
  • -

    Unlimited Users Set Limit

    -

    Users allowed Change Limit

    - +

    Unlimited Users Set Limit

    +

    Users allowed Change Limit

    +

    Settings