From db1674811f8cf804b223df336534812deca3a159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 8 Mar 2024 13:57:20 +0100 Subject: [PATCH] Finish fixing code QL warnings --- app/cli.php | 25 +- app/controllers/api/account.php | 76 +-- app/controllers/api/avatars.php | 25 +- app/controllers/api/console.php | 2 +- app/controllers/api/databases.php | 197 +++++--- app/controllers/api/functions.php | 57 ++- app/controllers/api/graphql.php | 2 +- app/controllers/api/health.php | 12 +- app/controllers/api/locale.php | 2 +- app/controllers/api/messaging.php | 54 ++- app/controllers/api/migrations.php | 10 +- app/controllers/api/project.php | 5 +- app/controllers/api/projects.php | 15 +- app/controllers/api/proxy.php | 4 +- app/controllers/api/storage.php | 80 ++-- app/controllers/api/teams.php | 24 +- app/controllers/api/users.php | 12 +- app/controllers/api/vcs.php | 16 +- app/controllers/general.php | 23 +- app/controllers/mock.php | 6 +- app/controllers/shared/api.php | 25 +- app/controllers/shared/api/auth.php | 2 +- app/controllers/web/home.php | 2 +- app/http.php | 434 +++++++----------- app/init.php | 35 +- app/realtime.php | 60 ++- app/worker.php | 29 +- composer.json | 10 +- composer.lock | 176 +++++-- src/Appwrite/GraphQL/Resolvers.php | 20 +- src/Appwrite/GraphQL/Schema.php | 8 +- src/Appwrite/GraphQL/Types/Mapper.php | 2 +- src/Appwrite/Messaging/Adapter/Realtime.php | 2 +- src/Appwrite/Migration/Migration.php | 2 +- src/Appwrite/Migration/Version/V15.php | 2 +- src/Appwrite/Migration/Version/V19.php | 2 +- src/Appwrite/Platform/Tasks/CalcTierStats.php | 4 +- .../Platform/Tasks/CreateInfMetric.php | 2 +- .../Platform/Tasks/DeleteOrphanedProjects.php | 17 +- .../Tasks/DevGenerateTranslations.php | 2 +- src/Appwrite/Platform/Tasks/Doctor.php | 2 +- .../Platform/Tasks/GetMigrationStats.php | 16 +- src/Appwrite/Platform/Tasks/Hamster.php | 2 +- src/Appwrite/Platform/Tasks/Install.php | 2 +- src/Appwrite/Platform/Tasks/Maintenance.php | 2 +- src/Appwrite/Platform/Tasks/Migrate.php | 8 +- .../PatchRecreateRepositoriesDocuments.php | 2 +- src/Appwrite/Platform/Tasks/QueueCount.php | 2 +- src/Appwrite/Platform/Tasks/QueueRetry.php | 4 +- src/Appwrite/Platform/Tasks/SSL.php | 4 +- src/Appwrite/Platform/Tasks/ScheduleBase.php | 2 +- src/Appwrite/Platform/Tasks/Specs.php | 6 +- src/Appwrite/Platform/Tasks/Vars.php | 2 +- src/Appwrite/Platform/Tasks/Version.php | 2 +- src/Appwrite/Platform/Tasks/VolumeSync.php | 2 +- src/Appwrite/Platform/Workers/Audits.php | 8 +- src/Appwrite/Platform/Workers/Builds.php | 2 +- .../Platform/Workers/Certificates.php | 2 +- src/Appwrite/Platform/Workers/Deletes.php | 22 +- src/Appwrite/Platform/Workers/Functions.php | 2 +- src/Appwrite/Platform/Workers/Hamster.php | 4 +- src/Appwrite/Platform/Workers/Messaging.php | 2 +- src/Appwrite/Platform/Workers/Usage.php | 2 +- src/Appwrite/Platform/Workers/UsageDump.php | 2 +- src/Appwrite/Platform/Workers/Webhooks.php | 2 +- src/Appwrite/Specification/Format.php | 8 +- .../Specification/Format/OpenAPI3.php | 2 +- .../Specification/Format/Swagger2.php | 2 +- src/Appwrite/Utopia/Request.php | 8 + src/Appwrite/Utopia/Response.php | 5 +- src/Appwrite/Vcs/Comment.php | 2 +- tests/e2e/General/AbuseTest.php | 2 +- tests/e2e/Services/GraphQL/AbuseTest.php | 2 +- tests/e2e/Services/GraphQL/MessagingTest.php | 2 +- .../e2e/Services/Messaging/MessagingBase.php | 2 +- .../e2e/Services/VCS/VCSConsoleClientTest.php | 2 +- tests/unit/Event/EventTest.php | 2 +- .../unit/Messaging/MessagingChannelsTest.php | 1 - tests/unit/Usage/StatsTest.php | 2 +- 79 files changed, 889 insertions(+), 742 deletions(-) diff --git a/app/cli.php b/app/cli.php index 86daad2ae3..744c74e759 100644 --- a/app/cli.php +++ b/app/cli.php @@ -8,7 +8,6 @@ use Appwrite\Event\Delete; use Appwrite\Event\Func; use Appwrite\Event\Hamster; use Appwrite\Platform\Appwrite; -use Utopia\Http\Http; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; use Utopia\CLI\CLI; @@ -17,6 +16,7 @@ use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Http; use Utopia\Logger\Log; use Utopia\Platform\Service; use Utopia\Pools\Group; @@ -25,8 +25,6 @@ use Utopia\Registry\Registry; global $register; -$auth->disable(); - CLI::setResource('register', fn () => $register); CLI::setResource('cache', function ($pools) { @@ -48,7 +46,7 @@ CLI::setResource('pools', function (Registry $register) { return $register->get('pools'); }, ['register']); -CLI::setResource('dbForConsole', function ($pools, $cache) { +CLI::setResource('dbForConsole', function ($pools, $cache, $auth) { $sleep = 3; $maxAttempts = 5; $attempts = 0; @@ -64,6 +62,7 @@ CLI::setResource('dbForConsole', function ($pools, $cache) { ->getResource(); $dbForConsole = new Database($dbAdapter, $cache); + $dbForConsole->setAuthorization($auth); $dbForConsole ->setNamespace('_console') @@ -91,12 +90,12 @@ CLI::setResource('dbForConsole', function ($pools, $cache) { } return $dbForConsole; -}, ['pools', 'cache']); +}, ['pools', 'cache', 'auth']); -CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $cache) { +CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $cache, $auth) { $databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools - return function (Document $project) use ($pools, $dbForConsole, $cache, &$databases) { + return function (Document $project) use ($pools, $dbForConsole, $cache, &$databases, $auth) { if ($project->isEmpty() || $project->getId() === 'console') { return $dbForConsole; } @@ -115,6 +114,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, ->getResource(); $database = new Database($dbAdapter, $cache); + $database->setAuthorization($auth); $databases[$databaseName] = $database; @@ -125,7 +125,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, return $database; }; -}, ['pools', 'dbForConsole', 'cache']); +}, ['pools', 'dbForConsole', 'cache', 'auth']); CLI::setResource('queue', function (Group $pools) { return $pools->get('queue')->pop()->getResource(); @@ -178,11 +178,20 @@ CLI::setResource('logError', function (Registry $register) { }; }, ['register']); +CLI::setResource('auth', fn () => new Authorization()); + $platform = new Appwrite(); $platform->init(Service::TYPE_CLI); $cli = $platform->getCli(); +$cli + ->init() + ->inject('auth') + ->action(function (Authorization $auth) { + $auth->disable(); + }); + $cli ->error() ->inject('error') diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 2def54db58..2b1804dce2 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -28,7 +28,6 @@ use Appwrite\Utopia\Database\Validator\Queries\Identities; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use MaxMind\Db\Reader; -use Utopia\Http\Http; use Utopia\Audit\Audit as EventAudit; use Utopia\Config\Config; use Utopia\Database\Database; @@ -45,7 +44,7 @@ use Utopia\Database\Validator\Queries; use Utopia\Database\Validator\Query\Limit; use Utopia\Database\Validator\Query\Offset; use Utopia\Database\Validator\UID; -use Utopia\Locale\Locale; +use Utopia\Http\Http; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Assoc; use Utopia\Http\Validator\Boolean; @@ -53,6 +52,7 @@ use Utopia\Http\Validator\Host; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\URL; use Utopia\Http\Validator\WhiteList; +use Utopia\Locale\Locale; $oauthDefaultSuccess = '/auth/oauth2/success'; $oauthDefaultFailure = '/auth/oauth2/failure'; @@ -85,7 +85,8 @@ Http::post('/v1/account') ->inject('dbForProject') ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $name, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { + ->inject('auth') + ->action(function (string $userId, string $email, string $password, string $name, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks, Authorization $auth) { $email = \strtolower($email); if ('console' === $project->getId()) { @@ -186,7 +187,7 @@ Http::post('/v1/account') throw new Exception(Exception::USER_ALREADY_EXISTS); } - $auth->unsetRole(Role::guests()->toString()); + $auth->removeRole(Role::guests()->toString()); $auth->addRole(Role::user($user->getId())->toString()); $auth->addRole(Role::users()->toString()); @@ -227,7 +228,8 @@ Http::post('/v1/account/sessions/email') ->inject('geodb') ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $email, string $password, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Hooks $hooks) { + ->inject('auth') + ->action(function (string $email, string $password, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Hooks $hooks, Authorization $auth) { $email = \strtolower($email); $protocol = $request->getProtocol(); @@ -551,7 +553,8 @@ Http::get('/v1/account/sessions/oauth2/:provider/redirect') ->inject('dbForProject') ->inject('geodb') ->inject('queueForEvents') - ->action(function (string $provider, string $code, string $state, string $error, string $error_description, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Reader $geodb, Event $queueForEvents) use ($oauthDefaultSuccess) { + ->inject('auth') + ->action(function (string $provider, string $code, string $state, string $error, string $error_description, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Reader $geodb, Event $queueForEvents, Authorization $auth) use ($oauthDefaultSuccess) { $protocol = $request->getProtocol(); $callback = $protocol . '://' . $request->getHostname() . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId(); $defaultState = ['success' => $project->getAttribute('url', ''), 'failure' => '']; @@ -1098,7 +1101,8 @@ Http::post('/v1/account/tokens/magic-url') ->inject('locale') ->inject('queueForEvents') ->inject('queueForMails') - ->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) { + ->inject('Auth') + ->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $auth) { if (empty(Http::getEnv('_APP_SMTP_HOST'))) { throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled'); @@ -1340,7 +1344,8 @@ Http::post('/v1/account/tokens/email') ->inject('locale') ->inject('queueForEvents') ->inject('queueForMails') - ->action(function (string $userId, string $email, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) { + ->inject('auth') + ->action(function (string $userId, string $email, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $auth) { if (empty(Http::getEnv('_APP_SMTP_HOST'))) { throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled'); } @@ -1541,7 +1546,7 @@ 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) { +$createSession = function (string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Authorization $auth) { $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); @@ -1676,6 +1681,7 @@ Http::put('/v1/account/sessions/magic-url') ->inject('locale') ->inject('geodb') ->inject('queueForEvents') + ->inject('auth') ->action($createSession); Http::put('/v1/account/sessions/phone') @@ -1706,6 +1712,7 @@ Http::put('/v1/account/sessions/phone') ->inject('locale') ->inject('geodb') ->inject('queueForEvents') + ->inject('auth') ->action($createSession); Http::post('/v1/account/sessions/token') @@ -1735,6 +1742,7 @@ Http::post('/v1/account/sessions/token') ->inject('locale') ->inject('geodb') ->inject('queueForEvents') + ->inject('auth') ->action($createSession); Http::post('/v1/account/tokens/phone') @@ -1765,7 +1773,8 @@ Http::post('/v1/account/tokens/phone') ->inject('queueForEvents') ->inject('queueForMessaging') ->inject('locale') - ->action(function (string $userId, string $phone, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Locale $locale) { + ->inject('auth') + ->action(function (string $userId, string $phone, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Locale $locale, Authorization $auth) { if (empty(Http::getEnv('_APP_SMS_PROVIDER'))) { throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured'); } @@ -1933,7 +1942,8 @@ Http::post('/v1/account/sessions/anonymous') ->inject('dbForProject') ->inject('geodb') ->inject('queueForEvents') - ->action(function (Request $request, Response $response, Locale $locale, Document $user, Document $project, Database $dbForProject, Reader $geodb, Event $queueForEvents) { + ->inject('auth') + ->action(function (Request $request, Response $response, Locale $locale, Document $user, Document $project, Database $dbForProject, Reader $geodb, Event $queueForEvents, Authorization $auth) { $protocol = $request->getProtocol(); $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); @@ -2153,7 +2163,8 @@ Http::get('/v1/account/sessions') ->inject('user') ->inject('locale') ->inject('project') - ->action(function (Response $response, Document $user, Locale $locale, Document $project) { + ->inject('auth') + ->action(function (Response $response, Document $user, Locale $locale, Document $project, Authorization $auth) { $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); @@ -2195,7 +2206,8 @@ Http::get('/v1/account/logs') ->inject('locale') ->inject('geodb') ->inject('dbForProject') - ->action(function (array $queries, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject) { + ->inject('auth') + ->action(function (array $queries, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject, Authorization $auth) { try { $queries = Query::parseQueries($queries); @@ -2207,7 +2219,7 @@ Http::get('/v1/account/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new EventAudit($dbForProject); + $audit = new EventAudit($dbForProject, $auth); $logs = $audit->getLogsByUser($user->getInternalId(), $limit, $offset); @@ -2261,7 +2273,8 @@ Http::get('/v1/account/sessions/:sessionId') ->inject('user') ->inject('locale') ->inject('project') - ->action(function (?string $sessionId, Response $response, Document $user, Locale $locale, Document $project) { + ->inject('auth') + ->action(function (?string $sessionId, Response $response, Document $user, Locale $locale, Document $project, Authorization $auth) { $roles = $auth->getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); @@ -2416,7 +2429,8 @@ Http::patch('/v1/account/email') ->inject('queueForEvents') ->inject('project') ->inject('hooks') - ->action(function (string $email, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks) { + ->inject('auth') + ->action(function (string $email, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks, Authorization $auth) { // passwordUpdate will be empty if the user has never set a password $passwordUpdate = $user->getAttribute('passwordUpdate'); @@ -2508,7 +2522,8 @@ Http::patch('/v1/account/phone') ->inject('queueForEvents') ->inject('project') ->inject('hooks') - ->action(function (string $phone, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks) { + ->inject('auth') + ->action(function (string $phone, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Hooks $hooks, Authorization $auth) { // passwordUpdate will be empty if the user has never set a password $passwordUpdate = $user->getAttribute('passwordUpdate'); @@ -2888,7 +2903,8 @@ Http::post('/v1/account/recovery') ->inject('locale') ->inject('queueForMails') ->inject('queueForEvents') - ->action(function (string $email, string $url, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Mail $queueForMails, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $email, string $url, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Mail $queueForMails, Event $queueForEvents, Authorization $auth) { if (empty(Http::getEnv('_APP_SMTP_HOST'))) { throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled'); @@ -3065,7 +3081,8 @@ Http::put('/v1/account/recovery') ->inject('project') ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $secret, string $password, Response $response, Document $user, Database $dbForProject, Document $project, Event $queueForEvents, Hooks $hooks) { + ->inject('auth') + ->action(function (string $userId, string $secret, string $password, Response $response, Document $user, Database $dbForProject, Document $project, Event $queueForEvents, Hooks $hooks, Authorization $auth) { $profile = $dbForProject->getDocument('users', $userId); if ($profile->isEmpty()) { @@ -3149,7 +3166,8 @@ Http::post('/v1/account/verification') ->inject('locale') ->inject('queueForEvents') ->inject('queueForMails') - ->action(function (string $url, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) { + ->inject('auth') + ->action(function (string $url, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, Authorization $auth) { if (empty(Http::getEnv('_APP_SMTP_HOST'))) { throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled'); @@ -3307,7 +3325,8 @@ Http::put('/v1/account/verification') ->inject('user') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $profile = $auth->skip(fn () => $dbForProject->getDocument('users', $userId)); @@ -3370,7 +3389,8 @@ Http::post('/v1/account/verification/phone') ->inject('queueForMessaging') ->inject('project') ->inject('locale') - ->action(function (Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Document $project, Locale $locale) { + ->inject('auth') + ->action(function (Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Document $project, Locale $locale, Authorization $auth) { if (empty(Http::getEnv('_APP_SMS_PROVIDER'))) { throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured'); } @@ -3479,7 +3499,8 @@ Http::put('/v1/account/verification/phone') ->inject('user') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $profile = $auth->skip(fn () => $dbForProject->getDocument('users', $userId)); @@ -4227,7 +4248,8 @@ Http::post('/v1/account/targets/push') ->inject('request') ->inject('response') ->inject('dbForProject') - ->action(function (string $targetId, string $identifier, string $providerId, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $targetId, string $identifier, string $providerId, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $auth) { $targetId = $targetId == 'unique()' ? ID::unique() : $targetId; $provider = $auth->skip(fn () => $dbForProject->getDocument('providers', $providerId)); @@ -4299,7 +4321,8 @@ Http::put('/v1/account/targets/:targetId/push') ->inject('request') ->inject('response') ->inject('dbForProject') - ->action(function (string $targetId, string $identifier, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $targetId, string $identifier, Event $queueForEvents, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $auth) { $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId)); @@ -4354,7 +4377,8 @@ Http::delete('/v1/account/targets/:targetId/push') ->inject('request') ->inject('response') ->inject('dbForProject') - ->action(function (string $targetId, Event $queueForEvents, Delete $queueForDeletes, Document $user, Request $request, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $targetId, Event $queueForEvents, Delete $queueForDeletes, Document $user, Request $request, Response $response, Database $dbForProject, Authorization $auth) { $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $targetId)); if ($target->isEmpty()) { diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 8a4b0b6afd..b6df369467 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -5,7 +5,6 @@ use Appwrite\URL\URL as URLParse; use Appwrite\Utopia\Response; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -14,15 +13,16 @@ use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\UID; use Utopia\Domains\Domain; -use Utopia\Image\Image; -use Utopia\Logger\Log; -use Utopia\Logger\Logger; +use Utopia\Http\Http; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\HexColor; use Utopia\Http\Validator\Range; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\URL; use Utopia\Http\Validator\WhiteList; +use Utopia\Image\Image; +use Utopia\Logger\Log; +use Utopia\Logger\Logger; $avatarCallback = function (string $type, string $code, int $width, int $height, int $quality, Response $response) { @@ -61,7 +61,7 @@ $avatarCallback = function (string $type, string $code, int $width, int $height, unset($image); }; -$getUserGitHub = function (string $userId, Document $project, Database $dbForProject, Database $dbForConsole, ?Logger $logger) { +$getUserGitHub = function (string $userId, Document $project, Database $dbForProject, Database $dbForConsole, ?Logger $logger, Authorization $auth) { try { $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); @@ -593,7 +593,8 @@ Http::get('/v1/cards/cloud') ->inject('contributors') ->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) { + ->inject('authp') + ->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, Authorization $auth) use ($getUserGitHub) { $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); if ($user->isEmpty() && empty($mock)) { @@ -605,7 +606,7 @@ Http::get('/v1/cards/cloud') $email = $user->getAttribute('email', ''); $createdAt = new \DateTime($user->getCreatedAt()); - $gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForConsole, $logger); + $gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForConsole, $logger, $auth); $githubName = $gitHub['name'] ?? ''; $githubId = $gitHub['id'] ?? ''; @@ -800,7 +801,8 @@ Http::get('/v1/cards/cloud-back') ->inject('contributors') ->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) { + ->inject('auth') + ->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, Authorization $auth) use ($getUserGitHub) { $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); if ($user->isEmpty() && empty($mock)) { @@ -811,7 +813,7 @@ Http::get('/v1/cards/cloud-back') $userId = $user->getId(); $email = $user->getAttribute('email', ''); - $gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForConsole, $logger); + $gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForConsole, $logger, $auth); $githubId = $gitHub['id'] ?? ''; $isHero = \array_key_exists($email, $heroes); @@ -878,7 +880,8 @@ Http::get('/v1/cards/cloud-og') ->inject('contributors') ->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) { + ->inject('auth') + ->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, Authorization $auth) use ($getUserGitHub) { $user = $auth->skip(fn () => $dbForConsole->getDocument('users', $userId)); if ($user->isEmpty() && empty($mock)) { @@ -894,7 +897,7 @@ Http::get('/v1/cards/cloud-og') $email = $user->getAttribute('email', ''); $createdAt = new \DateTime($user->getCreatedAt()); - $gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForConsole, $logger); + $gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForConsole, $logger, $auth); $githubName = $gitHub['name'] ?? ''; $githubId = $gitHub['id'] ?? ''; diff --git a/app/controllers/api/console.php b/app/controllers/api/console.php index 4edec4394a..ef2b283638 100644 --- a/app/controllers/api/console.php +++ b/app/controllers/api/console.php @@ -2,8 +2,8 @@ use Appwrite\Extend\Exception; use Appwrite\Utopia\Response; -use Utopia\Http\Http; use Utopia\Database\Document; +use Utopia\Http\Http; use Utopia\Http\Validator\Text; Http::init() diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index c2fc070cc3..b419e235c1 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -15,7 +15,6 @@ use Appwrite\Utopia\Database\Validator\Queries\Indexes; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use MaxMind\Db\Reader; -use Utopia\Http\Http; use Utopia\Audit\Audit; use Utopia\Config\Config; use Utopia\Database\Database; @@ -32,6 +31,7 @@ use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Authorization\Input; use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Index as IndexValidator; use Utopia\Database\Validator\Key; @@ -41,7 +41,7 @@ use Utopia\Database\Validator\Query\Limit; use Utopia\Database\Validator\Query\Offset; use Utopia\Database\Validator\Structure; use Utopia\Database\Validator\UID; -use Utopia\Locale\Locale; +use Utopia\Http\Http; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\FloatValidator; @@ -53,6 +53,7 @@ use Utopia\Http\Validator\Range; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\URL; use Utopia\Http\Validator\WhiteList; +use Utopia\Locale\Locale; /** * * Create attribute of varying type @@ -74,7 +75,7 @@ use Utopia\Http\Validator\WhiteList; * @throws ConflictException * @throws Exception */ -function createAttribute(string $databaseId, string $collectionId, Document $attribute, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): Document +function createAttribute(string $databaseId, string $collectionId, Document $attribute, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth): Document { $key = $attribute->getAttribute('key'); $type = $attribute->getAttribute('type', ''); @@ -223,6 +224,7 @@ function createAttribute(string $databaseId, string $collectionId, Document $att } function updateAttribute( + Authorization $auth, string $databaseId, string $collectionId, string $key, @@ -235,7 +237,7 @@ function updateAttribute( int|float $min = null, int|float $max = null, array $elements = null, - array $options = [] + array $options = [], ): Document { $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -564,7 +566,8 @@ Http::get('/v1/databases/:databaseId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $databaseId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $databaseId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $database = $dbForProject->getDocument('databases', $databaseId); @@ -582,7 +585,7 @@ Http::get('/v1/databases/:databaseId/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $resource = 'database/' . $databaseId; $logs = $audit->getLogsByResource($resource, $limit, $offset); @@ -750,7 +753,8 @@ Http::post('/v1/databases/:databaseId/collections') ->inject('dbForProject') ->inject('mode') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, Response $response, Database $dbForProject, string $mode, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, Response $response, Database $dbForProject, string $mode, Event $queueForEvents, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -811,7 +815,8 @@ Http::get('/v1/databases/:databaseId/collections') ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $databaseId, array $queries, string $search, Response $response, Database $dbForProject, string $mode) { + ->inject('auth') + ->action(function (string $databaseId, array $queries, string $search, Response $response, Database $dbForProject, string $mode, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -873,7 +878,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId') ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, string $mode) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, string $mode, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -909,7 +915,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -934,7 +941,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $resource = 'database/' . $databaseId . '/collection/' . $collectionId; $logs = $audit->getLogsByResource($resource, $limit, $offset); @@ -1015,7 +1022,8 @@ Http::put('/v1/databases/:databaseId/collections/:collectionId') ->inject('dbForProject') ->inject('mode') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, Response $response, Database $dbForProject, string $mode, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, Response $response, Database $dbForProject, string $mode, Event $queueForEvents, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -1079,7 +1087,8 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId') ->inject('queueForDatabase') ->inject('queueForEvents') ->inject('mode') - ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, string $mode) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, string $mode, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -1140,7 +1149,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/strin ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?int $size, ?bool $required, ?string $default, bool $array, bool $encrypt, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?int $size, ?bool $required, ?string $default, bool $array, bool $encrypt, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { // Ensure attribute default is within required size $validator = new Text($size, 0); @@ -1162,7 +1172,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/strin 'default' => $default, 'array' => $array, 'filters' => $filters, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) @@ -1194,7 +1204,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/email ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { $attribute = createAttribute($databaseId, $collectionId, new Document([ 'key' => $key, @@ -1204,7 +1215,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/email 'default' => $default, 'array' => $array, 'format' => APP_DATABASE_ATTRIBUTE_EMAIL, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) @@ -1237,7 +1248,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum' ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, array $elements, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, array $elements, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { if (!is_null($default) && !in_array($default, $elements)) { throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Default value not found in elements'); } @@ -1251,7 +1263,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum' 'array' => $array, 'format' => APP_DATABASE_ATTRIBUTE_ENUM, 'formatOptions' => ['elements' => $elements], - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) @@ -1283,7 +1295,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/ip') ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { $attribute = createAttribute($databaseId, $collectionId, new Document([ 'key' => $key, @@ -1293,7 +1306,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/ip') 'default' => $default, 'array' => $array, 'format' => APP_DATABASE_ATTRIBUTE_IP, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) @@ -1325,7 +1338,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/url') ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { $attribute = createAttribute($databaseId, $collectionId, new Document([ 'key' => $key, @@ -1335,7 +1349,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/url') 'default' => $default, 'array' => $array, 'format' => APP_DATABASE_ATTRIBUTE_URL, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) @@ -1369,7 +1383,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/integ ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { // Ensure attribute default is within range $min = (is_null($min)) ? PHP_INT_MIN : \intval($min); @@ -1399,7 +1414,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/integ 'min' => $min, 'max' => $max, ], - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $formatOptions = $attribute->getAttribute('formatOptions', []); @@ -1440,7 +1455,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { // Ensure attribute default is within range $min = (is_null($min)) ? -PHP_FLOAT_MAX : \floatval($min); @@ -1473,7 +1489,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float 'min' => $min, 'max' => $max, ], - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $formatOptions = $attribute->getAttribute('formatOptions', []); @@ -1512,7 +1528,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/boole ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { $attribute = createAttribute($databaseId, $collectionId, new Document([ 'key' => $key, @@ -1521,7 +1538,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/boole 'required' => $required, 'default' => $default, 'array' => $array, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) @@ -1553,7 +1570,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/datet ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { $filters[] = 'datetime'; @@ -1565,7 +1583,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/datet 'default' => $default, 'array' => $array, 'filters' => $filters, - ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); + ]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $auth); $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) @@ -1599,6 +1617,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relat ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') + ->inject('auth') ->action(function ( string $databaseId, string $collectionId, @@ -1611,7 +1630,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relat Response $response, Database $dbForProject, EventDatabase $queueForDatabase, - Event $queueForEvents + Event $queueForEvents, + Authorization $auth ) { $key ??= $relatedCollectionId; $twoWayKey ??= $collectionId; @@ -1686,7 +1706,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relat $response, $dbForProject, $queueForDatabase, - $queueForEvents + $queueForEvents, + $auth ); $options = $attribute->getAttribute('options', []); @@ -1717,7 +1738,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/attributes') ->param('queries', [], new Attributes(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Attributes::ALLOWED_ATTRIBUTES), true) ->inject('response') ->inject('dbForProject') - ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, Authorization $auth) { /** @var Document $database */ $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -1805,7 +1827,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key') ->param('key', '', new Key(), 'Attribute Key.') ->inject('response') ->inject('dbForProject') - ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -1874,9 +1897,11 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/stri ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -1913,8 +1938,10 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/emai ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -1953,8 +1980,10 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/enum ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?array $elements, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?array $elements, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -1993,8 +2022,10 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/ip/: ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -2032,8 +2063,10 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/url/ ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -2073,8 +2106,10 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/inte ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -2122,8 +2157,10 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/floa ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -2169,8 +2206,10 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/bool ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -2207,8 +2246,10 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/date ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $attribute = updateAttribute( + auth: $auth, databaseId: $databaseId, collectionId: $collectionId, key: $key, @@ -2244,6 +2285,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') + ->inject('auth') ->action(function ( string $databaseId, string $collectionId, @@ -2251,9 +2293,11 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key ?string $onDelete, Response $response, Database $dbForProject, - Event $queueForEvents + Event $queueForEvents, + Authorization $auth ) { $attribute = updateAttribute( + $auth, $databaseId, $collectionId, $key, @@ -2298,7 +2342,8 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:ke ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -2411,7 +2456,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/indexes') ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, string $type, array $attributes, array $orders, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, string $type, array $attributes, array $orders, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -2573,7 +2619,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/indexes') ->param('queries', [], new Indexes(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Indexes::ALLOWED_ATTRIBUTES), true) ->inject('response') ->inject('dbForProject') - ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, Authorization $auth) { /** @var Document $database */ $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -2643,7 +2690,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/indexes/:key') ->param('key', null, new Key(), 'Index Key.') ->inject('response') ->inject('dbForProject') - ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -2686,7 +2734,8 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key') ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $auth) { $db = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -2759,7 +2808,8 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/documents') ->inject('user') ->inject('queueForEvents') ->inject('mode') - ->action(function (string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, Response $response, Database $dbForProject, Document $user, Event $queueForEvents, string $mode) { + ->inject('auth') + ->action(function (string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, Response $response, Database $dbForProject, Document $user, Event $queueForEvents, string $mode, Authorization $auth) { $data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array @@ -2830,17 +2880,16 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/documents') $data['$permissions'] = $permissions; $document = new Document($data); - $checkPermissions = function (Document $collection, Document $document, string $permission) use (&$checkPermissions, $dbForProject, $database) { + $checkPermissions = function (Document $collection, Document $document, string $permission) use (&$checkPermissions, $dbForProject, $database, $auth) { $documentSecurity = $collection->getAttribute('documentSecurity', false); - $validator = new Authorization($permission); - $valid = $validator->isValid($collection->getPermissionsByType($permission)); + $valid = $auth->isValid(new Input($permission, $collection->getPermissionsByType($permission))); if (($permission === Database::PERMISSION_UPDATE && !$documentSecurity) || !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } if ($permission === Database::PERMISSION_UPDATE) { - $valid = $valid || $validator->isValid($document->getUpdate()); + $valid = $valid || $auth->isValid($document->getUpdate()); if ($documentSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -2921,7 +2970,7 @@ Http::post('/v1/databases/:databaseId/collections/:collectionId/documents') } // Add $collectionId and $databaseId for all documents - $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database) { + $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database, $auth) { $document->setAttribute('$databaseId', $database->getId()); $document->setAttribute('$collectionId', $collection->getId()); @@ -2987,7 +3036,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents') ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, string $mode) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, string $mode, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); @@ -3039,7 +3089,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents') } // Add $collectionId and $databaseId for all documents - $processDocument = (function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database): bool { + $processDocument = (function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database, $auth): bool { if ($document->isEmpty()) { return false; } @@ -3144,7 +3194,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents/:docume ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, string $mode) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, string $mode, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); @@ -3174,7 +3225,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents/:docume } // Add $collectionId and $databaseId for all documents - $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database) { + $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database, $auth) { if ($document->isEmpty()) { return; } @@ -3235,7 +3286,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents/:docume ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -3265,7 +3317,7 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/documents/:docume $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $resource = 'database/' . $databaseId . '/collection/' . $collectionId . '/document/' . $document->getId(); $logs = $audit->getLogsByResource($resource, $limit, $offset); @@ -3349,7 +3401,8 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu ->inject('dbForProject') ->inject('queueForEvents') ->inject('mode') - ->action(function (string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Event $queueForEvents, string $mode) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Event $queueForEvents, string $mode, Authorization $auth) { $data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array @@ -3416,7 +3469,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu $data['$permissions'] = $permissions; $newDocument = new Document($data); - $setCollection = (function (Document $collection, Document $document) use (&$setCollection, $dbForProject, $database) { + $setCollection = (function (Document $collection, Document $document) use (&$setCollection, $dbForProject, $database, $auth) { $relationships = \array_filter( $collection->getAttribute('attributes', []), fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP @@ -3502,7 +3555,7 @@ Http::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docu } // Add $collectionId and $databaseId for all documents - $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database) { + $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database, $auth) { $document->setAttribute('$databaseId', $database->getId()); $document->setAttribute('$collectionId', $collection->getId()); @@ -3575,7 +3628,8 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:doc ->inject('queueForDeletes') ->inject('queueForEvents') ->inject('mode') - ->action(function (string $databaseId, string $collectionId, string $documentId, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $queueForEvents, string $mode) { + ->inject('auth') + ->action(function (string $databaseId, string $collectionId, string $documentId, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $queueForEvents, string $mode, Authorization $auth) { $database = $auth->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); @@ -3612,7 +3666,7 @@ Http::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:doc }); // Add $collectionId and $databaseId for all documents - $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database) { + $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database, $auth) { $document->setAttribute('$databaseId', $database->getId()); $document->setAttribute('$collectionId', $collection->getId()); @@ -3674,7 +3728,8 @@ Http::get('/v1/databases/usage') ->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), '`Date range.', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $range, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $range, Response $response, Database $dbForProject, Authorization $auth) { $periods = Config::getParam('usage', []); $stats = $usage = []; @@ -3753,7 +3808,8 @@ Http::get('/v1/databases/:databaseId/usage') ->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), '`Date range.', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $databaseId, string $range, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $databaseId, string $range, Response $response, Database $dbForProject, Authorization $auth) { $database = $dbForProject->getDocument('databases', $databaseId); @@ -3838,7 +3894,8 @@ Http::get('/v1/databases/:databaseId/collections/:collectionId/usage') ->param('collectionId', '', new UID(), 'Collection ID.') ->inject('response') ->inject('dbForProject') - ->action(function (string $databaseId, string $range, string $collectionId, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $databaseId, string $range, string $collectionId, Response $response, Database $dbForProject, Authorization $auth) { $database = $dbForProject->getDocument('databases', $databaseId); $collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId); diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 59c3254d67..44ac1a926a 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -15,11 +15,11 @@ use Appwrite\Utopia\Database\Validator\CustomId; use Appwrite\Utopia\Database\Validator\Queries\Deployments; use Appwrite\Utopia\Database\Validator\Queries\Executions; use Appwrite\Utopia\Database\Validator\Queries\Functions; +use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model\Rule; use Executor\Executor; use MaxMind\Db\Reader; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -32,20 +32,21 @@ use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Authorization\Input; use Utopia\Database\Validator\Roles; use Utopia\Database\Validator\UID; -use Utopia\Storage\Device; -use Utopia\Storage\Validator\File; -use Utopia\Storage\Validator\FileExt; -use Utopia\Storage\Validator\FileSize; -use Utopia\Storage\Validator\Upload; -use Utopia\Swoole\Request; +use Utopia\Http\Http; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Assoc; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\Range; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\WhiteList; +use Utopia\Storage\Device; +use Utopia\Storage\Validator\File; +use Utopia\Storage\Validator\FileExt; +use Utopia\Storage\Validator\FileSize; +use Utopia\Storage\Validator\Upload; use Utopia\VCS\Adapter\Git\GitHub; use Utopia\VCS\Exception\RepositoryNotFound; @@ -479,7 +480,8 @@ Http::get('/v1/functions/:functionId/usage') ->param('range', '30d', new WhiteList(['24h', '30d', '90d']), 'Date range.', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $functionId, string $range, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $functionId, string $range, Response $response, Database $dbForProject, Authorization $auth) { $function = $dbForProject->getDocument('functions', $functionId); @@ -576,7 +578,8 @@ Http::get('/v1/functions/usage') ->param('range', '30d', new WhiteList(['24h', '30d', '90d']), 'Date range.', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $range, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $range, Response $response, Database $dbForProject, Authorization $auth) { $periods = Config::getParam('usage', []); $stats = $usage = []; @@ -694,7 +697,8 @@ Http::put('/v1/functions/:functionId') ->inject('queueForBuilds') ->inject('dbForConsole') ->inject('gitHub') - ->action(function (string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, Request $request, Response $response, Database $dbForProject, Document $project, Event $queueForEvents, Build $queueForBuilds, Database $dbForConsole, GitHub $github) use ($redeployVcs) { + ->inject('auth') + ->action(function (string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, Request $request, Response $response, Database $dbForProject, Document $project, Event $queueForEvents, Build $queueForBuilds, Database $dbForConsole, GitHub $github, Authorization $auth) use ($redeployVcs) { // TODO: If only branch changes, re-deploy $function = $dbForProject->getDocument('functions', $functionId); @@ -940,7 +944,8 @@ Http::patch('/v1/functions/:functionId/deployments/:deploymentId') ->inject('dbForProject') ->inject('queueForEvents') ->inject('dbForConsole') - ->action(function (string $functionId, string $deploymentId, Response $response, Database $dbForProject, Event $queueForEvents, Database $dbForConsole) { + ->inject('auth') + ->action(function (string $functionId, string $deploymentId, Response $response, Database $dbForProject, Event $queueForEvents, Database $dbForConsole, Authorization $auth) { $function = $dbForProject->getDocument('functions', $functionId); $deployment = $dbForProject->getDocument('deployments', $deploymentId); @@ -1001,7 +1006,8 @@ Http::delete('/v1/functions/:functionId') ->inject('queueForDeletes') ->inject('queueForEvents') ->inject('dbForConsole') - ->action(function (string $functionId, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $queueForEvents, Database $dbForConsole) { + ->inject('auth') + ->action(function (string $functionId, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $queueForEvents, Database $dbForConsole, Authorization $auth) { $function = $dbForProject->getDocument('functions', $functionId); @@ -1451,7 +1457,8 @@ Http::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId' ->inject('project') ->inject('queueForEvents') ->inject('queueForBuilds') - ->action(function (string $functionId, string $deploymentId, string $buildId, Request $request, Response $response, Database $dbForProject, Document $project, Event $queueForEvents, Build $queueForBuilds) { + ->inject('auth') + ->action(function (string $functionId, string $deploymentId, string $buildId, Request $request, Response $response, Database $dbForProject, Document $project, Event $queueForEvents, Build $queueForBuilds, Authorization $auth) { $function = $dbForProject->getDocument('functions', $functionId); @@ -1522,7 +1529,8 @@ Http::post('/v1/functions/:functionId/executions') ->inject('mode') ->inject('queueForFunctions') ->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) { + ->inject('auth') + ->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, Authorization $auth) { $function = $auth->skip(fn () => $dbForProject->getDocument('functions', $functionId)); @@ -1562,10 +1570,8 @@ Http::post('/v1/functions/:functionId/executions') throw new Exception(Exception::BUILD_NOT_READY); } - $validator = new Authorization('execute'); - - if (!$validator->isValid($function->getAttribute('execute'))) { // Check if user has write access to execute function - throw new Exception(Exception::USER_UNAUTHORIZED, $validator->getDescription()); + if (!$auth->isValid(new Input('execute', $function->getAttribute('execute')))) { // Check if user has write access to execute function + throw new Exception(Exception::USER_UNAUTHORIZED, $auth->getDescription()); } $jwt = ''; // initialize @@ -1803,7 +1809,8 @@ Http::get('/v1/functions/:functionId/executions') ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $functionId, array $queries, string $search, Response $response, Database $dbForProject, string $mode) { + ->inject('auth') + ->action(function (string $functionId, array $queries, string $search, Response $response, Database $dbForProject, string $mode, Authorization $auth) { $function = $auth->skip(fn () => $dbForProject->getDocument('functions', $functionId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); @@ -1883,7 +1890,8 @@ Http::get('/v1/functions/:functionId/executions/:executionId') ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $functionId, string $executionId, Response $response, Database $dbForProject, string $mode) { + ->inject('auth') + ->action(function (string $functionId, string $executionId, Response $response, Database $dbForProject, string $mode, Authorization $auth) { $function = $auth->skip(fn () => $dbForProject->getDocument('functions', $functionId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); @@ -1935,7 +1943,8 @@ Http::post('/v1/functions/:functionId/variables') ->inject('response') ->inject('dbForProject') ->inject('dbForConsole') - ->action(function (string $functionId, string $key, string $value, Response $response, Database $dbForProject, Database $dbForConsole) { + ->inject('auth') + ->action(function (string $functionId, string $key, string $value, Response $response, Database $dbForProject, Database $dbForConsole, Authorization $auth) { $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { @@ -2066,7 +2075,8 @@ Http::put('/v1/functions/:functionId/variables/:variableId') ->inject('response') ->inject('dbForProject') ->inject('dbForConsole') - ->action(function (string $functionId, string $variableId, string $key, ?string $value, Response $response, Database $dbForProject, Database $dbForConsole) { + ->inject('auth') + ->action(function (string $functionId, string $variableId, string $key, ?string $value, Response $response, Database $dbForProject, Database $dbForConsole, Authorization $auth) { $function = $dbForProject->getDocument('functions', $functionId); @@ -2124,7 +2134,8 @@ Http::delete('/v1/functions/:functionId/variables/:variableId') ->inject('response') ->inject('dbForProject') ->inject('dbForConsole') - ->action(function (string $functionId, string $variableId, Response $response, Database $dbForProject, Database $dbForConsole) { + ->inject('auth') + ->action(function (string $functionId, string $variableId, Response $response, Database $dbForProject, Database $dbForConsole, Authorization $auth) { $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { diff --git a/app/controllers/api/graphql.php b/app/controllers/api/graphql.php index c50811e0a3..4eb858b81c 100644 --- a/app/controllers/api/graphql.php +++ b/app/controllers/api/graphql.php @@ -12,8 +12,8 @@ use GraphQL\Validator\Rules\DisableIntrospection; use GraphQL\Validator\Rules\QueryComplexity; use GraphQL\Validator\Rules\QueryDepth; use Swoole\Coroutine\WaitGroup; -use Utopia\Http\Http; use Utopia\Database\Document; +use Utopia\Http\Http; use Utopia\Http\Validator\JSON; use Utopia\Http\Validator\Text; diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index 1fc0541d2e..26246db019 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -4,10 +4,15 @@ use Appwrite\ClamAV\Network; use Appwrite\Event\Event; use Appwrite\Extend\Exception; use Appwrite\Utopia\Response; -use Utopia\Http\Http; use Utopia\Config\Config; use Utopia\Database\Document; use Utopia\Domains\Validator\PublicDomain; +use Utopia\Http\Http; +use Utopia\Http\Validator\Domain; +use Utopia\Http\Validator\Integer; +use Utopia\Http\Validator\Multiple; +use Utopia\Http\Validator\Text; +use Utopia\Http\Validator\WhiteList; use Utopia\Pools\Group; use Utopia\Queue\Client; use Utopia\Queue\Connection; @@ -15,11 +20,6 @@ use Utopia\Registry\Registry; use Utopia\Storage\Device; use Utopia\Storage\Device\Local; use Utopia\Storage\Storage; -use Utopia\Http\Validator\Domain; -use Utopia\Http\Validator\Integer; -use Utopia\Http\Validator\Multiple; -use Utopia\Http\Validator\Text; -use Utopia\Http\Validator\WhiteList; Http::get('/v1/health') ->desc('Get HTTP') diff --git a/app/controllers/api/locale.php b/app/controllers/api/locale.php index e4bf57d5ab..fcaf0c03cb 100644 --- a/app/controllers/api/locale.php +++ b/app/controllers/api/locale.php @@ -3,9 +3,9 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use MaxMind\Db\Reader; -use Utopia\Http\Http; use Utopia\Config\Config; use Utopia\Database\Document; +use Utopia\Http\Http; use Utopia\Locale\Locale; Http::get('/v1/locale') diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 5e0d31a294..1adf08d4bc 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -19,7 +19,6 @@ use Appwrite\Utopia\Database\Validator\Queries\Targets; use Appwrite\Utopia\Database\Validator\Queries\Topics; use Appwrite\Utopia\Response; use MaxMind\Db\Reader; -use Utopia\Http\Http; use Utopia\Audit\Audit; use Utopia\Database\Database; use Utopia\Database\DateTime; @@ -29,6 +28,7 @@ use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Authorization\Input; use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Queries; use Utopia\Database\Validator\Query\Limit; @@ -36,7 +36,7 @@ use Utopia\Database\Validator\Query\Offset; use Utopia\Database\Validator\Roles; use Utopia\Database\Validator\UID; use Utopia\Domains\Domain; -use Utopia\Locale\Locale; +use Utopia\Http\Http; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\Integer; @@ -44,6 +44,7 @@ use Utopia\Http\Validator\JSON; use Utopia\Http\Validator\Range; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\WhiteList; +use Utopia\Locale\Locale; use function Swoole\Coroutine\batch; @@ -846,7 +847,8 @@ Http::get('/v1/messaging/providers') ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('dbForProject') ->inject('response') - ->action(function (array $queries, string $search, Database $dbForProject, Response $response) { + ->inject('auth') + ->action(function (array $queries, string $search, Database $dbForProject, Response $response, Authorization $auth) { try { $queries = Query::parseQueries($queries); } catch (QueryException $e) { @@ -899,7 +901,8 @@ Http::get('/v1/messaging/providers/:providerId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $providerId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $providerId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $provider = $dbForProject->getDocument('providers', $providerId); if ($provider->isEmpty()) { @@ -916,7 +919,7 @@ Http::get('/v1/messaging/providers/:providerId/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $resource = 'provider/' . $providerId; $logs = $audit->getLogsByResource($resource, $limit, $offset); $output = []; @@ -1980,7 +1983,8 @@ Http::get('/v1/messaging/topics') ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('dbForProject') ->inject('response') - ->action(function (array $queries, string $search, Database $dbForProject, Response $response) { + ->inject('auth') + ->action(function (array $queries, string $search, Database $dbForProject, Response $response, Authorization $auth) { try { $queries = Query::parseQueries($queries); } catch (QueryException $e) { @@ -2033,7 +2037,8 @@ Http::get('/v1/messaging/topics/:topicId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $topicId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $topicId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $topic = $dbForProject->getDocument('topics', $topicId); if ($topic->isEmpty()) { @@ -2050,7 +2055,7 @@ Http::get('/v1/messaging/topics/:topicId/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $resource = 'topic/' . $topicId; $logs = $audit->getLogsByResource($resource, $limit, $offset); @@ -2236,7 +2241,8 @@ Http::post('/v1/messaging/topics/:topicId/subscribers') ->inject('queueForEvents') ->inject('dbForProject') ->inject('response') - ->action(function (string $subscriberId, string $topicId, string $targetId, Event $queueForEvents, Database $dbForProject, Response $response) { + ->inject('auth') + ->action(function (string $subscriberId, string $topicId, string $targetId, Event $queueForEvents, Database $dbForProject, Response $response, Authorization $auth) { $subscriberId = $subscriberId == 'unique()' ? ID::unique() : $subscriberId; $topic = $auth->skip(fn () => $dbForProject->getDocument('topics', $topicId)); @@ -2245,9 +2251,9 @@ Http::post('/v1/messaging/topics/:topicId/subscribers') throw new Exception(Exception::TOPIC_NOT_FOUND); } - $validator = new Authorization('subscribe'); + $validator = new Authorization(); - if (!$validator->isValid($topic->getAttribute('subscribe'))) { + if (!$validator->isValid(new Input('subscribe', $topic->getAttribute('subscribe')))) { throw new Exception(Exception::USER_UNAUTHORIZED, $validator->getDescription()); } @@ -2328,7 +2334,8 @@ Http::get('/v1/messaging/topics/:topicId/subscribers') ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('dbForProject') ->inject('response') - ->action(function (string $topicId, array $queries, string $search, Database $dbForProject, Response $response) { + ->inject('auth') + ->action(function (string $topicId, array $queries, string $search, Database $dbForProject, Response $response, Authorization $auth) { try { $queries = Query::parseQueries($queries); } catch (QueryException $e) { @@ -2368,8 +2375,8 @@ Http::get('/v1/messaging/topics/:topicId/subscribers') $subscribers = $dbForProject->find('subscribers', $queries); - $subscribers = batch(\array_map(function (Document $subscriber) use ($dbForProject) { - return function () use ($subscriber, $dbForProject) { + $subscribers = batch(\array_map(function (Document $subscriber) use ($dbForProject, $auth) { + return function () use ($subscriber, $dbForProject, $auth) { $target = $auth->skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId'))); $user = $auth->skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId'))); @@ -2403,7 +2410,8 @@ Http::get('/v1/messaging/subscribers/:subscriberId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $subscriberId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $subscriberId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $subscriber = $dbForProject->getDocument('subscribers', $subscriberId); if ($subscriber->isEmpty()) { @@ -2420,7 +2428,7 @@ Http::get('/v1/messaging/subscribers/:subscriberId/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $resource = 'subscriber/' . $subscriberId; $logs = $audit->getLogsByResource($resource, $limit, $offset); @@ -2490,7 +2498,8 @@ Http::get('/v1/messaging/topics/:topicId/subscribers/:subscriberId') ->param('subscriberId', '', new UID(), 'Subscriber ID.') ->inject('dbForProject') ->inject('response') - ->action(function (string $topicId, string $subscriberId, Database $dbForProject, Response $response) { + ->inject('auth') + ->action(function (string $topicId, string $subscriberId, Database $dbForProject, Response $response, Authorization $auth) { $topic = $auth->skip(fn () => $dbForProject->getDocument('topics', $topicId)); if ($topic->isEmpty()) { @@ -2533,7 +2542,8 @@ Http::delete('/v1/messaging/topics/:topicId/subscribers/:subscriberId') ->inject('queueForEvents') ->inject('dbForProject') ->inject('response') - ->action(function (string $topicId, string $subscriberId, Event $queueForEvents, Database $dbForProject, Response $response) { + ->inject('auth') + ->action(function (string $topicId, string $subscriberId, Event $queueForEvents, Database $dbForProject, Response $response, Authorization $auth) { $topic = $auth->skip(fn () => $dbForProject->getDocument('topics', $topicId)); if ($topic->isEmpty()) { @@ -3022,7 +3032,8 @@ Http::get('/v1/messaging/messages') ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('dbForProject') ->inject('response') - ->action(function (array $queries, string $search, Database $dbForProject, Response $response) { + ->inject('auth') + ->action(function (array $queries, string $search, Database $dbForProject, Response $response, Authorization $auth) { try { $queries = Query::parseQueries($queries); } catch (QueryException $e) { @@ -3075,7 +3086,8 @@ Http::get('/v1/messaging/messages/:messageId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $messageId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $messageId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $message = $dbForProject->getDocument('messages', $messageId); if ($message->isEmpty()) { @@ -3092,7 +3104,7 @@ Http::get('/v1/messaging/messages/:messageId/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $resource = 'message/' . $messageId; $logs = $audit->getLogsByResource($resource, $limit, $offset); diff --git a/app/controllers/api/migrations.php b/app/controllers/api/migrations.php index badb482c34..84bad41465 100644 --- a/app/controllers/api/migrations.php +++ b/app/controllers/api/migrations.php @@ -9,7 +9,6 @@ use Appwrite\Role; use Appwrite\Utopia\Database\Validator\Queries\Migrations; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; -use Utopia\Http\Http; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; @@ -17,16 +16,17 @@ use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\UID; -use Utopia\Migration\Sources\Appwrite; -use Utopia\Migration\Sources\Firebase; -use Utopia\Migration\Sources\NHost; -use Utopia\Migration\Sources\Supabase; +use Utopia\Http\Http; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Host; use Utopia\Http\Validator\Integer; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\URL; use Utopia\Http\Validator\WhiteList; +use Utopia\Migration\Sources\Appwrite; +use Utopia\Migration\Sources\Firebase; +use Utopia\Migration\Sources\NHost; +use Utopia\Migration\Sources\Supabase; include_once __DIR__ . '/../shared/api.php'; diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index 15154fbbed..05a6c46389 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -2,7 +2,6 @@ use Appwrite\Extend\Exception; use Appwrite\Utopia\Response; -use Utopia\Http\Http; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Duplicate as DuplicateException; @@ -13,6 +12,7 @@ use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Datetime as DateTimeValidator; use Utopia\Database\Validator\UID; +use Utopia\Http\Http; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\WhiteList; @@ -31,7 +31,8 @@ Http::get('/v1/project/usage') ->param('period', '1d', new WhiteList(['1h', '1d']), 'Period used', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $startDate, string $endDate, string $period, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $startDate, string $endDate, string $period, Response $response, Database $dbForProject, Authorization $auth) { $stats = $total = $usage = []; $format = 'Y-m-d 00:00:00'; $firstDay = (new DateTime($startDate))->format($format); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 2a38e4433f..e868df2eeb 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -13,7 +13,6 @@ use Appwrite\Utopia\Database\Validator\Queries\Projects; use Appwrite\Utopia\Response; use PHPMailer\PHPMailer\PHPMailer; use Utopia\Abuse\Adapters\TimeLimit; -use Utopia\Http\Http; use Utopia\Audit\Audit; use Utopia\Cache\Cache; use Utopia\Config\Config; @@ -25,11 +24,11 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\UID; use Utopia\Domains\Validator\PublicDomain; -use Utopia\Locale\Locale; -use Utopia\Pools\Group; +use Utopia\Http\Http; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\Hostname; @@ -39,6 +38,8 @@ use Utopia\Http\Validator\Range; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\URL; use Utopia\Http\Validator\WhiteList; +use Utopia\Locale\Locale; +use Utopia\Pools\Group; Http::init() ->groups(['projects']) @@ -76,7 +77,8 @@ Http::post('/v1/projects') ->inject('dbForConsole') ->inject('cache') ->inject('pools') - ->action(function (string $projectId, string $name, string $teamId, string $region, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole, Cache $cache, Group $pools) { + ->inject('auth') + ->action(function (string $projectId, string $name, string $teamId, string $region, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole, Cache $cache, Group $pools, Authorization $auth) { $team = $dbForConsole->getDocument('teams', $teamId); @@ -177,13 +179,14 @@ Http::post('/v1/projects') } $dbForProject = new Database($pools->get($database)->pop()->getResource(), $cache); + $dbForProject->setAuthorization($auth); $dbForProject->setNamespace("_{$project->getInternalId()}"); $dbForProject->create(); - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $audit->setup(); - $adapter = new TimeLimit('', 0, 1, $dbForProject); + $adapter = new TimeLimit('', 0, 1, $dbForProject, $auth); $adapter->setup(); /** @var array $collections */ diff --git a/app/controllers/api/proxy.php b/app/controllers/api/proxy.php index 7f5564050f..3dff7bd7e9 100644 --- a/app/controllers/api/proxy.php +++ b/app/controllers/api/proxy.php @@ -7,7 +7,6 @@ use Appwrite\Extend\Exception; use Appwrite\Network\Validator\CNAME; use Appwrite\Utopia\Database\Validator\Queries\Rules; use Appwrite\Utopia\Response; -use Utopia\Http\Http; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Query as QueryException; @@ -15,10 +14,11 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\UID; use Utopia\Domains\Domain; -use Utopia\Logger\Log; +use Utopia\Http\Http; use Utopia\Http\Validator\Domain as ValidatorDomain; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\WhiteList; +use Utopia\Logger\Log; Http::post('/v1/proxy/rules') ->groups(['api', 'proxy']) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 859daf20f3..735773a545 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -9,8 +9,8 @@ use Appwrite\OpenSSL\OpenSSL; use Appwrite\Utopia\Database\Validator\CustomId; use Appwrite\Utopia\Database\Validator\Queries\Buckets; use Appwrite\Utopia\Database\Validator\Queries\Files; +use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; -use Utopia\Http\Http; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; @@ -24,8 +24,16 @@ use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Authorization\Input; use Utopia\Database\Validator\Permissions; use Utopia\Database\Validator\UID; +use Utopia\Http\Http; +use Utopia\Http\Validator\ArrayList; +use Utopia\Http\Validator\Boolean; +use Utopia\Http\Validator\HexColor; +use Utopia\Http\Validator\Range; +use Utopia\Http\Validator\Text; +use Utopia\Http\Validator\WhiteList; use Utopia\Image\Image; use Utopia\Storage\Compression\Algorithms\GZIP; use Utopia\Storage\Compression\Algorithms\Zstd; @@ -36,13 +44,6 @@ use Utopia\Storage\Validator\File; use Utopia\Storage\Validator\FileExt; use Utopia\Storage\Validator\FileSize; use Utopia\Storage\Validator\Upload; -use Utopia\Swoole\Request; -use Utopia\Http\Validator\ArrayList; -use Utopia\Http\Validator\Boolean; -use Utopia\Http\Validator\HexColor; -use Utopia\Http\Validator\Range; -use Utopia\Http\Validator\Text; -use Utopia\Http\Validator\WhiteList; Http::post('/v1/storage/buckets') ->desc('Create bucket') @@ -361,7 +362,8 @@ Http::post('/v1/storage/buckets/:bucketId/files') ->inject('mode') ->inject('deviceForFiles') ->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) { + ->inject('auth') + ->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, Authorization $auth) { $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); @@ -372,8 +374,7 @@ Http::post('/v1/storage/buckets/:bucketId/files') throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); } - $validator = new Authorization(Database::PERMISSION_CREATE); - if (!$validator->isValid($bucket->getCreate())) { + if (!$auth->isValid(new Input(Database::PERMISSION_CREATE, $bucket->getCreate()))) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -631,8 +632,7 @@ Http::post('/v1/storage/buckets/:bucketId/files') * However as with chunk upload even if we are updating, we are essentially creating a file * adding it's new chunk so we validate create permission instead of update */ - $validator = new Authorization(Database::PERMISSION_CREATE); - if (!$validator->isValid($bucket->getCreate())) { + if (!$auth->isValid(new Input(Database::PERMISSION_CREATE, $bucket->getCreate()))) { throw new Exception(Exception::USER_UNAUTHORIZED); } $file = $auth->skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); @@ -678,8 +678,7 @@ Http::post('/v1/storage/buckets/:bucketId/files') * However as with chunk upload even if we are updating, we are essentially creating a file * adding it's new chunk so we validate create permission instead of update */ - $validator = new Authorization(Database::PERMISSION_CREATE); - if (!$validator->isValid($bucket->getCreate())) { + if (!$auth->isValid(new Input(Database::PERMISSION_CREATE, $bucket->getCreate()))) { throw new Exception(Exception::USER_UNAUTHORIZED); } $file = $auth->skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); @@ -724,7 +723,8 @@ Http::get('/v1/storage/buckets/:bucketId/files') ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $bucketId, array $queries, string $search, Response $response, Database $dbForProject, string $mode) { + ->inject('auth') + ->action(function (string $bucketId, array $queries, string $search, Response $response, Database $dbForProject, string $mode, Authorization $auth) { $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); @@ -735,8 +735,7 @@ Http::get('/v1/storage/buckets/:bucketId/files') } $fileSecurity = $bucket->getAttribute('fileSecurity', false); - $validator = new Authorization(Database::PERMISSION_READ); - $valid = $validator->isValid($bucket->getRead()); + $valid = $auth->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead())); if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -808,7 +807,8 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId') ->inject('response') ->inject('dbForProject') ->inject('mode') - ->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, string $mode) { + ->inject('auth') + ->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, string $mode, Authorization $auth) { $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); @@ -819,8 +819,7 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId') } $fileSecurity = $bucket->getAttribute('fileSecurity', false); - $validator = new Authorization(Database::PERMISSION_READ); - $valid = $validator->isValid($bucket->getRead()); + $valid = $auth->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead())); if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -873,7 +872,8 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') ->inject('mode') ->inject('deviceForFiles') ->inject('deviceForLocal') - ->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, Request $request, Response $response, Document $project, Database $dbForProject, string $mode, Device $deviceForFiles, Device $deviceForLocal) { + ->inject('auth') + ->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, Request $request, Response $response, Document $project, Database $dbForProject, string $mode, Device $deviceForFiles, Device $deviceForLocal, Authorization $auth) { if (!\extension_loaded('imagick')) { throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing'); @@ -889,8 +889,7 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') } $fileSecurity = $bucket->getAttribute('fileSecurity', false); - $validator = new Authorization(Database::PERMISSION_READ); - $valid = $validator->isValid($bucket->getRead()); + $valid = $auth->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead())); if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -1033,7 +1032,8 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/download') ->inject('dbForProject') ->inject('mode') ->inject('deviceForFiles') - ->action(function (string $bucketId, string $fileId, Request $request, Response $response, Database $dbForProject, string $mode, Device $deviceForFiles) { + ->inject('auth') + ->action(function (string $bucketId, string $fileId, Request $request, Response $response, Database $dbForProject, string $mode, Device $deviceForFiles, Authorization $auth) { $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); @@ -1045,8 +1045,7 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/download') } $fileSecurity = $bucket->getAttribute('fileSecurity', false); - $validator = new Authorization(Database::PERMISSION_READ); - $valid = $validator->isValid($bucket->getRead()); + $valid = $auth->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead())); if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -1173,7 +1172,8 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/view') ->inject('dbForProject') ->inject('mode') ->inject('deviceForFiles') - ->action(function (string $bucketId, string $fileId, Response $response, Request $request, Database $dbForProject, string $mode, Device $deviceForFiles) { + ->inject('auth') + ->action(function (string $bucketId, string $fileId, Response $response, Request $request, Database $dbForProject, string $mode, Device $deviceForFiles, Authorization $auth) { $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); @@ -1184,8 +1184,7 @@ Http::get('/v1/storage/buckets/:bucketId/files/:fileId/view') } $fileSecurity = $bucket->getAttribute('fileSecurity', false); - $validator = new Authorization(Database::PERMISSION_READ); - $valid = $validator->isValid($bucket->getRead()); + $valid = $auth->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead())); if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -1333,7 +1332,8 @@ Http::put('/v1/storage/buckets/:bucketId/files/:fileId') ->inject('user') ->inject('mode') ->inject('queueForEvents') - ->action(function (string $bucketId, string $fileId, ?string $name, ?array $permissions, Response $response, Database $dbForProject, Document $user, string $mode, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $bucketId, string $fileId, ?string $name, ?array $permissions, Response $response, Database $dbForProject, Document $user, string $mode, Event $queueForEvents, Authorization $auth) { $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); @@ -1345,8 +1345,7 @@ Http::put('/v1/storage/buckets/:bucketId/files/:fileId') } $fileSecurity = $bucket->getAttribute('fileSecurity', false); - $validator = new Authorization(Database::PERMISSION_UPDATE); - $valid = $validator->isValid($bucket->getUpdate()); + $valid = $auth->isValid(new Input(Database::PERMISSION_UPDATE, $bucket->getUpdate())); if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -1439,7 +1438,8 @@ Http::delete('/v1/storage/buckets/:bucketId/files/:fileId') ->inject('mode') ->inject('deviceForFiles') ->inject('queueForDeletes') - ->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, Event $queueForEvents, string $mode, Device $deviceForFiles, Delete $queueForDeletes) { + ->inject('auth') + ->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, Event $queueForEvents, string $mode, Device $deviceForFiles, Delete $queueForDeletes, Authorization $auth) { $bucket = $auth->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); $isAPIKey = Auth::isAppUser($auth->getRoles()); @@ -1450,8 +1450,7 @@ Http::delete('/v1/storage/buckets/:bucketId/files/:fileId') } $fileSecurity = $bucket->getAttribute('fileSecurity', false); - $validator = new Authorization(Database::PERMISSION_DELETE); - $valid = $validator->isValid($bucket->getDelete()); + $valid = $auth->isValid(new Input(Database::PERMISSION_DELETE, $bucket->getDelete())); if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -1464,7 +1463,7 @@ Http::delete('/v1/storage/buckets/:bucketId/files/:fileId') } // Make sure we don't delete the file before the document permission check occurs - if ($fileSecurity && !$valid && !$validator->isValid($file->getDelete())) { + if ($fileSecurity && !$valid && !$auth->isValid($file->getDelete())) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -1524,7 +1523,8 @@ Http::get('/v1/storage/usage') ->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), 'Date range.', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $range, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $range, Response $response, Database $dbForProject, Authorization $auth) { $periods = Config::getParam('usage', []); $stats = $usage = []; @@ -1604,7 +1604,8 @@ Http::get('/v1/storage/:bucketId/usage') ->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), 'Date range.', true) ->inject('response') ->inject('dbForProject') - ->action(function (string $bucketId, string $range, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $bucketId, string $range, Response $response, Database $dbForProject, Authorization $auth) { $bucket = $dbForProject->getDocument('buckets', $bucketId); @@ -1620,7 +1621,6 @@ Http::get('/v1/storage/:bucketId/usage') str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE), ]; - $auth->skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { foreach ($metrics as $metric) { $result = $dbForProject->findOne('stats', [ diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index c3542645db..a60bd2f644 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -17,7 +17,6 @@ use Appwrite\Utopia\Database\Validator\Queries\Teams; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use MaxMind\Db\Reader; -use Utopia\Http\Http; use Utopia\Audit\Audit; use Utopia\Config\Config; use Utopia\Database\Database; @@ -36,11 +35,12 @@ use Utopia\Database\Validator\Queries; use Utopia\Database\Validator\Query\Limit; use Utopia\Database\Validator\Query\Offset; use Utopia\Database\Validator\UID; -use Utopia\Locale\Locale; +use Utopia\Http\Http; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Assoc; use Utopia\Http\Validator\Host; use Utopia\Http\Validator\Text; +use Utopia\Locale\Locale; Http::post('/v1/teams') ->desc('Create team') @@ -63,7 +63,8 @@ Http::post('/v1/teams') ->inject('user') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $teamId, string $name, array $roles, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $teamId, string $name, array $roles, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); $isAppUser = Auth::isAppUser($auth->getRoles()); @@ -396,7 +397,8 @@ Http::post('/v1/teams/:teamId/memberships') ->inject('queueForMails') ->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) { + ->inject('auth') + ->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, Authorization $auth) { $isAPIKey = Auth::isAppUser($auth->getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser($auth->getRoles()); @@ -863,7 +865,8 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId') ->inject('user') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $teamId, string $membershipId, array $roles, Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $teamId, string $membershipId, array $roles, Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { @@ -938,7 +941,8 @@ Http::patch('/v1/teams/:teamId/memberships/:membershipId/status') ->inject('project') ->inject('geodb') ->inject('queueForEvents') - ->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Reader $geodb, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Reader $geodb, Event $queueForEvents, Authorization $auth) { $protocol = $request->getProtocol(); $membership = $dbForProject->getDocument('memberships', $membershipId); @@ -1067,7 +1071,8 @@ Http::delete('/v1/teams/:teamId/memberships/:membershipId') ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') - ->action(function (string $teamId, string $membershipId, Response $response, Database $dbForProject, Event $queueForEvents) { + ->inject('auth') + ->action(function (string $teamId, string $membershipId, Response $response, Database $dbForProject, Event $queueForEvents, Authorization $auth) { $membership = $dbForProject->getDocument('memberships', $membershipId); @@ -1131,7 +1136,8 @@ Http::get('/v1/teams/:teamId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $teamId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $teamId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $team = $dbForProject->getDocument('teams', $teamId); @@ -1149,7 +1155,7 @@ Http::get('/v1/teams/:teamId/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $resource = 'team/' . $team->getId(); $logs = $audit->getLogsByResource($resource, $limit, $offset); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 6bb9d6e555..e6524ff21c 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -21,7 +21,6 @@ use Appwrite\Utopia\Database\Validator\Queries\Users; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use MaxMind\Db\Reader; -use Utopia\Http\Http; use Utopia\Audit\Audit; use Utopia\Config\Config; use Utopia\Database\Database; @@ -38,7 +37,7 @@ use Utopia\Database\Validator\Queries; use Utopia\Database\Validator\Query\Limit; use Utopia\Database\Validator\Query\Offset; use Utopia\Database\Validator\UID; -use Utopia\Locale\Locale; +use Utopia\Http\Http; use Utopia\Http\Validator\ArrayList; use Utopia\Http\Validator\Assoc; use Utopia\Http\Validator\Boolean; @@ -46,6 +45,7 @@ use Utopia\Http\Validator\Integer; use Utopia\Http\Validator\Range; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\WhiteList; +use Utopia\Locale\Locale; /** TODO: Remove function when we move to using utopia/platform */ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $email, ?string $password, ?string $phone, string $name, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks): Document @@ -777,7 +777,8 @@ Http::get('/v1/users/:userId/logs') ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function (string $userId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { + ->inject('auth') + ->action(function (string $userId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $auth) { $user = $dbForProject->getDocument('users', $userId); @@ -795,7 +796,7 @@ Http::get('/v1/users/:userId/logs') $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $logs = $audit->getLogsByUser($user->getInternalId(), $limit, $offset); @@ -2110,7 +2111,8 @@ Http::get('/v1/users/usage') ->inject('response') ->inject('dbForProject') ->inject('register') - ->action(function (string $range, Response $response, Database $dbForProject) { + ->inject('auth') + ->action(function (string $range, Response $response, Database $dbForProject, Authorization $auth) { $periods = Config::getParam('usage', []); $stats = $usage = []; diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index d1832a5825..e2451bc61a 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -8,7 +8,6 @@ use Appwrite\Utopia\Database\Validator\Queries\Installations; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Appwrite\Vcs\Comment; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -32,6 +31,7 @@ use Utopia\Detector\Adapter\Python; use Utopia\Detector\Adapter\Ruby; use Utopia\Detector\Adapter\Swift; use Utopia\Detector\Detector; +use Utopia\Http\Http; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\Host; use Utopia\Http\Validator\Text; @@ -40,7 +40,7 @@ use Utopia\VCS\Exception\RepositoryNotFound; use function Swoole\Coroutine\batch; -$createGitDeployments = function (GitHub $github, string $providerInstallationId, array $repositories, string $providerBranch, string $providerBranchUrl, string $providerRepositoryName, string $providerRepositoryUrl, string $providerRepositoryOwner, string $providerCommitHash, string $providerCommitAuthor, string $providerCommitAuthorUrl, string $providerCommitMessage, string $providerCommitUrl, string $providerPullRequestId, bool $external, Database $dbForConsole, Build $queueForBuilds, callable $getProjectDB, Request $request) { +$createGitDeployments = function (GitHub $github, string $providerInstallationId, array $repositories, string $providerBranch, string $providerBranchUrl, string $providerRepositoryName, string $providerRepositoryUrl, string $providerRepositoryOwner, string $providerCommitHash, string $providerCommitAuthor, string $providerCommitAuthorUrl, string $providerCommitMessage, string $providerCommitUrl, string $providerPullRequestId, bool $external, Database $dbForConsole, Build $queueForBuilds, callable $getProjectDB, Request $request, Authorization $auth) { foreach ($repositories as $resource) { $resourceType = $resource->getAttribute('resourceType'); @@ -821,8 +821,9 @@ Http::post('/v1/vcs/github/events') ->inject('dbForConsole') ->inject('getProjectDB') ->inject('queueForBuilds') + ->inject('auth') ->action( - function (GitHub $github, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Build $queueForBuilds) use ($createGitDeployments) { + function (GitHub $github, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Build $queueForBuilds, Authorization $auth) use ($createGitDeployments) { $payload = $request->getRawPayload(); $signatureRemote = $request->getHeader('x-hub-signature-256', ''); $signatureLocal = Http::getEnv('_APP_VCS_GITHUB_WEBHOOK_SECRET', ''); @@ -863,7 +864,7 @@ Http::post('/v1/vcs/github/events') // create new deployment only on push and not when branch is created if (!$providerBranchCreated) { - $createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthor, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, '', false, $dbForConsole, $queueForBuilds, $getProjectDB, $request); + $createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthor, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, '', false, $dbForConsole, $queueForBuilds, $getProjectDB, $request, $auth); } } elseif ($event == $github::EVENT_INSTALLATION) { if ($parsedPayload["action"] == "deleted") { @@ -919,7 +920,7 @@ Http::post('/v1/vcs/github/events') Query::orderDesc('$createdAt') ])); - $createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthor, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, $providerPullRequestId, $external, $dbForConsole, $queueForBuilds, $getProjectDB, $request); + $createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthor, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, $providerPullRequestId, $external, $dbForConsole, $queueForBuilds, $getProjectDB, $request, $auth); } elseif ($parsedPayload["action"] == "closed") { // Allowed external contributions cleanup @@ -1092,7 +1093,8 @@ Http::patch('/v1/vcs/github/installations/:installationId/repositories/:reposito ->inject('dbForConsole') ->inject('getProjectDB') ->inject('queueForBuilds') - ->action(function (string $installationId, string $repositoryId, string $providerPullRequestId, GitHub $github, Request $request, Response $response, Document $project, Database $dbForConsole, callable $getProjectDB, Build $queueForBuilds) use ($createGitDeployments) { + ->inject('auth') + ->action(function (string $installationId, string $repositoryId, string $providerPullRequestId, GitHub $github, Request $request, Response $response, Document $project, Database $dbForConsole, callable $getProjectDB, Build $queueForBuilds, Authorization $auth) use ($createGitDeployments) { $installation = $dbForConsole->getDocument('installations', $installationId); if ($installation->isEmpty()) { @@ -1140,7 +1142,7 @@ Http::patch('/v1/vcs/github/installations/:installationId/repositories/:reposito $providerBranch = \explode(':', $pullRequestResponse['head']['label'])[1] ?? ''; $providerCommitHash = $pullRequestResponse['head']['sha'] ?? ''; - $createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerCommitHash, $providerPullRequestId, true, $dbForConsole, $queueForBuilds, $getProjectDB, $request); + $createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerCommitHash, $providerPullRequestId, true, $dbForConsole, $queueForBuilds, $getProjectDB, $request, $auth); $response->noContent(); }); diff --git a/app/controllers/general.php b/app/controllers/general.php index 606cfac9db..138e8f6ee7 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -26,7 +26,6 @@ use Appwrite\Utopia\View; use Executor\Executor; use MaxMind\Db\Reader; use Swoole\Http\Request as SwooleRequest; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -35,18 +34,19 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Domains\Domain; +use Utopia\Http\Http; +use Utopia\Http\Validator\Hostname; +use Utopia\Http\Validator\Text; use Utopia\Locale\Locale; use Utopia\Logger\Log; use Utopia\Logger\Log\User; use Utopia\Logger\Logger; -use Utopia\Http\Validator\Hostname; -use Utopia\Http\Validator\Text; Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); -function router(App $utopia, Database $dbForConsole, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) +function router(Http $utopia, Database $dbForConsole, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Reader $geodb, Authorization $auth) { $utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml'); @@ -382,7 +382,8 @@ Http::init() ->inject('queueForUsage') ->inject('queueForEvents') ->inject('queueForCertificates') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, Usage $queueForUsage, Event $queueForEvents, Certificate $queueForCertificates) { + ->inject('auth') + ->action(function (Http $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, Usage $queueForUsage, Event $queueForEvents, Certificate $queueForCertificates, Authorization $auth) { /* * Appwrite Router */ @@ -390,7 +391,7 @@ Http::init() $mainDomain = Http::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { + if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb, $auth)) { return; } } @@ -627,7 +628,8 @@ Http::options() ->inject('queueForEvents') ->inject('queueForUsage') ->inject('geodb') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { + ->inject('auth') + ->action(function (Http $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Reader $geodb, Authorization $auth) { /* * Appwrite Router */ @@ -635,7 +637,7 @@ Http::options() $mainDomain = Http::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { + if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb, $auth)) { return; } } @@ -660,7 +662,8 @@ Http::error() ->inject('project') ->inject('logger') ->inject('log') - ->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log) { + ->inject('auth') + ->action(function (Throwable $error, Http $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Authorization $auth) { $version = Http::getEnv('_APP_VERSION', 'UNKNOWN'); $route = $utopia->getRoute(); @@ -734,7 +737,7 @@ Http::error() } /** Handle Utopia Errors */ - if ($error instanceof Utopia\Exception) { + if ($error instanceof Utopia\Http\Exception) { $error = new AppwriteException(AppwriteException::GENERAL_UNKNOWN, $message, $code, $error); switch ($code) { case 400: diff --git a/app/controllers/mock.php b/app/controllers/mock.php index 544c2a7dc8..1b7565d33d 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -5,16 +5,16 @@ global $utopia, $request, $response; use Appwrite\Extend\Exception; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; -use Utopia\Http\Http; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\UID; -use Utopia\Http\Validator\WhiteList; +use Utopia\Http\Http; use Utopia\Http\Validator\Host; use Utopia\Http\Validator\Text; +use Utopia\Http\Validator\WhiteList; use Utopia\VCS\Adapter\Git\GitHub; Http::get('/v1/mock/tests/general/oauth2') @@ -218,7 +218,7 @@ Http::shutdown() ->inject('utopia') ->inject('response') ->inject('request') - ->action(function (App $utopia, Response $response, Request $request) { + ->action(function (Http $utopia, Response $response, Request $request) { $result = []; $route = $utopia->getRoute(); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index e86215158b..fff4a7114c 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -16,7 +16,6 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; -use Utopia\Http\Http; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; use Utopia\Config\Config; @@ -25,7 +24,11 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Authorization\Input; +use Utopia\Http\Http; use Utopia\Http\Validator\WhiteList; +use Utopia\Pools\Group; +use Utopia\Pools\Pool; $parseLabel = function (string $label, array $responsePayload, array $requestParams, Document $user) { preg_match_all('/{(.*?)}/', $label, $matches); @@ -328,7 +331,7 @@ Http::init() foreach ($abuseKeyLabel as $abuseKey) { $start = $request->getContentRangeStart(); $end = $request->getContentRangeEnd(); - $timeLimit = new TimeLimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject); + $timeLimit = new TimeLimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject, $auth); $timeLimit ->setParam('{projectId}', $project->getId()) ->setParam('{userId}', $user->getId()) @@ -433,8 +436,7 @@ Http::init() } $fileSecurity = $bucket->getAttribute('fileSecurity', false); - $validator = new Authorization(Database::PERMISSION_READ); - $valid = $validator->isValid($bucket->getRead()); + $valid = $auth->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead())); if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } @@ -702,8 +704,6 @@ Http::shutdown() } } - - if ($project->getId() !== 'console') { if ($mode !== APP_MODE_ADMIN) { $fileSize = 0; @@ -747,3 +747,16 @@ Http::init() throw new Exception(Exception::GENERAL_USAGE_DISABLED); } }); + +Http::shutdown() + ->inject('pools') + ->action(function (Group $pools) { + $pools->reclaim(); + }); + + +Http::error() + ->inject('pools') + ->action(function (Group $pools) { + $pools->reclaim(); + }); diff --git a/app/controllers/shared/api/auth.php b/app/controllers/shared/api/auth.php index a8a0ac9e84..956847a774 100644 --- a/app/controllers/shared/api/auth.php +++ b/app/controllers/shared/api/auth.php @@ -4,10 +4,10 @@ use Appwrite\Auth\Auth; use Appwrite\Extend\Exception; use Appwrite\Utopia\Request; use MaxMind\Db\Reader; -use Utopia\Http\Http; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Http; Http::init() ->groups(['mfaProtected']) diff --git a/app/controllers/web/home.php b/app/controllers/web/home.php index 1d894b95bb..3577061d69 100644 --- a/app/controllers/web/home.php +++ b/app/controllers/web/home.php @@ -1,8 +1,8 @@ desc('Get Version') diff --git a/app/http.php b/app/http.php index 54c6374274..cfd09ce76f 100644 --- a/app/http.php +++ b/app/http.php @@ -4,13 +4,8 @@ require_once __DIR__ . '/../vendor/autoload.php'; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; -use Swoole\Constant; -use Swoole\Http\Request as SwooleRequest; -use Swoole\Http\Response as SwooleResponse; -use Swoole\Http\Server; use Swoole\Process; use Utopia\Abuse\Adapters\TimeLimit; -use Utopia\Http\Http; use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Config\Config; @@ -20,315 +15,198 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; -use Utopia\Logger\Log; -use Utopia\Logger\Log\User; +use Utopia\Http\Adapter\Swoole\Request as SwooleRequest; +use Utopia\Http\Adapter\Swoole\Response as SwooleResponse; +use Utopia\Http\Adapter\Swoole\Server; +use Utopia\Http\Http; use Utopia\Pools\Group; -use Utopia\Swoole\Files; - -$http = new Server( - host: "0.0.0.0", - port: Http::getEnv('PORT', 80), - mode: SWOOLE_PROCESS, -); $payloadSize = 6 * (1024 * 1024); // 6MB $workerNumber = swoole_cpu_num() * intval(Http::getEnv('_APP_WORKER_PER_CORE', 6)); -$http - ->set([ - 'worker_num' => $workerNumber, - 'open_http2_protocol' => true, - 'http_compression' => true, - 'http_compression_level' => 6, - 'package_max_length' => $payloadSize, - 'buffer_output_size' => $payloadSize, - ]); - -$http->on(Constant::EVENT_WORKER_START, function ($server, $workerId) { - Console::success('Worker ' . ++$workerId . ' started successfully'); -}); - -$http->on(Constant::EVENT_BEFORE_RELOAD, function ($server, $workerId) { - Console::success('Starting reload...'); -}); - -$http->on(Constant::EVENT_AFTER_RELOAD, function ($server, $workerId) { - Console::success('Reload completed...'); -}); - -Files::load(__DIR__ . '/../console'); - include __DIR__ . '/controllers/general.php'; -$http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $register) { - $app = new App('UTC'); +$http = new Http(new Server('0.0.0.0', Http::getEnv('PORT', 80), [ + 'open_http2_protocol' => true, + 'http_compression' => true, + 'http_compression_level' => 6, + 'package_max_length' => $payloadSize, + 'buffer_output_size' => $payloadSize, +]), 'UTC'); - go(function () use ($register, $app) { - $pools = $register->get('pools'); - /** @var Group $pools */ - Http::setResource('pools', fn () => $pools); +$http->setRequestClass(Request::class); +$http->setResponseClass(Response::class); - // wait for database to be ready - $attempts = 0; - $max = 10; - $sleep = 1; +$http->loadFiles(__DIR__ . '/../console'); - do { - try { - $attempts++; - $dbForConsole = $app->getResource('dbForConsole'); - $dbForConsole->ping(); - /** @var Utopia\Database\Database $dbForConsole */ - break; // leave the do-while if successful - } catch (\Throwable $e) { - Console::warning("Database not ready. Retrying connection ({$attempts})..."); - if ($attempts >= $max) { - throw new \Exception('Failed to connect to database: ' . $e->getMessage()); - } - sleep($sleep); - } - } while ($attempts < $max); +go(function () use ($register, $http, $payloadSize) { + $pools = $register->get('pools'); + /** @var Group $pools */ + Http::setResource('pools', fn () => $pools); + $auth = new Authorization(); - Console::success('[Setup] - Server database init started...'); + // wait for database to be ready + $attempts = 0; + $max = 10; + $sleep = 1; + do { try { - Console::success('[Setup] - Creating database: appwrite...'); - $dbForConsole->create(); + $attempts++; + $dbForConsole = $http->getResource('dbForConsole'); + $dbForConsole->ping(); + /** @var Utopia\Database\Database $dbForConsole */ + break; // leave the do-while if successful } catch (\Throwable $e) { - Console::success('[Setup] - Skip: metadata table already exists'); + Console::warning("Database not ready. Retrying connection ({$attempts})..."); + if ($attempts >= $max) { + throw new \Exception('Failed to connect to database: ' . $e->getMessage()); + } + sleep($sleep); + } + } while ($attempts < $max); + + Console::success('[Setup] - Server database init started...'); + + try { + Console::success('[Setup] - Creating database: appwrite...'); + $dbForConsole->create(); + } catch (\Throwable $e) { + Console::success('[Setup] - Skip: metadata table already exists'); + } + + if ($dbForConsole->getCollection(Audit::COLLECTION)->isEmpty()) { + $audit = new Audit($dbForConsole, $auth); + $audit->setup(); + } + + if ($dbForConsole->getCollection(TimeLimit::COLLECTION)->isEmpty()) { + $adapter = new TimeLimit("", 0, 1, $dbForConsole, $auth); + $adapter->setup(); + } + + /** @var array $collections */ + $collections = Config::getParam('collections', []); + $consoleCollections = $collections['console']; + foreach ($consoleCollections as $key => $collection) { + if (($collection['$collection'] ?? '') !== Database::METADATA) { + continue; + } + if (!$dbForConsole->getCollection($key)->isEmpty()) { + continue; } - if ($dbForConsole->getCollection(Audit::COLLECTION)->isEmpty()) { - $audit = new Audit($dbForConsole); - $audit->setup(); + Console::success('[Setup] - Creating collection: ' . $collection['$id'] . '...'); + + $attributes = []; + $indexes = []; + + foreach ($collection['attributes'] as $attribute) { + $attributes[] = new Document([ + '$id' => ID::custom($attribute['$id']), + 'type' => $attribute['type'], + 'size' => $attribute['size'], + 'required' => $attribute['required'], + 'signed' => $attribute['signed'], + 'array' => $attribute['array'], + 'filters' => $attribute['filters'], + 'default' => $attribute['default'] ?? null, + 'format' => $attribute['format'] ?? '' + ]); } - if ($dbForConsole->getCollection(TimeLimit::COLLECTION)->isEmpty()) { - $adapter = new TimeLimit("", 0, 1, $dbForConsole); - $adapter->setup(); + foreach ($collection['indexes'] as $index) { + $indexes[] = new Document([ + '$id' => ID::custom($index['$id']), + 'type' => $index['type'], + 'attributes' => $index['attributes'], + 'lengths' => $index['lengths'], + 'orders' => $index['orders'], + ]); } - /** @var array $collections */ - $collections = Config::getParam('collections', []); - $consoleCollections = $collections['console']; - foreach ($consoleCollections as $key => $collection) { - if (($collection['$collection'] ?? '') !== Database::METADATA) { - continue; - } - if (!$dbForConsole->getCollection($key)->isEmpty()) { - continue; - } + $dbForConsole->createCollection($key, $attributes, $indexes); + } - Console::success('[Setup] - Creating collection: ' . $collection['$id'] . '...'); + if ($dbForConsole->getDocument('buckets', 'default')->isEmpty() && !$dbForConsole->exists($dbForConsole->getDatabase(), 'bucket_1')) { + Console::success('[Setup] - Creating default bucket...'); + $dbForConsole->createDocument('buckets', new Document([ + '$id' => ID::custom('default'), + '$collection' => ID::custom('buckets'), + 'name' => 'Default', + 'maximumFileSize' => (int) Http::getEnv('_APP_STORAGE_LIMIT', 0), // 10MB + 'allowedFileExtensions' => [], + 'enabled' => true, + 'compression' => 'gzip', + 'encryption' => true, + 'antivirus' => true, + 'fileSecurity' => true, + '$permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'search' => 'buckets Default', + ])); - $attributes = []; - $indexes = []; + $bucket = $dbForConsole->getDocument('buckets', 'default'); - foreach ($collection['attributes'] as $attribute) { - $attributes[] = new Document([ - '$id' => ID::custom($attribute['$id']), - 'type' => $attribute['type'], - 'size' => $attribute['size'], - 'required' => $attribute['required'], - 'signed' => $attribute['signed'], - 'array' => $attribute['array'], - 'filters' => $attribute['filters'], - 'default' => $attribute['default'] ?? null, - 'format' => $attribute['format'] ?? '' - ]); - } - - foreach ($collection['indexes'] as $index) { - $indexes[] = new Document([ - '$id' => ID::custom($index['$id']), - 'type' => $index['type'], - 'attributes' => $index['attributes'], - 'lengths' => $index['lengths'], - 'orders' => $index['orders'], - ]); - } - - $dbForConsole->createCollection($key, $attributes, $indexes); + Console::success('[Setup] - Creating files collection for default bucket...'); + $files = $collections['buckets']['files'] ?? []; + if (empty($files)) { + throw new Exception('Files collection is not configured.'); } - if ($dbForConsole->getDocument('buckets', 'default')->isEmpty() && !$dbForConsole->exists($dbForConsole->getDatabase(), 'bucket_1')) { - Console::success('[Setup] - Creating default bucket...'); - $dbForConsole->createDocument('buckets', new Document([ - '$id' => ID::custom('default'), - '$collection' => ID::custom('buckets'), - 'name' => 'Default', - 'maximumFileSize' => (int) Http::getEnv('_APP_STORAGE_LIMIT', 0), // 10MB - 'allowedFileExtensions' => [], - 'enabled' => true, - 'compression' => 'gzip', - 'encryption' => true, - 'antivirus' => true, - 'fileSecurity' => true, - '$permissions' => [ - Permission::create(Role::any()), - Permission::read(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()), - ], - 'search' => 'buckets Default', - ])); + $attributes = []; + $indexes = []; - $bucket = $dbForConsole->getDocument('buckets', 'default'); - - Console::success('[Setup] - Creating files collection for default bucket...'); - $files = $collections['buckets']['files'] ?? []; - if (empty($files)) { - throw new Exception('Files collection is not configured.'); - } - - $attributes = []; - $indexes = []; - - foreach ($files['attributes'] as $attribute) { - $attributes[] = new Document([ - '$id' => ID::custom($attribute['$id']), - 'type' => $attribute['type'], - 'size' => $attribute['size'], - 'required' => $attribute['required'], - 'signed' => $attribute['signed'], - 'array' => $attribute['array'], - 'filters' => $attribute['filters'], - 'default' => $attribute['default'] ?? null, - 'format' => $attribute['format'] ?? '' - ]); - } - - foreach ($files['indexes'] as $index) { - $indexes[] = new Document([ - '$id' => ID::custom($index['$id']), - 'type' => $index['type'], - 'attributes' => $index['attributes'], - 'lengths' => $index['lengths'], - 'orders' => $index['orders'], - ]); - } - - $dbForConsole->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes); + foreach ($files['attributes'] as $attribute) { + $attributes[] = new Document([ + '$id' => ID::custom($attribute['$id']), + 'type' => $attribute['type'], + 'size' => $attribute['size'], + 'required' => $attribute['required'], + 'signed' => $attribute['signed'], + 'array' => $attribute['array'], + 'filters' => $attribute['filters'], + 'default' => $attribute['default'] ?? null, + 'format' => $attribute['format'] ?? '' + ]); } - $pools->reclaim(); + foreach ($files['indexes'] as $index) { + $indexes[] = new Document([ + '$id' => ID::custom($index['$id']), + 'type' => $index['type'], + 'attributes' => $index['attributes'], + 'lengths' => $index['lengths'], + 'orders' => $index['orders'], + ]); + } - Console::success('[Setup] - Server database init completed...'); - }); + $dbForConsole->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes); + } + + $pools->reclaim(); + + Console::success('[Setup] - Server database init completed...'); Console::success('Server started successfully (max payload is ' . number_format($payloadSize) . ' bytes)'); - Console::info("Master pid {$http->master_pid}, manager pid {$http->manager_pid}"); // listen ctrl + c Process::signal(2, function () use ($http) { Console::log('Stop by Ctrl+C'); $http->shutdown(); }); + + Http::init() + ->inject('auth') + ->action(function (Authorization $auth) { + $auth->cleanRoles(); + $auth->addRole(Role::any()->toString()); + }); + + $http->start(); }); -$http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) use ($register) { - Http::setResource('swooleRequest', fn () => $swooleRequest); - Http::setResource('swooleResponse', fn () => $swooleResponse); - - $request = new Request($swooleRequest); - $response = new Response($swooleResponse); - - if (Files::isFileLoaded($request->getURI())) { - $time = (60 * 60 * 24 * 365 * 2); // 45 days cache - - $response - ->setContentType(Files::getFileMimeType($request->getURI())) - ->addHeader('Cache-Control', 'public, max-age=' . $time) - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $time) . ' GMT') // 45 days cache - ->send(Files::getFileContents($request->getURI())); - - return; - } - - $app = new App('UTC'); - - $pools = $register->get('pools'); - Http::setResource('pools', fn () => $pools); - - try { - $auth->cleanRoles(); - $auth->addRole(Role::any()->toString()); - - $app->run($request, $response); - } catch (\Throwable $th) { - $version = Http::getEnv('_APP_VERSION', 'UNKNOWN'); - - $logger = $app->getResource("logger"); - if ($logger) { - try { - /** @var Utopia\Database\Document $user */ - $user = $app->getResource('user'); - } catch (\Throwable $_th) { - // All good, user is optional information for logger - } - - $route = $app->getRoute(); - - $log = $app->getResource("log"); - - if (isset($user) && !$user->isEmpty()) { - $log->setUser(new User($user->getId())); - } - - $log->setNamespace("http"); - $log->setServer(\gethostname()); - $log->setVersion($version); - $log->setType(Log::TYPE_ERROR); - $log->setMessage($th->getMessage()); - - $log->addTag('method', $route->getMethod()); - $log->addTag('url', $route->getPath()); - $log->addTag('verboseType', get_class($th)); - $log->addTag('code', $th->getCode()); - // $log->addTag('projectId', $project->getId()); // TODO: Figure out how to get ProjectID, if it becomes relevant - $log->addTag('hostname', $request->getHostname()); - $log->addTag('locale', (string)$request->getParam('locale', $request->getHeader('x-appwrite-locale', ''))); - - $log->addExtra('file', $th->getFile()); - $log->addExtra('line', $th->getLine()); - $log->addExtra('trace', $th->getTraceAsString()); - $log->addExtra('detailedTrace', $th->getTrace()); - $log->addExtra('roles', $auth->getRoles()); - - $action = $route->getLabel("sdk.namespace", "UNKNOWN_NAMESPACE") . '.' . $route->getLabel("sdk.method", "UNKNOWN_METHOD"); - $log->setAction($action); - - $isProduction = Http::getEnv('_APP_ENV', 'development') === 'production'; - $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); - - $responseCode = $logger->addLog($log); - Console::info('Log pushed with status code: ' . $responseCode); - } - - Console::error('[Error] Type: ' . get_class($th)); - Console::error('[Error] Message: ' . $th->getMessage()); - Console::error('[Error] File: ' . $th->getFile()); - Console::error('[Error] Line: ' . $th->getLine()); - - $swooleResponse->setStatusCode(500); - - $output = ((Http::isDevelopment())) ? [ - 'message' => 'Error: ' . $th->getMessage(), - 'code' => 500, - 'file' => $th->getFile(), - 'line' => $th->getLine(), - 'trace' => $th->getTrace(), - 'version' => $version, - ] : [ - 'message' => 'Error: Server Error', - 'code' => 500, - 'version' => $version, - ]; - - $swooleResponse->end(\json_encode($output)); - } finally { - $pools->reclaim(); - } -}); - -$http->start(); diff --git a/app/init.php b/app/init.php index ca6626223e..6773d11236 100644 --- a/app/init.php +++ b/app/init.php @@ -43,7 +43,6 @@ use Appwrite\URL\URL as AppwriteURL; use MaxMind\Db\Reader; use PHPMailer\PHPMailer\PHPMailer; use Swoole\Database\PDOProxy; -use Utopia\Http\Http; use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; @@ -62,8 +61,14 @@ use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Structure; use Utopia\Domains\Validator\PublicDomain; use Utopia\DSN\DSN; +use Utopia\Http\Http; use Utopia\Http\Request; use Utopia\Http\Response; +use Utopia\Http\Validator\Hostname; +use Utopia\Http\Validator\IP; +use Utopia\Http\Validator\Range; +use Utopia\Http\Validator\URL; +use Utopia\Http\Validator\WhiteList; use Utopia\Locale\Locale; use Utopia\Logger\Log; use Utopia\Logger\Logger; @@ -80,11 +85,6 @@ use Utopia\Storage\Device\Local; use Utopia\Storage\Device\S3; use Utopia\Storage\Device\Wasabi; use Utopia\Storage\Storage; -use Utopia\Http\Validator\Hostname; -use Utopia\Http\Validator\IP; -use Utopia\Http\Validator\Range; -use Utopia\Http\Validator\URL; -use Utopia\Http\Validator\WhiteList; use Utopia\VCS\Adapter\Git\GitHub as VcsGitHub; const APP_NAME = 'Appwrite'; @@ -1307,7 +1307,7 @@ Http::setResource('console', function () { ]); }, []); -Http::setResource('dbForProject', function (Group $pools, Database $dbForConsole, Cache $cache, Document $project) { +Http::setResource('dbForProject', function (Group $pools, Database $dbForConsole, Cache $cache, Document $project, Authorization $auth) { if ($project->isEmpty() || $project->getId() === 'console') { return $dbForConsole; } @@ -1318,6 +1318,7 @@ Http::setResource('dbForProject', function (Group $pools, Database $dbForConsole ->getResource(); $database = new Database($dbAdapter, $cache); + $database->setAuthorization($auth); $database ->setNamespace('_' . $project->getInternalId()) @@ -1326,9 +1327,9 @@ Http::setResource('dbForProject', function (Group $pools, Database $dbForConsole ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS); return $database; -}, ['pools', 'dbForConsole', 'cache', 'project']); +}, ['pools', 'dbForConsole', 'cache', 'project', 'auth']); -Http::setResource('dbForConsole', function (Group $pools, Cache $cache) { +Http::setResource('dbForConsole', function (Group $pools, Cache $cache, Authorization $auth) { $dbAdapter = $pools ->get('console') ->pop() @@ -1336,6 +1337,7 @@ Http::setResource('dbForConsole', function (Group $pools, Cache $cache) { ; $database = new Database($dbAdapter, $cache); + $database->setAuthorization($auth); $database ->setNamespace('_console') @@ -1344,12 +1346,12 @@ Http::setResource('dbForConsole', function (Group $pools, Cache $cache) { ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS); return $database; -}, ['pools', 'cache']); +}, ['pools', 'cache', 'auth']); -Http::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $cache) { +Http::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $cache, Authorization $auth) { $databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools - $getProjectDB = function (Document $project) use ($pools, $dbForConsole, $cache, &$databases) { + $getProjectDB = function (Document $project) use ($pools, $dbForConsole, $cache, &$databases, $auth) { if ($project->isEmpty() || $project->getId() === 'console') { return $dbForConsole; } @@ -1374,6 +1376,7 @@ Http::setResource('getProjectDB', function (Group $pools, Database $dbForConsole ->getResource(); $database = new Database($dbAdapter, $cache); + $database->setAuthorization($auth); $databases[$databaseName] = $database; @@ -1387,7 +1390,7 @@ Http::setResource('getProjectDB', function (Group $pools, Database $dbForConsole }; return $getProjectDB; -}, ['pools', 'dbForConsole', 'cache']); +}, ['pools', 'dbForConsole', 'cache', 'auth']); Http::setResource('cache', function (Group $pools) { $list = Config::getParam('pools-cache', []); @@ -1661,4 +1664,8 @@ Http::setResource('requestTimestamp', function ($request) { return $requestTimestamp; }, ['request']); -Http::setResource('auth', fn () => new Authorization()); \ No newline at end of file +Http::setResource('auth', fn () => new Authorization()); + +Http::setResource('pools', function ($register) { + return $register->get('pools'); +}, ['pools']); diff --git a/app/realtime.php b/app/realtime.php index e38caf488a..d8234a691c 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -13,7 +13,6 @@ use Swoole\Table; use Swoole\Timer; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; -use Utopia\Http\Http; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -26,6 +25,7 @@ use Utopia\Database\Helpers\Role; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Http\Adapter\FPM\Server as FPMServer; +use Utopia\Http\Http; use Utopia\Logger\Log; use Utopia\WebSocket\Adapter; use Utopia\WebSocket\Server; @@ -37,7 +37,7 @@ require_once __DIR__ . '/init.php'; Runtime::enableCoroutine(SWOOLE_HOOK_ALL); -function getConsoleDB(): Database +function getConsoleDB(Authorization $auth): Database { global $register; @@ -51,6 +51,7 @@ function getConsoleDB(): Database ; $database = new Database($dbAdapter, getCache()); + $database->setAuthorization($auth); $database ->setNamespace('_console') @@ -60,7 +61,7 @@ function getConsoleDB(): Database return $database; } -function getProjectDB(Document $project): Database +function getProjectDB(Document $project, Authorization $auth): Database { global $register; @@ -68,7 +69,7 @@ function getProjectDB(Document $project): Database $pools = $register->get('pools'); if ($project->isEmpty() || $project->getId() === 'console') { - return getConsoleDB(); + return getConsoleDB($auth); } $dbAdapter = $pools @@ -78,6 +79,7 @@ function getProjectDB(Document $project): Database ; $database = new Database($dbAdapter, getCache()); + $database->setAuthorization($auth); $database ->setNamespace('_' . $project->getInternalId()) @@ -170,15 +172,17 @@ $logError = function (Throwable $error, string $action) use ($register) { $server->error($logError); $server->onStart(function () use ($stats, $register, $containerId, &$statsDocument, $logError) { + $auth = new Authorization(); + sleep(5); // wait for the initial database schema to be ready Console::success('Server started successfully'); /** * Create document for this worker to share stats across Containers. */ - go(function () use ($register, $containerId, &$statsDocument) { + go(function () use ($register, $containerId, &$statsDocument, $auth) { $attempts = 0; - $database = getConsoleDB(); + $database = getConsoleDB($auth); do { try { @@ -206,7 +210,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume /** * Save current connections to the Database every 5 seconds. */ - Timer::tick(5000, function () use ($register, $stats, &$statsDocument, $logError) { + Timer::tick(5000, function () use ($register, $stats, &$statsDocument, $logError, $auth) { $payload = []; foreach ($stats as $projectId => $value) { $payload[$projectId] = $stats->get($projectId, 'connectionsTotal'); @@ -216,7 +220,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume } try { - $database = getConsoleDB(); + $database = getConsoleDB($auth); $statsDocument ->setAttribute('timestamp', DateTime::now()) @@ -238,16 +242,17 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, $attempts = 0; $start = time(); - Timer::tick(5000, function () use ($server, $register, $realtime, $stats, $logError) { + $auth = new Authorization(); + + Timer::tick(5000, function () use ($server, $register, $realtime, $stats, $logError, $auth) { /** * Sending current connections to project channels on the console project every 5 seconds. */ if ($realtime->hasSubscriber('console', Role::users()->toString(), 'project')) { - $database = getConsoleDB(); + $database = getConsoleDB($auth); $payload = []; - $auth = new Authorization(); $list = $auth->skip(fn () => $database->find('realtime', [ Query::greaterThan('timestamp', DateTime::addSeconds(new \DateTime(), -15)), ])); @@ -334,7 +339,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, Console::error('Pub/sub failed (worker: ' . $workerId . ')'); } - $redis->subscribe(['realtime'], function (Redis $redis, string $channel, string $payload) use ($server, $workerId, $stats, $register, $realtime) { + $redis->subscribe(['realtime'], function (Redis $redis, string $channel, string $payload) use ($server, $workerId, $stats, $register, $realtime, $auth) { $event = json_decode($payload, true); if ($event['permissionsChanged'] && isset($event['userId'])) { @@ -343,10 +348,10 @@ $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(); + $consoleDatabase = getConsoleDB($auth); $auth = new Authorization(); $project = $auth->skip(fn () => $consoleDatabase->getDocument('projects', $projectId)); - $database = getProjectDB($project); + $database = getProjectDB($project, $auth); $user = $database->getDocument('users', $userId); @@ -394,7 +399,9 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, }); $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $register, $stats, &$realtime, $logError) { - $app = new Http(new FPMServer(), 'UTC'); + $auth = new Authorization(); + + $http = new Http(new FPMServer(), 'UTC'); $request = new Request($request); $response = new Response(new SwooleResponse()); @@ -406,7 +413,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, try { /** @var Document $project */ - $project = $app->getResource('project'); + $project = $http->getResource('project'); /* * Project Check @@ -415,21 +422,22 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, throw new Exception(Exception::REALTIME_POLICY_VIOLATION, 'Missing or unknown project ID'); } - $dbForProject = getProjectDB($project); - $console = $app->getResource('console'); /** @var Document $console */ - $user = $app->getResource('user'); /** @var Document $user */ + $dbForProject = getProjectDB($project, $auth); + $console = $http->getResource('console'); /** @var Document $console */ + $user = $http->getResource('user'); /** @var Document $user */ + $auth = new Authorization(); /* * Abuse Check * * Abuse limits are connecting 128 times per minute and ip address. */ - $timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, $dbForProject); + $timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, $dbForProject, $auth); $timeLimit ->setParam('{ip}', $request->getIP()) ->setParam('{url}', $request->getURI()); - $abuse = new Abuse($timeLimit); + $abuse = new Abuse($timeLimit, $auth); if (Http::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled' && $abuse->check()) { throw new Exception(Exception::REALTIME_TOO_MANY_MESSAGES, 'Too many requests'); @@ -502,15 +510,17 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, }); $server->onMessage(function (int $connection, string $message) use ($server, $register, $realtime, $containerId) { + $auth = new Authorization(); + try { $response = new Response(new SwooleResponse()); $projectId = $realtime->connections[$connection]['projectId']; - $database = getConsoleDB(); + $database = getConsoleDB($auth); if ($projectId !== 'console') { $auth = new Authorization(); $project = $auth->skip(fn () => $database->getDocument('projects', $projectId)); - $database = getProjectDB($project); + $database = getProjectDB($project, $auth); } else { $project = null; } @@ -520,13 +530,13 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re * * Abuse limits are sending 32 times per minute and connection. */ - $timeLimit = new TimeLimit('url:{url},connection:{connection}', 32, 60, $database); + $timeLimit = new TimeLimit('url:{url},connection:{connection}', 32, 60, $database, $auth); $timeLimit ->setParam('{connection}', $connection) ->setParam('{container}', $containerId); - $abuse = new Abuse($timeLimit); + $abuse = new Abuse($timeLimit, $auth); if ($abuse->check() && Http::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') { throw new Exception(Exception::REALTIME_TOO_MANY_MESSAGES, 'Too many messages.'); diff --git a/app/worker.php b/app/worker.php index e81e0f9f5f..61203c2d5a 100644 --- a/app/worker.php +++ b/app/worker.php @@ -17,7 +17,6 @@ use Appwrite\Event\Usage; use Appwrite\Event\UsageDump; use Appwrite\Platform\Appwrite; use Swoole\Runtime; -use Utopia\Http\Http; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -26,6 +25,7 @@ use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Http; use Utopia\Logger\Log; use Utopia\Logger\Logger; use Utopia\Platform\Service; @@ -38,12 +38,11 @@ use Utopia\Storage\Device\Local; global $register; -$auth->disable(); Runtime::enableCoroutine(SWOOLE_HOOK_ALL); Server::setResource('register', fn () => $register); -Server::setResource('dbForConsole', function (Cache $cache, Registry $register) { +Server::setResource('dbForConsole', function (Cache $cache, Registry $register, Authorization $auth) { $pools = $register->get('pools'); $database = $pools ->get('console') @@ -51,10 +50,11 @@ Server::setResource('dbForConsole', function (Cache $cache, Registry $register) ->getResource(); $adapter = new Database($database, $cache); + $adapter->setAuthorization($auth); $adapter->setNamespace('_console'); return $adapter; -}, ['cache', 'register']); +}, ['cache', 'register', 'auth']); Server::setResource('project', function (Message $message, Database $dbForConsole) { $payload = $message->getPayload() ?? []; @@ -67,7 +67,7 @@ Server::setResource('project', function (Message $message, Database $dbForConsol return $dbForConsole->getDocument('projects', $project->getId()); }, ['message', 'dbForConsole']); -Server::setResource('dbForProject', function (Cache $cache, Registry $register, Message $message, Document $project, Database $dbForConsole) { +Server::setResource('dbForProject', function (Cache $cache, Registry $register, Message $message, Document $project, Database $dbForConsole, Authorization $auth) { if ($project->isEmpty() || $project->getId() === 'console') { return $dbForConsole; } @@ -79,14 +79,15 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register, ->getResource(); $adapter = new Database($database, $cache); + $adapter->setAuthorization($auth); $adapter->setNamespace('_' . $project->getInternalId()); return $adapter; -}, ['cache', 'register', 'message', 'project', 'dbForConsole']); +}, ['cache', 'register', 'message', 'project', 'dbForConsole', 'auth']); -Server::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $cache) { +Server::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $cache, Authorization $auth) { $databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools - return function (Document $project) use ($pools, $dbForConsole, $cache, &$databases): Database { + return function (Document $project) use ($pools, $dbForConsole, $cache, &$databases, $auth): Database { if ($project->isEmpty() || $project->getId() === 'console') { return $dbForConsole; } @@ -105,6 +106,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso ->getResource(); $database = new Database($dbAdapter, $cache); + $database->setAuthorization($auth); $databases[$databaseName] = $database; @@ -112,7 +114,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso return $database; }; -}, ['pools', 'dbForConsole', 'cache']); +}, ['pools', 'dbForConsole', 'cache', 'auth']); Server::setResource('abuseRetention', function () { return DateTime::addSeconds(new \DateTime(), -1 * Http::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', 86400)); @@ -228,7 +230,7 @@ Server::setResource('deviceForLocalFiles', function (Document $project) { return new Local(APP_STORAGE_UPLOADS . '/app-' . $project->getId()); }, ['project']); -Server::setResource('authorization', fn () => new Authorization()); +Server::setResource('auth', fn () => new Authorization()); $pools = $register->get('pools'); $platform = new Appwrite(); @@ -272,6 +274,13 @@ try { $worker = $platform->getWorker(); +$worker + ->init() + ->inject('auth') + ->action(function (Authorization $auth) { + $auth->disable(); + }); + $worker ->shutdown() ->inject('pools') diff --git a/composer.json b/composer.json index acb933c7e4..9440299990 100644 --- a/composer.json +++ b/composer.json @@ -45,16 +45,16 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.37.*", + "utopia-php/abuse": "dev-feat-framework-v2 as 0.37.99", "utopia-php/analytics": "dev-feat-framework-v2 as 0.10.99", - "utopia-php/audit": "0.39.*", + "utopia-php/audit": "dev-feat-framework-v2 as 0.39.99", "utopia-php/cache": "0.9.*", "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.*", + "utopia-php/domains": "dev-feat-framework-v2 as 0.5.99", "utopia-php/dsn": "0.2.*", - "utopia-php/framework": "0.34.*", + "utopia-php/framework": "dev-feat-framework-v2 as 0.34.99", "utopia-php/image": "0.6.*", "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.3.*", @@ -66,7 +66,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/storage": "dev-feat-framework-v2-v2 as 0.18.99", "utopia-php/vcs": "0.6.*", "utopia-php/websocket": "0.1.*", "matomo/device-detector": "6.1.*", diff --git a/composer.lock b/composer.lock index a90d6b2d3e..95d7ddd8fa 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": "98a533604587b5d0f5cc3c52ae177aeb", + "content-hash": "750df68fe066fde9554f4d1ba4a9afb5", "packages": [ { "name": "adhocore/jwt", @@ -482,16 +482,16 @@ }, { "name": "jean85/pretty-package-versions", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af" + "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/ae547e455a3d8babd07b96966b17d7fd21d9c6af", - "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/f9fdd29ad8e6d024f52678b570e5593759b550b4", + "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4", "shasum": "" }, "require": { @@ -499,9 +499,9 @@ "php": "^7.1|^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.17", + "friendsofphp/php-cs-fixer": "^3.2", "jean85/composer-provided-replaced-stub-package": "^1.0", - "phpstan/phpstan": "^0.12.66", + "phpstan/phpstan": "^1.4", "phpunit/phpunit": "^7.5|^8.5|^9.4", "vimeo/psalm": "^4.3" }, @@ -535,9 +535,9 @@ ], "support": { "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.5" + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.6" }, - "time": "2021-10-08T21:21:46+00:00" + "time": "2024-03-08T09:58:59+00:00" }, { "name": "league/csv", @@ -771,11 +771,54 @@ "version": "0.6.3", "source": { "type": "git", - "url": "https://github.com/mustangostang/spyc", + "url": "https://github.com/mustangostang/spyc.git", "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, "type": "library", - "notification-url": "https://packagist.org/downloads/" + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "support": { + "issues": "https://github.com/mustangostang/spyc/issues", + "source": "https://github.com/mustangostang/spyc/tree/0.6.3" + }, + "time": "2019-09-10T13:16:29+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -1221,23 +1264,23 @@ }, { "name": "utopia-php/abuse", - "version": "0.37.0", + "version": "dev-feat-framework-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062" + "reference": "55b34b581c957fc98f912943d94dcdc7079f191e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/2de5c12886cbd516e511e559afdd9e615d871062", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/55b34b581c957fc98f912943d94dcdc7079f191e", + "reference": "55b34b581c957fc98f912943d94dcdc7079f191e", "shasum": "" }, "require": { "ext-curl": "*", "ext-pdo": "*", "php": ">=8.0", - "utopia-php/database": "0.49.*" + "utopia-php/database": "dev-feat-framework-v2 as 0.49.99" }, "require-dev": { "laravel/pint": "1.5.*", @@ -1264,9 +1307,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.37.0" + "source": "https://github.com/utopia-php/abuse/tree/feat-framework-v2" }, - "time": "2024-03-06T21:20:27+00:00" + "time": "2024-03-08T11:27:58+00:00" }, { "name": "utopia-php/analytics", @@ -1316,21 +1359,21 @@ }, { "name": "utopia-php/audit", - "version": "0.39.0", + "version": "dev-feat-framework-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c" + "reference": "59f88d71f9d93603393aeda368a975b10b8ddb17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/f0bc15012e05cc0b9dde012ab27d25f193768a2c", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/59f88d71f9d93603393aeda368a975b10b8ddb17", + "reference": "59f88d71f9d93603393aeda368a975b10b8ddb17", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "0.49.*" + "utopia-php/database": "dev-feat-framework-v2 as 0.49.99" }, "require-dev": { "laravel/pint": "1.5.*", @@ -1357,9 +1400,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.39.0" + "source": "https://github.com/utopia-php/audit/tree/feat-framework-v2" }, - "time": "2024-03-06T21:20:37+00:00" + "time": "2024-03-08T11:29:31+00:00" }, { "name": "utopia-php/cache", @@ -1570,21 +1613,21 @@ }, { "name": "utopia-php/domains", - "version": "0.5.0", + "version": "dev-feat-framework-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/domains.git", - "reference": "bf07f60326f8389f378ddf6fcde86217e5cfe18c" + "reference": "4e7055f0aaba0c16ae60c972faefb9189fa0db1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/bf07f60326f8389f378ddf6fcde86217e5cfe18c", - "reference": "bf07f60326f8389f378ddf6fcde86217e5cfe18c", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/4e7055f0aaba0c16ae60c972faefb9189fa0db1c", + "reference": "4e7055f0aaba0c16ae60c972faefb9189fa0db1c", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/framework": "0.*.*" + "utopia-php/framework": "0.34.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -1624,9 +1667,9 @@ ], "support": { "issues": "https://github.com/utopia-php/domains/issues", - "source": "https://github.com/utopia-php/domains/tree/0.5.0" + "source": "https://github.com/utopia-php/domains/tree/feat-framework-v2" }, - "time": "2024-01-03T22:04:27+00:00" + "time": "2024-03-08T09:24:35+00:00" }, { "name": "utopia-php/dsn", @@ -1716,16 +1759,16 @@ }, { "name": "utopia-php/framework", - "version": "0.34.2", + "version": "dev-feat-framework-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "fd126c02b78cc80678c9638f7b335dfb4a841b78" + "reference": "e2e7498aa16cefcdcb474548c3d04ce720ec6430" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/fd126c02b78cc80678c9638f7b335dfb4a841b78", - "reference": "fd126c02b78cc80678c9638f7b335dfb4a841b78", + "url": "https://api.github.com/repos/utopia-php/http/zipball/e2e7498aa16cefcdcb474548c3d04ce720ec6430", + "reference": "e2e7498aa16cefcdcb474548c3d04ce720ec6430", "shasum": "" }, "require": { @@ -1758,9 +1801,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.34.2" + "source": "https://github.com/utopia-php/http/tree/feat-framework-v2" }, - "time": "2024-02-20T11:36:56+00:00" + "time": "2024-03-08T10:38:48+00:00" }, { "name": "utopia-php/image", @@ -2229,12 +2272,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "e613ccc1d4da4219b60576ddfe79dadb182bb74e" + "reference": "0e9ba1b32169d64a78909fd77891db4d64344a63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/e613ccc1d4da4219b60576ddfe79dadb182bb74e", - "reference": "e613ccc1d4da4219b60576ddfe79dadb182bb74e", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/0e9ba1b32169d64a78909fd77891db4d64344a63", + "reference": "0e9ba1b32169d64a78909fd77891db4d64344a63", "shasum": "" }, "require": { @@ -2282,7 +2325,7 @@ "issues": "https://github.com/utopia-php/queue/issues", "source": "https://github.com/utopia-php/queue/tree/feat-framework-v2-v2" }, - "time": "2024-03-07T15:43:35+00:00" + "time": "2024-03-08T09:29:41+00:00" }, { "name": "utopia-php/registry", @@ -2338,16 +2381,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.3", + "version": "dev-feat-framework-v2-v2", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "faa0279519ac14f3501e8b138e0865ad9d12bff6" + "reference": "80eafa63cb86b33ce35d48c0189bae6ebdc02734" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/faa0279519ac14f3501e8b138e0865ad9d12bff6", - "reference": "faa0279519ac14f3501e8b138e0865ad9d12bff6", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/80eafa63cb86b33ce35d48c0189bae6ebdc02734", + "reference": "80eafa63cb86b33ce35d48c0189bae6ebdc02734", "shasum": "" }, "require": { @@ -2359,7 +2402,7 @@ "ext-zlib": "*", "ext-zstd": "*", "php": ">=8.0", - "utopia-php/framework": "0.*.*", + "utopia-php/framework": "0.34.*", "utopia-php/system": "0.*.*" }, "require-dev": { @@ -2387,9 +2430,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.3" + "source": "https://github.com/utopia-php/storage/tree/feat-framework-v2-v2" }, - "time": "2023-12-31T11:45:12+00:00" + "time": "2024-03-08T09:39:46+00:00" }, { "name": "utopia-php/system", @@ -5458,18 +5501,42 @@ } ], "aliases": [ + { + "package": "utopia-php/abuse", + "version": "dev-feat-framework-v2", + "alias": "0.37.99", + "alias_normalized": "0.37.99.0" + }, { "package": "utopia-php/analytics", "version": "dev-feat-framework-v2", "alias": "0.10.99", "alias_normalized": "0.10.99.0" }, + { + "package": "utopia-php/audit", + "version": "dev-feat-framework-v2", + "alias": "0.39.99", + "alias_normalized": "0.39.99.0" + }, { "package": "utopia-php/database", "version": "dev-feat-framework-v2", "alias": "0.49.99", "alias_normalized": "0.49.99.0" }, + { + "package": "utopia-php/domains", + "version": "dev-feat-framework-v2", + "alias": "0.5.99", + "alias_normalized": "0.5.99.0" + }, + { + "package": "utopia-php/framework", + "version": "dev-feat-framework-v2", + "alias": "0.34.99", + "alias_normalized": "0.34.99.0" + }, { "package": "utopia-php/orchestration", "version": "dev-feat-framework-v2", @@ -5487,15 +5554,26 @@ "version": "dev-feat-framework-v2-v2", "alias": "0.7.99", "alias_normalized": "0.7.99.0" + }, + { + "package": "utopia-php/storage", + "version": "dev-feat-framework-v2-v2", + "alias": "0.18.99", + "alias_normalized": "0.18.99.0" } ], "minimum-stability": "stable", "stability-flags": { + "utopia-php/abuse": 20, "utopia-php/analytics": 20, + "utopia-php/audit": 20, "utopia-php/database": 20, + "utopia-php/domains": 20, + "utopia-php/framework": 20, "utopia-php/orchestration": 20, "utopia-php/platform": 20, "utopia-php/queue": 20, + "utopia-php/storage": 20, "appwrite/sdk-generator": 5 }, "prefer-stable": false, diff --git a/src/Appwrite/GraphQL/Resolvers.php b/src/Appwrite/GraphQL/Resolvers.php index 31f1ce45b4..2c25f163c3 100644 --- a/src/Appwrite/GraphQL/Resolvers.php +++ b/src/Appwrite/GraphQL/Resolvers.php @@ -6,8 +6,8 @@ use Appwrite\GraphQL\Exception as GQLException; use Appwrite\Promises\Swoole; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; -use Utopia\Http\Http; use Utopia\Exception; +use Utopia\Http\Http; use Utopia\Http\Route; class Resolvers @@ -15,7 +15,7 @@ class Resolvers /** * Create a resolver for a given API {@see Route}. * - * @param App $utopia + * @param Http $utopia * @param ?Route $route * @return callable */ @@ -25,7 +25,7 @@ class Resolvers ): callable { return static fn ($type, $args, $context, $info) => new Swoole( function (callable $resolve, callable $reject) use ($utopia, $route, $args, $context, $info) { - /** @var App $utopia */ + /** @var Http $utopia */ /** @var Response $response */ /** @var Request $request */ @@ -60,7 +60,7 @@ class Resolvers /** * Create a resolver for a document in a specified database and collection with a specific method type. * - * @param App $utopia + * @param Http $utopia * @param string $databaseId * @param string $collectionId * @param string $methodType @@ -82,7 +82,7 @@ class Resolvers /** * Create a resolver for getting a document in a specified database and collection. * - * @param App $utopia + * @param Http $utopia * @param string $databaseId * @param string $collectionId * @param callable $url @@ -111,7 +111,7 @@ class Resolvers /** * Create a resolver for listing documents in a specified database and collection. * - * @param App $utopia + * @param Http $utopia * @param string $databaseId * @param string $collectionId * @param callable $url @@ -147,7 +147,7 @@ class Resolvers /** * Create a resolver for creating a document in a specified database and collection. * - * @param App $utopia + * @param Http $utopia * @param string $databaseId * @param string $collectionId * @param callable $url @@ -179,7 +179,7 @@ class Resolvers /** * Create a resolver for updating a document in a specified database and collection. * - * @param App $utopia + * @param Http $utopia * @param string $databaseId * @param string $collectionId * @param callable $url @@ -211,7 +211,7 @@ class Resolvers /** * Create a resolver for deleting a document in a specified database and collection. * - * @param App $utopia + * @param Http $utopia * @param string $databaseId * @param string $collectionId * @param callable $url @@ -238,7 +238,7 @@ class Resolvers } /** - * @param App $utopia + * @param Http $utopia * @param Request $request * @param Response $response * @param callable $resolve diff --git a/src/Appwrite/GraphQL/Schema.php b/src/Appwrite/GraphQL/Schema.php index 49544a7c93..887ea621dd 100644 --- a/src/Appwrite/GraphQL/Schema.php +++ b/src/Appwrite/GraphQL/Schema.php @@ -6,8 +6,8 @@ use Appwrite\GraphQL\Types\Mapper; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; use GraphQL\Type\Schema as GQLSchema; -use Utopia\Http\Http; use Utopia\Exception; +use Utopia\Http\Http; use Utopia\Http\Route; class Schema @@ -17,7 +17,7 @@ class Schema /** * - * @param App $utopia + * @param Http $utopia * @param callable $complexity Function to calculate complexity * @param callable $attributes Function to get attributes * @param array $urls Array of functions to get urls for specific method types @@ -80,7 +80,7 @@ class Schema * This function iterates all API routes and builds a GraphQL * schema defining types and resolvers for all response models. * - * @param App $utopia + * @param Http $utopia * @param callable $complexity * @return array * @throws Exception @@ -134,7 +134,7 @@ class Schema * Iterates all of a projects attributes and builds GraphQL * queries and mutations for the collections they make up. * - * @param App $utopia + * @param Http $utopia * @param callable $complexity * @param callable $attributes * @param array $urls diff --git a/src/Appwrite/GraphQL/Types/Mapper.php b/src/Appwrite/GraphQL/Types/Mapper.php index d81d8ea885..41c7de6e56 100644 --- a/src/Appwrite/GraphQL/Types/Mapper.php +++ b/src/Appwrite/GraphQL/Types/Mapper.php @@ -205,7 +205,7 @@ class Mapper /** * Map a {@see Route} parameter to a GraphQL Type * - * @param App $utopia + * @param Http $utopia * @param Validator|callable $validator * @param bool $required * @param array $injections diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index 475b92f2f7..e34b961a4e 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -3,11 +3,11 @@ namespace Appwrite\Messaging\Adapter; use Appwrite\Messaging\Adapter; -use Utopia\Http\Http; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; +use Utopia\Http\Http; class Realtime extends Adapter { diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index ac9fc164d5..fc3cc56517 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -4,7 +4,6 @@ namespace Appwrite\Migration; use Exception; use Swoole\Runtime; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -12,6 +11,7 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Http; Runtime::enableCoroutine(SWOOLE_HOOK_ALL); diff --git a/src/Appwrite/Migration/Version/V15.php b/src/Appwrite/Migration/Version/V15.php index b724dc33e3..1ea9d26773 100644 --- a/src/Appwrite/Migration/Version/V15.php +++ b/src/Appwrite/Migration/Version/V15.php @@ -4,7 +4,6 @@ namespace Appwrite\Migration\Version; use Appwrite\Migration\Migration; use Appwrite\OpenSSL\OpenSSL; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -12,6 +11,7 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; +use Utopia\Http\Http; class V15 extends Migration { diff --git a/src/Appwrite/Migration/Version/V19.php b/src/Appwrite/Migration/Version/V19.php index 75e5b31d17..037b3e1ef4 100644 --- a/src/Appwrite/Migration/Version/V19.php +++ b/src/Appwrite/Migration/Version/V19.php @@ -3,7 +3,6 @@ namespace Appwrite\Migration\Version; use Appwrite\Migration\Migration; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -11,6 +10,7 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception; use Utopia\Database\Query; +use Utopia\Http\Http; class V19 extends Migration { diff --git a/src/Appwrite/Platform/Tasks/CalcTierStats.php b/src/Appwrite/Platform/Tasks/CalcTierStats.php index 137a497ae3..665b60519a 100644 --- a/src/Appwrite/Platform/Tasks/CalcTierStats.php +++ b/src/Appwrite/Platform/Tasks/CalcTierStats.php @@ -4,17 +4,17 @@ namespace Appwrite\Platform\Tasks; use League\Csv\Writer; use PHPMailer\PHPMailer\PHPMailer; -use Utopia\Http\Http; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Http; +use Utopia\Http\Validator\Text; use Utopia\Platform\Action; use Utopia\Pools\Group; use Utopia\Registry\Registry; -use Utopia\Http\Validator\Text; class CalcTierStats extends Action { diff --git a/src/Appwrite/Platform/Tasks/CreateInfMetric.php b/src/Appwrite/Platform/Tasks/CreateInfMetric.php index 099076fdd5..8f5fb30dfb 100644 --- a/src/Appwrite/Platform/Tasks/CreateInfMetric.php +++ b/src/Appwrite/Platform/Tasks/CreateInfMetric.php @@ -8,8 +8,8 @@ use Utopia\Database\Document; use Utopia\Database\Exception; use Utopia\Database\Exception\Duplicate; use Utopia\Database\Query; -use Utopia\Platform\Action; use Utopia\Http\Validator\Text; +use Utopia\Platform\Action; class CreateInfMetric extends Action { diff --git a/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php b/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php index bcccf8dcb0..92c42be3e1 100644 --- a/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php +++ b/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php @@ -2,18 +2,19 @@ namespace Appwrite\Platform\Tasks; -use Utopia\Http\Http; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization; use Utopia\Http\Adapter\FPM\Server; +use Utopia\Http\Http; +use Utopia\Http\Validator\Boolean; use Utopia\Platform\Action; use Utopia\Pools\Group; use Utopia\Registry\Registry; -use Utopia\Http\Validator\Boolean; class DeleteOrphanedProjects extends Action { @@ -32,13 +33,14 @@ class DeleteOrphanedProjects extends Action ->inject('cache') ->inject('dbForConsole') ->inject('register') - ->callback(function (bool $commit, Group $pools, Cache $cache, Database $dbForConsole, Registry $register) { - $this->action($commit, $pools, $cache, $dbForConsole, $register); + ->inject('auth') + ->callback(function (bool $commit, Group $pools, Cache $cache, Database $dbForConsole, Registry $register, Authorization $auth) { + $this->action($commit, $pools, $cache, $dbForConsole, $register, $auth); }); } - public function action(bool $commit, Group $pools, Cache $cache, Database $dbForConsole, Registry $register): void + public function action(bool $commit, Group $pools, Cache $cache, Database $dbForConsole, Registry $register, Authorization $auth): void { Console::title('Delete orphaned projects V1'); @@ -59,8 +61,8 @@ class DeleteOrphanedProjects extends Action ], $collectionsConfig); /* Initialise new Utopia app */ - $app = new Http(new Server(), 'UTC'); - $console = $app->getResource('console'); + $http = new Http(new Server(), 'UTC'); + $console = $http->getResource('console'); $projects = [$console]; /** Database connections */ @@ -91,6 +93,7 @@ class DeleteOrphanedProjects extends Action ->getResource(); $dbForProject = new Database($adapter, $cache); + $dbForProject->setAuthorization($auth); $dbForProject->setDatabase('appwrite'); $dbForProject->setNamespace('_' . $project->getInternalId()); diff --git a/src/Appwrite/Platform/Tasks/DevGenerateTranslations.php b/src/Appwrite/Platform/Tasks/DevGenerateTranslations.php index d47d3e990b..e09c69c6ec 100644 --- a/src/Appwrite/Platform/Tasks/DevGenerateTranslations.php +++ b/src/Appwrite/Platform/Tasks/DevGenerateTranslations.php @@ -6,9 +6,9 @@ use Exception; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Fetch\Client; -use Utopia\Platform\Action; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\Text; +use Utopia\Platform\Action; class DevGenerateTranslations extends Action { diff --git a/src/Appwrite/Platform/Tasks/Doctor.php b/src/Appwrite/Platform/Tasks/Doctor.php index e53f2ba8d7..0f2d12c0a6 100644 --- a/src/Appwrite/Platform/Tasks/Doctor.php +++ b/src/Appwrite/Platform/Tasks/Doctor.php @@ -3,10 +3,10 @@ namespace Appwrite\Platform\Tasks; use Appwrite\ClamAV\Network; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Domains\Domain; +use Utopia\Http\Http; use Utopia\Logger\Logger; use Utopia\Platform\Action; use Utopia\Registry\Registry; diff --git a/src/Appwrite/Platform/Tasks/GetMigrationStats.php b/src/Appwrite/Platform/Tasks/GetMigrationStats.php index c525a92b20..973f55a237 100644 --- a/src/Appwrite/Platform/Tasks/GetMigrationStats.php +++ b/src/Appwrite/Platform/Tasks/GetMigrationStats.php @@ -5,12 +5,14 @@ namespace Appwrite\Platform\Tasks; use League\Csv\CannotInsertRecord; use League\Csv\Writer; use PHPMailer\PHPMailer\PHPMailer; -use Utopia\Http\Http; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Database\Database; +use Utopia\Database\Exception\Authorization; use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization as ValidatorAuthorization; use Utopia\Http\Adapter\FPM\Server; +use Utopia\Http\Http; use Utopia\Platform\Action; use Utopia\Pools\Group; use Utopia\Registry\Registry; @@ -47,8 +49,9 @@ class GetMigrationStats extends Action ->inject('cache') ->inject('dbForConsole') ->inject('register') - ->callback(function (Group $pools, Cache $cache, Database $dbForConsole, Registry $register) { - $this->action($pools, $cache, $dbForConsole, $register); + ->inject('auth') + ->callback(function (Group $pools, Cache $cache, Database $dbForConsole, Registry $register, ValidatorAuthorization $auth) { + $this->action($pools, $cache, $dbForConsole, $register, $auth); }); } @@ -56,7 +59,7 @@ class GetMigrationStats extends Action * @throws \Utopia\Exception * @throws CannotInsertRecord */ - public function action(Group $pools, Cache $cache, Database $dbForConsole, Registry $register): void + public function action(Group $pools, Cache $cache, Database $dbForConsole, Registry $register, ValidatorAuthorization $auth): void { //docker compose exec -t appwrite get-migration-stats @@ -64,8 +67,8 @@ class GetMigrationStats extends Action Console::success(APP_NAME . ' Migration stats calculation has started'); /* Initialise new Utopia app */ - $app = new Http(new Server(), 'UTC'); - $console = $app->getResource('console'); + $http = new Http(new Server(), 'UTC'); + $console = $http->getResource('console'); /** CSV stuff */ $this->date = date('Y-m-d'); @@ -102,6 +105,7 @@ class GetMigrationStats extends Action ->getResource(); $dbForProject = new Database($adapter, $cache); + $dbForProject->setAuthorization($auth); $dbForProject->setDatabase('appwrite'); $dbForProject->setNamespace('_' . $project->getInternalId()); diff --git a/src/Appwrite/Platform/Tasks/Hamster.php b/src/Appwrite/Platform/Tasks/Hamster.php index 95e5cf0e4d..bf0732a0a3 100644 --- a/src/Appwrite/Platform/Tasks/Hamster.php +++ b/src/Appwrite/Platform/Tasks/Hamster.php @@ -3,11 +3,11 @@ namespace Appwrite\Platform\Tasks; use Appwrite\Event\Hamster as EventHamster; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; +use Utopia\Http\Http; use Utopia\Platform\Action; class Hamster extends Action diff --git a/src/Appwrite/Platform/Tasks/Install.php b/src/Appwrite/Platform/Tasks/Install.php index 8b64002c8d..9e03d10255 100644 --- a/src/Appwrite/Platform/Tasks/Install.php +++ b/src/Appwrite/Platform/Tasks/Install.php @@ -8,9 +8,9 @@ use Appwrite\Docker\Env; use Appwrite\Utopia\View; use Utopia\CLI\Console; use Utopia\Config\Config; -use Utopia\Platform\Action; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\Text; +use Utopia\Platform\Action; class Install extends Action { diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index ec8d3253ca..ee7ba4b2c0 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -4,12 +4,12 @@ namespace Appwrite\Platform\Tasks; use Appwrite\Event\Certificate; use Appwrite\Event\Delete; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Query; +use Utopia\Http\Http; use Utopia\Platform\Action; class Maintenance extends Action diff --git a/src/Appwrite/Platform/Tasks/Migrate.php b/src/Appwrite/Platform/Tasks/Migrate.php index ad158b1b42..f5a4d66994 100644 --- a/src/Appwrite/Platform/Tasks/Migrate.php +++ b/src/Appwrite/Platform/Tasks/Migrate.php @@ -3,7 +3,6 @@ namespace Appwrite\Platform\Tasks; use Appwrite\Migration\Migration; -use Utopia\Http\Http; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Database\Database; @@ -11,9 +10,10 @@ use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Http\Adapter\FPM\Server; +use Utopia\Http\Http; +use Utopia\Http\Validator\Text; use Utopia\Platform\Action; use Utopia\Registry\Registry; -use Utopia\Http\Validator\Text; class Migrate extends Action { @@ -54,11 +54,11 @@ class Migrate extends Action return; } - $app = new Http(new Server(), 'UTC'); + $http = new Http(new Server(), 'UTC'); Console::success('Starting Data Migration to version ' . $version); - $console = $app->getResource('console'); + $console = $http->getResource('console'); $limit = 30; $sum = 30; diff --git a/src/Appwrite/Platform/Tasks/PatchRecreateRepositoriesDocuments.php b/src/Appwrite/Platform/Tasks/PatchRecreateRepositoriesDocuments.php index 87bd73cc32..8f4216fed9 100644 --- a/src/Appwrite/Platform/Tasks/PatchRecreateRepositoriesDocuments.php +++ b/src/Appwrite/Platform/Tasks/PatchRecreateRepositoriesDocuments.php @@ -9,8 +9,8 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; -use Utopia\Platform\Action; use Utopia\Http\Validator\Text; +use Utopia\Platform\Action; class PatchRecreateRepositoriesDocuments extends Action { diff --git a/src/Appwrite/Platform/Tasks/QueueCount.php b/src/Appwrite/Platform/Tasks/QueueCount.php index 55a2e5ee98..a8ec9cdacc 100644 --- a/src/Appwrite/Platform/Tasks/QueueCount.php +++ b/src/Appwrite/Platform/Tasks/QueueCount.php @@ -4,10 +4,10 @@ namespace Appwrite\Platform\Tasks; use Appwrite\Event\Event; use Utopia\CLI\Console; +use Utopia\Http\Validator\WhiteList; use Utopia\Platform\Action; use Utopia\Queue\Client; use Utopia\Queue\Connection; -use Utopia\Http\Validator\WhiteList; class QueueCount extends Action { diff --git a/src/Appwrite/Platform/Tasks/QueueRetry.php b/src/Appwrite/Platform/Tasks/QueueRetry.php index e1312e7cc5..3d5f95da0c 100644 --- a/src/Appwrite/Platform/Tasks/QueueRetry.php +++ b/src/Appwrite/Platform/Tasks/QueueRetry.php @@ -4,11 +4,11 @@ namespace Appwrite\Platform\Tasks; use Appwrite\Event\Event; use Utopia\CLI\Console; +use Utopia\Http\Validator\WhiteList; +use Utopia\Http\Validator\Wildcard; use Utopia\Platform\Action; use Utopia\Queue\Client; use Utopia\Queue\Connection; -use Utopia\Http\Validator\WhiteList; -use Utopia\Http\Validator\Wildcard; class QueueRetry extends Action { diff --git a/src/Appwrite/Platform/Tasks/SSL.php b/src/Appwrite/Platform/Tasks/SSL.php index 061679b3bf..0677253a39 100644 --- a/src/Appwrite/Platform/Tasks/SSL.php +++ b/src/Appwrite/Platform/Tasks/SSL.php @@ -3,12 +3,12 @@ namespace Appwrite\Platform\Tasks; use Appwrite\Event\Certificate; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Database\Document; -use Utopia\Platform\Action; +use Utopia\Http\Http; use Utopia\Http\Validator\Boolean; use Utopia\Http\Validator\Hostname; +use Utopia\Platform\Action; class SSL extends Action { diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 91b98dd28c..7685ae9f54 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -3,13 +3,13 @@ namespace Appwrite\Platform\Tasks; use Swoole\Timer; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception; use Utopia\Database\Query; +use Utopia\Http\Http; use Utopia\Platform\Action; use Utopia\Pools\Group; diff --git a/src/Appwrite/Platform/Tasks/Specs.php b/src/Appwrite/Platform/Tasks/Specs.php index 04c4f225e4..c97928f5b5 100644 --- a/src/Appwrite/Platform/Tasks/Specs.php +++ b/src/Appwrite/Platform/Tasks/Specs.php @@ -9,7 +9,6 @@ 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; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -17,10 +16,11 @@ 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\Http\Http; use Utopia\Http\Validator\Text; use Utopia\Http\Validator\WhiteList; +use Utopia\Platform\Action; +use Utopia\Registry\Registry; class Specs extends Action { diff --git a/src/Appwrite/Platform/Tasks/Vars.php b/src/Appwrite/Platform/Tasks/Vars.php index 3d2cb2c36a..6d6866ccd4 100644 --- a/src/Appwrite/Platform/Tasks/Vars.php +++ b/src/Appwrite/Platform/Tasks/Vars.php @@ -2,9 +2,9 @@ namespace Appwrite\Platform\Tasks; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; +use Utopia\Http\Http; use Utopia\Platform\Action; class Vars extends Action diff --git a/src/Appwrite/Platform/Tasks/Version.php b/src/Appwrite/Platform/Tasks/Version.php index 8cfe3099c6..bac9b91da4 100644 --- a/src/Appwrite/Platform/Tasks/Version.php +++ b/src/Appwrite/Platform/Tasks/Version.php @@ -2,8 +2,8 @@ namespace Appwrite\Platform\Tasks; -use Utopia\Http\Http; use Utopia\CLI\Console; +use Utopia\Http\Http; use Utopia\Platform\Action; class Version extends Action diff --git a/src/Appwrite/Platform/Tasks/VolumeSync.php b/src/Appwrite/Platform/Tasks/VolumeSync.php index 17ae9730f9..272edbd446 100644 --- a/src/Appwrite/Platform/Tasks/VolumeSync.php +++ b/src/Appwrite/Platform/Tasks/VolumeSync.php @@ -4,9 +4,9 @@ namespace Appwrite\Platform\Tasks; use Utopia\CLI\Console; use Utopia\Database\DateTime; -use Utopia\Platform\Action; use Utopia\Http\Validator\Integer; use Utopia\Http\Validator\Text; +use Utopia\Platform\Action; class VolumeSync extends Action { diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 86ca59d3fd..0650906538 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -9,6 +9,7 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Structure; +use Utopia\Database\Validator\Authorization as ValidatorAuthorization; use Utopia\Platform\Action; use Utopia\Queue\Message; @@ -28,7 +29,8 @@ class Audits extends Action ->desc('Audits worker') ->inject('message') ->inject('dbForProject') - ->callback(fn ($message, $dbForProject) => $this->action($message, $dbForProject)); + ->inject('auth') + ->callback(fn ($message, $dbForProject, ValidatorAuthorization $auth) => $this->action($message, $dbForProject, $auth)); } @@ -41,7 +43,7 @@ class Audits extends Action * @throws Authorization * @throws Structure */ - public function action(Message $message, Database $dbForProject): void + public function action(Message $message, Database $dbForProject, ValidatorAuthorization $auth): void { $payload = $message->getPayload() ?? []; @@ -61,7 +63,7 @@ class Audits extends Action $userName = $user->getAttribute('name', ''); $userEmail = $user->getAttribute('email', ''); - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $audit->log( userId: $user->getInternalId(), // Pass first, most verbose event pattern diff --git a/src/Appwrite/Platform/Workers/Builds.php b/src/Appwrite/Platform/Workers/Builds.php index 723af17a38..575ba4d8c8 100644 --- a/src/Appwrite/Platform/Workers/Builds.php +++ b/src/Appwrite/Platform/Workers/Builds.php @@ -10,7 +10,6 @@ use Appwrite\Utopia\Response\Model\Deployment; use Appwrite\Vcs\Comment; use Executor\Executor; use Swoole\Coroutine as Co; -use Utopia\Http\Http; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Config\Config; @@ -22,6 +21,7 @@ use Utopia\Database\Exception\Restricted; use Utopia\Database\Exception\Structure; use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Http; use Utopia\Logger\Log; use Utopia\Platform\Action; use Utopia\Queue\Message; diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index 5cbb36ed8e..6fd7af3ffb 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -11,7 +11,6 @@ use Appwrite\Template\Template; use Appwrite\Utopia\Response\Model\Rule; use Exception; use Throwable; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\DateTime; @@ -22,6 +21,7 @@ use Utopia\Database\Exception\Structure; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Domains\Domain; +use Utopia\Http\Http; use Utopia\Locale\Locale; use Utopia\Logger\Log; use Utopia\Platform\Action; diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 8247e00799..228a0b8bed 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -8,7 +8,6 @@ use Executor\Executor; use Throwable; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; -use Utopia\Http\Http; use Utopia\Audit\Audit; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; @@ -22,6 +21,8 @@ use Utopia\Database\Exception\Conflict; use Utopia\Database\Exception\Restricted; use Utopia\Database\Exception\Structure; use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization as ValidatorAuthorization; +use Utopia\Http\Http; use Utopia\Logger\Log; use Utopia\Platform\Action; use Utopia\Queue\Message; @@ -52,14 +53,15 @@ class Deletes extends Action ->inject('executionRetention') ->inject('auditRetention') ->inject('log') - ->callback(fn ($message, $dbForConsole, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, string $abuseRetention, string $executionRetention, string $auditRetention, Log $log) => $this->action($message, $dbForConsole, $getProjectDB, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $abuseRetention, $executionRetention, $auditRetention, $log)); + ->inject('auth') + ->callback(fn ($message, $dbForConsole, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, string $abuseRetention, string $executionRetention, string $auditRetention, Log $log, ValidatorAuthorization $auth) => $this->action($message, $dbForConsole, $getProjectDB, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $abuseRetention, $executionRetention, $auditRetention, $log, $auth)); } /** * @throws Exception * @throws Throwable */ - public function action(Message $message, Database $dbForConsole, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, string $abuseRetention, string $executionRetention, string $auditRetention, Log $log): void + public function action(Message $message, Database $dbForConsole, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, string $abuseRetention, string $executionRetention, string $auditRetention, Log $log, ValidatorAuthorization $auth): void { $payload = $message->getPayload() ?? []; @@ -127,7 +129,7 @@ class Deletes extends Action break; case DELETE_TYPE_AUDIT: if (!$project->isEmpty()) { - $this->deleteAuditLogs($project, $getProjectDB, $auditRetention); + $this->deleteAuditLogs($project, $getProjectDB, $auditRetention, $auth); } if (!$document->isEmpty()) { @@ -135,7 +137,7 @@ class Deletes extends Action } break; case DELETE_TYPE_ABUSE: - $this->deleteAbuseLogs($project, $getProjectDB, $abuseRetention); + $this->deleteAbuseLogs($project, $getProjectDB, $abuseRetention, $auth); break; case DELETE_TYPE_REALTIME: $this->deleteRealtimeUsage($dbForConsole, $datetime); @@ -724,12 +726,12 @@ class Deletes extends Action * @return void * @throws Exception */ - private function deleteAbuseLogs(Document $project, callable $getProjectDB, string $abuseRetention): void + private function deleteAbuseLogs(Document $project, callable $getProjectDB, string $abuseRetention, ValidatorAuthorization $auth): void { $projectId = $project->getId(); $dbForProject = $getProjectDB($project); - $timeLimit = new TimeLimit("", 0, 1, $dbForProject); - $abuse = new Abuse($timeLimit); + $timeLimit = new TimeLimit("", 0, 1, $dbForProject, $auth); + $abuse = new Abuse($timeLimit, $auth); $status = $abuse->cleanup($abuseRetention); if (!$status) { throw new Exception('Failed to delete Abuse logs for project ' . $projectId); @@ -743,11 +745,11 @@ class Deletes extends Action * @return void * @throws Exception */ - private function deleteAuditLogs(Document $project, callable $getProjectDB, string $auditRetention): void + private function deleteAuditLogs(Document $project, callable $getProjectDB, string $auditRetention, ValidatorAuthorization $auth): void { $projectId = $project->getId(); $dbForProject = $getProjectDB($project); - $audit = new Audit($dbForProject); + $audit = new Audit($dbForProject, $auth); $status = $audit->cleanup($auditRetention); if (!$status) { throw new Exception('Failed to delete Audit logs for project' . $projectId); diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index 0d325f7bb3..4cb6cb9f06 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -9,7 +9,6 @@ use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Utopia\Response\Model\Execution; use Exception; use Executor\Executor; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -21,6 +20,7 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; +use Utopia\Http\Http; use Utopia\Logger\Log; use Utopia\Platform\Action; use Utopia\Queue\Message; diff --git a/src/Appwrite/Platform/Workers/Hamster.php b/src/Appwrite/Platform/Workers/Hamster.php index 817291dff1..84a813d157 100644 --- a/src/Appwrite/Platform/Workers/Hamster.php +++ b/src/Appwrite/Platform/Workers/Hamster.php @@ -4,10 +4,8 @@ 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; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Config\Config; @@ -15,6 +13,7 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Http\Http; use Utopia\Platform\Action; use Utopia\Pools\Group; use Utopia\Queue\Message; @@ -123,6 +122,7 @@ class Hamster extends Action ->getResource(); $dbForProject = new Database($adapter, $cache); + $dbForProject->setAuthorization($auth); $dbForProject->setDatabase('appwrite'); $dbForProject->setNamespace('_' . $project->getInternalId()); diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 19ecc707dd..4535a8d8a8 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -4,7 +4,6 @@ namespace Appwrite\Platform\Workers; use Appwrite\Event\Usage; use Appwrite\Messaging\Status as MessageStatus; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; @@ -13,6 +12,7 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\DSN\DSN; +use Utopia\Http\Http; use Utopia\Logger\Log; use Utopia\Messaging\Adapter\Email as EmailAdapter; use Utopia\Messaging\Adapter\Email\Mailgun; diff --git a/src/Appwrite/Platform/Workers/Usage.php b/src/Appwrite/Platform/Workers/Usage.php index 14e004194f..284165a476 100644 --- a/src/Appwrite/Platform/Workers/Usage.php +++ b/src/Appwrite/Platform/Workers/Usage.php @@ -4,10 +4,10 @@ namespace Appwrite\Platform\Workers; use Appwrite\Event\UsageDump; use Exception; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Database\DateTime; use Utopia\Database\Document; +use Utopia\Http\Http; use Utopia\Platform\Action; use Utopia\Queue\Message; diff --git a/src/Appwrite/Platform/Workers/UsageDump.php b/src/Appwrite/Platform/Workers/UsageDump.php index 96cb1e9e0b..d33906b24e 100644 --- a/src/Appwrite/Platform/Workers/UsageDump.php +++ b/src/Appwrite/Platform/Workers/UsageDump.php @@ -3,11 +3,11 @@ namespace Appwrite\Platform\Workers; use Appwrite\Extend\Exception; -use Utopia\Http\Http; use Utopia\CLI\Console; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception\Duplicate; +use Utopia\Http\Http; use Utopia\Platform\Action; use Utopia\Queue\Message; diff --git a/src/Appwrite/Platform/Workers/Webhooks.php b/src/Appwrite/Platform/Workers/Webhooks.php index 88a6dd4c68..1835b16d7d 100644 --- a/src/Appwrite/Platform/Workers/Webhooks.php +++ b/src/Appwrite/Platform/Workers/Webhooks.php @@ -5,10 +5,10 @@ namespace Appwrite\Platform\Workers; use Appwrite\Event\Mail; use Appwrite\Template\Template; use Exception; -use Utopia\Http\Http; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; +use Utopia\Http\Http; use Utopia\Logger\Log; use Utopia\Platform\Action; use Utopia\Queue\Message; diff --git a/src/Appwrite/Specification/Format.php b/src/Appwrite/Specification/Format.php index fdb4841a93..e2048971be 100644 --- a/src/Appwrite/Specification/Format.php +++ b/src/Appwrite/Specification/Format.php @@ -3,13 +3,13 @@ namespace Appwrite\Specification; use Appwrite\Utopia\Response\Model; -use Utopia\Http\Http; use Utopia\Config\Config; +use Utopia\Http\Http; use Utopia\Http\Route; abstract class Format { - protected Http $app; + protected Http $http; /** * @var Route[] @@ -50,9 +50,9 @@ abstract class Format ] ]; - public function __construct(Http $app, array $services, array $routes, array $models, array $keys, int $authCount) + public function __construct(Http $http, array $services, array $routes, array $models, array $keys, int $authCount) { - $this->app = $app; + $this->http = $http; $this->services = $services; $this->routes = $routes; $this->models = $models; diff --git a/src/Appwrite/Specification/Format/OpenAPI3.php b/src/Appwrite/Specification/Format/OpenAPI3.php index 5ee3011ebd..1da6fb7ef0 100644 --- a/src/Appwrite/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/Specification/Format/OpenAPI3.php @@ -275,7 +275,7 @@ class OpenAPI3 extends Format /** * @var \Utopia\Http\Validator $validator */ - $validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->app->getResources($param['injections'])) : $param['validator']; + $validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->http->getResources($param['injections'])) : $param['validator']; $node = [ 'name' => $name, diff --git a/src/Appwrite/Specification/Format/Swagger2.php b/src/Appwrite/Specification/Format/Swagger2.php index d75568976c..d53649db73 100644 --- a/src/Appwrite/Specification/Format/Swagger2.php +++ b/src/Appwrite/Specification/Format/Swagger2.php @@ -271,7 +271,7 @@ class Swagger2 extends Format foreach ($parameters as $name => $param) { // Set params /** @var Validator $validator */ - $validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->app->getResources($param['injections'])) : $param['validator']; + $validator = (\is_callable($param['validator'])) ? call_user_func_array($param['validator'], $this->http->getResources($param['injections'])) : $param['validator']; $node = [ 'name' => $name, diff --git a/src/Appwrite/Utopia/Request.php b/src/Appwrite/Utopia/Request.php index ee488d6a13..c5c900d82f 100644 --- a/src/Appwrite/Utopia/Request.php +++ b/src/Appwrite/Utopia/Request.php @@ -11,6 +11,14 @@ class Request extends SwooleRequest private static ?Filter $filter = null; private static ?Route $route = null; + /** + * Request constructor. + */ + public function __construct(SwooleRequest $request) + { + parent::__construct($request->getSwooleRequest()); + } + /** * @inheritdoc */ diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 4f6ebd3cc5..280962e139 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -102,7 +102,6 @@ use Appwrite\Utopia\Response\Model\User; use Appwrite\Utopia\Response\Model\Variable; use Appwrite\Utopia\Response\Model\Webhook; use Exception; -use Swoole\Http\Response as SwooleHTTPResponse; // Keep last use Utopia\Database\Document; use Utopia\Http\Adapter\Swoole\Response as SwooleResponse; @@ -313,8 +312,10 @@ class Response extends SwooleResponse * * @param float $time */ - public function __construct(SwooleHTTPResponse $response) + public function __construct(SwooleResponse $swooleResponse) { + $response = $swooleResponse->getSwooleResponse(); + $this // General ->setModel(new None()) diff --git a/src/Appwrite/Vcs/Comment.php b/src/Appwrite/Vcs/Comment.php index 6731365638..aa2b9ff031 100644 --- a/src/Appwrite/Vcs/Comment.php +++ b/src/Appwrite/Vcs/Comment.php @@ -2,8 +2,8 @@ namespace Appwrite\Vcs; -use Utopia\Http\Http; use Utopia\Database\Document; +use Utopia\Http\Http; class Comment { diff --git a/tests/e2e/General/AbuseTest.php b/tests/e2e/General/AbuseTest.php index 0c8e363b37..5557e52462 100644 --- a/tests/e2e/General/AbuseTest.php +++ b/tests/e2e/General/AbuseTest.php @@ -7,10 +7,10 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideNone; -use Utopia\Http\Http; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; +use Utopia\Http\Http; class AbuseTest extends Scope { diff --git a/tests/e2e/Services/GraphQL/AbuseTest.php b/tests/e2e/Services/GraphQL/AbuseTest.php index 958baa3b90..92080191d5 100644 --- a/tests/e2e/Services/GraphQL/AbuseTest.php +++ b/tests/e2e/Services/GraphQL/AbuseTest.php @@ -6,10 +6,10 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Utopia\Http\Http; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; +use Utopia\Http\Http; class AbuseTest extends Scope { diff --git a/tests/e2e/Services/GraphQL/MessagingTest.php b/tests/e2e/Services/GraphQL/MessagingTest.php index 839d80b09e..3e6a3d4b1b 100644 --- a/tests/e2e/Services/GraphQL/MessagingTest.php +++ b/tests/e2e/Services/GraphQL/MessagingTest.php @@ -6,9 +6,9 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Utopia\Http\Http; use Utopia\Database\Helpers\ID; use Utopia\DSN\DSN; +use Utopia\Http\Http; class MessagingTest extends Scope { diff --git a/tests/e2e/Services/Messaging/MessagingBase.php b/tests/e2e/Services/Messaging/MessagingBase.php index a0669a1f8d..30df11ba0f 100644 --- a/tests/e2e/Services/Messaging/MessagingBase.php +++ b/tests/e2e/Services/Messaging/MessagingBase.php @@ -4,13 +4,13 @@ namespace Tests\E2E\Services\Messaging; use Appwrite\Messaging\Status as MessageStatus; use Tests\E2E\Client; -use Utopia\Http\Http; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; use Utopia\DSN\DSN; +use Utopia\Http\Http; trait MessagingBase { diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 37cef56628..1f783b91b2 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -6,11 +6,11 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; -use Utopia\Http\Http; use Utopia\Cache\Adapter\None; use Utopia\Cache\Cache; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; +use Utopia\Http\Http; use Utopia\VCS\Adapter\Git\GitHub; class VCSConsoleClientTest extends Scope diff --git a/tests/unit/Event/EventTest.php b/tests/unit/Event/EventTest.php index e512797896..3966bf9a3b 100644 --- a/tests/unit/Event/EventTest.php +++ b/tests/unit/Event/EventTest.php @@ -6,8 +6,8 @@ use Appwrite\Event\Event; use Appwrite\URL\URL; use InvalidArgumentException; use PHPUnit\Framework\TestCase; -use Utopia\Http\Http; use Utopia\DSN\DSN; +use Utopia\Http\Http; use Utopia\Queue; use Utopia\Queue\Client; diff --git a/tests/unit/Messaging/MessagingChannelsTest.php b/tests/unit/Messaging/MessagingChannelsTest.php index 2f0443c34f..77b3cee7d6 100644 --- a/tests/unit/Messaging/MessagingChannelsTest.php +++ b/tests/unit/Messaging/MessagingChannelsTest.php @@ -6,7 +6,6 @@ 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; diff --git a/tests/unit/Usage/StatsTest.php b/tests/unit/Usage/StatsTest.php index fdef412ac8..092c75ba37 100644 --- a/tests/unit/Usage/StatsTest.php +++ b/tests/unit/Usage/StatsTest.php @@ -4,8 +4,8 @@ namespace Tests\Unit\Usage; use Appwrite\URL\URL as AppwriteURL; use PHPUnit\Framework\TestCase; -use Utopia\Http\Http; use Utopia\DSN\DSN; +use Utopia\Http\Http; use Utopia\Queue; use Utopia\Queue\Client; use Utopia\Queue\Connection;