Refactor authorization handling across multiple modules to use the new getAuthorization() method. Update CHANGES.md to reflect the change in usage worker authorization. Adjust composer.json to specify the correct version for utopia-php/database. Update plugin-api-version in composer.lock.

This commit is contained in:
shimon
2025-10-22 16:35:48 +03:00
parent 16a2dd0b27
commit 33f88fa5e0
91 changed files with 688 additions and 551 deletions
+2 -2
View File
@@ -453,11 +453,11 @@ class Auth
* @param Document $user
* @return array<string>
*/
public static function getRoles(Document $user): array
public static function getRoles(Document $user, Authorization $authorization): array
{
$roles = [];
if (!self::isPrivilegedUser(Authorization::getRoles()) && !self::isAppUser(Authorization::getRoles())) {
if (!self::isPrivilegedUser($authorization->getRoles()) && !self::isAppUser($authorization->getRoles())) {
if ($user->getId()) {
$roles[] = Role::user($user->getId())->toString();
$roles[] = Role::users()->toString();
+2 -2
View File
@@ -342,12 +342,12 @@ class TransactionState
*/
private function getTransactionState(string $transactionId): array
{
$transaction = Authorization::skip(fn () => $this->dbForProject->getDocument('transactions', $transactionId));
$transaction = $this->dbForProject->getAuthorization()->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->dbForProject->getAuthorization()->skip(fn () => $this->dbForProject->find('transactionLogs', [
Query::equal('transactionInternalId', [$transaction->getSequence()]),
Query::orderAsc(),
Query::limit(PHP_INT_MAX)
+3 -2
View File
@@ -99,8 +99,6 @@ abstract class Migration
public function __construct()
{
Authorization::disable();
Authorization::setDefaultStatus(false);
$this->collections = Config::getParam('collections', []);
@@ -135,6 +133,9 @@ abstract class Migration
$this->dbForPlatform = $dbForPlatform;
$this->getProjectDB = $getProjectDB;
$this->dbForPlatform->getAuthorization()->disable();
$this->dbForPlatform->getAuthorization()->setDefaultStatus(false);
return $this;
}
@@ -205,7 +205,7 @@ class Base extends Action
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain) : ID::unique();
Authorization::skip(
$dbForProject->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -231,7 +231,7 @@ class Base extends Action
$domain = "commit-" . substr($commitDetails['commitHash'], 0, 16) . ".{$sitesDomain}";
$ruleId = md5($domain);
try {
Authorization::skip(
$dbForProject->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -268,7 +268,7 @@ class Base extends Action
$domain = "branch-{$branchPrefix}-{$resourceProjectHash}.{$sitesDomain}";
$ruleId = md5($domain);
try {
Authorization::skip(
$dbForProject->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -124,7 +124,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 = $dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->findOne('rules', [
Query::equal('domain', [$value]),
]));
@@ -310,7 +310,7 @@ abstract class Action extends UtopiaAction
throw new Exception($this->getSpatialTypeNotSupportedException());
}
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -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 = !$dbForProject->getAuthorization()->skip(fn () => $dbForProject
->findOne('database_' . $db->getSequence() . '_collection_' . $collection->getSequence()))
->isEmpty();
@@ -474,7 +474,7 @@ abstract class Action extends UtopiaAction
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
{
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -72,7 +72,7 @@ class Delete extends Action
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
{
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
@@ -73,7 +73,7 @@ class Get extends Action
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
@@ -90,7 +90,7 @@ class Create extends Action
$key ??= $relatedCollectionId;
$twoWayKey ??= $collectionId;
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
@@ -67,7 +67,7 @@ class XList extends Action
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
@@ -82,7 +82,7 @@ class Create extends Action
public function action(string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -69,7 +69,7 @@ class Delete extends Action
public function action(string $databaseId, string $collectionId, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
@@ -297,7 +297,7 @@ abstract class Action extends AppwriteAction
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
if (!isset($collectionsCache[$relatedCollectionId])) {
$relatedCollectionDoc = Authorization::skip(
$relatedCollectionDoc = $dbForProject->getAuthorization()->skip(
fn () => $dbForProject->getDocument(
'database_' . $database->getSequence(),
$relatedCollectionId
@@ -89,15 +89,15 @@ class Decrement extends 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
{
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty()) {
throw new Exception($this->getParentNotFoundException());
}
@@ -105,7 +105,7 @@ class Decrement extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $dbForProject->getAuthorization()->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 non‑pending transaction');
@@ -89,15 +89,15 @@ class Increment extends 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
{
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty()) {
throw new Exception($this->getParentNotFoundException());
}
@@ -105,7 +105,7 @@ class Increment extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $dbForProject->getAuthorization()->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 non‑pending transaction');
@@ -23,7 +23,7 @@ use Utopia\Database\Exception\Structure as StructureException;
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;
@@ -177,19 +177,19 @@ class Create extends Action
$documents = [$data];
}
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
if ($isBulk && !$isAPIKey && !$isPrivilegedUser) {
throw new Exception(Exception::GENERAL_UNAUTHORIZED_SCOPE);
}
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException());
}
@@ -246,8 +246,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 (!$dbForProject->getAuthorization()->hasRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $dbForProject->getAuthorization()->getRoles()) . ')');
}
}
}
@@ -262,17 +262,17 @@ class Create extends Action
$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 = $dbForProject->getAuthorization()->isValid(new Input($permission, $collection->getPermissionsByType($permission)));
if (($permission === Database::PERMISSION_UPDATE && !$documentSecurity) || !$validCollection) {
throw new Exception(Exception::USER_UNAUTHORIZED, $dbForProject->getAuthorization()->getDescription());
}
if ($permission === Database::PERMISSION_UPDATE) {
$valid = $valid || $validator->isValid($document->getUpdate());
$validDocument= $dbForProject->getAuthorization()->isValid(new Input($permission, $document->getUpdate()));
$valid = $validCollection || $validDocument;
if ($documentSecurity && !$valid) {
throw new Exception(Exception::USER_UNAUTHORIZED);
throw new Exception(Exception::USER_UNAUTHORIZED, $dbForProject->getAuthorization()->getDescription());
}
}
@@ -297,7 +297,7 @@ class Create extends Action
}
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
$relatedCollection = $dbForProject->getAuthorization()->skip(
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
);
@@ -313,7 +313,7 @@ class Create extends Action
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
$current = Authorization::skip(
$current = $dbForProject->getAuthorization()->skip(
fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(), $relation->getId())
);
@@ -368,7 +368,7 @@ class Create extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND);
@@ -503,4 +503,4 @@ class Create extends Action
$this->getResponseModel()
);
}
}
}
@@ -98,16 +98,16 @@ class Delete extends Action
TransactionState $transactionState,
array $plan
): void {
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException());
@@ -120,7 +120,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 = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
}
if ($document->isEmpty()) {
@@ -130,7 +130,7 @@ class Delete extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND);
@@ -74,15 +74,15 @@ class Get extends Action
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState): void
{
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException());
@@ -78,7 +78,7 @@ class XList extends Action
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
@@ -97,16 +97,16 @@ class Update extends Action
throw new Exception($this->getMissingPayloadException());
}
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException());
@@ -120,7 +120,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 = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
}
if ($document->isEmpty()) {
@@ -135,7 +135,7 @@ class Update extends Action
]);
// Users can only manage their own roles, API keys and Admin users can manage any
$roles = Authorization::getRoles();
$roles = $dbForProject->getAuthorization()->getRoles();
if (!$isAPIKey && !$isPrivilegedUser && !\is_null($permissions)) {
foreach (Database::PERMISSIONS as $type) {
foreach ($permissions as $permission) {
@@ -148,7 +148,7 @@ class Update extends Action
$permission->getIdentifier(),
$permission->getDimension()
))->toString();
if (!Authorization::isRole($role)) {
if (!$dbForProject->getAuthorization()->hasRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
}
}
@@ -190,7 +190,7 @@ class Update extends Action
}
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
$relatedCollection = $dbForProject->getAuthorization()->skip(
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
);
@@ -207,7 +207,7 @@ class Update extends Action
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
$oldDocument = Authorization::skip(fn () => $dbForProject->getDocument(
$oldDocument = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument(
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
$relation->getId()
));
@@ -245,7 +245,7 @@ class Update extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND);
@@ -105,15 +105,15 @@ class Upsert extends Action
throw new Exception($this->getMissingPayloadException());
}
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException());
}
@@ -134,7 +134,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 = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId));
}
if ($oldDocument->isEmpty()) {
if (!empty($user->getId())) {
@@ -150,7 +150,7 @@ class Upsert extends Action
}
// Users can only manage their own roles, API keys and Admin users can manage any
$roles = Authorization::getRoles();
$roles = $dbForProject->getAuthorization()->getRoles();
if (!$isAPIKey && !$isPrivilegedUser && !\is_null($permissions)) {
foreach (Database::PERMISSIONS as $type) {
foreach ($permissions as $permission) {
@@ -163,7 +163,7 @@ class Upsert extends Action
$permission->getIdentifier(),
$permission->getDimension()
))->toString();
if (!Authorization::isRole($role)) {
if (!$dbForProject->getAuthorization()->hasRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
}
}
@@ -200,7 +200,7 @@ class Upsert extends Action
}
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
$relatedCollection = Authorization::skip(
$relatedCollection = $dbForProject->getAuthorization()->skip(
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
);
@@ -217,7 +217,7 @@ class Upsert extends Action
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
$oldDocument = Authorization::skip(fn () => $dbForProject->getDocument(
$oldDocument = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument(
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
$relation->getId()
));
@@ -254,7 +254,7 @@ class Upsert extends Action
// Handle transaction staging
if ($transactionId !== null) {
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND);
@@ -76,15 +76,15 @@ class XList extends Action
public function action(string $databaseId, string $collectionId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState): void
{
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception($this->getParentNotFoundException());
}
@@ -112,7 +112,7 @@ class XList extends Action
$documentId = $cursor->getValue();
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId));
$cursorDocument = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId));
if ($cursorDocument->isEmpty()) {
$type = ucfirst($this->getContext());
@@ -62,7 +62,7 @@ class Get extends Action
public function action(string $databaseId, string $collectionId, UtopiaResponse $response, Database $dbForProject): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -84,7 +84,7 @@ class Create extends 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
{
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -75,7 +75,7 @@ class Delete extends Action
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents): void
{
$db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$db = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($db->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -64,7 +64,7 @@ class Get extends Action
public function action(string $databaseId, string $collectionId, string $key, UtopiaResponse $response, Database $dbForProject): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -70,7 +70,7 @@ class XList extends Action
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject): void
{
/** @var Document $database */
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -110,7 +110,7 @@ class XList extends Action
}
$indexId = $cursor->getValue();
$cursorDocument = Authorization::skip(fn () => $dbForProject->find('indexes', [
$cursorDocument = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->find('indexes', [
Query::equal('collectionInternalId', [$collection->getSequence()]),
Query::equal('databaseInternalId', [$database->getSequence()]),
Query::equal('key', [$indexId]),
@@ -77,7 +77,7 @@ class XList extends Action
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -75,7 +75,7 @@ class Update extends Action
public function action(string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
@@ -83,7 +83,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) {
$dbForProject->getAuthorization()->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -70,7 +70,7 @@ class XList extends Action
public function action(string $databaseId, array $queries, string $search, UtopiaResponse $response, Database $dbForProject): void
{
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
@@ -73,7 +73,7 @@ class Create extends Action
}
}
$transaction = Authorization::skip(fn () => $dbForProject->createDocument('transactions', new Document([
$transaction = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->createDocument('transactions', new Document([
'$id' => ID::unique(),
'$permissions' => $permissions,
'status' => 'pending',
@@ -17,7 +17,7 @@ use Utopia\Database\Document;
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;
@@ -72,12 +72,12 @@ class Create extends Action
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Operations array cannot be empty');
}
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
// API keys and admins can read any transaction, regular users need permissions
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND);
@@ -113,13 +113,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']] ??= $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('databases', $operation['databaseId']));
if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $collections[$operation[$this->getGroupId()]] ??=
Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $operation[$this->getGroupId()]));
$dbForProject->getAuthorization()->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);
@@ -165,8 +165,10 @@ 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 = $dbForProject->getAuthorization()->isValid(
new input($permissionType, $collection->getPermissionsByType($permissionType))
);
$documentValid = false;
if ($document !== null && !$document->isEmpty() && $documentSecurity) {
if ($permissionType === Database::PERMISSION_UPDATE) {
@@ -189,7 +191,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 = $dbForProject->getAuthorization()->getRoles();
foreach (Database::PERMISSIONS as $type) {
foreach ($permissions as $permission) {
$permission = Permission::parse($permission);
@@ -201,7 +203,7 @@ class Create extends Action
$permission->getIdentifier(),
$permission->getDimension()
))->toString();
if (!Authorization::isRole($role)) {
if (!$dbForProject->getAuthorization()->hasRole($role)) {
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
}
}
@@ -230,7 +232,7 @@ class Create extends Action
}
}
$transaction = Authorization::skip(fn () => $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged, $existing, $operations) {
$transaction = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged, $existing, $operations) {
$dbForProject->createDocuments('transactionLogs', $staged);
return $dbForProject->increaseDocumentAttribute(
'transactions',
@@ -111,11 +111,11 @@ class Update extends Action
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Cannot commit and rollback at the same time');
}
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
$transaction = ($isAPIKey || $isPrivilegedUser)
? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
? $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('transactions', $transactionId))
: $dbForProject->getDocument('transactions', $transactionId);
if ($transaction->isEmpty()) {
throw new Exception(Exception::TRANSACTION_NOT_FOUND);
@@ -138,11 +138,11 @@ class Update extends Action
try {
$dbForProject->withTransaction(function () use ($dbForProject, $transactionState, $queueForDeletes, $transactionId, &$transaction, &$operations, &$totalOperations, &$databaseOperations, $queueForEvents, $queueForStatsUsage, $queueForRealtime, $queueForFunctions, $queueForWebhooks) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$dbForProject->getAuthorization()->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'committing',
])));
$operations = Authorization::skip(fn () => $dbForProject->find('transactionLogs', [
$operations = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->find('transactionLogs', [
Query::equal('transactionInternalId', [$transaction->getSequence()]),
Query::orderAsc(),
Query::limit(PHP_INT_MAX),
@@ -218,7 +218,7 @@ class Update extends Action
}
}
$transaction = Authorization::skip(fn () => $dbForProject->updateDocument(
$transaction = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->updateDocument(
'transactions',
$transactionId,
new Document(['status' => 'committed'])
@@ -230,32 +230,32 @@ class Update extends Action
});
} catch (NotFoundException $e) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$dbForProject->getAuthorization()->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'failed',
])));
throw new Exception(Exception::DOCUMENT_NOT_FOUND, previous: $e);
} catch (DuplicateException|ConflictException $e) {
Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
$dbForProject->getAuthorization()->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([
$dbForProject->getAuthorization()->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([
$dbForProject->getAuthorization()->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([
$dbForProject->getAuthorization()->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([
$dbForProject->getAuthorization()->skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([
'status' => 'failed',
])));
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
@@ -283,11 +283,11 @@ class Update extends Action
$data = $data->getArrayCopy();
}
$database = Authorization::skip(fn () => $dbForProject->findOne('databases', [
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->findOne('databases', [
Query::equal('$sequence', [$databaseInternalId])
]));
$collection = Authorization::skip(fn () => $dbForProject->findOne('database_' . $databaseInternalId, [
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->findOne('database_' . $databaseInternalId, [
Query::equal('$sequence', [$collectionInternalId])
]));
@@ -379,7 +379,7 @@ class Update extends Action
}
if ($rollback) {
$transaction = Authorization::skip(fn () => $dbForProject->updateDocument(
$transaction = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->updateDocument(
'transactions',
$transactionId,
new Document(['status' => 'failed'])
@@ -81,7 +81,7 @@ class Get extends Action
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES)
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$dbForProject->getAuthorization()->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -74,7 +74,7 @@ class XList extends Action
METRIC_DATABASES_OPERATIONS_WRITES,
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$dbForProject->getAuthorization()->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -26,7 +26,7 @@ use Utopia\Database\Document;
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\Datetime as DatetimeValidator;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
@@ -152,10 +152,10 @@ class Create extends Base
throw new Exception($validator->getDescription(), 400);
}
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
$function = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('functions', $functionId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRole);
if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::FUNCTION_NOT_FOUND);
@@ -171,7 +171,7 @@ class Create extends Base
throw new Exception(Exception::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported');
}
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deploymentId', '')));
$deployment = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deploymentId', '')));
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
@@ -185,10 +185,8 @@ class Create extends Base
throw new Exception(Exception::BUILD_NOT_READY);
}
$validator = new Authorization('execute');
if (!$validator->isValid($function->getAttribute('execute'))) { // Check if user has write access to execute function
throw new Exception(Exception::USER_UNAUTHORIZED, $validator->getDescription());
if (!$dbForProject->getAuthorization()->isValid(new Input('execute', $function->getAttribute('execute')))) { // Check if user has write access to execute function
throw new Exception(Exception::USER_UNAUTHORIZED, $dbForProject->getAuthorization()->getDescription());
}
$jwt = ''; // initialize
@@ -286,7 +284,7 @@ class Create extends Base
if ($async) {
if (is_null($scheduledAt)) {
$execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution));
$execution = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->createDocument('executions', $execution));
$queueForFunctions
->setType('http')
->setExecution($execution)
@@ -327,7 +325,7 @@ class Create extends Base
->setAttribute('scheduleInternalId', $schedule->getSequence())
->setAttribute('scheduledAt', $scheduledAt);
$execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution));
$execution = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->createDocument('executions', $execution));
}
return $response
@@ -480,7 +478,7 @@ class Create extends Base
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS), (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
;
$execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution));
$execution = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->createDocument('executions', $execution));
}
$executionResponse['headers']['x-appwrite-execution-id'] = $execution->getId();
@@ -108,7 +108,7 @@ class Delete extends Base
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('active', false);
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
}
}
@@ -61,10 +61,10 @@ class Get extends Base
Response $response,
Database $dbForProject
) {
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
$function = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('functions', $functionId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::FUNCTION_NOT_FOUND);
@@ -67,10 +67,10 @@ class XList extends Base
Response $response,
Database $dbForProject
) {
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
$function = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('functions', $functionId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::FUNCTION_NOT_FOUND);
@@ -237,7 +237,7 @@ class Create extends Base
throw new Exception(Exception::FUNCTION_ALREADY_EXISTS);
}
$schedule = Authorization::skip(
$schedule = $dbForProject->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('schedules', new Document([
'region' => $project->getAttribute('region'),
'resourceType' => SCHEDULE_RESOURCE_TYPE_FUNCTION,
@@ -365,7 +365,7 @@ class Create extends Base
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain) : ID::unique();
$rule = Authorization::skip(
$rule = $dbForPlatform->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -87,7 +87,7 @@ class Delete extends Base
$schedule
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('active', false);
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$queueForDeletes
->setType(DELETE_TYPE_DOCUMENT)
@@ -101,7 +101,7 @@ class Update extends Base
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('schedule', $function->getAttribute('schedule'))
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deploymentId')));
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$queries = [
Query::equal('trigger', ['manual']),
@@ -112,12 +112,12 @@ class Update extends Base
Query::equal('projectInternalId', [$project->getSequence()])
];
Authorization::skip(fn () => $dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getSequence());
Authorization::skip(fn () => $dbForPlatform->updateDocument('rules', $rule->getId(), $rule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('rules', $rule->getId(), $rule));
}, $queries));
$queueForEvents
@@ -282,7 +282,7 @@ class Update extends Base
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('schedule', $function->getAttribute('schedule'))
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deploymentId')));
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$queueForEvents->setParam('functionId', $function->getId());
@@ -83,7 +83,7 @@ class Get extends Base
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_FAILED),
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$dbForProject->getAuthorization()->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -75,7 +75,7 @@ class XList extends Base
str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_BUILDS_FAILED),
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$dbForProject->getAuthorization()->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -119,7 +119,7 @@ class Create extends Base
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('schedule', $function->getAttribute('schedule'))
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deploymentId')));
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
@@ -92,7 +92,7 @@ class Delete extends Base
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('schedule', $function->getAttribute('schedule'))
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deploymentId')));
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$response->noContent();
}
@@ -109,7 +109,7 @@ class Update extends Base
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('schedule', $function->getAttribute('schedule'))
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deploymentId')));
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$response->dynamic($variable, Response::MODEL_VARIABLE);
}
@@ -916,7 +916,7 @@ class Builds extends Action
->trigger();
try {
$rule = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
$rule = $dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->findOne('rules', [
Query::equal("projectInternalId", [$project->getSequence()]),
Query::equal("type", ["deployment"]),
Query::equal('deploymentInternalId', [$deployment->getSequence()]),
@@ -930,7 +930,7 @@ class Builds extends Action
$client->setTimeout(\intval($resource->getAttribute('timeout', '15')));
$client->addHeader('content-type', FetchClient::CONTENT_TYPE_APPLICATION_JSON);
$bucket = Authorization::skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots'));
$bucket = $dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots'));
$configs = [
'screenshotLight' => [
@@ -1052,7 +1052,7 @@ class Builds extends Action
'metadata' => ['content_type' => $mimeType],
]);
Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getSequence(), $file));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getSequence(), $file));
$deployment->setAttribute($key, $fileId);
}
@@ -1275,7 +1275,7 @@ class Builds extends Action
->setAttribute('resourceUpdatedAt', DateTime::now())
->setAttribute('schedule', $resource->getAttribute('schedule'))
->setAttribute('active', !empty($resource->getAttribute('schedule')) && !empty($resource->getAttribute('deploymentId')));
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
}
Console::info('Deployment action finished');
@@ -1570,7 +1570,7 @@ class Builds extends Action
default => throw new \Exception('Invalid resource type')
};
$rule = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
$rule = $dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->findOne('rules', [
Query::equal("projectInternalId", [$project->getSequence()]),
Query::equal("type", ["deployment"]),
Query::equal("deploymentInternalId", [$deployment->getSequence()]),
@@ -274,7 +274,7 @@ class Create extends Action
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain) : ID::unique();
Authorization::skip(
$dbForPlatform->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -339,7 +339,7 @@ class Create extends Action
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
$ruleId = md5($domain);
Authorization::skip(
$dbForPlatform->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -146,7 +146,7 @@ class Create extends Action
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain) : ID::unique();
Authorization::skip(
$dbForPlatform->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -176,7 +176,7 @@ class Create extends Base
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain) : ID::unique();
Authorization::skip(
$dbForPlatform->getAuthorization()->skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
@@ -104,12 +104,12 @@ class Update extends Base
Query::equal('projectInternalId', [$project->getSequence()])
];
Authorization::skip(fn () => $dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getSequence());
Authorization::skip(fn () => $dbForPlatform->updateDocument('rules', $rule->getId(), $rule));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('rules', $rule->getId(), $rule));
}, $queries));
$queueForEvents
@@ -91,7 +91,7 @@ class Get extends Base
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$dbForProject->getAuthorization()->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -78,7 +78,7 @@ class XList extends Base
METRIC_SITES_OUTBOUND,
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
$dbForProject->getAuthorization()->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$result = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
@@ -5,33 +5,31 @@ namespace Appwrite\Platform\Modules\Tokens\Http\Tokens\Buckets\Files;
use Appwrite\Auth\Auth;
use Appwrite\Extend\Exception;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Authorization\Input;
use Utopia\Platform\Action as UtopiaAction;
class Action extends UtopiaAction
{
protected function getFileAndBucket(Database $dbForProject, string $bucketId, string $fileId): array
{
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$bucket = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$isAPIKey = Auth::isAppUser($dbForProject->getAuthorization()->getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser($dbForProject->getAuthorization()->getRoles());
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$validator = new Authorization(Database::PERMISSION_READ);
$valid = $validator->isValid($bucket->getRead());
if (!$valid) {
throw new Exception(Exception::USER_UNAUTHORIZED);
if (!$dbForProject->getAuthorization()->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()))){
throw new Exception(Exception::USER_UNAUTHORIZED, $dbForProject->getAuthorization()->getDescription());
}
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
if ($fileSecurity) {
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
} else {
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
$file = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
}
if ($file->isEmpty()) {
@@ -13,7 +13,7 @@ use Appwrite\Utopia\Response;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Authorization\Input;
use Utopia\Database\Validator\Datetime as DatetimeValidator;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Scope\HTTP;
@@ -78,11 +78,10 @@ class Create extends Action
['bucket' => $bucket, 'file' => $file] = $this->getFileAndBucket($dbForProject, $bucketId, $fileId);
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
$validator = new Authorization(Database::PERMISSION_UPDATE);
$bucketPermission = $validator->isValid($bucket->getUpdate());
$bucketPermission = $dbForProject->getAuthorization()->isValid(new Input(Database::PERMISSION_UPDATE, $bucket->getUpdate()));
if ($fileSecurity) {
$filePermission = $validator->isValid($file->getUpdate());
$filePermission = $dbForProject->getAuthorization()->isValid(new Input(Database::PERMISSION_UPDATE, $file->getUpdate()));
if (!$bucketPermission && !$filePermission) {
throw new Exception(Exception::USER_UNAUTHORIZED);
}
+1 -1
View File
@@ -48,7 +48,7 @@ class Migrate extends Action
callable $getProjectDB,
Registry $register,
): void {
Authorization::disable();
$dbForPlatform->getAuthorization()->disable();
if (!\array_key_exists($version, Migration::$versions)) {
Console::error("No migration found for version $version.");
+1 -1
View File
@@ -62,7 +62,7 @@ abstract class ScheduleBase extends Action
$accessedAt = $project->getAttribute('accessedAt', 0);
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $accessedAt) {
$project->setAttribute('accessedAt', DateTime::now());
Authorization::skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
}
}
}
@@ -61,9 +61,9 @@ class StatsResources extends Action
$interval = (int) System::getEnv('_APP_STATS_RESOURCES_INTERVAL', '3600');
Console::loop(function () use ($queue) {
Authorization::disable();
Authorization::setDefaultStatus(false);
Console::loop(function () use ($queue, $dbForPlatform) {
$dbForPlatform->getAuthorization()->disable();
$dbForPlatform->getAuthorization()->setDefaultStatus(false);
$last24Hours = (new \DateTime())->sub(\DateInterval::createFromDateString('24 hours'));
/**
+2 -2
View File
@@ -954,14 +954,14 @@ class Deletes extends Action
}
Console::info("Deleting screenshots for deployment " . $deployment->getId());
$bucket = ValidatorAuthorization::skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots'));
$bucket = $dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots'));
if ($bucket->isEmpty()) {
Console::error('Failed to get bucket for deployment screenshots');
return;
}
foreach ($screenshotIds as $id) {
$file = ValidatorAuthorization::skip(fn () => $dbForPlatform->getDocument('bucket_' . $bucket->getSequence(), $id));
$file = $dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->getDocument('bucket_' . $bucket->getSequence(), $id));
if ($file->isEmpty()) {
Console::error('Failed to get deployment screenshot: ' . $id);
+8 -1
View File
@@ -210,7 +210,7 @@ class Request extends UtopiaRequest
{
$forwardedUserAgent = $this->getHeader('x-forwarded-user-agent');
if (!empty($forwardedUserAgent)) {
$roles = Authorization::getRoles();
$roles = $this->authorization->getRoles();
$isAppUser = Auth::isAppUser($roles);
if ($isAppUser) {
@@ -233,4 +233,11 @@ class Request extends UtopiaRequest
ksort($params);
return md5($this->getURI() . '*' . serialize($params) . '*' . APP_CACHE_BUSTER);
}
private Authorization $authorization;
public function setAuthorization(Authorization $authorization): void
{
$this->authorization = $authorization;
}
}
+2 -2
View File
@@ -139,7 +139,7 @@ class V20 extends Filter
}
try {
$database = Authorization::skip(fn () => $dbForProject->getDocument(
$database = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument(
'databases',
$databaseId
));
@@ -151,7 +151,7 @@ class V20 extends Filter
}
try {
$collection = Authorization::skip(fn () => $dbForProject->getDocument(
$collection = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->getDocument(
'database_' . $database->getSequence(),
$collectionId
));
+8 -1
View File
@@ -809,7 +809,7 @@ class Response extends SwooleResponse
}
if ($rule['sensitive']) {
$roles = Authorization::getRoles();
$roles = $this->authorization->getRoles();
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
$isAppUser = Auth::isAppUser($roles);
@@ -977,4 +977,11 @@ class Response extends SwooleResponse
self::$showSensitive = false;
}
}
private Authorization $authorization;
public function setAuthorization(Authorization $authorization): void
{
$this->authorization = $authorization;
}
}