Use authorization instance

This commit is contained in:
Jake Barnby
2026-01-07 20:04:28 +13:00
parent 6dc836307e
commit 7573ee75a2
182 changed files with 1230 additions and 776 deletions
+6 -4
View File
@@ -20,10 +20,12 @@ use Utopia\Database\Validator\Authorization;
class TransactionState
{
private Database $dbForProject;
public function __construct(Database $dbForProject)
private Authorization $authorization;
/** @var Authorization $authorization */
public function __construct(Database $dbForProject, Authorization $authorization)
{
$this->dbForProject = $dbForProject;
$this->authorization = $authorization;
}
@@ -342,12 +344,12 @@ class TransactionState
*/
private function getTransactionState(string $transactionId): array
{
$transaction = Authorization::skip(fn () => $this->dbForProject->getDocument('transactions', $transactionId));
$transaction = $this->authorization->skip(fn () => $this->dbForProject->getDocument('transactions', $transactionId));
if ($transaction->isEmpty() || $transaction->getAttribute('status') !== 'pending') {
return [];
}
$operations = Authorization::skip(fn () => $this->dbForProject->find('transactionLogs', [
$operations = $this->authorization->skip(fn () => $this->dbForProject->find('transactionLogs', [
Query::equal('transactionInternalId', [$transaction->getSequence()]),
Query::orderAsc(),
Query::limit(PHP_INT_MAX)
+4 -2
View File
@@ -100,8 +100,6 @@ abstract class Migration
public function __construct()
{
Authorization::disable();
Authorization::setDefaultStatus(false);
$this->collections = Config::getParam('collections', []);
@@ -129,6 +127,7 @@ abstract class Migration
Document $project,
Database $dbForProject,
Database $dbForPlatform,
Authorization $authorization,
?callable $getProjectDB = null
): self {
$this->project = $project;
@@ -136,6 +135,9 @@ abstract class Migration
$this->dbForPlatform = $dbForPlatform;
$this->getProjectDB = $getProjectDB;
$authorization->disable();
$authorization->setDefaultStatus(false);
return $this;
}
+37 -4
View File
@@ -13,6 +13,7 @@ use Utopia\Database\Exception\Duplicate;
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\Swoole\Request;
use Utopia\System\System;
@@ -142,7 +143,7 @@ class Base extends Action
return $deployment;
}
public function redeployVcsSite(Request $request, Document $site, Document $project, Document $installation, Database $dbForProject, Database $dbForPlatform, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, string $referenceType = 'branch', string $reference = ''): Document
public function redeployVcsSite(Request $request, Document $site, Document $project, Document $installation, Database $dbForProject, Database $dbForPlatform, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, Authorization $authorization, string $referenceType = 'branch', string $reference = ''): Document
{
$deploymentId = ID::unique();
$providerInstallationId = $installation->getAttribute('providerInstallationId', '');
@@ -239,7 +240,7 @@ class Base extends Action
$isMd5 = System::getEnv('_APP_RULES_FORMAT') === 'md5';
$ruleId = $isMd5 ? md5($domain) : ID::unique();
Authorization::skip(
$authorization->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -265,7 +266,7 @@ class Base extends Action
$domain = "commit-" . substr($commitDetails['commitHash'], 0, 16) . ".{$sitesDomain}";
$ruleId = md5($domain);
try {
Authorization::skip(
$authorization->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -302,7 +303,7 @@ class Base extends Action
$domain = "branch-{$branchPrefix}-{$resourceProjectHash}.{$sitesDomain}";
$ruleId = md5($domain);
try {
Authorization::skip(
$authorization->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -328,6 +329,8 @@ class Base extends Action
}
}
$this->updateEmptyManualRule($project, $site, $deployment, $dbForPlatform, $authorization);
$queueForBuilds
->setType(BUILD_TYPE_DEPLOYMENT)
->setResource($site)
@@ -336,4 +339,34 @@ class Base extends Action
return $deployment;
}
/**
* Update empty manual rule for deployment.
* In case of first deployment, deployment ID will be empty in the rules, so we need to update it here.
*
* @param \Utopia\Database\Document $project
* @param \Utopia\Database\Document $resource
* @param \Utopia\Database\Document $deployment
* @param \Utopia\Database\Database $dbForPlatform
* @return void
*/
public static function updateEmptyManualRule(Document $project, Document $resource, Document $deployment, Database $dbForPlatform, Authorization $authorization)
{
$resourceType = $resource->getCollection() === 'sites' ? 'site' : 'function';
$queries = [
Query::equal('projectInternalId', [$project->getSequence()]),
Query::equal('deploymentResourceInternalId', [$resource->getSequence()]),
Query::equal('deploymentResourceType', [$resourceType]),
Query::equal('deploymentId', ['']),
Query::equal('type', ['deployment']),
Query::equal('trigger', ['manual']),
];
$dbForPlatform->forEach('rules', function (Document $rule) use ($deployment, $dbForPlatform, $authorization) {
$authorization->skip(fn () => $dbForPlatform->updateDocument('rules', $rule->getId(), new Document([
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getSequence(),
])));
}, $queries);
}
}
@@ -60,6 +60,7 @@ class Get extends Action
->inject('response')
->inject('dbForPlatform')
->inject('platform')
->inject('authorization')
->callback($this->action(...));
}
@@ -68,7 +69,8 @@ class Get extends Action
string $type,
Response $response,
Database $dbForPlatform,
array $platform
array $platform,
Authorization $authorization,
) {
$domains = $platform['hostnames'] ?? [];
if ($type === 'rules') {
@@ -121,7 +123,7 @@ class Get extends Action
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
}
$document = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
$document = $authorization->skip(fn () => $dbForPlatform->findOne('rules', [
Query::equal('domain', [$value]),
]));
@@ -292,7 +292,7 @@ abstract class Action extends UtopiaAction
};
}
protected function createAttribute(string $databaseId, string $collectionId, Document $attribute, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): Document
protected function createAttribute(string $databaseId, string $collectionId, Document $attribute, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): Document
{
$key = $attribute->getAttribute('key');
$type = $attribute->getAttribute('type', '');
@@ -310,7 +310,7 @@ abstract class Action extends UtopiaAction
throw new Exception($this->getSpatialTypeNotSupportedException(), params: [$type]);
}
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -371,7 +371,7 @@ abstract class Action extends UtopiaAction
\in_array($attribute->getAttribute('type'), Database::SPATIAL_TYPES) &&
$attribute->getAttribute('required')
) {
$hasData = !Authorization::skip(fn () => $dbForProject
$hasData = !$authorization->skip(fn () => $dbForProject
->findOne('database_' . $db->getSequence() . '_collection_' . $collection->getSequence()))
->isEmpty();
@@ -472,9 +472,9 @@ abstract class Action extends UtopiaAction
return $attribute;
}
protected function updateAttribute(string $databaseId, string $collectionId, string $key, Database $dbForProject, Event $queueForEvents, string $type, int $size = null, string $filter = null, string|bool|int|float|array $default = null, bool $required = null, int|float|null $min = null, int|float|null $max = null, array $elements = null, array $options = [], string $newKey = null): Document
protected function updateAttribute(string $databaseId, string $collectionId, string $key, Database $dbForProject, Event $queueForEvents, Authorization $authorization, string $type, int $size = null, string $filter = null, string|bool|int|float|array $default = null, bool $required = null, int|float|null $min = null, int|float|null $max = null, array $elements = null, array $options = [], string $newKey = null): Document
{
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -69,10 +70,11 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
'key' => $key,
@@ -81,7 +83,7 @@ class Create extends Action
'required' => $required,
'default' => $default,
'array' => $array,
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -68,10 +69,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -79,6 +81,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_BOOLEAN,
default: $default,
required: $required,
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Datetime as DatetimeValidator;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
@@ -70,10 +71,11 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->createAttribute(
$databaseId,
@@ -90,7 +92,8 @@ class Create extends Action
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents
$queueForEvents,
$authorization
);
$response
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Datetime as DatetimeValidator;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
@@ -69,10 +70,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -80,6 +82,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_DATETIME,
default: $default,
required: $required,
@@ -67,12 +67,13 @@ class Delete extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
@@ -13,6 +13,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -70,10 +71,11 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->createAttribute(
$databaseId,
@@ -90,7 +92,8 @@ class Create extends Action
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents
$queueForEvents,
$authorization
);
$response
@@ -12,6 +12,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -69,10 +70,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -80,6 +82,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_STRING,
filter: APP_DATABASE_ATTRIBUTE_EMAIL,
default: $default,
@@ -13,6 +13,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -73,10 +74,11 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, array $elements, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, array $elements, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
if (!is_null($default) && !\in_array($default, $elements, true)) {
throw new Exception($this->getInvalidValueException(), 'Default value not found in elements');
@@ -98,7 +100,8 @@ class Create extends Action
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents
$queueForEvents,
$authorization
);
$response
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -71,10 +72,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?array $elements, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?array $elements, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -82,6 +84,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_STRING,
filter: APP_DATABASE_ATTRIBUTE_ENUM,
default: $default,
@@ -13,6 +13,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -74,10 +75,11 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$min ??= -PHP_FLOAT_MAX;
$max ??= PHP_FLOAT_MAX;
@@ -100,7 +102,7 @@ class Create extends Action
'array' => $array,
'format' => APP_DATABASE_ATTRIBUTE_FLOAT_RANGE,
'formatOptions' => ['min' => $min, 'max' => $max],
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
$formatOptions = $attribute->getAttribute('formatOptions', []);
if (!empty($formatOptions)) {
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -71,10 +72,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -82,6 +84,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_FLOAT,
default: $default,
required: $required,
@@ -68,12 +68,13 @@ class Get extends Action
->param('key', '', new Key(), 'Attribute Key.')
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -70,10 +71,11 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->createAttribute(
$databaseId,
@@ -90,7 +92,8 @@ class Create extends Action
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents
$queueForEvents,
$authorization
);
$response
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -69,10 +70,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?string $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -80,6 +82,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_STRING,
filter: APP_DATABASE_ATTRIBUTE_IP,
default: $default,
@@ -13,6 +13,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -74,10 +75,11 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$min ??= \PHP_INT_MIN;
$max ??= \PHP_INT_MAX;
@@ -102,7 +104,7 @@ class Create extends Action
'array' => $array,
'format' => APP_DATABASE_ATTRIBUTE_INT_RANGE,
'formatOptions' => ['min' => $min, 'max' => $max],
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
$formatOptions = $attribute->getAttribute('formatOptions', []);
if (!empty($formatOptions)) {
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -71,10 +72,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -82,6 +84,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_INTEGER,
default: $default,
required: $required,
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\Spatial;
use Utopia\Database\Validator\UID;
@@ -69,17 +70,18 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
'key' => $key,
'type' => Database::VAR_LINESTRING,
'required' => $required,
'default' => $default
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\Spatial;
use Utopia\Database\Validator\UID;
@@ -69,10 +70,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -80,6 +82,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_LINESTRING,
default: $default,
required: $required,
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\Spatial;
use Utopia\Database\Validator\UID;
@@ -69,17 +70,18 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
'key' => $key,
'type' => Database::VAR_POINT,
'required' => $required,
'default' => $default,
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\Spatial;
use Utopia\Database\Validator\UID;
@@ -69,10 +70,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -80,6 +82,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_POINT,
default: $default,
required: $required,
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\Spatial;
use Utopia\Database\Validator\UID;
@@ -69,17 +70,18 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
'key' => $key,
'type' => Database::VAR_POLYGON,
'required' => $required,
'default' => $default,
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\Spatial;
use Utopia\Database\Validator\UID;
@@ -69,10 +70,11 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?array $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -80,6 +82,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_POLYGON,
default: $default,
required: $required,
@@ -83,16 +83,17 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $relatedCollectionId, string $type, bool $twoWay, ?string $key, ?string $twoWayKey, string $onDelete, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $relatedCollectionId, string $type, bool $twoWay, ?string $key, ?string $twoWayKey, string $onDelete, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$key ??= $relatedCollectionId;
$twoWayKeyWasProvided = $twoWayKey !== null;
$twoWayKey ??= $collectionId;
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
@@ -154,7 +155,7 @@ class Create extends Action
'twoWayKey' => $twoWayKey,
'onDelete' => $onDelete,
]
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
foreach ($attribute->getAttribute('options', []) as $k => $option) {
$attribute->setAttribute($k, $option);
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -71,6 +72,7 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
@@ -82,7 +84,8 @@ class Update extends Action
?string $newKey,
UtopiaResponse $response,
Database $dbForProject,
Event $queueForEvents
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -90,6 +93,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_RELATIONSHIP,
required: false,
options: [
@@ -14,6 +14,7 @@ use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\App;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -77,6 +78,7 @@ class Create extends Action
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
@@ -93,7 +95,8 @@ class Create extends Action
Database $dbForProject,
EventDatabase $queueForDatabase,
Event $queueForEvents,
array $plan
array $plan,
Authorization $authorization
): void {
if (!App::isDevelopment() && $encrypt && !empty($plan) && !($plan['databasesAllowEncrypt'] ?? false)) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Encrypted string ' . $this->getSDKGroup() . ' are not available on your plan. Please upgrade to create encrypted string ' . $this->getSDKGroup() . '.');
@@ -132,7 +135,8 @@ class Create extends Action
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents
$queueForEvents,
$authorization
);
$attribute->setAttribute('encrypt', $encrypt);
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -72,6 +73,7 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
@@ -85,7 +87,8 @@ class Update extends Action
?string $newKey,
UtopiaResponse $response,
Database $dbForProject,
Event $queueForEvents
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->updateAttribute(
databaseId: $databaseId,
@@ -93,6 +96,7 @@ class Update extends Action
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_STRING,
size: $size,
default: $default,
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -70,6 +71,7 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
@@ -83,7 +85,8 @@ class Create extends Action
UtopiaResponse $response,
Database $dbForProject,
EventDatabase $queueForDatabase,
Event $queueForEvents
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
'key' => $key,
@@ -93,7 +96,7 @@ class Create extends Action
'default' => $default,
'array' => $array,
'format' => APP_DATABASE_ATTRIBUTE_URL,
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
@@ -11,6 +11,7 @@ use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -69,6 +70,7 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
@@ -81,7 +83,8 @@ class Update extends Action
?string $newKey,
UtopiaResponse $response,
Database $dbForProject,
Event $queueForEvents
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->updateAttribute(
$databaseId,
@@ -89,6 +92,7 @@ class Update extends Action
$key,
$dbForProject,
$queueForEvents,
$authorization,
type: Database::VAR_STRING,
filter: APP_DATABASE_ATTRIBUTE_URL,
default: $default,
@@ -64,12 +64,13 @@ class XList extends Action
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, array $queries, bool $includeTotal, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $collectionId, array $queries, bool $includeTotal, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
@@ -85,12 +85,13 @@ class Create extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, array $attributes, array $indexes, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, array $attributes, array $indexes, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -64,12 +64,13 @@ class Delete extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
@@ -258,9 +258,9 @@ abstract class Action extends DatabasesAction
Document $collection,
Document $document,
Database $dbForProject,
/* options */
array &$collectionsCache,
Authorization $authorization,
?int &$operations = null,
): bool {
@@ -297,7 +297,7 @@ abstract class Action extends DatabasesAction
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
if (!isset($collectionsCache[$relatedCollectionId])) {
$relatedCollectionDoc = Authorization::skip(
$relatedCollectionDoc = $authorization->skip(
fn () => $dbForProject->getDocument(
'database_' . $database->getSequence(),
$relatedCollectionId
@@ -323,7 +323,8 @@ abstract class Action extends DatabasesAction
document: $relation,
dbForProject: $dbForProject,
collectionsCache: $collectionsCache,
operations: $operations
operations: $operations,
authorization: $authorization
);
}
}
@@ -85,20 +85,21 @@ class Decrement extends Action
->inject('queueForEvents')
->inject('queueForStatsUsage')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $documentId, string $attribute, int|float $value, int|float|null $min, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, array $plan): void
public function action(string $databaseId, string $collectionId, string $documentId, string $attribute, int|float $value, int|float|null $min, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, array $plan, Authorization $authorization): void
{
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty()) {
throw new Exception($this->getParentNotFoundException(), params: [$collectionId]);
}
@@ -106,7 +107,7 @@ class Decrement extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $authorization->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty() || $transaction->getAttribute('status', '') !== 'pending') {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid or nonpending transaction');
@@ -85,20 +85,21 @@ class Increment extends Action
->inject('queueForEvents')
->inject('queueForStatsUsage')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $documentId, string $attribute, int|float $value, int|float|null $max, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, array $plan): void
public function action(string $databaseId, string $collectionId, string $documentId, string $attribute, int|float $value, int|float|null $max, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, array $plan, Authorization $authorization): void
{
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty()) {
throw new Exception($this->getParentNotFoundException(), params: [$collectionId]);
}
@@ -106,7 +107,7 @@ class Increment extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $authorization->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty() || $transaction->getAttribute('status', '') !== 'pending') {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid or nonpending transaction');
@@ -24,6 +24,7 @@ use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Authorization\Input;
use Utopia\Database\Validator\Permissions;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
@@ -132,9 +133,10 @@ class Create extends Action
->inject('queueForFunctions')
->inject('queueForWebhooks')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, ?array $documents, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Document $user, Event $queueForEvents, StatsUsage $queueForStatsUsage, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void
public function action(string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, ?array $documents, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Document $user, Event $queueForEvents, StatsUsage $queueForStatsUsage, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan, Authorization $authorization): void
{
$data = \is_string($data)
? \json_decode($data, true)
@@ -178,19 +180,19 @@ class Create extends Action
$documents = [$data];
}
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
if ($isBulk && !$isAPIKey && !$isPrivilegedUser) {
throw new Exception(Exception::GENERAL_UNAUTHORIZED_SCOPE);
}
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException(), params: [$collectionId]);
}
@@ -204,7 +206,7 @@ class Create extends Action
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk create is not supported for ' . $this->getSDKNamespace() .' with relationship ' . $this->getStructureContext());
}
$setPermissions = function (Document $document, ?array $permissions) use ($user, $isAPIKey, $isPrivilegedUser, $isBulk) {
$setPermissions = function (Document $document, ?array $permissions) use ($user, $isAPIKey, $isPrivilegedUser, $isBulk, $dbForProject, $authorization) {
$allowedPermissions = [
Database::PERMISSION_READ,
Database::PERMISSION_UPDATE,
@@ -247,8 +249,8 @@ class Create extends Action
$permission->getIdentifier(),
$permission->getDimension()
))->toString();
if (!Authorization::isRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', Authorization::getRoles()) . ')');
if (!$authorization->hasRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $authorization->getRoles()) . ')');
}
}
}
@@ -259,21 +261,25 @@ class Create extends Action
$operations = 0;
$checkPermissions = function (Document $collection, Document $document, string $permission) use ($isAPIKey, $isPrivilegedUser, &$checkPermissions, $dbForProject, $database, &$operations) {
$checkPermissions = function (Document $collection, Document $document, string $permission) use ($isAPIKey, $isPrivilegedUser, &$checkPermissions, $dbForProject, $database, &$operations, $authorization) {
$operations++;
$documentSecurity = $collection->getAttribute('documentSecurity', false);
$validator = new Authorization($permission);
$valid = $validator->isValid($collection->getPermissionsByType($permission));
if (($permission === Database::PERMISSION_UPDATE && !$documentSecurity) || !$valid) {
throw new Exception(Exception::USER_UNAUTHORIZED);
$validCollection = $authorization->isValid(
new Input($permission, $collection->getPermissionsByType($permission))
);
if (($permission === Database::PERMISSION_UPDATE && !$documentSecurity) || !$validCollection) {
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
}
if ($permission === Database::PERMISSION_UPDATE) {
$valid = $valid || $validator->isValid($document->getUpdate());
$validDocument = $authorization->isValid(
new Input($permission, $document->getUpdate())
);
$valid = $validCollection || $validDocument;
if ($documentSecurity && !$valid) {
throw new Exception(Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
}
}
@@ -298,7 +304,7 @@ class Create extends Action
}
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
$relatedCollection = $authorization->skip(
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
);
@@ -314,7 +320,7 @@ class Create extends Action
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
$current = Authorization::skip(
$current = $authorization->skip(
fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(), $relation->getId())
);
@@ -369,7 +375,7 @@ class Create extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $authorization->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND, params: [$transactionId]);
@@ -468,6 +474,7 @@ class Create extends Action
document: $document,
dbForProject: $dbForProject,
collectionsCache: $collectionsCache,
authorization: $authorization
);
}
@@ -83,6 +83,7 @@ class Delete extends Action
->inject('queueForStatsUsage')
->inject('transactionState')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
@@ -97,18 +98,19 @@ class Delete extends Action
Event $queueForEvents,
StatsUsage $queueForStatsUsage,
TransactionState $transactionState,
array $plan
array $plan,
Authorization $authorization
): void {
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException(), params: [$collectionId]);
@@ -121,7 +123,7 @@ class Delete extends Action
// Use transaction-aware document retrieval to see changes from same transaction
$document = $transactionState->getDocument($collectionTableId, $documentId, $transactionId);
} else {
$document = Authorization::skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
$document = $authorization->skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
}
if ($document->isEmpty()) {
@@ -131,7 +133,7 @@ class Delete extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $authorization->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND, params: [$transactionId]);
@@ -205,6 +207,7 @@ class Delete extends Action
document: $document,
dbForProject: $dbForProject,
collectionsCache: $collectionsCache,
authorization: $authorization
);
$queueForStatsUsage
@@ -70,20 +70,21 @@ class Get extends Action
->inject('dbForProject')
->inject('queueForStatsUsage')
->inject('transactionState')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState): void
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState, Authorization $authorization): void
{
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException(), params: [$collectionId]);
@@ -125,6 +126,7 @@ class Get extends Action
document: $document,
dbForProject: $dbForProject,
collectionsCache: $collectionsCache,
authorization: $authorization,
operations: $operations
);
@@ -72,13 +72,14 @@ class XList extends Action
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('authorization')
->inject('audit')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $authorization, Audit $audit): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
@@ -87,10 +87,11 @@ class Update extends Action
->inject('queueForStatsUsage')
->inject('transactionState')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?string $transactionId, ?\DateTime $requestTimestamp, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, TransactionState $transactionState, array $plan): void
public function action(string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?string $transactionId, ?\DateTime $requestTimestamp, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, TransactionState $transactionState, array $plan, Authorization $authorization): void
{
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
@@ -98,16 +99,16 @@ class Update extends Action
throw new Exception($this->getMissingPayloadException());
}
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException(), params: [$collectionId]);
@@ -125,7 +126,7 @@ class Update extends Action
// Use transaction-aware document retrieval to see changes from same transaction
$document = $transactionState->getDocument($collectionTableId, $documentId, $transactionId);
} else {
$document = Authorization::skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
$document = $authorization->skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
}
if ($document->isEmpty()) {
@@ -140,7 +141,7 @@ class Update extends Action
]);
// Users can only manage their own roles, API keys and Admin users can manage any
$roles = Authorization::getRoles();
$roles = $authorization->getRoles();
if (!$isAPIKey && !$isPrivilegedUser && !\is_null($permissions)) {
foreach (Database::PERMISSIONS as $type) {
foreach ($permissions as $permission) {
@@ -153,7 +154,7 @@ class Update extends Action
$permission->getIdentifier(),
$permission->getDimension()
))->toString();
if (!Authorization::isRole($role)) {
if (!$authorization->hasRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
}
}
@@ -171,7 +172,7 @@ class Update extends Action
$operations = 0;
$setCollection = (function (Document $collection, Document $document) use ($isAPIKey, $isPrivilegedUser, &$setCollection, $dbForProject, $database, &$operations) {
$setCollection = (function (Document $collection, Document $document) use ($isAPIKey, $isPrivilegedUser, &$setCollection, $dbForProject, $database, &$operations, $authorization) {
$operations++;
$relationships = \array_filter(
@@ -195,7 +196,7 @@ class Update extends Action
}
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
$relatedCollection = $authorization->skip(
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
);
@@ -212,7 +213,7 @@ class Update extends Action
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
$oldDocument = Authorization::skip(fn () => $dbForProject->getDocument(
$oldDocument = $authorization->skip(fn () => $dbForProject->getDocument(
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
$relation->getId()
));
@@ -249,7 +250,7 @@ class Update extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $authorization->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND, params: [$transactionId]);
@@ -340,6 +341,7 @@ class Update extends Action
document: $document,
dbForProject: $dbForProject,
collectionsCache: $collectionsCache,
authorization: $authorization,
);
$response->dynamic($document, $this->getResponseModel());
@@ -91,10 +91,11 @@ class Upsert extends Action
->inject('queueForStatsUsage')
->inject('transactionState')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?string $transactionId, ?\DateTime $requestTimestamp, UtopiaResponse $response, Document $user, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, TransactionState $transactionState, array $plan): void
public function action(string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?string $transactionId, ?\DateTime $requestTimestamp, UtopiaResponse $response, Document $user, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, TransactionState $transactionState, array $plan, Authorization $authorization): void
{
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
@@ -106,15 +107,15 @@ class Upsert extends Action
throw new Exception($this->getMissingPayloadException());
}
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException(), params: [$collectionId]);
}
@@ -139,7 +140,7 @@ class Upsert extends Action
// Use transaction-aware document retrieval to see changes from same transaction
$oldDocument = $transactionState->getDocument($collectionTableId, $documentId, $transactionId);
} else {
$oldDocument = Authorization::skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
$oldDocument = $authorization->skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
}
if ($oldDocument->isEmpty()) {
if (!empty($user->getId())) {
@@ -155,7 +156,7 @@ class Upsert extends Action
}
// Users can only manage their own roles, API keys and Admin users can manage any
$roles = Authorization::getRoles();
$roles = $authorization->getRoles();
if (!$isAPIKey && !$isPrivilegedUser && !\is_null($permissions)) {
foreach (Database::PERMISSIONS as $type) {
foreach ($permissions as $permission) {
@@ -168,7 +169,7 @@ class Upsert extends Action
$permission->getIdentifier(),
$permission->getDimension()
))->toString();
if (!Authorization::isRole($role)) {
if (!$authorization->hasRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
}
}
@@ -181,7 +182,7 @@ class Upsert extends Action
$newDocument = new Document($data);
$operations = 0;
$setCollection = (function (Document $collection, Document $document) use ($isAPIKey, $isPrivilegedUser, &$setCollection, $dbForProject, $database, &$operations) {
$setCollection = (function (Document $collection, Document $document) use ($isAPIKey, $isPrivilegedUser, &$setCollection, $dbForProject, $database, &$operations, $authorization) {
$operations++;
$relationships = \array_filter(
@@ -205,7 +206,7 @@ class Upsert extends Action
}
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
$relatedCollection = $authorization->skip(
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
);
@@ -222,7 +223,7 @@ class Upsert extends Action
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
$oldDocument = Authorization::skip(fn () => $dbForProject->getDocument(
$oldDocument = $authorization->skip(fn () => $dbForProject->getDocument(
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
$relation->getId()
));
@@ -259,7 +260,7 @@ class Upsert extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $authorization->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND, params: [$transactionId]);
@@ -361,6 +362,7 @@ class Upsert extends Action
document: $document,
dbForProject: $dbForProject,
collectionsCache: $collectionsCache,
authorization: $authorization
);
$relationships = \array_map(
@@ -74,20 +74,21 @@ class XList extends Action
->inject('dbForProject')
->inject('queueForStatsUsage')
->inject('transactionState')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, array $queries, ?string $transactionId, bool $includeTotal, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState): void
public function action(string $databaseId, string $collectionId, array $queries, ?string $transactionId, bool $includeTotal, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState, Authorization $authorization): void
{
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException(), params: [$collectionId]);
}
@@ -115,7 +116,7 @@ class XList extends Action
$documentId = $cursor->getValue();
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId));
$cursorDocument = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId));
if ($cursorDocument->isEmpty()) {
$type = ucfirst($this->getContext());
@@ -161,7 +162,8 @@ class XList extends Action
document: $document,
dbForProject: $dbForProject,
collectionsCache: $collectionsCache,
operations: $operations,
authorization: $authorization,
operations: $operations
);
}
@@ -57,12 +57,13 @@ class Get extends Action
->param('collectionId', '', new UID(), 'Collection ID.')
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $collectionId, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -79,12 +79,13 @@ class Create extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, string $type, array $attributes, array $orders, array $lengths, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, string $type, array $attributes, array $orders, array $lengths, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -70,12 +70,13 @@ class Delete extends Action
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
{
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -59,12 +59,13 @@ class Get extends Action
->param('key', null, new Key(), 'Index Key.')
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -66,13 +66,14 @@ class XList extends Action
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, array $queries, bool $includeTotal, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $collectionId, array $queries, bool $includeTotal, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
/** @var Document $database */
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -112,7 +113,7 @@ class XList extends Action
}
$indexId = $cursor->getValue();
$cursorDocument = Authorization::skip(fn () => $dbForProject->find('indexes', [
$cursorDocument = $authorization->skip(fn () => $dbForProject->find('indexes', [
Query::equal('collectionInternalId', [$collection->getSequence()]),
Query::equal('databaseInternalId', [$database->getSequence()]),
Query::equal('key', [$indexId]),
@@ -71,13 +71,14 @@ class XList extends Action
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('authorization')
->inject('audit')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Authorization $authorization, Audit $audit): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -112,9 +113,9 @@ class XList extends Action
$detector = new Detector($log['userAgent']);
$detector->skipBotDetection(); // OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then)
$os = $detector->getOS();
$client = $detector->getClient();
$device = $detector->getDevice();
$os = $detector->getOS() ?: [];
$client = $detector->getClient() ?: [];
$device = $detector->getDevice() ?: [];
$output[$i] = new Document([
'event' => $log['event'],
@@ -122,20 +123,20 @@ class XList extends Action
'userEmail' => $log['data']['userEmail'] ?? null,
'userName' => $log['data']['userName'] ?? null,
'mode' => $log['data']['mode'] ?? null,
'ip' => $log['ip'],
'time' => $log['time'],
'osCode' => $os['osCode'],
'osName' => $os['osName'],
'osVersion' => $os['osVersion'],
'clientType' => $client['clientType'],
'clientCode' => $client['clientCode'],
'clientName' => $client['clientName'],
'clientVersion' => $client['clientVersion'],
'clientEngine' => $client['clientEngine'],
'clientEngineVersion' => $client['clientEngineVersion'],
'deviceName' => $device['deviceName'],
'deviceBrand' => $device['deviceBrand'],
'deviceModel' => $device['deviceModel']
'ip' => $log['ip'] ?? null,
'time' => $log['time'] ?? null,
'osCode' => $os['osCode'] ?? null,
'osName' => $os['osName'] ?? null,
'osVersion' => $os['osVersion'] ?? null,
'clientType' => $client['clientType'] ?? null,
'clientCode' => $client['clientCode'] ?? null,
'clientName' => $client['clientName'] ?? null,
'clientVersion' => $client['clientVersion'] ?? null,
'clientEngine' => $client['clientEngine'] ?? null,
'clientEngineVersion' => $client['clientEngineVersion'] ?? null,
'deviceName' => $device['deviceName'] ?? null,
'deviceBrand' => $device['deviceBrand'] ?? null,
'deviceModel' => $device['deviceModel'] ?? null
]);
$record = $geodb->get($log['ip']);
@@ -71,12 +71,13 @@ class Update extends Action
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
}
@@ -63,10 +63,11 @@ class Get extends Action
->param('collectionId', '', new UID(), 'Collection ID.')
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $range, string $collectionId, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $range, string $collectionId, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
$database = $dbForProject->getDocument('databases', $databaseId);
$collectionDocument = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
@@ -83,7 +84,7 @@ class Get extends Action
str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collectionDocument->getSequence()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS),
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -67,12 +67,13 @@ class XList extends Action
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, array $queries, string $search, bool $includeTotal, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, array $queries, string $search, bool $includeTotal, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]);
@@ -55,10 +55,11 @@ class Create extends Action
->inject('response')
->inject('dbForProject')
->inject('user')
->inject('authorization')
->callback($this->action(...));
}
public function action(int $ttl, UtopiaResponse $response, Database $dbForProject, Document $user): void
public function action(int $ttl, UtopiaResponse $response, Database $dbForProject, Document $user, Authorization $authorization): void
{
$permissions = [];
if (!empty($user->getId())) {
@@ -73,7 +74,7 @@ class Create extends Action
}
}
$transaction = Authorization::skip(fn () => $dbForProject->createDocument('transactions', new Document([
$transaction = $authorization->skip(fn () => $dbForProject->createDocument('transactions', new Document([
'$id' => ID::unique(),
'$permissions' => $permissions,
'status' => 'pending',
@@ -18,6 +18,7 @@ use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Authorization\Input;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\ArrayList;
@@ -63,21 +64,22 @@ class Create extends Action
->inject('dbForProject')
->inject('transactionState')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $transactionId, array $operations, UtopiaResponse $response, Database $dbForProject, TransactionState $transactionState, array $plan): void
public function action(string $transactionId, array $operations, UtopiaResponse $response, Database $dbForProject, TransactionState $transactionState, array $plan, Authorization $authorization): void
{
if (empty($operations)) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Operations array cannot be empty');
}
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
// API keys and admins can read any transaction, regular users need permissions
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $authorization->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND, params: [$transactionId]);
@@ -113,13 +115,13 @@ class Create extends Action
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$database = $databases[$operation['databaseId']] ??= Authorization::skip(fn () => $dbForProject->getDocument('databases', $operation['databaseId']));
$database = $databases[$operation['databaseId']] ??= $authorization->skip(fn () => $dbForProject->getDocument('databases', $operation['databaseId']));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$operation['databaseId']]);
}
$collection = $collections[$operation[$this->getGroupId()]] ??=
Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $operation[$this->getGroupId()]));
$authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $operation[$this->getGroupId()]));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::COLLECTION_NOT_FOUND, params: [$operation[$this->getGroupId()]]);
@@ -165,14 +167,20 @@ class Create extends Action
// For individual operations, enforce permissions unless using API key/admin
if (!$isAPIKey && !$isPrivilegedUser) {
$documentSecurity = $collection->getAttribute('documentSecurity', false);
$validator = new Authorization($permissionType);
$collectionValid = $validator->isValid($collection->getPermissionsByType($permissionType));
$collectionValid = $authorization->isValid(
new Input($permissionType, $collection->getPermissionsByType($permissionType))
);
$documentValid = false;
if ($document !== null && !$document->isEmpty() && $documentSecurity) {
if ($permissionType === Database::PERMISSION_UPDATE) {
$documentValid = $validator->isValid($document->getUpdate());
$documentValid = $authorization->isValid(
new Input(Database::PERMISSION_UPDATE, $document->getUpdate())
);
} elseif ($permissionType === Database::PERMISSION_DELETE) {
$documentValid = $validator->isValid($document->getDelete());
$documentValid = $authorization->isValid(
new Input(Database::PERMISSION_DELETE, $document->getDelete())
);
}
}
@@ -189,7 +197,7 @@ class Create extends Action
// Users can only set permissions for roles they have
if (isset($operation['data']['$permissions'])) {
$permissions = $operation['data']['$permissions'];
$roles = Authorization::getRoles();
$roles = $authorization->getRoles();
foreach (Database::PERMISSIONS as $type) {
foreach ($permissions as $permission) {
$permission = Permission::parse($permission);
@@ -201,7 +209,7 @@ class Create extends Action
$permission->getIdentifier(),
$permission->getDimension()
))->toString();
if (!Authorization::isRole($role)) {
if (!$authorization->hasRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
}
}
@@ -230,7 +238,7 @@ class Create extends Action
}
}
$transaction = Authorization::skip(fn () => $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged, $existing, $operations) {
$transaction = $authorization->skip(fn () => $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged, $existing, $operations) {
$dbForProject->createDocuments('transactionLogs', $staged);
return $dbForProject->increaseDocumentAttribute(
'transactions',
@@ -76,6 +76,7 @@ class Update extends Action
->inject('queueForRealtime')
->inject('queueForFunctions')
->inject('queueForWebhooks')
->inject('authorization')
->callback($this->action(...));
}
@@ -102,7 +103,7 @@ class Update extends Action
* @throws Structure
* @throws \Utopia\Exception
*/
public function action(string $transactionId, bool $commit, bool $rollback, UtopiaResponse $response, Database $dbForProject, Document $user, TransactionState $transactionState, Delete $queueForDeletes, Event $queueForEvents, StatsUsage $queueForStatsUsage, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks): void
public function action(string $transactionId, bool $commit, bool $rollback, UtopiaResponse $response, Database $dbForProject, Document $user, TransactionState $transactionState, Delete $queueForDeletes, Event $queueForEvents, StatsUsage $queueForStatsUsage, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, Authorization $authorization): void
{
if (!$commit && !$rollback) {
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Either commit or rollback must be true');
@@ -111,11 +112,11 @@ class Update extends Action
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Cannot commit and rollback at the same time');
}
$isAPIKey = User::isApp(Authorization::getRoles());
$isPrivilegedUser = User::isPrivileged(Authorization::getRoles());
$isAPIKey = User::isApp($authorization->getRoles());
$isPrivilegedUser = User::isPrivileged($authorization->getRoles());
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $authorization->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND, params: [$transactionId]);
@@ -138,12 +139,12 @@ class Update extends Action
$currentDocumentId = null;
try {
$dbForProject->withTransaction(function () use ($dbForProject, $transactionState, $queueForDeletes, $transactionId, &$transaction, &$operations, &$totalOperations, &$databaseOperations, &$currentDocumentId, $queueForEvents, $queueForStatsUsage, $queueForRealtime, $queueForFunctions, $queueForWebhooks) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$dbForProject->withTransaction(function () use ($dbForProject, $transactionState, $queueForDeletes, $transactionId, &$transaction, &$operations, &$totalOperations, &$databaseOperations, &$currentDocumentId, $queueForEvents, $queueForStatsUsage, $queueForRealtime, $queueForFunctions, $queueForWebhooks, $authorization) {
$authorization->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'committing',
])));
$operations = Authorization::skip(fn () => $dbForProject->find('transactionLogs', [
$operations = $authorization->skip(fn () => $dbForProject->find('transactionLogs', [
Query::equal('transactionInternalId', [$transaction->getSequence()]),
Query::orderAsc(),
Query::limit(PHP_INT_MAX),
@@ -167,7 +168,7 @@ class Update extends Action
}
if (!isset($collections[$collectionId])) {
$collections[$collectionId] = Authorization::skip(
$collections[$collectionId] = $authorization->skip(
fn () => $dbForProject->getCollection($collectionId)
);
}
@@ -232,7 +233,7 @@ class Update extends Action
}
}
$transaction = Authorization::skip(fn () => $dbForProject->updateDocument(
$transaction = $authorization->skip(fn () => $dbForProject->updateDocument(
'transactions',
$transactionId,
new Document(['status' => 'committed'])
@@ -243,33 +244,33 @@ class Update extends Action
->setDocument($transaction);
});
} catch (NotFoundException $e) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$authorization->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'failed',
])));
throw new Exception(Exception::DOCUMENT_NOT_FOUND, previous: $e, params: [$currentDocumentId ?? 'unknown']);
} catch (DuplicateException | ConflictException $e) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$authorization->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'failed',
])));
throw new Exception(Exception::TRANSACTION_CONFLICT, previous: $e);
} catch (StructureException $e) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$authorization->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'failed',
])));
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $e->getMessage());
} catch (LimitException $e) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$authorization->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'failed',
])));
throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED, $e->getMessage());
} catch (TransactionException $e) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$authorization->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'failed',
])));
throw new Exception(Exception::TRANSACTION_FAILED, $e->getMessage());
} catch (QueryException $e) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$authorization->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'failed',
])));
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
@@ -297,11 +298,11 @@ class Update extends Action
$data = $data->getArrayCopy();
}
$database = Authorization::skip(fn () => $dbForProject->findOne('databases', [
$database = $authorization->skip(fn () => $dbForProject->findOne('databases', [
Query::equal('$sequence', [$databaseInternalId])
]));
$collection = Authorization::skip(fn () => $dbForProject->findOne('database_' . $databaseInternalId, [
$collection = $authorization->skip(fn () => $dbForProject->findOne('database_' . $databaseInternalId, [
Query::equal('$sequence', [$collectionInternalId])
]));
@@ -393,7 +394,7 @@ class Update extends Action
}
if ($rollback) {
$transaction = Authorization::skip(fn () => $dbForProject->updateDocument(
$transaction = $authorization->skip(fn () => $dbForProject->updateDocument(
'transactions',
$transactionId,
new Document(['status' => 'failed'])
@@ -59,10 +59,11 @@ class Get extends Action
->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), 'Date range.', true)
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $databaseId, string $range, UtopiaResponse $response, Database $dbForProject): void
public function action(string $databaseId, string $range, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
$database = $dbForProject->getDocument('databases', $databaseId);
@@ -81,7 +82,7 @@ class Get extends Action
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES)
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -56,10 +56,11 @@ class XList extends Action
->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), 'Date range.', true)
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
public function action(string $range, UtopiaResponse $response, Database $dbForProject): void
public function action(string $range, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
{
$periods = Config::getParam('usage', []);
@@ -74,7 +75,7 @@ class XList extends Action
METRIC_DATABASES_OPERATIONS_WRITES,
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -60,6 +60,7 @@ class Create extends BooleanCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Update extends BooleanUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -62,6 +62,7 @@ class Create extends DatetimeCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -63,6 +63,7 @@ class Update extends DatetimeUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -58,6 +58,7 @@ class Delete extends AttributesDelete
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Create extends EmailCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -62,6 +62,7 @@ class Update extends EmailUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -64,6 +64,7 @@ class Create extends EnumCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -65,6 +65,7 @@ class Update extends EnumUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -63,6 +63,7 @@ class Create extends FloatCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -64,6 +64,7 @@ class Update extends FloatUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Get extends AttributesGet
->param('key', '', new Key(), 'Column Key.')
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Create extends IPCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -62,6 +62,7 @@ class Update extends IPUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -63,6 +63,7 @@ class Create extends IntegerCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -64,6 +64,7 @@ class Update extends IntegerUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Create extends LineCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -63,6 +63,7 @@ class Update extends LineUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Create extends PointCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -63,6 +63,7 @@ class Update extends PointUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Create extends PolygonCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -63,6 +63,7 @@ class Update extends PolygonUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -73,6 +73,7 @@ class Create extends RelationshipCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -65,6 +65,7 @@ class Update extends RelationshipUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -66,6 +66,7 @@ class Create extends StringCreate
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -65,6 +65,7 @@ class Update extends StringUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Create extends URLCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -62,6 +62,7 @@ class Update extends URLUpdate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -52,6 +52,7 @@ class XList extends AttributesXList
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -67,6 +67,7 @@ class Create extends CollectionCreate
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -55,6 +55,7 @@ class Delete extends CollectionDelete
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -50,6 +50,7 @@ class Get extends CollectionGet
->param('tableId', '', new UID(), 'Table ID.')
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -66,6 +66,8 @@ class Create extends IndexCreate
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -61,6 +61,7 @@ class Delete extends IndexDelete
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -52,6 +52,7 @@ class Get extends IndexGet
->param('key', null, new Key(), 'Index Key.')
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -54,6 +54,7 @@ class XList extends IndexXList
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
->inject('response')
->inject('dbForProject')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -50,6 +50,7 @@ class XList extends CollectionLogXList
->inject('dbForProject')
->inject('locale')
->inject('geodb')
->inject('authorization')
->inject('audit')
->callback($this->action(...));
}
@@ -66,6 +66,7 @@ class Delete extends DocumentsDelete
->inject('queueForFunctions')
->inject('queueForWebhooks')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -68,6 +68,7 @@ class Update extends DocumentsUpdate
->inject('queueForFunctions')
->inject('queueForWebhooks')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
}
@@ -68,6 +68,7 @@ class Upsert extends DocumentsUpsert
->inject('queueForFunctions')
->inject('queueForWebhooks')
->inject('plan')
->inject('authorization')
->callback($this->action(...));
}
}

Some files were not shown because too many files have changed in this diff Show More