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', []);