diff --git a/app/config/scopes/project.php b/app/config/scopes/project.php index a048920de9..5f9e4877b3 100644 --- a/app/config/scopes/project.php +++ b/app/config/scopes/project.php @@ -286,6 +286,16 @@ return [ 'category' => 'Messaging', ], + // Proxy + 'rules.read' => [ + 'description' => 'Access to read proxy rules.', + 'category' => 'Proxy', + ], + 'rules.write' => [ + 'description' => 'Access to create, update, and delete proxy rules.', + 'category' => 'Proxy', + ], + // Other "webhooks.read" => [ "description" => @@ -339,12 +349,4 @@ return [ 'description' => 'Access to create, update, and delete resources under VCS service.', 'category' => 'Other', ], - 'rules.read' => [ - 'description' => 'Access to read proxy rules.', - 'category' => 'Other', - ], - 'rules.write' => [ - 'description' => 'Access to create, update, and delete proxy rules.', - 'category' => 'Other', - ], ]; diff --git a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/API/Create.php b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/API/Create.php index a6a3e44194..13c06c3e91 100644 --- a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/API/Create.php +++ b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/API/Create.php @@ -9,11 +9,13 @@ use Appwrite\Platform\Modules\Proxy\Action; use Appwrite\SDK\AuthType; use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; +use Appwrite\Utopia\Database\Validator\CustomId; use Appwrite\Utopia\Response; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Duplicate; use Utopia\Database\Helpers\ID; +use Utopia\Database\Validator\Authorization; use Utopia\Logger\Log; use Utopia\Platform\Scope\HTTP; use Utopia\System\System; @@ -47,8 +49,10 @@ class Create extends Action name: 'createAPIRule', description: <<inject('dbForPlatform') ->inject('platform') ->inject('log') + ->inject('authorization') ->callback($this->action(...)); } - public function action(string $domain, Response $response, Document $project, Certificate $publisherForCertificates, Event $queueForEvents, Database $dbForPlatform, array $platform, Log $log) - { + public function action( + string $domain, + Response $response, + Document $project, + Certificate $publisherForCertificates, + Event $queueForEvents, + Database $dbForPlatform, + array $platform, + Log $log, + Authorization $authorization, + ) { $this->validateDomainRestrictions($domain, $platform); // TODO: (@Meldiron) Remove after 1.7.x migration @@ -108,7 +122,7 @@ class Create extends Action } try { - $rule = $dbForPlatform->createDocument('rules', $rule); + $rule = $authorization->skip(fn() => $dbForPlatform->createDocument('rules', $rule)); } catch (Duplicate $e) { throw new Exception(Exception::RULE_ALREADY_EXISTS); } diff --git a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Delete.php b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Delete.php index 1d5b770496..2bbe4a530a 100644 --- a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Delete.php +++ b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Delete.php @@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\UID; use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; @@ -43,7 +44,7 @@ class Delete extends Action description: <<inject('dbForPlatform') ->inject('queueForDeletes') ->inject('queueForEvents') + ->inject('authorization') ->callback($this->action(...)); } @@ -67,15 +69,16 @@ class Delete extends Action Document $project, Database $dbForPlatform, DeleteEvent $queueForDeletes, - Event $queueForEvents + Event $queueForEvents, + Authorization $authorization, ) { - $rule = $dbForPlatform->getDocument('rules', $ruleId); + $rule = $authorization->skip(fn() => $dbForPlatform->getDocument('rules', $ruleId)); if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getSequence()) { throw new Exception(Exception::RULE_NOT_FOUND); } - $dbForPlatform->deleteDocument('rules', $rule->getId()); + $authorization->skip(fn() => $dbForPlatform->deleteDocument('rules', $rule->getId())); $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) diff --git a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Get.php b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Get.php index b88a4ffc06..03841bf1e5 100644 --- a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Get.php +++ b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Get.php @@ -10,6 +10,7 @@ use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\UID; use Utopia\Platform\Scope\HTTP; @@ -39,7 +40,7 @@ class Get extends Action description: <<inject('response') ->inject('project') ->inject('dbForPlatform') + ->inject('authorization') ->callback($this->action(...)); } @@ -58,15 +60,16 @@ class Get extends Action string $ruleId, Response $response, Document $project, - Database $dbForPlatform + Database $dbForPlatform, + Authorization $authorization, ) { - $rule = $dbForPlatform->getDocument('rules', $ruleId); + $rule = $authorization->skip(fn() => $dbForPlatform->getDocument('rules', $ruleId)); if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getSequence()) { throw new Exception(Exception::RULE_NOT_FOUND); } - $certificate = $dbForPlatform->getDocument('certificates', $rule->getAttribute('certificateId', '')); + $certificate = $authorization->skip(fn() => $dbForPlatform->getDocument('certificates', $rule->getAttribute('certificateId', ''))); // Give priority to certificate generation logs if present if (!empty($certificate->getAttribute('logs', ''))) { diff --git a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Verification/Update.php b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Verification/Update.php index 9e81f6ff18..f567077c23 100644 --- a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Verification/Update.php +++ b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/Verification/Update.php @@ -13,6 +13,7 @@ use Appwrite\Utopia\Response; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; +use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\UID; use Utopia\Logger\Log; use Utopia\Platform\Scope\HTTP; @@ -44,9 +45,9 @@ class Update extends Action group: null, name: 'updateRuleVerification', description: <<inject('project') ->inject('dbForPlatform') ->inject('log') + ->inject('authorization') ->callback($this->action(...)); } @@ -71,9 +73,10 @@ class Update extends Action Event $queueForEvents, Document $project, Database $dbForPlatform, - Log $log + Log $log, + Authorization $authorization, ) { - $rule = $dbForPlatform->getDocument('rules', $ruleId); + $rule = $authorization->skip(fn() => $dbForPlatform->getDocument('rules', $ruleId)); if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getSequence()) { throw new Exception(Exception::RULE_NOT_FOUND); @@ -90,22 +93,22 @@ class Update extends Action try { $this->verifyRule($rule, $log); // Reset logs and status for the rule - $rule = $dbForPlatform->updateDocument('rules', $rule->getId(), new Document([ + $rule = $authorization->skip(fn() => $dbForPlatform->updateDocument('rules', $rule->getId(), new Document([ 'logs' => '', 'status' => RULE_STATUS_CERTIFICATE_GENERATING, - ])); + ]))); $certificateId = $rule->getAttribute('certificateId', ''); // Reset logs for the associated certificate. if (!empty($certificateId)) { - $certificate = $dbForPlatform->updateDocument('certificates', $certificateId, new Document([ + $certificate = $authorization->skip(fn() => $dbForPlatform->updateDocument('certificates', $certificateId, new Document([ 'logs' => '', - ])); + ]))); } } catch (Exception $err) { - $dbForPlatform->updateDocument('rules', $rule->getId(), new Document([ + $authorization->skip(fn() => $dbForPlatform->updateDocument('rules', $rule->getId(), new Document([ '$updatedAt' => DateTime::now(), - ])); + ]))); throw $err; } diff --git a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/XList.php b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/XList.php index 19daf8c8d2..655563aa3b 100644 --- a/src/Appwrite/Platform/Modules/Proxy/Http/Rules/XList.php +++ b/src/Appwrite/Platform/Modules/Proxy/Http/Rules/XList.php @@ -13,6 +13,7 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Query\Cursor; use Utopia\Platform\Scope\HTTP; use Utopia\Validator\Boolean; @@ -44,7 +45,7 @@ class XList extends Action description: <<param('queries', [], new Rules(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). 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(', ', Rules::ALLOWED_ATTRIBUTES), true) - ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true) + ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true, deprecated: true) ->inject('response') ->inject('project') ->inject('dbForPlatform') + ->inject('authorization') ->callback($this->action(...)); } public function action( array $queries, + bool $total, string $search, - bool $includeTotal, Response $response, Document $project, - Database $dbForPlatform + Database $dbForPlatform, + Authorization $authorization, ) { try { $queries = Query::parseQueries($queries); @@ -91,7 +94,7 @@ class XList extends Action } $ruleId = $cursor->getValue(); - $cursorDocument = $dbForPlatform->getDocument('rules', $ruleId); + $cursorDocument = $authorization->skip(fn() => $dbForPlatform->getDocument('rules', $ruleId)); if ($cursorDocument->isEmpty()) { throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Rule '{$ruleId}' for the 'cursor' value not found."); @@ -102,9 +105,9 @@ class XList extends Action $filterQueries = Query::groupByType($queries)['filters']; - $rules = $dbForPlatform->find('rules', $queries); + $rules = $authorization->skip(fn() => $dbForPlatform->find('rules', $queries)); foreach ($rules as $rule) { - $certificate = $dbForPlatform->getDocument('certificates', $rule->getAttribute('certificateId', '')); + $certificate = $authorization->skip(fn() => $dbForPlatform->getDocument('certificates', $rule->getAttribute('certificateId', ''))); // Give priority to certificate generation logs if present if (!empty($certificate->getAttribute('logs', ''))) { @@ -116,7 +119,7 @@ class XList extends Action $response->dynamic(new Document([ 'rules' => $rules, - 'total' => $includeTotal ? $dbForPlatform->count('rules', $filterQueries, APP_LIMIT_COUNT) : 0, + 'total' => $total ? $authorization->skip(fn() => $dbForPlatform->count('rules', $filterQueries, APP_LIMIT_COUNT)) : 0, ]), Response::MODEL_PROXY_RULE_LIST); } }