From 005a2399321fb1c07c4088b56cb6af0a26b477ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 7 Mar 2024 18:24:01 +0100 Subject: [PATCH] Auth fixes --- CHANGES.md | 2 +- app/cli.php | 2 +- app/controllers/api/account.php | 100 ++++---- app/controllers/api/avatars.php | 12 +- app/controllers/api/databases.php | 116 ++++----- app/controllers/api/functions.php | 50 ++-- app/controllers/api/messaging.php | 32 +-- app/controllers/api/project.php | 2 +- app/controllers/api/projects.php | 18 +- app/controllers/api/storage.php | 86 +++---- app/controllers/api/teams.php | 40 +-- app/controllers/api/users.php | 2 +- app/controllers/api/vcs.php | 26 +- app/controllers/general.php | 20 +- app/controllers/shared/api.php | 41 +-- app/controllers/shared/api/auth.php | 7 +- app/http.php | 6 +- app/init.php | 47 ++-- app/realtime.php | 25 +- app/worker.php | 9 +- composer.json | 11 +- composer.lock | 235 ++++++++++++------ src/Appwrite/Auth/Auth.php | 5 +- src/Appwrite/Auth/Validator/Password.php | 2 +- src/Appwrite/Auth/Validator/Phone.php | 2 +- src/Appwrite/Event/Validator/Event.php | 2 +- src/Appwrite/GraphQL/Resolvers.php | 16 +- src/Appwrite/GraphQL/Schema.php | 6 +- src/Appwrite/GraphQL/Types/Mapper.php | 6 +- src/Appwrite/Migration/Migration.php | 6 +- src/Appwrite/Network/Validator/CNAME.php | 2 +- src/Appwrite/Network/Validator/Email.php | 4 +- src/Appwrite/Network/Validator/Origin.php | 2 +- src/Appwrite/Platform/Tasks/CalcTierStats.php | 17 +- .../Platform/Tasks/DeleteOrphanedProjects.php | 5 +- .../Platform/Tasks/GetMigrationStats.php | 5 +- src/Appwrite/Platform/Tasks/Migrate.php | 10 +- src/Appwrite/Platform/Tasks/Specs.php | 5 +- src/Appwrite/Platform/Workers/Builds.php | 13 +- src/Appwrite/Platform/Workers/Hamster.php | 14 +- src/Appwrite/Specification/Format.php | 4 +- .../Specification/Format/OpenAPI3.php | 4 +- .../Specification/Format/Swagger2.php | 2 +- src/Appwrite/Task/Validator/Cron.php | 2 +- .../Utopia/Database/Validator/CompoundUID.php | 2 +- .../Utopia/Database/Validator/ProjectId.php | 2 +- src/Appwrite/Utopia/Request.php | 8 +- src/Appwrite/Utopia/View.php | 2 +- .../DatabasesPermissionsGuestTest.php | 19 +- tests/unit/Auth/AuthTest.php | 27 +- .../unit/Messaging/MessagingChannelsTest.php | 10 +- 51 files changed, 600 insertions(+), 493 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5dd4ba8770..387d7e0f55 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -33,7 +33,7 @@ * Bump console to version 3.2.7 [#7148](https://github.com/appwrite/appwrite/pull/7148) * Chore update database to 0.45.2 [#7138](https://github.com/appwrite/appwrite/pull/7138) * Implement queue thresholds for the health API [#7123](https://github.com/appwrite/appwrite/pull/7123) -* Add Authorization::skip to the usage worker [#7124](https://github.com/appwrite/appwrite/pull/7124) +* Add $auth->skip to the usage worker [#7124](https://github.com/appwrite/appwrite/pull/7124) ## Bug fixes * fix: use queueForDeletes in git installation delete endpoint [#7140](https://github.com/appwrite/appwrite/pull/7140) diff --git a/app/cli.php b/app/cli.php index 95981033b3..86daad2ae3 100644 --- a/app/cli.php +++ b/app/cli.php @@ -25,7 +25,7 @@ use Utopia\Registry\Registry; global $register; -Authorization::disable(); +$auth->disable(); CLI::setResource('register', fn () => $register); diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 60b1e3d48d..2def54db58 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -160,9 +160,9 @@ Http::post('/v1/account') 'accessedAt' => DateTime::now(), ]); $user->removeAttribute('$internalId'); - $user = Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); + $user = $auth->skip(fn () => $dbForProject->createDocument('users', $user)); try { - $target = Authorization::skip(fn () => $dbForProject->createDocument('targets', new Document([ + $target = $auth->skip(fn () => $dbForProject->createDocument('targets', new Document([ '$permissions' => [ Permission::read(Role::user($user->getId())), Permission::update(Role::user($user->getId())), @@ -186,9 +186,9 @@ Http::post('/v1/account') throw new Exception(Exception::USER_ALREADY_EXISTS); } - Authorization::unsetRole(Role::guests()->toString()); - Authorization::setRole(Role::user($user->getId())->toString()); - Authorization::setRole(Role::users()->toString()); + $auth->unsetRole(Role::guests()->toString()); + $auth->addRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::users()->toString()); $queueForEvents->setParam('userId', $user->getId()); @@ -243,7 +243,7 @@ Http::post('/v1/account/sessions/email') throw new Exception(Exception::USER_BLOCKED); // User is in status blocked } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -274,7 +274,7 @@ Http::post('/v1/account/sessions/email') $detector->getDevice() )); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); // Re-hash if not using recommended algo if ($user->getAttribute('hash') !== Auth::DEFAULT_ALGO) { @@ -775,7 +775,7 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect') 'accessedAt' => DateTime::now(), ]); $user->removeAttribute('$internalId'); - $user = Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); + $user = $auth->skip(fn () => $dbForProject->createDocument('users', $user)); $dbForProject->createDocument('targets', new Document([ '$permissions' => [ @@ -794,8 +794,8 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect') } } - Authorization::setRole(Role::user($user->getId())->toString()); - Authorization::setRole(Role::users()->toString()); + $auth->addRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::users()->toString()); if (false === $user->getAttribute('status')) { // Account is blocked $failureRedirect(Exception::USER_BLOCKED); // User is in status blocked @@ -854,7 +854,7 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect') $dbForProject->updateDocument('users', $user->getId(), $user); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $state['success'] = URLParser::parse($state['success']); $query = URLParser::parseQuery($state['success']['query']); @@ -876,7 +876,7 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect') 'ip' => $request->getIP(), ]); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $token = $dbForProject->createDocument('tokens', $token ->setAttribute('$permissions', [ @@ -1108,7 +1108,7 @@ Http::post('/v1/account/tokens/magic-url') $phrase = Phrase::generate(); } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -1163,7 +1163,7 @@ Http::post('/v1/account/tokens/magic-url') ]); $user->removeAttribute('$internalId'); - $user = Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); + $user = $auth->skip(fn () => $dbForProject->createDocument('users', $user)); } $tokenSecret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_MAGIC_URL); @@ -1180,7 +1180,7 @@ Http::post('/v1/account/tokens/magic-url') 'ip' => $request->getIP(), ]); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $token = $dbForProject->createDocument('tokens', $token ->setAttribute('$permissions', [ @@ -1349,7 +1349,7 @@ Http::post('/v1/account/tokens/email') $phrase = Phrase::generate(); } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -1402,7 +1402,7 @@ Http::post('/v1/account/tokens/email') ]); $user->removeAttribute('$internalId'); - $user = Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); + $user = $auth->skip(fn () => $dbForProject->createDocument('users', $user)); } $tokenSecret = Auth::codeGenerator(6); @@ -1419,7 +1419,7 @@ Http::post('/v1/account/tokens/email') 'ip' => $request->getIP(), ]); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $token = $dbForProject->createDocument('tokens', $token ->setAttribute('$permissions', [ @@ -1542,12 +1542,12 @@ Http::post('/v1/account/tokens/email') }); $createSession = function (string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents) { - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); /** @var Utopia\Database\Document $user */ - $userFromRequest = Authorization::skip(fn () => $dbForProject->getDocument('users', $userId)); + $userFromRequest = $auth->skip(fn () => $dbForProject->getDocument('users', $userId)); if ($userFromRequest->isEmpty()) { throw new Exception(Exception::USER_INVALID_TOKEN); @@ -1593,7 +1593,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res $detector->getDevice() )); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $session = $dbForProject->createDocument('sessions', $session ->setAttribute('$permissions', [ @@ -1603,7 +1603,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res ])); $dbForProject->purgeCachedDocument('users', $user->getId()); - Authorization::skip(fn () => $dbForProject->deleteDocument('tokens', $verifiedToken->getId())); + $auth->skip(fn () => $dbForProject->deleteDocument('tokens', $verifiedToken->getId())); $dbForProject->purgeCachedDocument('users', $user->getId()); if ($verifiedToken->getAttribute('type') === Auth::TOKEN_TYPE_MAGIC_URL) { @@ -1770,7 +1770,7 @@ Http::post('/v1/account/tokens/phone') throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured'); } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -1814,9 +1814,9 @@ Http::post('/v1/account/tokens/phone') ]); $user->removeAttribute('$internalId'); - $user = Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); + $user = $auth->skip(fn () => $dbForProject->createDocument('users', $user)); try { - $target = Authorization::skip(fn () => $dbForProject->createDocument('targets', new Document([ + $target = $auth->skip(fn () => $dbForProject->createDocument('targets', new Document([ '$permissions' => [ Permission::read(Role::user($user->getId())), Permission::update(Role::user($user->getId())), @@ -1851,7 +1851,7 @@ Http::post('/v1/account/tokens/phone') 'ip' => $request->getIP(), ]); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $token = $dbForProject->createDocument('tokens', $token ->setAttribute('$permissions', [ @@ -1935,7 +1935,7 @@ Http::post('/v1/account/sessions/anonymous') ->inject('queueForEvents') ->action(function (Request $request, Response $response, Locale $locale, Document $user, Document $project, Database $dbForProject, Reader $geodb, Event $queueForEvents) { $protocol = $request->getProtocol(); - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -1981,7 +1981,7 @@ Http::post('/v1/account/sessions/anonymous') 'accessedAt' => DateTime::now(), ]); $user->removeAttribute('$internalId'); - $user = Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); + $user = $auth->skip(fn () => $dbForProject->createDocument('users', $user)); // Create session token $duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; @@ -2007,7 +2007,7 @@ Http::post('/v1/account/sessions/anonymous') $detector->getDevice() )); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $session = $dbForProject->createDocument('sessions', $session-> setAttribute('$permissions', [ Permission::read(Role::user($user->getId())), @@ -2155,7 +2155,7 @@ Http::get('/v1/account/sessions') ->inject('project') ->action(function (Response $response, Document $user, Locale $locale, Document $project) { - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -2263,7 +2263,7 @@ Http::get('/v1/account/sessions/:sessionId') ->inject('project') ->action(function (?string $sessionId, Response $response, Document $user, Locale $locale, Document $project) { - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -2455,7 +2455,7 @@ Http::patch('/v1/account/email') ->setAttribute('passwordUpdate', DateTime::now()); } - $target = Authorization::skip(fn () => $dbForProject->findOne('targets', [ + $target = $auth->skip(fn () => $dbForProject->findOne('targets', [ Query::equal('identifier', [$email]), ])); @@ -2471,7 +2471,7 @@ Http::patch('/v1/account/email') $oldTarget = $user->find('identifier', $oldEmail, 'targets'); if ($oldTarget instanceof Document && !$oldTarget->isEmpty()) { - Authorization::skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email))); + $auth->skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email))); } $dbForProject->purgeCachedDocument('users', $user->getId()); } catch (Duplicate) { @@ -2521,7 +2521,7 @@ Http::patch('/v1/account/phone') $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, false]); - $target = Authorization::skip(fn () => $dbForProject->findOne('targets', [ + $target = $auth->skip(fn () => $dbForProject->findOne('targets', [ Query::equal('identifier', [$phone]), ])); @@ -2552,7 +2552,7 @@ Http::patch('/v1/account/phone') $oldTarget = $user->find('identifier', $oldPhone, 'targets'); if ($oldTarget instanceof Document && !$oldTarget->isEmpty()) { - Authorization::skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone))); + $auth->skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone))); } $dbForProject->purgeCachedDocument('users', $user->getId()); } catch (Duplicate $th) { @@ -2894,7 +2894,7 @@ Http::post('/v1/account/recovery') throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled'); } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -2928,7 +2928,7 @@ Http::post('/v1/account/recovery') 'ip' => $request->getIP(), ]); - Authorization::setRole(Role::user($profile->getId())->toString()); + $auth->addRole(Role::user($profile->getId())->toString()); $recovery = $dbForProject->createDocument('tokens', $recovery ->setAttribute('$permissions', [ @@ -3079,7 +3079,7 @@ Http::put('/v1/account/recovery') throw new Exception(Exception::USER_INVALID_TOKEN); } - Authorization::setRole(Role::user($profile->getId())->toString()); + $auth->addRole(Role::user($profile->getId())->toString()); $newPassword = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS); @@ -3159,7 +3159,7 @@ Http::post('/v1/account/verification') throw new Exception(Exception::USER_EMAIL_ALREADY_VERIFIED); } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); $verificationSecret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_VERIFICATION); @@ -3176,7 +3176,7 @@ Http::post('/v1/account/verification') 'ip' => $request->getIP(), ]); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $verification = $dbForProject->createDocument('tokens', $verification ->setAttribute('$permissions', [ @@ -3309,7 +3309,7 @@ Http::put('/v1/account/verification') ->inject('queueForEvents') ->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { - $profile = Authorization::skip(fn () => $dbForProject->getDocument('users', $userId)); + $profile = $auth->skip(fn () => $dbForProject->getDocument('users', $userId)); if ($profile->isEmpty()) { throw new Exception(Exception::USER_NOT_FOUND); @@ -3322,7 +3322,7 @@ Http::put('/v1/account/verification') throw new Exception(Exception::USER_INVALID_TOKEN); } - Authorization::setRole(Role::user($profile->getId())->toString()); + $auth->addRole(Role::user($profile->getId())->toString()); $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('emailVerification', true)); @@ -3383,7 +3383,7 @@ Http::post('/v1/account/verification/phone') throw new Exception(Exception::USER_PHONE_ALREADY_VERIFIED); } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); $secret = Auth::codeGenerator(); @@ -3400,7 +3400,7 @@ Http::post('/v1/account/verification/phone') 'ip' => $request->getIP(), ]); - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $verification = $dbForProject->createDocument('tokens', $verification ->setAttribute('$permissions', [ @@ -3481,7 +3481,7 @@ Http::put('/v1/account/verification/phone') ->inject('queueForEvents') ->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { - $profile = Authorization::skip(fn () => $dbForProject->getDocument('users', $userId)); + $profile = $auth->skip(fn () => $dbForProject->getDocument('users', $userId)); if ($profile->isEmpty()) { throw new Exception(Exception::USER_NOT_FOUND); @@ -3493,7 +3493,7 @@ Http::put('/v1/account/verification/phone') throw new Exception(Exception::USER_INVALID_TOKEN); } - Authorization::setRole(Role::user($profile->getId())->toString()); + $auth->addRole(Role::user($profile->getId())->toString()); $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('phoneVerification', true)); @@ -4230,9 +4230,9 @@ Http::post('/v1/account/targets/push') ->action(function (string $targetId, string $identifier, string $providerId, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject) { $targetId = $targetId == 'unique()' ? ID::unique() : $targetId; - $provider = Authorization::skip(fn () => $dbForProject->getDocument('providers', $providerId)); + $provider = $auth->skip(fn () => $dbForProject->getDocument('providers', $providerId)); - $target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $targetId)); + $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId)); if (!$target->isEmpty()) { throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); @@ -4301,7 +4301,7 @@ Http::put('/v1/account/targets/:targetId/push') ->inject('dbForProject') ->action(function (string $targetId, string $identifier, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject) { - $target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $targetId)); + $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId)); if ($target->isEmpty()) { throw new Exception(Exception::USER_TARGET_NOT_FOUND); @@ -4355,7 +4355,7 @@ Http::delete('/v1/account/targets/:targetId/push') ->inject('response') ->inject('dbForProject') ->action(function (string $targetId, Event $queueForEvents, Delete $queueForDeletes, Document $user, Request $request, Response $response, Database $dbForProject) { - $target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $targetId)); + $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId)); if ($target->isEmpty()) { throw new Exception(Exception::USER_TARGET_NOT_FOUND); diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index cd63da8cfe..8a4b0b6afd 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -63,7 +63,7 @@ $avatarCallback = function (string $type, string $code, int $width, int $height, $getUserGitHub = function (string $userId, Document $project, Database $dbForProject, Database $dbForConsole, ?Logger $logger) { try { - $user = Authorization::skip(fn () => $dbForConsole->getDocument('users', $userId)); + $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); $sessions = $user->getAttribute('sessions', []); @@ -114,7 +114,7 @@ $getUserGitHub = function (string $userId, Document $project, Database $dbForPro ->setAttribute('providerRefreshToken', $refreshToken) ->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$oauth2->getAccessTokenExpiry(''))); - Authorization::skip(fn () => $dbForProject->updateDocument('sessions', $gitHubSession->getId(), $gitHubSession)); + $auth->skip(fn () => $dbForProject->updateDocument('sessions', $gitHubSession->getId(), $gitHubSession)); $dbForProject->purgeCachedDocument('users', $user->getId()); } catch (Throwable $err) { @@ -122,7 +122,7 @@ $getUserGitHub = function (string $userId, Document $project, Database $dbForPro do { $previousAccessToken = $gitHubSession->getAttribute('providerAccessToken'); - $user = Authorization::skip(fn () => $dbForConsole->getDocument('users', $userId)); + $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); $sessions = $user->getAttribute('sessions', []); $gitHubSession = new Document(); @@ -594,7 +594,7 @@ Http::get('/v1/cards/cloud') ->inject('employees') ->inject('logger') ->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForConsole, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger) use ($getUserGitHub) { - $user = Authorization::skip(fn () => $dbForConsole->getDocument('users', $userId)); + $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); if ($user->isEmpty() && empty($mock)) { throw new Exception(Exception::USER_NOT_FOUND); @@ -801,7 +801,7 @@ Http::get('/v1/cards/cloud-back') ->inject('employees') ->inject('logger') ->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForConsole, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger) use ($getUserGitHub) { - $user = Authorization::skip(fn () => $dbForConsole->getDocument('users', $userId)); + $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); if ($user->isEmpty() && empty($mock)) { throw new Exception(Exception::USER_NOT_FOUND); @@ -879,7 +879,7 @@ Http::get('/v1/cards/cloud-og') ->inject('employees') ->inject('logger') ->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForConsole, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger) use ($getUserGitHub) { - $user = Authorization::skip(fn () => $dbForConsole->getDocument('users', $userId)); + $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); if ($user->isEmpty() && empty($mock)) { throw new Exception(Exception::USER_NOT_FOUND); diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 4668adc63c..c2fc070cc3 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -88,7 +88,7 @@ function createAttribute(string $databaseId, string $collectionId, Document $att $default = $attribute->getAttribute('default'); $options = $attribute->getAttribute('options', []); - $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($db->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -237,7 +237,7 @@ function updateAttribute( array $elements = null, array $options = [] ): Document { - $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($db->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -752,7 +752,7 @@ Http::post('/v1/databases/:databaseId/collections') ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, Response $response, Database $dbForProject, string $mode, Event $queueForEvents) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -813,7 +813,7 @@ Http::get('/v1/databases/:databaseId/collections') ->inject('mode') ->action(function (string $databaseId, array $queries, string $search, Response $response, Database $dbForProject, string $mode) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -875,7 +875,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId') ->inject('mode') ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, string $mode) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -911,7 +911,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/logs') ->inject('geodb') ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1017,7 +1017,7 @@ Http::put('/v1/databases/:databaseId/collections/:collectionId') ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, Response $response, Database $dbForProject, string $mode, Event $queueForEvents) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1081,7 +1081,7 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId') ->inject('mode') ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, string $mode) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1616,7 +1616,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relat $key ??= $relatedCollectionId; $twoWayKey ??= $collectionId; - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1719,7 +1719,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/attributes') ->inject('dbForProject') ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject) { /** @var Document $database */ - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1753,7 +1753,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/attributes') if ($cursor) { $attributeId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn () => $dbForProject->find('attributes', [ + $cursorDocument = $auth->skip(fn () => $dbForProject->find('attributes', [ Query::equal('collectionInternalId', [$collection->getInternalId()]), Query::equal('databaseInternalId', [$database->getInternalId()]), Query::equal('key', [$attributeId]), @@ -1807,7 +1807,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key') ->inject('dbForProject') ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2300,7 +2300,7 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:ke ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { - $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($db->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2413,7 +2413,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/indexes') ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $key, string $type, array $attributes, array $orders, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { - $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($db->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2575,7 +2575,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/indexes') ->inject('dbForProject') ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject) { /** @var Document $database */ - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2605,7 +2605,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/indexes') if ($cursor) { $indexId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn () => $dbForProject->find('indexes', [ + $cursorDocument = $auth->skip(fn () => $dbForProject->find('indexes', [ Query::equal('collectionInternalId', [$collection->getInternalId()]), Query::equal('databaseInternalId', [$database->getInternalId()]), Query::equal('key', [$indexId]), @@ -2645,7 +2645,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/indexes/:key') ->inject('dbForProject') ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2688,7 +2688,7 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key') ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { - $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($db->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2771,16 +2771,16 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/documents') throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, '$id is not allowed for creating new documents, try update instead'); } - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -2818,8 +2818,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/documents') $permission->getIdentifier(), $permission->getDimension() ))->toString(); - if (!Authorization::isRole($role)) { - throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', Authorization::getRoles()) . ')'); + if (!$auth->isRole($role)) { + throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $auth->getRoles()) . ')'); } } } @@ -2867,7 +2867,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/documents') } $relatedCollectionId = $relationship->getAttribute('relatedCollection'); - $relatedCollection = Authorization::skip( + $relatedCollection = $auth->skip( fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); @@ -2881,7 +2881,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/documents') $relation = new Document($relation); } if ($relation instanceof Document) { - $current = Authorization::skip( + $current = $auth->skip( fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId(), $relation->getId()) ); @@ -2941,7 +2941,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/documents') } $relatedCollectionId = $relationship->getAttribute('relatedCollection'); - $relatedCollection = Authorization::skip( + $relatedCollection = $auth->skip( fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); @@ -2988,15 +2988,15 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents') ->inject('dbForProject') ->inject('mode') ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, string $mode) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -3020,7 +3020,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents') if ($cursor) { $documentId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); + $cursorDocument = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); if ($cursorDocument->isEmpty()) { throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Document '{$documentId}' for the 'cursor' value not found."); @@ -3066,7 +3066,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents') } $relatedCollectionId = $relationship->getAttribute('relatedCollection'); - $relatedCollection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)); + $relatedCollection = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)); foreach ($relations as $index => $doc) { if ($doc instanceof Document) { @@ -3145,16 +3145,16 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents/:docume ->inject('dbForProject') ->inject('mode') ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, string $mode) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -3198,7 +3198,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents/:docume } $relatedCollectionId = $relationship->getAttribute('relatedCollection'); - $relatedCollection = Authorization::skip( + $relatedCollection = $auth->skip( fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); @@ -3237,7 +3237,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents/:docume ->inject('geodb') ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -3357,16 +3357,16 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu throw new Exception(Exception::DOCUMENT_MISSING_PAYLOAD); } - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -3374,7 +3374,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu // Read permission should not be required for update /** @var Document $document */ - $document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); + $document = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); if ($document->isEmpty()) { throw new Exception(Exception::DOCUMENT_NOT_FOUND); @@ -3388,7 +3388,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu ]); // Users can only manage their own roles, API keys and Admin users can manage any - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); if (!$isAPIKey && !$isPrivilegedUser && !\is_null($permissions)) { foreach (Database::PERMISSIONS as $type) { foreach ($permissions as $permission) { @@ -3401,7 +3401,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu $permission->getIdentifier(), $permission->getDimension() ))->toString(); - if (!Authorization::isRole($role)) { + if (!$auth->isRole($role)) { throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')'); } } @@ -3438,7 +3438,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu } $relatedCollectionId = $relationship->getAttribute('relatedCollection'); - $relatedCollection = Authorization::skip( + $relatedCollection = $auth->skip( fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); @@ -3453,7 +3453,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu $relation = new Document($relation); } if ($relation instanceof Document) { - $oldDocument = Authorization::skip(fn () => $dbForProject->getDocument( + $oldDocument = $auth->skip(fn () => $dbForProject->getDocument( 'database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId(), $relation->getId() )); @@ -3522,7 +3522,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu } $relatedCollectionId = $relationship->getAttribute('relatedCollection'); - $relatedCollection = Authorization::skip( + $relatedCollection = $auth->skip( fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); @@ -3576,23 +3576,23 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:doc ->inject('queueForEvents') ->inject('mode') ->action(function (string $databaseId, string $collectionId, string $documentId, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $queueForEvents, string $mode) { - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); } // Read permission should not be required for delete - $document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); + $document = $auth->skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); if ($document->isEmpty()) { throw new Exception(Exception::DOCUMENT_NOT_FOUND); @@ -3632,7 +3632,7 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:doc } $relatedCollectionId = $relationship->getAttribute('relatedCollection'); - $relatedCollection = Authorization::skip( + $relatedCollection = $auth->skip( fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); @@ -3685,7 +3685,7 @@ Http::get('/v1/databases/usage') METRIC_DOCUMENTS, ]; - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), @@ -3769,7 +3769,7 @@ Http::get('/v1/databases/:databaseId/usage') str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_DOCUMENTS), ]; - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), @@ -3855,7 +3855,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/usage') str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getInternalId(), $collectionDocument->getInternalId()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), ]; - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 29d8ddb9da..59c3254d67 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -500,7 +500,7 @@ Http::get('/v1/functions/:functionId/usage') str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), ]; - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), @@ -592,7 +592,7 @@ Http::get('/v1/functions/usage') METRIC_EXECUTIONS_COMPUTE, ]; - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), @@ -828,7 +828,7 @@ Http::put('/v1/functions/:functionId') ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('schedule', $function->getAttribute('schedule')) ->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment'))); - Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); + $auth->skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); $queueForEvents->setParam('functionId', $function->getId()); @@ -973,7 +973,7 @@ Http::patch('/v1/functions/:functionId/deployments/:deploymentId') ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('schedule', $function->getAttribute('schedule')) ->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment'))); - Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); + $auth->skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); $queueForEvents ->setParam('functionId', $function->getId()) @@ -1018,7 +1018,7 @@ Http::delete('/v1/functions/:functionId') $schedule ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('active', false); - Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); + $auth->skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) @@ -1465,7 +1465,7 @@ Http::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId' throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); } - $build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $buildId)); + $build = $auth->skip(fn () => $dbForProject->getDocument('builds', $buildId)); if ($build->isEmpty()) { throw new Exception(Exception::BUILD_NOT_FOUND); @@ -1524,10 +1524,10 @@ Http::post('/v1/functions/:functionId/executions') ->inject('geodb') ->action(function (string $functionId, string $body, bool $async, string $path, string $method, array $headers, Response $response, Document $project, Database $dbForProject, Document $user, Event $queueForEvents, Usage $queueForUsage, string $mode, Func $queueForFunctions, Reader $geodb) { - $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); + $function = $auth->skip(fn () => $dbForProject->getDocument('functions', $functionId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::FUNCTION_NOT_FOUND); @@ -1542,7 +1542,7 @@ Http::post('/v1/functions/:functionId/executions') throw new Exception(Exception::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported'); } - $deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', ''))); + $deployment = $auth->skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', ''))); if ($deployment->getAttribute('resourceId') !== $function->getId()) { throw new Exception(Exception::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function'); @@ -1553,7 +1553,7 @@ Http::post('/v1/functions/:functionId/executions') } /** Check if build has completed */ - $build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''))); + $build = $auth->skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''))); if ($build->isEmpty()) { throw new Exception(Exception::BUILD_NOT_FOUND); } @@ -1646,7 +1646,7 @@ Http::post('/v1/functions/:functionId/executions') if ($async) { if ($function->getAttribute('logging')) { /** @var Document $execution */ - $execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution)); + $execution = $auth->skip(fn () => $dbForProject->createDocument('executions', $execution)); } $queueForFunctions @@ -1761,10 +1761,10 @@ Http::post('/v1/functions/:functionId/executions') if ($function->getAttribute('logging')) { /** @var Document $execution */ - $execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution)); + $execution = $auth->skip(fn () => $dbForProject->createDocument('executions', $execution)); } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -1804,10 +1804,10 @@ Http::get('/v1/functions/:functionId/executions') ->inject('dbForProject') ->inject('mode') ->action(function (string $functionId, array $queries, string $search, Response $response, Database $dbForProject, string $mode) { - $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); + $function = $auth->skip(fn () => $dbForProject->getDocument('functions', $functionId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::FUNCTION_NOT_FOUND); @@ -1850,7 +1850,7 @@ Http::get('/v1/functions/:functionId/executions') $results = $dbForProject->find('executions', $queries); $total = $dbForProject->count('executions', $filterQueries, APP_LIMIT_COUNT); - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); if (!$isPrivilegedUser && !$isAppUser) { @@ -1884,10 +1884,10 @@ Http::get('/v1/functions/:functionId/executions/:executionId') ->inject('dbForProject') ->inject('mode') ->action(function (string $functionId, string $executionId, Response $response, Database $dbForProject, string $mode) { - $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); + $function = $auth->skip(fn () => $dbForProject->getDocument('functions', $functionId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::FUNCTION_NOT_FOUND); @@ -1903,7 +1903,7 @@ Http::get('/v1/functions/:functionId/executions/:executionId') throw new Exception(Exception::EXECUTION_NOT_FOUND); } - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); if (!$isPrivilegedUser && !$isAppUser) { @@ -1973,7 +1973,7 @@ Http::post('/v1/functions/:functionId/variables') ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('schedule', $function->getAttribute('schedule')) ->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment'))); - Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); + $auth->skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -2102,7 +2102,7 @@ Http::put('/v1/functions/:functionId/variables/:variableId') ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('schedule', $function->getAttribute('schedule')) ->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment'))); - Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); + $auth->skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); $response->dynamic($variable, Response::MODEL_VARIABLE); }); @@ -2150,7 +2150,7 @@ Http::delete('/v1/functions/:functionId/variables/:variableId') ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('schedule', $function->getAttribute('schedule')) ->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment'))); - Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); + $auth->skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); $response->noContent(); }); diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 1bb08c74a0..5e0d31a294 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -867,7 +867,7 @@ Http::get('/v1/messaging/providers') if ($cursor) { $providerId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('providers', $providerId)); + $cursorDocument = $auth->skip(fn () => $dbForProject->getDocument('providers', $providerId)); if ($cursorDocument->isEmpty()) { throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Provider '{$providerId}' for the 'cursor' value not found."); @@ -2001,7 +2001,7 @@ Http::get('/v1/messaging/topics') if ($cursor) { $topicId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId)); + $cursorDocument = $auth->skip(fn () => $dbForProject->getDocument('topics', $topicId)); if ($cursorDocument->isEmpty()) { throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Topic '{$topicId}' for the 'cursor' value not found."); @@ -2239,7 +2239,7 @@ Http::post('/v1/messaging/topics/:topicId/subscribers') ->action(function (string $subscriberId, string $topicId, string $targetId, Event $queueForEvents, Database $dbForProject, Response $response) { $subscriberId = $subscriberId == 'unique()' ? ID::unique() : $subscriberId; - $topic = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId)); + $topic = $auth->skip(fn () => $dbForProject->getDocument('topics', $topicId)); if ($topic->isEmpty()) { throw new Exception(Exception::TOPIC_NOT_FOUND); @@ -2251,13 +2251,13 @@ Http::post('/v1/messaging/topics/:topicId/subscribers') throw new Exception(Exception::USER_UNAUTHORIZED, $validator->getDescription()); } - $target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $targetId)); + $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId)); if ($target->isEmpty()) { throw new Exception(Exception::USER_TARGET_NOT_FOUND); } - $user = Authorization::skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId'))); + $user = $auth->skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId'))); $subscriber = new Document([ '$id' => $subscriberId, @@ -2290,7 +2290,7 @@ Http::post('/v1/messaging/topics/:topicId/subscribers') default => throw new Exception(Exception::TARGET_PROVIDER_INVALID_TYPE), }; - Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute( + $auth->skip(fn () => $dbForProject->increaseDocumentAttribute( 'topics', $topicId, $totalAttribute, @@ -2339,7 +2339,7 @@ Http::get('/v1/messaging/topics/:topicId/subscribers') $queries[] = Query::search('search', $search); } - $topic = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId)); + $topic = $auth->skip(fn () => $dbForProject->getDocument('topics', $topicId)); if ($topic->isEmpty()) { throw new Exception(Exception::TOPIC_NOT_FOUND); @@ -2357,7 +2357,7 @@ Http::get('/v1/messaging/topics/:topicId/subscribers') if ($cursor) { $subscriberId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('subscribers', $subscriberId)); + $cursorDocument = $auth->skip(fn () => $dbForProject->getDocument('subscribers', $subscriberId)); if ($cursorDocument->isEmpty()) { throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Subscriber '{$subscriberId}' for the 'cursor' value not found."); @@ -2370,8 +2370,8 @@ Http::get('/v1/messaging/topics/:topicId/subscribers') $subscribers = batch(\array_map(function (Document $subscriber) use ($dbForProject) { return function () use ($subscriber, $dbForProject) { - $target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId'))); - $user = Authorization::skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId'))); + $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId'))); + $user = $auth->skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId'))); return $subscriber ->setAttribute('target', $target) @@ -2491,7 +2491,7 @@ Http::get('/v1/messaging/topics/:topicId/subscribers/:subscriberId') ->inject('dbForProject') ->inject('response') ->action(function (string $topicId, string $subscriberId, Database $dbForProject, Response $response) { - $topic = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId)); + $topic = $auth->skip(fn () => $dbForProject->getDocument('topics', $topicId)); if ($topic->isEmpty()) { throw new Exception(Exception::TOPIC_NOT_FOUND); @@ -2503,8 +2503,8 @@ Http::get('/v1/messaging/topics/:topicId/subscribers/:subscriberId') throw new Exception(Exception::SUBSCRIBER_NOT_FOUND); } - $target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId'))); - $user = Authorization::skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId'))); + $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId'))); + $user = $auth->skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId'))); $subscriber ->setAttribute('target', $target) @@ -2534,7 +2534,7 @@ Http::delete('/v1/messaging/topics/:topicId/subscribers/:subscriberId') ->inject('dbForProject') ->inject('response') ->action(function (string $topicId, string $subscriberId, Event $queueForEvents, Database $dbForProject, Response $response) { - $topic = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId)); + $topic = $auth->skip(fn () => $dbForProject->getDocument('topics', $topicId)); if ($topic->isEmpty()) { throw new Exception(Exception::TOPIC_NOT_FOUND); @@ -2557,7 +2557,7 @@ Http::delete('/v1/messaging/topics/:topicId/subscribers/:subscriberId') default => throw new Exception(Exception::TARGET_PROVIDER_INVALID_TYPE), }; - Authorization::skip(fn () => $dbForProject->decreaseDocumentAttribute( + $auth->skip(fn () => $dbForProject->decreaseDocumentAttribute( 'topics', $topicId, $totalAttribute, @@ -3043,7 +3043,7 @@ Http::get('/v1/messaging/messages') if ($cursor) { $messageId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('messages', $messageId)); + $cursorDocument = $auth->skip(fn () => $dbForProject->getDocument('messages', $messageId)); if ($cursorDocument->isEmpty()) { throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Message '{$messageId}' for the 'cursor' value not found."); diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index dc84dc060a..15154fbbed 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -70,7 +70,7 @@ Http::get('/v1/project/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - Authorization::skip(function () use ($dbForProject, $firstDay, $lastDay, $period, $metrics, &$total, &$stats) { + $auth->skip(function () use ($dbForProject, $firstDay, $lastDay, $period, $metrics, &$total, &$stats) { foreach ($metrics['total'] as $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 17f19a926f..2a38e4433f 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -30,15 +30,15 @@ use Utopia\Database\Validator\UID; use Utopia\Domains\Validator\PublicDomain; use Utopia\Locale\Locale; use Utopia\Pools\Group; -use Utopia\Validator\ArrayList; -use Utopia\Validator\Boolean; -use Utopia\Validator\Hostname; -use Utopia\Validator\Integer; -use Utopia\Validator\Multiple; -use Utopia\Validator\Range; -use Utopia\Validator\Text; -use Utopia\Validator\URL; -use Utopia\Validator\WhiteList; +use Utopia\Http\Validator\ArrayList; +use Utopia\Http\Validator\Boolean; +use Utopia\Http\Validator\Hostname; +use Utopia\Http\Validator\Integer; +use Utopia\Http\Validator\Multiple; +use Utopia\Http\Validator\Range; +use Utopia\Http\Validator\Text; +use Utopia\Http\Validator\URL; +use Utopia\Http\Validator\WhiteList; Http::init() ->groups(['projects']) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 591ac5f58d..859daf20f3 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -363,10 +363,10 @@ Http::post('/v1/storage/buckets/:bucketId/files') ->inject('deviceForLocal') ->action(function (string $bucketId, string $fileId, mixed $file, ?array $permissions, Request $request, Response $response, Database $dbForProject, Document $user, Event $queueForEvents, string $mode, Device $deviceForFiles, Device $deviceForLocal) { - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -397,7 +397,7 @@ Http::post('/v1/storage/buckets/:bucketId/files') } // Users can only manage their own roles, API keys and Admin users can manage any - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); if (!Auth::isAppUser($roles) && !Auth::isPrivilegedUser($roles)) { foreach (Database::PERMISSIONS as $type) { foreach ($permissions as $permission) { @@ -410,7 +410,7 @@ Http::post('/v1/storage/buckets/:bucketId/files') $permission->getIdentifier(), $permission->getDimension() ))->toString(); - if (!Authorization::isRole($role)) { + if (!$auth->isRole($role)) { throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')'); } } @@ -635,7 +635,7 @@ Http::post('/v1/storage/buckets/:bucketId/files') if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); } - $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + $file = $auth->skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } } catch (AuthorizationException) { throw new Exception(Exception::USER_UNAUTHORIZED); @@ -682,7 +682,7 @@ Http::post('/v1/storage/buckets/:bucketId/files') if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); } - $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + $file = $auth->skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } } catch (AuthorizationException) { throw new Exception(Exception::USER_UNAUTHORIZED); @@ -725,10 +725,10 @@ Http::get('/v1/storage/buckets/:bucketId/files') ->inject('dbForProject') ->inject('mode') ->action(function (string $bucketId, array $queries, string $search, Response $response, Database $dbForProject, string $mode) { - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -765,7 +765,7 @@ Http::get('/v1/storage/buckets/:bucketId/files') if ($fileSecurity && !$valid) { $cursorDocument = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $cursorDocument = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($cursorDocument->isEmpty()) { @@ -781,8 +781,8 @@ Http::get('/v1/storage/buckets/:bucketId/files') $files = $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries); $total = $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT); } else { - $files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries)); - $total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT)); + $files = $auth->skip(fn () => $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries)); + $total = $auth->skip(fn () => $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT)); } $response->dynamic(new Document([ @@ -809,10 +809,10 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId') ->inject('dbForProject') ->inject('mode') ->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, string $mode) { - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -828,7 +828,7 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId') if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -879,10 +879,10 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing'); } - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -898,7 +898,7 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -1035,10 +1035,10 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/download') ->inject('deviceForFiles') ->action(function (string $bucketId, string $fileId, Request $request, Response $response, Database $dbForProject, string $mode, Device $deviceForFiles) { - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -1054,7 +1054,7 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/download') if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -1174,10 +1174,10 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/view') ->inject('mode') ->inject('deviceForFiles') ->action(function (string $bucketId, string $fileId, Response $response, Request $request, Database $dbForProject, string $mode, Device $deviceForFiles) { - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -1193,7 +1193,7 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/view') if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -1335,10 +1335,10 @@ Http::put('/v1/storage/buckets/:bucketId/files/:fileId') ->inject('queueForEvents') ->action(function (string $bucketId, string $fileId, ?string $name, ?array $permissions, Response $response, Database $dbForProject, Document $user, string $mode, Event $queueForEvents) { - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -1352,7 +1352,7 @@ Http::put('/v1/storage/buckets/:bucketId/files/:fileId') } // Read permission should not be required for update - $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); if ($file->isEmpty()) { throw new Exception(Exception::STORAGE_FILE_NOT_FOUND); @@ -1366,7 +1366,7 @@ Http::put('/v1/storage/buckets/:bucketId/files/:fileId') ]); // Users can only manage their own roles, API keys and Admin users can manage any - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); if (!Auth::isAppUser($roles) && !Auth::isPrivilegedUser($roles) && !\is_null($permissions)) { foreach (Database::PERMISSIONS as $type) { foreach ($permissions as $permission) { @@ -1379,7 +1379,7 @@ Http::put('/v1/storage/buckets/:bucketId/files/:fileId') $permission->getIdentifier(), $permission->getDimension() ))->toString(); - if (!Authorization::isRole($role)) { + if (!$auth->isRole($role)) { throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')'); } } @@ -1403,7 +1403,7 @@ Http::put('/v1/storage/buckets/:bucketId/files/:fileId') throw new Exception(Exception::USER_UNAUTHORIZED); } } else { - $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + $file = $auth->skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } $queueForEvents @@ -1440,10 +1440,10 @@ Http::delete('/v1/storage/buckets/:bucketId/files/:fileId') ->inject('deviceForFiles') ->inject('queueForDeletes') ->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, Event $queueForEvents, string $mode, Device $deviceForFiles, Delete $queueForDeletes) { - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -1457,7 +1457,7 @@ Http::delete('/v1/storage/buckets/:bucketId/files/:fileId') } // Read permission should not be required for delete - $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); if ($file->isEmpty()) { throw new Exception(Exception::STORAGE_FILE_NOT_FOUND); @@ -1491,7 +1491,7 @@ Http::delete('/v1/storage/buckets/:bucketId/files/:fileId') throw new Exception(Exception::USER_UNAUTHORIZED); } } else { - $deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $deleted = $auth->skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if (!$deleted) { @@ -1536,7 +1536,7 @@ Http::get('/v1/storage/usage') ]; $total = []; - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { + $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { foreach ($metrics as $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), @@ -1621,7 +1621,7 @@ Http::get('/v1/storage/:bucketId/usage') ]; - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { + $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { foreach ($metrics as $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 8f1e6018e0..c3542645db 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -65,13 +65,13 @@ Http::post('/v1/teams') ->inject('queueForEvents') ->action(function (string $teamId, string $name, array $roles, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); - $isAppUser = Auth::isAppUser(Authorization::getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); + $isAppUser = Auth::isAppUser($auth->getRoles()); $teamId = $teamId == 'unique()' ? ID::unique() : $teamId; try { - $team = Authorization::skip(fn () => $dbForProject->createDocument('teams', new Document([ + $team = $auth->skip(fn () => $dbForProject->createDocument('teams', new Document([ '$id' => $teamId, '$permissions' => [ Permission::read(Role::team($teamId)), @@ -397,8 +397,8 @@ Http::post('/v1/teams/:teamId/memberships') ->inject('queueForMessaging') ->inject('queueForEvents') ->action(function (string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Mail $queueForMails, Messaging $queueForMessaging, Event $queueForEvents) { - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if (empty($url)) { if (!$isAPIKey && !$isPrivilegedUser) { @@ -409,8 +409,8 @@ Http::post('/v1/teams/:teamId/memberships') if (empty($userId) && empty($email) && empty($phone)) { throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'At least one of userId, email, or phone is required'); } - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); - $isAppUser = Auth::isAppUser(Authorization::getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); + $isAppUser = Auth::isAppUser($auth->getRoles()); if (!$isPrivilegedUser && !$isAppUser && empty(Http::getEnv('_APP_SMTP_HOST'))) { throw new Exception(Exception::GENERAL_SMTP_DISABLED); @@ -470,7 +470,7 @@ Http::post('/v1/teams/:teamId/memberships') try { $userId = ID::unique(); - $invitee = Authorization::skip(fn () => $dbForProject->createDocument('users', new Document([ + $invitee = $auth->skip(fn () => $dbForProject->createDocument('users', new Document([ '$id' => $userId, '$permissions' => [ Permission::read(Role::any()), @@ -506,7 +506,7 @@ Http::post('/v1/teams/:teamId/memberships') } } - $isOwner = Authorization::isRole('team:' . $team->getId() . '/owner'); + $isOwner = $auth->isRole('team:' . $team->getId() . '/owner'); if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server) throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to send invitations for this team'); @@ -538,12 +538,12 @@ Http::post('/v1/teams/:teamId/memberships') if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership try { - $membership = Authorization::skip(fn () => $dbForProject->createDocument('memberships', $membership)); + $membership = $auth->skip(fn () => $dbForProject->createDocument('memberships', $membership)); } catch (Duplicate $th) { throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS); } - Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1)); + $auth->skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1)); $dbForProject->purgeCachedDocument('users', $invitee->getId()); } else { @@ -880,9 +880,9 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId') throw new Exception(Exception::USER_NOT_FOUND); } - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); - $isAppUser = Auth::isAppUser(Authorization::getRoles()); - $isOwner = Authorization::isRole('team:' . $team->getId() . '/owner'); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); + $isAppUser = Auth::isAppUser($auth->getRoles()); + $isOwner = $auth->isRole('team:' . $team->getId() . '/owner'); if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server) throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to modify roles'); @@ -951,7 +951,7 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId/status') throw new Exception(Exception::TEAM_MEMBERSHIP_MISMATCH); } - $team = Authorization::skip(fn () => $dbForProject->getDocument('teams', $teamId)); + $team = $auth->skip(fn () => $dbForProject->getDocument('teams', $teamId)); if ($team->isEmpty()) { throw new Exception(Exception::TEAM_NOT_FOUND); @@ -982,11 +982,11 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId/status') ->setAttribute('confirm', true) ; - Authorization::skip(fn () => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true))); + $auth->skip(fn () => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true))); // Log user in - Authorization::setRole(Role::user($user->getId())->toString()); + $auth->addRole(Role::user($user->getId())->toString()); $detector = new Detector($request->getUserAgent('UNKNOWN')); $record = $geodb->get($request->getIP()); @@ -1016,13 +1016,13 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId/status') $dbForProject->purgeCachedDocument('users', $user->getId()); - Authorization::setRole(Role::user($userId)->toString()); + $auth->addRole(Role::user($userId)->toString()); $membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership); $dbForProject->purgeCachedDocument('users', $user->getId()); - Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1)); + $auth->skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1)); $queueForEvents ->setParam('teamId', $team->getId()) @@ -1102,7 +1102,7 @@ Http::delete('/v1/teams/:teamId/memberships/:membershipId') $dbForProject->purgeCachedDocument('users', $user->getId()); if ($membership->getAttribute('confirm')) { // Count only confirmed members - Authorization::skip(fn () => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0)); + $auth->skip(fn () => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0)); } $queueForEvents diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 74b3138313..6bb9d6e555 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -2120,7 +2120,7 @@ Http::get('/v1/users/usage') METRIC_SESSIONS, ]; - Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { + $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $count => $metric) { $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index 7be9c2e1ad..d1832a5825 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -46,11 +46,11 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId if ($resourceType === "function") { $projectId = $resource->getAttribute('projectId'); - $project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId)); + $project = $auth->skip(fn () => $dbForConsole->getDocument('projects', $projectId)); $dbForProject = $getProjectDB($project); $functionId = $resource->getAttribute('resourceId'); - $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); + $function = $auth->skip(fn () => $dbForProject->getDocument('functions', $functionId)); $functionInternalId = $function->getInternalId(); $deploymentId = ID::unique(); @@ -97,7 +97,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId $latestCommentId = ''; if (!empty($providerPullRequestId)) { - $latestComment = Authorization::skip(fn () => $dbForConsole->findOne('vcsComments', [ + $latestComment = $auth->skip(fn () => $dbForConsole->findOne('vcsComments', [ Query::equal('providerRepositoryId', [$providerRepositoryId]), Query::equal('providerPullRequestId', [$providerPullRequestId]), Query::orderDesc('$createdAt'), @@ -118,7 +118,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId if (!empty($latestCommentId)) { $teamId = $project->getAttribute('teamId', ''); - $latestComment = Authorization::skip(fn () => $dbForConsole->createDocument('vcsComments', new Document([ + $latestComment = $auth->skip(fn () => $dbForConsole->createDocument('vcsComments', new Document([ '$id' => ID::unique(), '$permissions' => [ Permission::read(Role::team(ID::custom($teamId))), @@ -139,7 +139,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId } } } elseif (!empty($providerBranch)) { - $latestComments = Authorization::skip(fn () => $dbForConsole->find('vcsComments', [ + $latestComments = $auth->skip(fn () => $dbForConsole->find('vcsComments', [ Query::equal('providerRepositoryId', [$providerRepositoryId]), Query::equal('providerBranch', [$providerBranch]), Query::orderDesc('$createdAt'), @@ -856,7 +856,7 @@ Http::post('/v1/vcs/github/events') $github->initializeVariables($providerInstallationId, $privateKey, $githubAppId); //find functionId from functions table - $repositories = Authorization::skip(fn () => $dbForConsole->find('repositories', [ + $repositories = $auth->skip(fn () => $dbForConsole->find('repositories', [ Query::equal('providerRepositoryId', [$providerRepositoryId]), Query::limit(100), ])); @@ -876,13 +876,13 @@ Http::post('/v1/vcs/github/events') ]); foreach ($installations as $installation) { - $repositories = Authorization::skip(fn () => $dbForConsole->find('repositories', [ + $repositories = $auth->skip(fn () => $dbForConsole->find('repositories', [ Query::equal('installationInternalId', [$installation->getInternalId()]), Query::limit(1000) ])); foreach ($repositories as $repository) { - Authorization::skip(fn () => $dbForConsole->deleteDocument('repositories', $repository->getId())); + $auth->skip(fn () => $dbForConsole->deleteDocument('repositories', $repository->getId())); } $dbForConsole->deleteDocument('installations', $installation->getId()); @@ -914,7 +914,7 @@ Http::post('/v1/vcs/github/events') $providerCommitAuthor = $commitDetails["commitAuthor"] ?? ''; $providerCommitMessage = $commitDetails["commitMessage"] ?? ''; - $repositories = Authorization::skip(fn () => $dbForConsole->find('repositories', [ + $repositories = $auth->skip(fn () => $dbForConsole->find('repositories', [ Query::equal('providerRepositoryId', [$providerRepositoryId]), Query::orderDesc('$createdAt') ])); @@ -928,7 +928,7 @@ Http::post('/v1/vcs/github/events') $external = $parsedPayload["external"] ?? true; if ($external) { - $repositories = Authorization::skip(fn () => $dbForConsole->find('repositories', [ + $repositories = $auth->skip(fn () => $dbForConsole->find('repositories', [ Query::equal('providerRepositoryId', [$providerRepositoryId]), Query::orderDesc('$createdAt') ])); @@ -939,7 +939,7 @@ Http::post('/v1/vcs/github/events') if (\in_array($providerPullRequestId, $providerPullRequestIds)) { $providerPullRequestIds = \array_diff($providerPullRequestIds, [$providerPullRequestId]); $repository = $repository->setAttribute('providerPullRequestIds', $providerPullRequestIds); - $repository = Authorization::skip(fn () => $dbForConsole->updateDocument('repositories', $repository->getId(), $repository)); + $repository = $auth->skip(fn () => $dbForConsole->updateDocument('repositories', $repository->getId(), $repository)); } } } @@ -1099,7 +1099,7 @@ Http::patch('/v1/vcs/github/installations/:installationId/repositories/:reposito throw new Exception(Exception::INSTALLATION_NOT_FOUND); } - $repository = Authorization::skip(fn () => $dbForConsole->getDocument('repositories', $repositoryId, [ + $repository = $auth->skip(fn () => $dbForConsole->getDocument('repositories', $repositoryId, [ Query::equal('projectInternalId', [$project->getInternalId()]) ])); @@ -1116,7 +1116,7 @@ Http::patch('/v1/vcs/github/installations/:installationId/repositories/:reposito // TODO: Delete from array when PR is closed - $repository = Authorization::skip(fn () => $dbForConsole->updateDocument('repositories', $repository->getId(), $repository)); + $repository = $auth->skip(fn () => $dbForConsole->updateDocument('repositories', $repository->getId(), $repository)); $privateKey = Http::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY'); $githubAppId = Http::getEnv('_APP_VCS_GITHUB_APP_ID'); diff --git a/app/controllers/general.php b/app/controllers/general.php index d14da35f7c..606cfac9db 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -52,7 +52,7 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $host = $request->getHostname() ?? ''; - $route = Authorization::skip( + $route = $auth->skip( fn () => $dbForConsole->find('rules', [ Query::equal('domain', [$host]), Query::limit(1) @@ -80,7 +80,7 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo } $projectId = $route->getAttribute('projectId'); - $project = Authorization::skip( + $project = $auth->skip( fn () => $dbForConsole->getDocument('projects', $projectId) ); if (array_key_exists('proxy', $project->getAttribute('services', []))) { @@ -124,11 +124,11 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $requestHeaders = $request->getHeaders(); - $project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId)); + $project = $auth->skip(fn () => $dbForConsole->getDocument('projects', $projectId)); $dbForProject = $getProjectDB($project); - $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); + $function = $auth->skip(fn () => $dbForProject->getDocument('functions', $functionId)); if ($function->isEmpty() || !$function->getAttribute('enabled')) { throw new AppwriteException(AppwriteException::FUNCTION_NOT_FOUND); @@ -143,7 +143,7 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported'); } - $deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', ''))); + $deployment = $auth->skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', ''))); if ($deployment->getAttribute('resourceId') !== $function->getId()) { throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function'); @@ -154,7 +154,7 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo } /** Check if build has completed */ - $build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''))); + $build = $auth->skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''))); if ($build->isEmpty()) { throw new AppwriteException(AppwriteException::BUILD_NOT_FOUND); } @@ -316,7 +316,7 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo if ($function->getAttribute('logging')) { /** @var Document $execution */ - $execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution)); + $execution = $auth->skip(fn () => $dbForProject->createDocument('executions', $execution)); } $execution->setAttribute('logs', ''); @@ -444,7 +444,7 @@ Http::init() } elseif (str_starts_with($request->getURI(), '/.well-known/acme-challenge')) { Console::warning('Skipping SSL certificates generation on ACME challenge.'); } else { - Authorization::disable(); + $auth->disable(); $envDomain = Http::getEnv('_APP_DOMAIN', ''); $mainDomain = null; @@ -483,7 +483,7 @@ Http::init() } $domains[$domain->get()] = true; - Authorization::reset(); // ensure authorization is re-enabled + $auth->reset(); // ensure authorization is re-enabled } Config::setParam('domains', $domains); } @@ -701,7 +701,7 @@ Http::error() $log->addExtra('line', $error->getLine()); $log->addExtra('trace', $error->getTraceAsString()); $log->addExtra('detailedTrace', $error->getTrace()); - $log->addExtra('roles', Authorization::getRoles()); + $log->addExtra('roles', $auth->getRoles()); $action = $route->getLabel("sdk.namespace", "UNKNOWN_NAMESPACE") . '.' . $route->getLabel("sdk.method", "UNKNOWN_METHOD"); $log->setAction($action); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 3c17f3ae8c..e86215158b 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -156,7 +156,8 @@ Http::init() ->inject('session') ->inject('servers') ->inject('mode') - ->action(function (App $utopia, Request $request, Database $dbForConsole, Document $project, Document $user, ?Document $session, array $servers, string $mode) { + ->inject('auth') + ->action(function (Http $utopia, Request $request, Database $dbForConsole, Document $project, Document $user, ?Document $session, array $servers, string $mode, Authorization $auth) { $route = $utopia->getRoute(); if ($project->isEmpty()) { @@ -220,8 +221,8 @@ Http::init() throw new Exception(Exception::PROJECT_KEY_EXPIRED); } - Authorization::setRole(Auth::USER_ROLE_APPS); - Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys. + $auth->addRole(Auth::USER_ROLE_APPS); + $auth->setDefaultStatus(false); // Cancel security segmentation for API keys. $accessedAt = $key->getAttribute('accessedAt', ''); if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_KEY_ACCCESS)) > $accessedAt) { @@ -247,10 +248,10 @@ Http::init() } } - Authorization::setRole($role); + $auth->addRole($role); - foreach (Auth::getRoles($user) as $authRole) { - Authorization::setRole($authRole); + foreach (Auth::getRoles($user, $auth) as $authRole) { + $auth->addRole($authRole); } $service = $route->getLabel('sdk.namespace', ''); @@ -258,7 +259,7 @@ Http::init() if ( array_key_exists($service, $project->getAttribute('services', [])) && !$project->getAttribute('services', [])[$service] - && !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles())) + && !(Auth::isPrivilegedUser($auth->getRoles()) || Auth::isAppUser($auth->getRoles())) ) { throw new Exception(Exception::GENERAL_SERVICE_DISABLED); } @@ -311,7 +312,8 @@ Http::init() ->inject('queueForUsage') ->inject('dbForProject') ->inject('mode') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode) use ($databaseListener) { + ->inject('auth') + ->action(function (Http $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode, Authorization $auth) use ($databaseListener) { $route = $utopia->getRoute(); @@ -340,7 +342,7 @@ Http::init() $closestLimit = null; - $roles = Authorization::getRoles(); + $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -421,10 +423,10 @@ Http::init() if ($type === 'bucket') { $bucketId = $parts[1] ?? null; - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = Auth::isAppUser(Authorization::getRoles()); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $isAPIKey = Auth::isAppUser($auth->getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); @@ -443,7 +445,7 @@ Http::init() if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = $auth->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -490,7 +492,7 @@ Http::shutdown() ->inject('response') ->inject('project') ->inject('dbForProject') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Database $dbForProject) { + ->action(function (Http $utopia, Request $request, Response $response, Document $project, Database $dbForProject) { $sessionLimit = $project->getAttribute('auths', [])['maxSessions'] ?? APP_LIMIT_USER_SESSIONS_DEFAULT; $session = $response->getPayload(); $userId = $session['userId'] ?? ''; @@ -535,9 +537,10 @@ Http::shutdown() ->inject('queueForFunctions') ->inject('mode') ->inject('dbForConsole') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Database $dbForProject, Func $queueForFunctions, string $mode, Database $dbForConsole) use ($parseLabel) { + ->inject('auth') + ->action(function (Http $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Database $dbForProject, Func $queueForFunctions, string $mode, Database $dbForConsole, Authorization $auth) use ($parseLabel) { if (!empty($user) && !$user->isEmpty() && empty($user->getInternalId())) { - $user = Authorization::skip(fn () => $dbForProject->getDocument('users', $user->getId())); + $user = $auth->skip(fn () => $dbForProject->getDocument('users', $user->getId())); } $responsePayload = $response->getPayload(); @@ -675,11 +678,11 @@ Http::shutdown() ]) ; $signature = md5($data); - $cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key)); + $cacheLog = $auth->skip(fn () => $dbForProject->getDocument('cache', $key)); $accessedAt = $cacheLog->getAttribute('accessedAt', ''); $now = DateTime::now(); if ($cacheLog->isEmpty()) { - Authorization::skip(fn () => $dbForProject->createDocument('cache', new Document([ + $auth->skip(fn () => $dbForProject->createDocument('cache', new Document([ '$id' => $key, 'resource' => $resource, 'accessedAt' => $now, @@ -687,7 +690,7 @@ Http::shutdown() ]))); } elseif (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_CACHE_UPDATE)) > $accessedAt) { $cacheLog->setAttribute('accessedAt', $now); - Authorization::skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog)); + $auth->skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog)); } if ($signature !== $cacheLog->getAttribute('signature')) { diff --git a/app/controllers/shared/api/auth.php b/app/controllers/shared/api/auth.php index 6880f73e81..a8a0ac9e84 100644 --- a/app/controllers/shared/api/auth.php +++ b/app/controllers/shared/api/auth.php @@ -34,7 +34,8 @@ Http::init() ->inject('request') ->inject('project') ->inject('geodb') - ->action(function (App $utopia, Request $request, Document $project, Reader $geodb) { + ->inject('auth') + ->action(function (Http $utopia, Request $request, Document $project, Reader $geodb, Authorization $auth) { $denylist = Http::getEnv('_APP_CONSOLE_COUNTRIES_DENYLIST', ''); if (!empty($denylist && $project->getId() === 'console')) { $countries = explode(',', $denylist); @@ -47,8 +48,8 @@ Http::init() $route = $utopia->match($request); - $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); - $isAppUser = Auth::isAppUser(Authorization::getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); + $isAppUser = Auth::isAppUser($auth->getRoles()); if ($isAppUser || $isPrivilegedUser) { // Skip limits for app and console devs return; diff --git a/app/http.php b/app/http.php index 34e6b12c1a..54c6374274 100644 --- a/app/http.php +++ b/app/http.php @@ -251,8 +251,8 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo Http::setResource('pools', fn () => $pools); try { - Authorization::cleanRoles(); - Authorization::setRole(Role::any()->toString()); + $auth->cleanRoles(); + $auth->addRole(Role::any()->toString()); $app->run($request, $response); } catch (\Throwable $th) { @@ -293,7 +293,7 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo $log->addExtra('line', $th->getLine()); $log->addExtra('trace', $th->getTraceAsString()); $log->addExtra('detailedTrace', $th->getTrace()); - $log->addExtra('roles', Authorization::getRoles()); + $log->addExtra('roles', $auth->getRoles()); $action = $route->getLabel("sdk.namespace", "UNKNOWN_NAMESPACE") . '.' . $route->getLabel("sdk.method", "UNKNOWN_METHOD"); $log->setAction($action); diff --git a/app/init.php b/app/init.php index ed21d599b9..ca6626223e 100644 --- a/app/init.php +++ b/app/init.php @@ -62,6 +62,8 @@ use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Structure; use Utopia\Domains\Validator\PublicDomain; use Utopia\DSN\DSN; +use Utopia\Http\Request; +use Utopia\Http\Response; use Utopia\Locale\Locale; use Utopia\Logger\Log; use Utopia\Logger\Logger; @@ -436,7 +438,7 @@ Database::addFilter( return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn () => $database->find('sessions', [ + return $database->getAuthorization()->skip(fn () => $database->find('sessions', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), ])); @@ -449,7 +451,7 @@ Database::addFilter( return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn () => $database + return $database->getAuthorization()->skip(fn () => $database ->find('tokens', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), @@ -463,7 +465,7 @@ Database::addFilter( return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn () => $database + return $database->getAuthorization()->skip(fn () => $database ->find('challenges', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), @@ -477,7 +479,7 @@ Database::addFilter( return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn () => $database + return $database->getAuthorization()->skip(fn () => $database ->find('authenticators', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), @@ -491,7 +493,7 @@ Database::addFilter( return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn () => $database + return $database->getAuthorization()->skip(fn () => $database ->find('memberships', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), @@ -583,7 +585,7 @@ Database::addFilter( return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn () => $database + return $database->getAuthorization()->skip(fn () => $database ->find('targets', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY) @@ -597,7 +599,7 @@ Database::addFilter( return; }, function (mixed $value, Document $document, Database $database) { - $targetIds = Authorization::skip(fn () => \array_map( + $targetIds = $database->getAuthorization()->skip(fn () => \array_map( fn ($document) => $document->getAttribute('targetInternalId'), $database->find('subscribers', [ Query::equal('topicInternalId', [$document->getInternalId()]), @@ -1129,15 +1131,9 @@ Http::setResource('clients', function ($request, $console, $project) { return $clients; }, ['request', 'console', 'project']); -Http::setResource('user', function ($mode, $project, $console, $request, $response, $dbForProject, $dbForConsole) { - /** @var Appwrite\Utopia\Request $request */ - /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForProject */ - /** @var Utopia\Database\Database $dbForConsole */ - /** @var string $mode */ +Http::setResource('user', function (string $mode, Document $project, Document $console, Request $request, Response $response, Database $dbForProject, Database $dbForConsole, Authorization $auth) { - Authorization::setDefaultStatus(true); + $auth->setDefaultStatus(true); Auth::setCookieName('a_session_' . $project->getId()); @@ -1201,7 +1197,7 @@ Http::setResource('user', function ($mode, $project, $console, $request, $respon if (APP_MODE_ADMIN === $mode) { if ($user->find('teamId', $project->getAttribute('teamId'), 'memberships')) { - Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users. + $auth->setDefaultStatus(false); // Cancel security segmentation for admin users. } else { $user = new Document([]); } @@ -1234,12 +1230,9 @@ Http::setResource('user', function ($mode, $project, $console, $request, $respon $dbForConsole->setMetadata('user', $user->getId()); return $user; -}, ['mode', 'project', 'console', 'request', 'response', 'dbForProject', 'dbForConsole']); +}, ['mode', 'project', 'console', 'request', 'response', 'dbForProject', 'dbForConsole', 'auth']); -Http::setResource('project', function ($dbForConsole, $request, $console) { - /** @var Appwrite\Utopia\Request $request */ - /** @var Utopia\Database\Database $dbForConsole */ - /** @var Utopia\Database\Document $console */ +Http::setResource('project', function (Database $dbForConsole, Request $request, Document $console, Authorization $auth) { $projectId = $request->getParam('project', $request->getHeader('x-appwrite-project', '')); @@ -1247,10 +1240,10 @@ Http::setResource('project', function ($dbForConsole, $request, $console) { return $console; } - $project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId)); + $project = $auth->skip(fn () => $dbForConsole->getDocument('projects', $projectId)); return $project; -}, ['dbForConsole', 'request', 'console']); +}, ['dbForConsole', 'request', 'console', 'auth']); Http::setResource('session', function (Document $user, Document $project) { if ($user->isEmpty()) { @@ -1546,7 +1539,7 @@ Http::setResource('promiseAdapter', function ($register) { return $register->get('promiseAdapter'); }, ['register']); -Http::setResource('schema', function ($utopia, $dbForProject) { +Http::setResource('schema', function (Http $utopia, Database $dbForProject, Authorization $auth) { $complexity = function (int $complexity, array $args) { $queries = Query::parseQueries($args['queries'] ?? []); @@ -1556,8 +1549,8 @@ Http::setResource('schema', function ($utopia, $dbForProject) { return $complexity * $limit; }; - $attributes = function (int $limit, int $offset) use ($dbForProject) { - $attrs = Authorization::skip(fn () => $dbForProject->find('attributes', [ + $attributes = function (int $limit, int $offset) use ($dbForProject, $auth) { + $attrs = $auth->skip(fn () => $dbForProject->find('attributes', [ Query::limit($limit), Query::offset($offset), ])); @@ -1630,7 +1623,7 @@ Http::setResource('schema', function ($utopia, $dbForProject) { $urls, $params, ); -}, ['utopia', 'dbForProject']); +}, ['utopia', 'dbForProject', 'auth']); Http::setResource('contributors', function () { $path = 'app/config/contributors.json'; diff --git a/app/realtime.php b/app/realtime.php index 1fa6733575..e38caf488a 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -25,6 +25,7 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Adapter\FPM\Server as FPMServer; use Utopia\Logger\Log; use Utopia\WebSocket\Adapter; use Utopia\WebSocket\Server; @@ -191,7 +192,8 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume 'value' => '{}' ]); - $statsDocument = Authorization::skip(fn () => $database->createDocument('realtime', $document)); + $auth = new Authorization(); + $statsDocument = $auth->skip(fn () => $database->createDocument('realtime', $document)); break; } catch (Throwable) { Console::warning("Collection not ready. Retrying connection ({$attempts})..."); @@ -220,7 +222,8 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume ->setAttribute('timestamp', DateTime::now()) ->setAttribute('value', json_encode($payload)); - Authorization::skip(fn () => $database->updateDocument('realtime', $statsDocument->getId(), $statsDocument)); + $auth = new Authorization(); + $auth->skip(fn () => $database->updateDocument('realtime', $statsDocument->getId(), $statsDocument)); } catch (Throwable $th) { call_user_func($logError, $th, "updateWorkerDocument"); } finally { @@ -244,7 +247,8 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, $payload = []; - $list = Authorization::skip(fn () => $database->find('realtime', [ + $auth = new Authorization(); + $list = $auth->skip(fn () => $database->find('realtime', [ Query::greaterThan('timestamp', DateTime::addSeconds(new \DateTime(), -15)), ])); @@ -340,12 +344,13 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, if ($realtime->hasSubscriber($projectId, 'user:' . $userId)) { $connection = array_key_first(reset($realtime->subscriptions[$projectId]['user:' . $userId])); $consoleDatabase = getConsoleDB(); - $project = Authorization::skip(fn () => $consoleDatabase->getDocument('projects', $projectId)); + $auth = new Authorization(); + $project = $auth->skip(fn () => $consoleDatabase->getDocument('projects', $projectId)); $database = getProjectDB($project); $user = $database->getDocument('users', $userId); - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $auth); $realtime->subscribe($projectId, $connection, $roles, $realtime->connections[$connection]['channels']); @@ -389,7 +394,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, }); $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $register, $stats, &$realtime, $logError) { - $app = new App('UTC'); + $app = new Http(new FPMServer(), 'UTC'); $request = new Request($request); $response = new Response(new SwooleResponse()); @@ -442,7 +447,8 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, throw new Exception(Exception::REALTIME_POLICY_VIOLATION, $originValidator->getDescription()); } - $roles = Auth::getRoles($user); + $auth = new Authorization(); + $roles = Auth::getRoles($user, $auth); $channels = Realtime::convertChannels($request->getQuery('channels', []), $user->getId()); @@ -502,7 +508,8 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re $database = getConsoleDB(); if ($projectId !== 'console') { - $project = Authorization::skip(fn () => $database->getDocument('projects', $projectId)); + $auth = new Authorization(); + $project = $auth->skip(fn () => $database->getDocument('projects', $projectId)); $database = getProjectDB($project); } else { $project = null; @@ -554,7 +561,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Session is not valid.'); } - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $auth); $channels = Realtime::convertChannels(array_flip($realtime->connections[$connection]['channels']), $user->getId()); $realtime->subscribe($realtime->connections[$connection]['projectId'], $connection, $roles, $channels); diff --git a/app/worker.php b/app/worker.php index ea1c67734c..e81e0f9f5f 100644 --- a/app/worker.php +++ b/app/worker.php @@ -38,7 +38,7 @@ use Utopia\Storage\Device\Local; global $register; -Authorization::disable(); +$auth->disable(); Runtime::enableCoroutine(SWOOLE_HOOK_ALL); Server::setResource('register', fn () => $register); @@ -228,6 +228,8 @@ Server::setResource('deviceForLocalFiles', function (Document $project) { return new Local(APP_STORAGE_UPLOADS . '/app-' . $project->getId()); }, ['project']); +Server::setResource('authorization', fn () => new Authorization()); + $pools = $register->get('pools'); $platform = new Appwrite(); $args = $_SERVER['argv']; @@ -284,7 +286,8 @@ $worker ->inject('log') ->inject('pools') ->inject('project') - ->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project) use ($queueName) { + ->inject('auth') + ->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project, Authorization $auth) use ($queueName) { $pools->reclaim(); $version = Http::getEnv('_APP_VERSION', 'UNKNOWN'); @@ -306,7 +309,7 @@ $worker $log->addExtra('line', $error->getLine()); $log->addExtra('trace', $error->getTraceAsString()); $log->addExtra('detailedTrace', $error->getTrace()); - $log->addExtra('roles', Authorization::getRoles()); + $log->addExtra('roles', $auth->getRoles()); $isProduction = Http::getEnv('_APP_ENV', 'development') === 'production'; $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); diff --git a/composer.json b/composer.json index c95f4012bc..acb933c7e4 100644 --- a/composer.json +++ b/composer.json @@ -46,10 +46,10 @@ "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "0.37.*", - "utopia-php/analytics": "0.10.*", + "utopia-php/analytics": "dev-feat-framework-v2 as 0.10.99", "utopia-php/audit": "0.39.*", "utopia-php/cache": "0.9.*", - "utopia-php/cli": "0.15.*", + "utopia-php/cli": "0.17.*", "utopia-php/config": "0.2.*", "utopia-php/database": "dev-feat-framework-v2 as 0.49.99", "utopia-php/domains": "0.5.*", @@ -60,10 +60,11 @@ "utopia-php/logger": "0.3.*", "utopia-php/messaging": "0.10.*", "utopia-php/migration": "0.4.*", - "utopia-php/orchestration": "0.9.*", - "utopia-php/platform": "0.5.*", + "utopia-php/orchestration": "dev-feat-framework-v2 as 0.9.99", + "utopia-php/platform": "dev-feat-framework-v2 as 0.5.99", "utopia-php/pools": "0.4.*", - "utopia-php/queue": "0.7.*", + "utopia-php/view": "0.1.*", + "utopia-php/queue": "dev-feat-framework-v2-v2 as 0.7.99", "utopia-php/registry": "0.5.*", "utopia-php/storage": "0.18.*", "utopia-php/vcs": "0.6.*", diff --git a/composer.lock b/composer.lock index 3052c56b4a..a90d6b2d3e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f51e2c69cdc67f3a07c4cf5d91bf5de2", + "content-hash": "98a533604587b5d0f5cc3c52ae177aeb", "packages": [ { "name": "adhocore/jwt", @@ -1270,21 +1270,21 @@ }, { "name": "utopia-php/analytics", - "version": "0.10.2", + "version": "dev-feat-framework-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/analytics.git", - "reference": "14c805114736f44c26d6d24b176a2f8b93d86a1f" + "reference": "5d59c2e50381a25adecbca979ed5a7c81307442f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/analytics/zipball/14c805114736f44c26d6d24b176a2f8b93d86a1f", - "reference": "14c805114736f44c26d6d24b176a2f8b93d86a1f", + "url": "https://api.github.com/repos/utopia-php/analytics/zipball/5d59c2e50381a25adecbca979ed5a7c81307442f", + "reference": "5d59c2e50381a25adecbca979ed5a7c81307442f", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/cli": "^0.15.0" + "utopia-php/cli": "0.17.*" }, "require-dev": { "laravel/pint": "dev-main", @@ -1310,9 +1310,9 @@ ], "support": { "issues": "https://github.com/utopia-php/analytics/issues", - "source": "https://github.com/utopia-php/analytics/tree/0.10.2" + "source": "https://github.com/utopia-php/analytics/tree/feat-framework-v2" }, - "time": "2023-03-22T12:01:09+00:00" + "time": "2024-03-07T15:54:19+00:00" }, { "name": "utopia-php/audit", @@ -1413,21 +1413,21 @@ }, { "name": "utopia-php/cli", - "version": "0.15.0", + "version": "0.17.0", "source": { "type": "git", "url": "https://github.com/utopia-php/cli.git", - "reference": "ccb7c8125ffe0254fef8f25744bfa376eb7bd0ea" + "reference": "0829fd5215afe88f53f3091cedc808da801fd1bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cli/zipball/ccb7c8125ffe0254fef8f25744bfa376eb7bd0ea", - "reference": "ccb7c8125ffe0254fef8f25744bfa376eb7bd0ea", + "url": "https://api.github.com/repos/utopia-php/cli/zipball/0829fd5215afe88f53f3091cedc808da801fd1bb", + "reference": "0829fd5215afe88f53f3091cedc808da801fd1bb", "shasum": "" }, "require": { "php": ">=7.4", - "utopia-php/framework": "0.*.*" + "utopia-php/framework": "0.34.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -1456,9 +1456,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cli/issues", - "source": "https://github.com/utopia-php/cli/tree/0.15.0" + "source": "https://github.com/utopia-php/cli/tree/0.17.0" }, - "time": "2023-03-01T05:55:14+00:00" + "time": "2024-01-24T11:37:29+00:00" }, { "name": "utopia-php/config", @@ -1517,12 +1517,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "79fd5790227e039832372f2c6c9c284f6f1284bb" + "reference": "bdd9140e40c77faadb0cf2f5050b466c34eef673" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/79fd5790227e039832372f2c6c9c284f6f1284bb", - "reference": "79fd5790227e039832372f2c6c9c284f6f1284bb", + "url": "https://api.github.com/repos/utopia-php/database/zipball/bdd9140e40c77faadb0cf2f5050b466c34eef673", + "reference": "bdd9140e40c77faadb0cf2f5050b466c34eef673", "shasum": "" }, "require": { @@ -1530,6 +1530,7 @@ "ext-pdo": "*", "php": ">=8.0", "utopia-php/cache": "0.9.*", + "utopia-php/fetch": "0.1.*", "utopia-php/framework": "0.34.*", "utopia-php/mongo": "0.3.*" }, @@ -1565,7 +1566,7 @@ "issues": "https://github.com/utopia-php/database/issues", "source": "https://github.com/utopia-php/database/tree/feat-framework-v2" }, - "time": "2024-02-27T10:05:08+00:00" + "time": "2024-03-07T16:55:44+00:00" }, { "name": "utopia-php/domains", @@ -1674,6 +1675,45 @@ }, "time": "2023-11-02T12:01:43+00:00" }, + { + "name": "utopia-php/fetch", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/fetch.git", + "reference": "2fa214b9262acd1a3583515a364da4f35929d5c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/fetch/zipball/2fa214b9262acd1a3583515a364da4f35929d5c5", + "reference": "2fa214b9262acd1a3583515a364da4f35929d5c5", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "^1.5.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Fetch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library that provides an interface for making HTTP Requests.", + "support": { + "issues": "https://github.com/utopia-php/fetch/issues", + "source": "https://github.com/utopia-php/fetch/tree/0.1.0" + }, + "time": "2023-10-10T11:58:32+00:00" + }, { "name": "utopia-php/framework", "version": "0.34.2", @@ -2034,21 +2074,21 @@ }, { "name": "utopia-php/orchestration", - "version": "0.9.1", + "version": "dev-feat-framework-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/orchestration.git", - "reference": "55f43513b3f940a3f4f9c2cde7682d0c2581beb0" + "reference": "ede2b7a60bd1630ef8bd7fdbbc3cf73275fc9f28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/55f43513b3f940a3f4f9c2cde7682d0c2581beb0", - "reference": "55f43513b3f940a3f4f9c2cde7682d0c2581beb0", + "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/ede2b7a60bd1630ef8bd7fdbbc3cf73275fc9f28", + "reference": "ede2b7a60bd1630ef8bd7fdbbc3cf73275fc9f28", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/cli": "0.15.*" + "utopia-php/cli": "0.17.*" }, "require-dev": { "laravel/pint": "^1.2", @@ -2078,30 +2118,31 @@ ], "support": { "issues": "https://github.com/utopia-php/orchestration/issues", - "source": "https://github.com/utopia-php/orchestration/tree/0.9.1" + "source": "https://github.com/utopia-php/orchestration/tree/feat-framework-v2" }, - "time": "2023-03-17T15:05:06+00:00" + "time": "2024-03-07T15:56:18+00:00" }, { "name": "utopia-php/platform", - "version": "0.5.1", + "version": "dev-feat-framework-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285" + "reference": "88711a2992ff0edbf196cdf1f48b5614e1e423f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/3eceef0b6593fe0f7d2efd36d40402a395a4c285", - "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/88711a2992ff0edbf196cdf1f48b5614e1e423f7", + "reference": "88711a2992ff0edbf196cdf1f48b5614e1e423f7", "shasum": "" }, "require": { "ext-json": "*", "ext-redis": "*", "php": ">=8.0", - "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.*.*" + "utopia-php/cli": "0.17.*", + "utopia-php/framework": "0.34.*", + "utopia-php/queue": "dev-feat-framework-v2-v2 as 0.7.99" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2127,9 +2168,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.5.1" + "source": "https://github.com/utopia-php/platform/tree/feat-framework-v2" }, - "time": "2023-12-26T16:14:41+00:00" + "time": "2024-03-07T15:44:09+00:00" }, { "name": "utopia-php/pools", @@ -2184,22 +2225,22 @@ }, { "name": "utopia-php/queue", - "version": "0.7.0", + "version": "dev-feat-framework-v2-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "917565256eb94bcab7246f7a746b1a486813761b" + "reference": "e613ccc1d4da4219b60576ddfe79dadb182bb74e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/917565256eb94bcab7246f7a746b1a486813761b", - "reference": "917565256eb94bcab7246f7a746b1a486813761b", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/e613ccc1d4da4219b60576ddfe79dadb182bb74e", + "reference": "e613ccc1d4da4219b60576ddfe79dadb182bb74e", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.*.*" + "utopia-php/cli": "0.17.*", + "utopia-php/framework": "0.34.*" }, "require-dev": { "laravel/pint": "^0.2.3", @@ -2239,9 +2280,9 @@ ], "support": { "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.7.0" + "source": "https://github.com/utopia-php/queue/tree/feat-framework-v2-v2" }, - "time": "2024-01-17T19:00:43+00:00" + "time": "2024-03-07T15:43:35+00:00" }, { "name": "utopia-php/registry", @@ -2455,6 +2496,49 @@ }, "time": "2024-01-08T17:11:12+00:00" }, + { + "name": "utopia-php/view", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/view.git", + "reference": "013a495af4e625df172d9bd534011014cb32bbab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/view/zipball/013a495af4e625df172d9bd534011014cb32bbab", + "reference": "013a495af4e625df172d9bd534011014cb32bbab", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "^1.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.25" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\View\\": "src/View" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple, light and advanced PHP rendering engine", + "keywords": [ + "php", + "view" + ], + "support": { + "issues": "https://github.com/utopia-php/view/issues", + "source": "https://github.com/utopia-php/view/tree/0.1.0" + }, + "time": "2023-09-10T12:07:26+00:00" + }, { "name": "utopia-php/websocket", "version": "0.1.0", @@ -5371,58 +5455,47 @@ } ], "time": "2023-11-21T18:54:41+00:00" - }, - { - "name": "utopia-php/fetch", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/fetch.git", - "reference": "2fa214b9262acd1a3583515a364da4f35929d5c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/fetch/zipball/2fa214b9262acd1a3583515a364da4f35929d5c5", - "reference": "2fa214b9262acd1a3583515a364da4f35929d5c5", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "laravel/pint": "^1.5.0", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Fetch\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple library that provides an interface for making HTTP Requests.", - "support": { - "issues": "https://github.com/utopia-php/fetch/issues", - "source": "https://github.com/utopia-php/fetch/tree/0.1.0" - }, - "time": "2023-10-10T11:58:32+00:00" } ], "aliases": [ + { + "package": "utopia-php/analytics", + "version": "dev-feat-framework-v2", + "alias": "0.10.99", + "alias_normalized": "0.10.99.0" + }, { "package": "utopia-php/database", "version": "dev-feat-framework-v2", "alias": "0.49.99", "alias_normalized": "0.49.99.0" + }, + { + "package": "utopia-php/orchestration", + "version": "dev-feat-framework-v2", + "alias": "0.9.99", + "alias_normalized": "0.9.99.0" + }, + { + "package": "utopia-php/platform", + "version": "dev-feat-framework-v2", + "alias": "0.5.99", + "alias_normalized": "0.5.99.0" + }, + { + "package": "utopia-php/queue", + "version": "dev-feat-framework-v2-v2", + "alias": "0.7.99", + "alias_normalized": "0.7.99.0" } ], "minimum-stability": "stable", "stability-flags": { + "utopia-php/analytics": 20, "utopia-php/database": 20, + "utopia-php/orchestration": 20, + "utopia-php/platform": 20, + "utopia-php/queue": 20, "appwrite/sdk-generator": 5 }, "prefer-stable": false, diff --git a/src/Appwrite/Auth/Auth.php b/src/Appwrite/Auth/Auth.php index 1e8109622e..291c16bf0d 100644 --- a/src/Appwrite/Auth/Auth.php +++ b/src/Appwrite/Auth/Auth.php @@ -439,13 +439,14 @@ class Auth * Returns all roles for a user. * * @param Document $user + * @param Authorization $auth * @return array */ - public static function getRoles(Document $user): array + public static function getRoles(Document $user, Authorization $auth): array { $roles = []; - if (!self::isPrivilegedUser(Authorization::getRoles()) && !self::isAppUser(Authorization::getRoles())) { + if (!self::isPrivilegedUser($auth->getRoles()) && !self::isAppUser($auth->getRoles())) { if ($user->getId()) { $roles[] = Role::user($user->getId())->toString(); $roles[] = Role::users()->toString(); diff --git a/src/Appwrite/Auth/Validator/Password.php b/src/Appwrite/Auth/Validator/Password.php index bfe5577889..913701f7a3 100644 --- a/src/Appwrite/Auth/Validator/Password.php +++ b/src/Appwrite/Auth/Validator/Password.php @@ -2,7 +2,7 @@ namespace Appwrite\Auth\Validator; -use Utopia\Validator; +use Utopia\Http\Validator; /** * Password. diff --git a/src/Appwrite/Auth/Validator/Phone.php b/src/Appwrite/Auth/Validator/Phone.php index 26aa687278..d5f6df60c8 100644 --- a/src/Appwrite/Auth/Validator/Phone.php +++ b/src/Appwrite/Auth/Validator/Phone.php @@ -2,7 +2,7 @@ namespace Appwrite\Auth\Validator; -use Utopia\Validator; +use Utopia\Http\Validator; /** * Phone. diff --git a/src/Appwrite/Event/Validator/Event.php b/src/Appwrite/Event/Validator/Event.php index 2061d53ed8..a63d6f9da2 100644 --- a/src/Appwrite/Event/Validator/Event.php +++ b/src/Appwrite/Event/Validator/Event.php @@ -3,7 +3,7 @@ namespace Appwrite\Event\Validator; use Utopia\Config\Config; -use Utopia\Validator; +use Utopia\Http\Validator; class Event extends Validator { diff --git a/src/Appwrite/GraphQL/Resolvers.php b/src/Appwrite/GraphQL/Resolvers.php index 69b153ef72..31f1ce45b4 100644 --- a/src/Appwrite/GraphQL/Resolvers.php +++ b/src/Appwrite/GraphQL/Resolvers.php @@ -20,7 +20,7 @@ class Resolvers * @return callable */ public static function api( - App $utopia, + Http $utopia, ?Route $route, ): callable { return static fn ($type, $args, $context, $info) => new Swoole( @@ -67,7 +67,7 @@ class Resolvers * @return callable */ public static function document( - App $utopia, + Http $utopia, string $databaseId, string $collectionId, string $methodType, @@ -89,7 +89,7 @@ class Resolvers * @return callable */ public static function documentGet( - App $utopia, + Http $utopia, string $databaseId, string $collectionId, callable $url, @@ -119,7 +119,7 @@ class Resolvers * @return callable */ public static function documentList( - App $utopia, + Http $utopia, string $databaseId, string $collectionId, callable $url, @@ -155,7 +155,7 @@ class Resolvers * @return callable */ public static function documentCreate( - App $utopia, + Http $utopia, string $databaseId, string $collectionId, callable $url, @@ -187,7 +187,7 @@ class Resolvers * @return callable */ public static function documentUpdate( - App $utopia, + Http $utopia, string $databaseId, string $collectionId, callable $url, @@ -218,7 +218,7 @@ class Resolvers * @return callable */ public static function documentDelete( - App $utopia, + Http $utopia, string $databaseId, string $collectionId, callable $url, @@ -249,7 +249,7 @@ class Resolvers * @throws Exception */ private static function resolve( - App $utopia, + Http $utopia, Request $request, Response $response, callable $resolve, diff --git a/src/Appwrite/GraphQL/Schema.php b/src/Appwrite/GraphQL/Schema.php index 2399452797..49544a7c93 100644 --- a/src/Appwrite/GraphQL/Schema.php +++ b/src/Appwrite/GraphQL/Schema.php @@ -26,7 +26,7 @@ class Schema * @throws Exception */ public static function build( - App $utopia, + Http $utopia, callable $complexity, callable $attributes, array $urls, @@ -85,7 +85,7 @@ class Schema * @return array * @throws Exception */ - protected static function api(App $utopia, callable $complexity): array + protected static function api(Http $utopia, callable $complexity): array { Mapper::init($utopia ->getResource('response') @@ -143,7 +143,7 @@ class Schema * @throws \Exception */ protected static function collections( - App $utopia, + Http $utopia, callable $complexity, callable $attributes, array $urls, diff --git a/src/Appwrite/GraphQL/Types/Mapper.php b/src/Appwrite/GraphQL/Types/Mapper.php index 3f50bd4967..d81d8ea885 100644 --- a/src/Appwrite/GraphQL/Types/Mapper.php +++ b/src/Appwrite/GraphQL/Types/Mapper.php @@ -10,7 +10,7 @@ use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\UnionType; use Utopia\Http\Http; use Utopia\Http\Route; -use Utopia\Validator; +use Utopia\Http\Validator; use Utopia\Http\Validator\Nullable; class Mapper @@ -75,7 +75,7 @@ class Mapper } public static function route( - App $utopia, + Http $utopia, Route $route, callable $complexity ): iterable { @@ -213,7 +213,7 @@ class Mapper * @throws Exception */ public static function param( - App $utopia, + Http $utopia, Validator|callable $validator, bool $required, array $injections diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index 646fa8b8fe..ac9fc164d5 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -86,10 +86,10 @@ abstract class Migration */ protected array $collections; - public function __construct() + public function __construct(Authorization $auth) { - Authorization::disable(); - Authorization::setDefaultStatus(false); + $auth->disable(); + $auth->setDefaultStatus(false); $this->collections = Config::getParam('collections', []); diff --git a/src/Appwrite/Network/Validator/CNAME.php b/src/Appwrite/Network/Validator/CNAME.php index e1ae061c84..e9e2b586a5 100644 --- a/src/Appwrite/Network/Validator/CNAME.php +++ b/src/Appwrite/Network/Validator/CNAME.php @@ -2,7 +2,7 @@ namespace Appwrite\Network\Validator; -use Utopia\Validator; +use Utopia\Http\Validator; class CNAME extends Validator { diff --git a/src/Appwrite/Network/Validator/Email.php b/src/Appwrite/Network/Validator/Email.php index 3209a4aada..bae0ff0bbf 100644 --- a/src/Appwrite/Network/Validator/Email.php +++ b/src/Appwrite/Network/Validator/Email.php @@ -2,14 +2,14 @@ namespace Appwrite\Network\Validator; -use Utopia\Validator; +use Utopia\Http\Validator; /** * Email * * Validate that an variable is a valid email address * - * @package Utopia\Validator + * @package Utopia\Http\Validator */ class Email extends Validator { diff --git a/src/Appwrite/Network/Validator/Origin.php b/src/Appwrite/Network/Validator/Origin.php index e64f42ce6d..4d696735bf 100644 --- a/src/Appwrite/Network/Validator/Origin.php +++ b/src/Appwrite/Network/Validator/Origin.php @@ -2,7 +2,7 @@ namespace Appwrite\Network\Validator; -use Utopia\Validator; +use Utopia\Http\Validator; use Utopia\Http\Validator\Hostname; class Origin extends Validator diff --git a/src/Appwrite/Platform/Tasks/CalcTierStats.php b/src/Appwrite/Platform/Tasks/CalcTierStats.php index 7256047c35..137a497ae3 100644 --- a/src/Appwrite/Platform/Tasks/CalcTierStats.php +++ b/src/Appwrite/Platform/Tasks/CalcTierStats.php @@ -73,13 +73,14 @@ class CalcTierStats extends Action ->inject('dbForConsole') ->inject('getProjectDB') ->inject('register') - ->callback(function ($after, $projectId, Group $pools, Cache $cache, Database $dbForConsole, callable $getProjectDB, Registry $register) { - $this->action($after, $projectId, $pools, $cache, $dbForConsole, $getProjectDB, $register); + ->inject('auth') + ->callback(function ($after, $projectId, Group $pools, Cache $cache, Database $dbForConsole, callable $getProjectDB, Registry $register, Authorization $auth) { + $this->action($after, $projectId, $pools, $cache, $dbForConsole, $getProjectDB, $register, $auth); }); } - public function action(string $after, string $projectId, Group $pools, Cache $cache, Database $dbForConsole, callable $getProjectDB, Registry $register): void + public function action(string $after, string $projectId, Group $pools, Cache $cache, Database $dbForConsole, callable $getProjectDB, Registry $register, Authorization $auth): void { //docker compose exec -t appwrite calc-tier-stats @@ -97,7 +98,7 @@ class CalcTierStats extends Action console::log("Project " . $projectId); $project = $dbForConsole->getDocument('projects', $projectId); $dbForProject = call_user_func($getProjectDB, $project); - $data = $this->getData($project, $dbForConsole, $dbForProject); + $data = $this->getData($project, $dbForConsole, $dbForProject, $auth); $csv->insertOne($data); $this->sendMail($register); @@ -121,12 +122,12 @@ class CalcTierStats extends Action Console::info("Iterating all projects"); } - $this->foreachDocument($dbForConsole, 'projects', $queries, function (Document $project) use ($getProjectDB, $dbForConsole, $csv) { + $this->foreachDocument($dbForConsole, 'projects', $queries, function (Document $project) use ($getProjectDB, $dbForConsole, $csv, $auth) { $projectId = $project->getId(); console::log("Project " . $projectId); try { $dbForProject = call_user_func($getProjectDB, $project); - $data = $this->getData($project, $dbForConsole, $dbForProject); + $data = $this->getData($project, $dbForConsole, $dbForProject, $auth); $csv->insertOne($data); } catch (\Throwable $th) { Console::error("Unexpected error occured with Project ID {$projectId}"); @@ -204,7 +205,7 @@ class CalcTierStats extends Action } - private function getData(Document $project, Database $dbForConsole, Database $dbForProject): array + private function getData(Document $project, Database $dbForConsole, Database $dbForProject, Authorization $auth): array { $stats['Project ID'] = $project->getId(); $stats['Organization ID'] = $project->getAttribute('teamId', null); @@ -263,7 +264,7 @@ class CalcTierStats extends Action $tmp = []; $metrics = $this->usageStats; - Authorization::skip(function () use ($dbForProject, $periods, $range, $metrics, &$tmp) { + $auth->skip(function () use ($dbForProject, $periods, $range, $metrics, &$tmp) { foreach ($metrics as $metric => $name) { $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; diff --git a/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php b/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php index c2d4128b72..bcccf8dcb0 100644 --- a/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php +++ b/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php @@ -9,6 +9,7 @@ use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; +use Utopia\Http\Adapter\FPM\Server; use Utopia\Platform\Action; use Utopia\Pools\Group; use Utopia\Registry\Registry; @@ -58,7 +59,7 @@ class DeleteOrphanedProjects extends Action ], $collectionsConfig); /* Initialise new Utopia app */ - $app = new App('UTC'); + $app = new Http(new Server(), 'UTC'); $console = $app->getResource('console'); $projects = [$console]; @@ -123,7 +124,7 @@ class DeleteOrphanedProjects extends Action $dbForConsole->deleteDocument('projects', $project->getId()); $dbForConsole->purgeCachedDocument('projects', $project->getId()); - if ($dbForProject->exists($dbForProject->getDefaultDatabase(), Database::METADATA)) { + if ($dbForProject->exists($dbForProject->getDatabase(), Database::METADATA)) { try { $dbForProject->deleteCollection(Database::METADATA); $dbForProject->purgeCachedCollection(Database::METADATA); diff --git a/src/Appwrite/Platform/Tasks/GetMigrationStats.php b/src/Appwrite/Platform/Tasks/GetMigrationStats.php index ebd00e8dc1..c525a92b20 100644 --- a/src/Appwrite/Platform/Tasks/GetMigrationStats.php +++ b/src/Appwrite/Platform/Tasks/GetMigrationStats.php @@ -10,6 +10,7 @@ use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Query; +use Utopia\Http\Adapter\FPM\Server; use Utopia\Platform\Action; use Utopia\Pools\Group; use Utopia\Registry\Registry; @@ -63,7 +64,7 @@ class GetMigrationStats extends Action Console::success(APP_NAME . ' Migration stats calculation has started'); /* Initialise new Utopia app */ - $app = new App('UTC'); + $app = new Http(new Server(), 'UTC'); $console = $app->getResource('console'); /** CSV stuff */ @@ -101,7 +102,7 @@ class GetMigrationStats extends Action ->getResource(); $dbForProject = new Database($adapter, $cache); - $dbForProject->setDefaultDatabase('appwrite'); + $dbForProject->setDatabase('appwrite'); $dbForProject->setNamespace('_' . $project->getInternalId()); /** Get Project ID */ diff --git a/src/Appwrite/Platform/Tasks/Migrate.php b/src/Appwrite/Platform/Tasks/Migrate.php index c322f17a55..ad158b1b42 100644 --- a/src/Appwrite/Platform/Tasks/Migrate.php +++ b/src/Appwrite/Platform/Tasks/Migrate.php @@ -10,6 +10,7 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Adapter\FPM\Server; use Utopia\Platform\Action; use Utopia\Registry\Registry; use Utopia\Http\Validator\Text; @@ -31,7 +32,8 @@ class Migrate extends Action ->inject('dbForConsole') ->inject('getProjectDB') ->inject('register') - ->callback(fn ($version, $cache, $dbForConsole, $getProjectDB, Registry $register) => $this->action($version, $cache, $dbForConsole, $getProjectDB, $register)); + ->inject('auth') + ->callback(fn ($version, $cache, $dbForConsole, $getProjectDB, Registry $register, Authorization $auth) => $this->action($version, $cache, $dbForConsole, $getProjectDB, $register, $auth)); } private function clearProjectsCache(Cache $cache, Document $project) @@ -43,16 +45,16 @@ class Migrate extends Action } } - public function action(string $version, Cache $cache, Database $dbForConsole, callable $getProjectDB, Registry $register) + public function action(string $version, Cache $cache, Database $dbForConsole, callable $getProjectDB, Registry $register, Authorization $auth) { - Authorization::disable(); + $auth->disable(); if (!array_key_exists($version, Migration::$versions)) { Console::error("Version {$version} not found."); Console::exit(1); return; } - $app = new App('UTC'); + $app = new Http(new Server(), 'UTC'); Console::success('Starting Data Migration to version ' . $version); diff --git a/src/Appwrite/Platform/Tasks/Specs.php b/src/Appwrite/Platform/Tasks/Specs.php index 1c79fee034..04c4f225e4 100644 --- a/src/Appwrite/Platform/Tasks/Specs.php +++ b/src/Appwrite/Platform/Tasks/Specs.php @@ -7,6 +7,7 @@ use Appwrite\Specification\Format\Swagger2; use Appwrite\Specification\Specification; use Appwrite\Utopia\Response; use Exception; +use Swoole\Http\Request; use Swoole\Http\Response as HttpResponse; use Utopia\Http\Http; use Utopia\Cache\Adapter\None; @@ -15,9 +16,9 @@ use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Adapter\MySQL; use Utopia\Database\Database; +use Utopia\Http\Adapter\FPM\Server; use Utopia\Platform\Action; use Utopia\Registry\Registry; -use Utopia\Request; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\WhiteList; @@ -248,7 +249,7 @@ class Specs extends Action } } - $arguments = [new App('UTC'), $services, $routes, $models, $keys[$platform], $authCounts[$platform] ?? 0]; + $arguments = [new Http(new Server(), 'UTC'), $services, $routes, $models, $keys[$platform], $authCounts[$platform] ?? 0]; foreach (['swagger2', 'open-api3'] as $format) { $formatInstance = match ($format) { 'swagger2' => new Swagger2(...$arguments), diff --git a/src/Appwrite/Platform/Workers/Builds.php b/src/Appwrite/Platform/Workers/Builds.php index a0cf080c86..723af17a38 100644 --- a/src/Appwrite/Platform/Workers/Builds.php +++ b/src/Appwrite/Platform/Workers/Builds.php @@ -52,7 +52,8 @@ class Builds extends Action ->inject('dbForProject') ->inject('deviceForFunctions') ->inject('log') - ->callback(fn ($message, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions, Usage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log) => $this->action($message, $dbForConsole, $queueForEvents, $queueForFunctions, $usage, $cache, $dbForProject, $deviceForFunctions, $log)); + ->inject('auth') + ->callback(fn ($message, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions, Usage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log, Authorization $auth) => $this->action($message, $dbForConsole, $queueForEvents, $queueForFunctions, $usage, $cache, $dbForProject, $deviceForFunctions, $log, $auth)); } /** @@ -65,10 +66,11 @@ class Builds extends Action * @param Database $dbForProject * @param Device $deviceForFunctions * @param Log $log + * @param Authorization $auth * @return void * @throws \Utopia\Database\Exception */ - public function action(Message $message, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions, Usage $queueForUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log): void + public function action(Message $message, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions, Usage $queueForUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log, Authorization $auth): void { $payload = $message->getPayload() ?? []; @@ -90,7 +92,7 @@ class Builds extends Action case BUILD_TYPE_RETRY: Console::info('Creating build for deployment: ' . $deployment->getId()); $github = new GitHub($cache); - $this->buildDeployment($deviceForFunctions, $queueForFunctions, $queueForEvents, $queueForUsage, $dbForConsole, $dbForProject, $github, $project, $resource, $deployment, $template, $log); + $this->buildDeployment($deviceForFunctions, $queueForFunctions, $queueForEvents, $queueForUsage, $dbForConsole, $dbForProject, $github, $project, $resource, $deployment, $template, $log, $auth); break; default: @@ -111,11 +113,12 @@ class Builds extends Action * @param Document $deployment * @param Document $template * @param Log $log + * @param Authorization $auth * @return void * @throws \Utopia\Database\Exception * @throws Exception */ - protected function buildDeployment(Device $deviceForFunctions, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Database $dbForConsole, Database $dbForProject, GitHub $github, Document $project, Document $function, Document $deployment, Document $template, Log $log): void + protected function buildDeployment(Device $deviceForFunctions, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Database $dbForConsole, Database $dbForProject, GitHub $github, Document $project, Document $function, Document $deployment, Document $template, Log $log, Authorization $auth): void { $executor = new Executor(Http::getEnv('_APP_EXECUTOR_HOST')); @@ -502,7 +505,7 @@ class Builds extends Action ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('schedule', $function->getAttribute('schedule')) ->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment'))); - Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); + $auth->skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); } catch (\Throwable $th) { $endTime = DateTime::now(); $durationEnd = \microtime(true); diff --git a/src/Appwrite/Platform/Workers/Hamster.php b/src/Appwrite/Platform/Workers/Hamster.php index 3f7bd86e8a..817291dff1 100644 --- a/src/Appwrite/Platform/Workers/Hamster.php +++ b/src/Appwrite/Platform/Workers/Hamster.php @@ -4,6 +4,7 @@ namespace Appwrite\Platform\Workers; use Appwrite\Event\Hamster as EventHamster; use Appwrite\Network\Validator\Origin; +use PharIo\Manifest\Author; use Utopia\Analytics\Adapter\Mixpanel; use Utopia\Analytics\Event as AnalyticsEvent; use Utopia\Http\Http; @@ -53,7 +54,8 @@ class Hamster extends Action ->inject('pools') ->inject('cache') ->inject('dbForConsole') - ->callback(fn (Message $message, Group $pools, Cache $cache, Database $dbForConsole) => $this->action($message, $pools, $cache, $dbForConsole)); + ->inject('auth') + ->callback(fn (Message $message, Group $pools, Cache $cache, Database $dbForConsole, Authorization $auth) => $this->action($message, $pools, $cache, $dbForConsole, $auth)); } /** @@ -65,7 +67,7 @@ class Hamster extends Action * @return void * @throws \Utopia\Database\Exception */ - public function action(Message $message, Group $pools, Cache $cache, Database $dbForConsole): void + public function action(Message $message, Group $pools, Cache $cache, Database $dbForConsole, Authorization $auth): void { $token = Http::getEnv('_APP_MIXPANEL_TOKEN', ''); if (empty($token)) { @@ -83,7 +85,7 @@ class Hamster extends Action switch ($type) { case EventHamster::TYPE_PROJECT: - $this->getStatsForProject(new Document($payload['project']), $pools, $cache, $dbForConsole); + $this->getStatsForProject(new Document($payload['project']), $pools, $cache, $dbForConsole, $auth); break; case EventHamster::TYPE_ORGANISATION: $this->getStatsForOrganization(new Document($payload['organization']), $dbForConsole); @@ -101,7 +103,7 @@ class Hamster extends Action * @param Database $dbForConsole * @throws \Utopia\Database\Exception */ - private function getStatsForProject(Document $project, Group $pools, Cache $cache, Database $dbForConsole): void + private function getStatsForProject(Document $project, Group $pools, Cache $cache, Database $dbForConsole, Authorization $auth): void { /** * Skip user projects with id 'console' @@ -121,7 +123,7 @@ class Hamster extends Action ->getResource(); $dbForProject = new Database($adapter, $cache); - $dbForProject->setDefaultDatabase('appwrite'); + $dbForProject->setDatabase('appwrite'); $dbForProject->setNamespace('_' . $project->getInternalId()); $statsPerProject = []; @@ -279,7 +281,7 @@ class Hamster extends Action ], ]; - Authorization::skip(function () use ($dbForProject, $periods, &$statsPerProject) { + $auth->skip(function () use ($dbForProject, $periods, &$statsPerProject) { foreach ($this->metrics as $key => $metric) { foreach ($periods as $periodKey => $periodValue) { $limit = $periodValue['limit']; diff --git a/src/Appwrite/Specification/Format.php b/src/Appwrite/Specification/Format.php index 26d8e5d73f..fdb4841a93 100644 --- a/src/Appwrite/Specification/Format.php +++ b/src/Appwrite/Specification/Format.php @@ -9,7 +9,7 @@ use Utopia\Http\Route; abstract class Format { - protected App $app; + protected Http $app; /** * @var Route[] @@ -50,7 +50,7 @@ abstract class Format ] ]; - public function __construct(App $app, array $services, array $routes, array $models, array $keys, int $authCount) + public function __construct(Http $app, array $services, array $routes, array $models, array $keys, int $authCount) { $this->app = $app; $this->services = $services; diff --git a/src/Appwrite/Specification/Format/OpenAPI3.php b/src/Appwrite/Specification/Format/OpenAPI3.php index b845bc001b..5ee3011ebd 100644 --- a/src/Appwrite/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/Specification/Format/OpenAPI3.php @@ -7,7 +7,7 @@ use Appwrite\Template\Template; use Appwrite\Utopia\Response\Model; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; -use Utopia\Validator; +use Utopia\Http\Validator; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Nullable; use Utopia\Http\Validator\Range; @@ -273,7 +273,7 @@ class OpenAPI3 extends Format foreach ($route->getParams() as $name => $param) { // Set params /** - * @var \Utopia\Validator $validator + * @var \Utopia\Http\Validator $validator */ $validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->app->getResources($param['injections'])) : $param['validator']; diff --git a/src/Appwrite/Specification/Format/Swagger2.php b/src/Appwrite/Specification/Format/Swagger2.php index 82dedaef57..d75568976c 100644 --- a/src/Appwrite/Specification/Format/Swagger2.php +++ b/src/Appwrite/Specification/Format/Swagger2.php @@ -7,7 +7,7 @@ use Appwrite\Template\Template; use Appwrite\Utopia\Response\Model; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; -use Utopia\Validator; +use Utopia\Http\Validator; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Nullable; use Utopia\Http\Validator\Range; diff --git a/src/Appwrite/Task/Validator/Cron.php b/src/Appwrite/Task/Validator/Cron.php index 03bd1c5220..afa19c50a6 100644 --- a/src/Appwrite/Task/Validator/Cron.php +++ b/src/Appwrite/Task/Validator/Cron.php @@ -3,7 +3,7 @@ namespace Appwrite\Task\Validator; use Cron\CronExpression; -use Utopia\Validator; +use Utopia\Http\Validator; class Cron extends Validator { diff --git a/src/Appwrite/Utopia/Database/Validator/CompoundUID.php b/src/Appwrite/Utopia/Database/Validator/CompoundUID.php index 3f23500952..b851d8ba85 100644 --- a/src/Appwrite/Utopia/Database/Validator/CompoundUID.php +++ b/src/Appwrite/Utopia/Database/Validator/CompoundUID.php @@ -3,7 +3,7 @@ namespace Appwrite\Utopia\Database\Validator; use Utopia\Database\Validator\UID; -use Utopia\Validator; +use Utopia\Http\Validator; class CompoundUID extends Validator { diff --git a/src/Appwrite/Utopia/Database/Validator/ProjectId.php b/src/Appwrite/Utopia/Database/Validator/ProjectId.php index 46b0cdf53e..28abe176fe 100644 --- a/src/Appwrite/Utopia/Database/Validator/ProjectId.php +++ b/src/Appwrite/Utopia/Database/Validator/ProjectId.php @@ -2,7 +2,7 @@ namespace Appwrite\Utopia\Database\Validator; -use Utopia\Validator; +use Utopia\Http\Validator; class ProjectId extends Validator { diff --git a/src/Appwrite/Utopia/Request.php b/src/Appwrite/Utopia/Request.php index a711afb283..ee488d6a13 100644 --- a/src/Appwrite/Utopia/Request.php +++ b/src/Appwrite/Utopia/Request.php @@ -4,19 +4,13 @@ namespace Appwrite\Utopia; use Appwrite\Utopia\Request\Filter; use Utopia\Http\Adapter\Swoole\Request as SwooleRequest; -use Utopia\Http\Request as HttpRequest; use Utopia\Http\Route; -class Request extends HttpRequest +class Request extends SwooleRequest { private static ?Filter $filter = null; private static ?Route $route = null; - public function __construct(SwooleRequest $request) - { - parent::__construct($request); - } - /** * @inheritdoc */ diff --git a/src/Appwrite/Utopia/View.php b/src/Appwrite/Utopia/View.php index e4ed8164c9..60cafb1ca8 100644 --- a/src/Appwrite/Utopia/View.php +++ b/src/Appwrite/Utopia/View.php @@ -2,7 +2,7 @@ namespace Appwrite\Utopia; -use Utopia\View as OldView; +use Utopia\View\View as OldView; class View extends OldView { diff --git a/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php b/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php index ca8753f374..877e66cb03 100644 --- a/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php +++ b/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php @@ -17,6 +17,13 @@ class DatabasesPermissionsGuestTest extends Scope use SideClient; use DatabasesPermissionsScope; + protected Authorization $auth; + + public function setUp(): void + { + $this->auth = new Authorization(); + } + public function createCollection(): array { $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ @@ -111,8 +118,8 @@ class DatabasesPermissionsGuestTest extends Scope $this->assertEquals(201, $publicResponse['headers']['status-code']); $this->assertEquals(201, $privateResponse['headers']['status-code']); - $roles = Authorization::getRoles(); - Authorization::cleanRoles(); + $roles = $this->auth->getRoles(); + $this->auth->cleanRoles(); $publicDocuments = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ 'content-type' => 'application/json', @@ -134,7 +141,7 @@ class DatabasesPermissionsGuestTest extends Scope } foreach ($roles as $role) { - Authorization::setRole($role); + $this->auth->addRole($role); } } @@ -145,8 +152,8 @@ class DatabasesPermissionsGuestTest extends Scope $privateCollectionId = $data['privateCollectionId']; $databaseId = $data['databaseId']; - $roles = Authorization::getRoles(); - Authorization::cleanRoles(); + $roles = $this->auth->getRoles(); + $this->auth->cleanRoles(); $publicResponse = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', [ 'content-type' => 'application/json', @@ -222,7 +229,7 @@ class DatabasesPermissionsGuestTest extends Scope $this->assertEquals(401, $privateDocument['headers']['status-code']); foreach ($roles as $role) { - Authorization::setRole($role); + $this->auth->addRole($role); } } diff --git a/tests/unit/Auth/AuthTest.php b/tests/unit/Auth/AuthTest.php index 705da42879..2bbe690c02 100644 --- a/tests/unit/Auth/AuthTest.php +++ b/tests/unit/Auth/AuthTest.php @@ -13,13 +13,20 @@ use Utopia\Database\Validator\Roles; class AuthTest extends TestCase { + protected Authorization $auth; + + public function setUp(): void + { + $this->auth = new Authorization(); + } + /** * Reset Roles */ public function tearDown(): void { - Authorization::cleanRoles(); - Authorization::setRole(Role::any()->toString()); + $this->auth->cleanRoles(); + $this->auth->addRole(Role::any()->toString()); } public function testCookieName(): void @@ -347,7 +354,7 @@ class AuthTest extends TestCase '$id' => '' ]); - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $this->auth); $this->assertCount(1, $roles); $this->assertContains(Role::guests()->toString(), $roles); } @@ -383,7 +390,7 @@ class AuthTest extends TestCase ] ]); - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $this->auth); $this->assertCount(13, $roles); $this->assertContains(Role::users()->toString(), $roles); @@ -404,21 +411,21 @@ class AuthTest extends TestCase $user['emailVerification'] = false; $user['phoneVerification'] = false; - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $this->auth); $this->assertContains(Role::users(Roles::DIMENSION_UNVERIFIED)->toString(), $roles); $this->assertContains(Role::user(ID::custom('123'), Roles::DIMENSION_UNVERIFIED)->toString(), $roles); // Enable single verification type $user['emailVerification'] = true; - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $this->auth); $this->assertContains(Role::users(Roles::DIMENSION_VERIFIED)->toString(), $roles); $this->assertContains(Role::user(ID::custom('123'), Roles::DIMENSION_VERIFIED)->toString(), $roles); } public function testPrivilegedUserRoles(): void { - Authorization::setRole(Auth::USER_ROLE_OWNER); + $this->auth->addRole(Auth::USER_ROLE_OWNER); $user = new Document([ '$id' => ID::custom('123'), 'emailVerification' => true, @@ -444,7 +451,7 @@ class AuthTest extends TestCase ] ]); - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $this->auth); $this->assertCount(7, $roles); $this->assertNotContains(Role::users()->toString(), $roles); @@ -462,7 +469,7 @@ class AuthTest extends TestCase public function testAppUserRoles(): void { - Authorization::setRole(Auth::USER_ROLE_APPS); + $this->auth->addRole(Auth::USER_ROLE_APPS); $user = new Document([ '$id' => ID::custom('123'), 'memberships' => [ @@ -486,7 +493,7 @@ class AuthTest extends TestCase ] ]); - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $this->auth); $this->assertCount(7, $roles); $this->assertNotContains(Role::users()->toString(), $roles); diff --git a/tests/unit/Messaging/MessagingChannelsTest.php b/tests/unit/Messaging/MessagingChannelsTest.php index 8ba0374093..2f0443c34f 100644 --- a/tests/unit/Messaging/MessagingChannelsTest.php +++ b/tests/unit/Messaging/MessagingChannelsTest.php @@ -6,8 +6,10 @@ use Appwrite\Auth\Auth; use Appwrite\Messaging\Adapter\Realtime; use PHPUnit\Framework\TestCase; use Utopia\Database\Document; +use Utopia\Database\Exception\Authorization; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; +use Utopia\Database\Validator\Authorization as ValidatorAuthorization; class MessagingChannelsTest extends TestCase { @@ -34,8 +36,12 @@ class MessagingChannelsTest extends TestCase 'functions.1', ]; + protected ValidatorAuthorization $auth; + public function setUp(): void { + $this->auth = new ValidatorAuthorization(); + /** * Setup global Counts */ @@ -66,7 +72,7 @@ class MessagingChannelsTest extends TestCase ] ]); - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $this->auth); $parsedChannels = Realtime::convertChannels([0 => $channel], $user->getId()); @@ -90,7 +96,7 @@ class MessagingChannelsTest extends TestCase '$id' => '' ]); - $roles = Auth::getRoles($user); + $roles = Auth::getRoles($user, $this->auth); $parsedChannels = Realtime::convertChannels([0 => $channel], $user->getId());