diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index e8ae76312b..4ff26c3c28 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -31,9 +31,10 @@ $oauthDefaultFailure = App::getEnv('_APP_HOME').'/auth/oauth2/failure'; App::post('/v1/account') ->desc('Create Account') - ->groups(['api', 'account']) + ->groups(['api', 'account', 'auth']) ->label('event', 'account.create') ->label('scope', 'public') + ->label('auth.type', 'emailPassword') ->label('sdk.platform', [APP_PLATFORM_CLIENT]) ->label('sdk.namespace', 'account') ->label('sdk.method', 'create') @@ -75,6 +76,22 @@ App::post('/v1/account') } } + $limit = $project->getAttribute('usersAuthLimit', 0); + + if ($limit !== 0) { + $projectDB->getCollection([ // Count users + 'filters' => [ + '$collection='.Database::SYSTEM_COLLECTION_USERS, + ], + ]); + + $sum = $projectDB->getSum(); + + if($sum >= $limit) { + throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); + } + } + $profile = $projectDB->getCollectionFirst([ // Get user by email address 'limit' => 1, 'filters' => [ @@ -465,7 +482,23 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') ], ]); - if (!$user || empty($user->getId())) { // Last option -> create user alone, generate random password + if (!$user || empty($user->getId())) { // Last option -> create the user, generate random password + $limit = $project->getAttribute('usersAuthLimit', 0); + + if ($limit !== 0) { + $projectDB->getCollection([ // Count users + 'filters' => [ + '$collection='.Database::SYSTEM_COLLECTION_USERS, + ], + ]); + + $sum = $projectDB->getSum(); + + if($sum >= $limit) { + throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); + } + } + Authorization::disable(); try { @@ -566,8 +599,9 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') App::post('/v1/account/jwt') ->desc('Create Account JWT') - ->groups(['api', 'account']) + ->groups(['api', 'account', 'auth']) ->label('scope', 'account') + ->label('auth.type', 'jwt') ->label('docs', false) // Hidden for now - private beta ->label('sdk.platform', [APP_PLATFORM_CLIENT]) ->label('sdk.namespace', 'account') diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index c4a9e4875d..25d85dd37e 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -251,9 +251,10 @@ App::delete('/v1/teams/:teamId') App::post('/v1/teams/:teamId/memberships') ->desc('Create Team Membership') - ->groups(['api', 'teams']) + ->groups(['api', 'teams', 'auth']) ->label('event', 'teams.memberships.create') ->label('scope', 'teams.write') + ->label('auth.type', 'invites') ->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER]) ->label('sdk.namespace', 'teams') ->label('sdk.method', 'createMembership') @@ -310,6 +311,22 @@ App::post('/v1/teams/:teamId/memberships') if (empty($invitee)) { // Create new user if no user with same email found + $limit = $project->getAttribute('usersAuthLimit', 0); + + if ($limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed. + $projectDB->getCollection([ // Count users + 'filters' => [ + '$collection='.Database::SYSTEM_COLLECTION_USERS, + ], + ]); + + $sum = $projectDB->getSum(); + + if($sum >= $limit) { + throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); + } + } + Authorization::disable(); try { diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 8dc0c097c7..41bae62c67 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -110,6 +110,61 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e }, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes'], 'api'); + +App::init(function ($utopia, $request, $response, $project, $user) { + /** @var Utopia\App $utopia */ + /** @var Utopia\Swoole\Request $request */ + /** @var Appwrite\Utopia\Response $response */ + /** @var Appwrite\Database\Document $project */ + /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Registry\Registry $register */ + /** @var Appwrite\Event\Event $events */ + /** @var Appwrite\Event\Event $audits */ + /** @var Appwrite\Event\Event $usage */ + /** @var Appwrite\Event\Event $deletes */ + /** @var Appwrite\Event\Event $functions */ + + $route = $utopia->match($request); + + $isPreviliggedUser = Auth::isPreviliggedUser(Authorization::$roles); + $isAppUser = Auth::isAppUser(Authorization::$roles); + + if($isAppUser || $isPreviliggedUser) { // Skip limits for app and console devs + return; + } + + switch ($route->getLabel('auth.type', '')) { + case 'emailPassword': + if($project->getAttribute('usersAuthEmailPassword', false) === false) { + throw new Exception('Email / Password authentication is disabled for this project', 501); + } + break; + + case 'anonymous': + if($project->getAttribute('usersAuthAnonymous', false) === false) { + throw new Exception('Anonymous authentication is disabled for this project', 501); + } + break; + + case 'invites': + if($project->getAttribute('usersAuthInvites', false) === false) { + throw new Exception('Invites authentication is disabled for this project', 501); + } + break; + + case 'jwt': + if($project->getAttribute('usersAuthJWT', false) === false) { + throw new Exception('JWT authentication is disabled for this project', 501); + } + break; + + default: + throw new Exception('Unsupported authentication route'); + break; + } + +}, ['utopia', 'request', 'response', 'project', 'user'], 'auth'); + App::shutdown(function ($utopia, $request, $response, $project, $events, $audits, $usage, $deletes, $mode) { /** @var Utopia\App $utopia */ /** @var Utopia\Swoole\Request $request */ diff --git a/app/views/console/users/index.phtml b/app/views/console/users/index.phtml index 056a4245de..4376b4f5c9 100644 --- a/app/views/console/users/index.phtml +++ b/app/views/console/users/index.phtml @@ -334,7 +334,7 @@ $auth = $this->getParam('auth', []);
-
This limit will prevent new users from signing up for your project, no matter what auth method has been used. For an unlimited amount of users, set the limit to 0.
+
This limit will prevent new users from signing up for your project, no matter what auth method has been used. You will still be able to create users and team memberships from your Appwrite console. For an unlimited amount of users, set the limit to 0.