From 27370b6acbd53ad66d64994be9018e81a12ac43c Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 18 May 2026 03:27:34 +0000 Subject: [PATCH 1/5] feat!: rename ACTIVITY_TYPE_* constants to ACTOR_TYPE_* Renames the actor identity constants used by the audit/auth flow: - ACTIVITY_TYPE_USER -> ACTOR_TYPE_USER ('user') - ACTIVITY_TYPE_ADMIN -> ACTOR_TYPE_ADMIN ('admin') - ACTIVITY_TYPE_GUEST -> ACTOR_TYPE_GUEST ('guest') - ACTIVITY_TYPE_KEY_PROJECT -> ACTOR_TYPE_KEY_PROJECT ('keyProject') - ACTIVITY_TYPE_KEY_ACCOUNT -> ACTOR_TYPE_KEY_ACCOUNT ('keyAccount') - ACTIVITY_TYPE_KEY_ORGANIZATION -> ACTOR_TYPE_KEY_ORGANIZATION ('keyOrganization') Values are unchanged. Call sites updated in: - app/controllers/shared/api.php - src/Appwrite/Platform/Workers/Audits.php Audit payload key rename (userType -> actorType) and utopia-php/audit bump will land in a follow-up PR. BREAKING CHANGE: ACTIVITY_TYPE_* global constants are removed. Any downstream extension or plugin importing those names must be updated to the ACTOR_TYPE_* equivalents. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/controllers/shared/api.php | 14 +++++++------- app/init/constants.php | 14 +++++++------- src/Appwrite/Platform/Workers/Audits.php | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index f2373572b7..2ee601f685 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -186,7 +186,7 @@ Http::init() $user = new User([ '$id' => '', 'status' => true, - 'type' => ACTIVITY_TYPE_KEY_PROJECT, + 'type' => ACTOR_TYPE_KEY_PROJECT, 'email' => 'app.' . $project->getId() . '@service.' . $request->getHostname(), 'password' => '', 'name' => $apiKey->getName(), @@ -258,9 +258,9 @@ Http::init() $userClone = clone $user; $userClone->setAttribute('type', match ($apiKey->getType()) { - API_KEY_STANDARD => ACTIVITY_TYPE_KEY_PROJECT, - API_KEY_ACCOUNT => ACTIVITY_TYPE_KEY_ACCOUNT, - default => ACTIVITY_TYPE_KEY_ORGANIZATION, + API_KEY_STANDARD => ACTOR_TYPE_KEY_PROJECT, + API_KEY_ACCOUNT => ACTOR_TYPE_KEY_ACCOUNT, + default => ACTOR_TYPE_KEY_ORGANIZATION, }); $auditContext->user = $userClone; } @@ -602,7 +602,7 @@ Http::init() $userClone = clone $user; // $user doesn't support `type` and can cause unintended effects. if (empty($user->getAttribute('type'))) { - $userClone->setAttribute('type', $mode === APP_MODE_ADMIN ? ACTIVITY_TYPE_ADMIN : ACTIVITY_TYPE_USER); + $userClone->setAttribute('type', $mode === APP_MODE_ADMIN ? ACTOR_TYPE_ADMIN : ACTOR_TYPE_USER); } $auditContext->user = $userClone; } @@ -913,7 +913,7 @@ Http::shutdown() $userClone = clone $user; // $user doesn't support `type` and can cause unintended effects. if (empty($user->getAttribute('type'))) { - $userClone->setAttribute('type', $mode === APP_MODE_ADMIN ? ACTIVITY_TYPE_ADMIN : ACTIVITY_TYPE_USER); + $userClone->setAttribute('type', $mode === APP_MODE_ADMIN ? ACTOR_TYPE_ADMIN : ACTOR_TYPE_USER); } $auditContext->user = $userClone; } elseif ($auditContext->user === null || $auditContext->user->isEmpty()) { @@ -928,7 +928,7 @@ Http::shutdown() $user = new User([ '$id' => '', 'status' => true, - 'type' => ACTIVITY_TYPE_GUEST, + 'type' => ACTOR_TYPE_GUEST, 'email' => 'guest.' . $project->getId() . '@service.' . $request->getHostname(), 'password' => '', 'name' => 'Guest', diff --git a/app/init/constants.php b/app/init/constants.php index b271b56a14..4bb607e2fb 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -159,14 +159,14 @@ const SESSION_PROVIDER_TOKEN = 'token'; const SESSION_PROVIDER_SERVER = 'server'; /** - * Activity associated with user or the app. + * Actor that performed the request (user, admin, guest, or API key). */ -const ACTIVITY_TYPE_USER = 'user'; -const ACTIVITY_TYPE_ADMIN = 'admin'; -const ACTIVITY_TYPE_GUEST = 'guest'; -const ACTIVITY_TYPE_KEY_PROJECT = 'keyProject'; -const ACTIVITY_TYPE_KEY_ACCOUNT = 'keyAccount'; -const ACTIVITY_TYPE_KEY_ORGANIZATION = 'keyOrganization'; +const ACTOR_TYPE_USER = 'user'; +const ACTOR_TYPE_ADMIN = 'admin'; +const ACTOR_TYPE_GUEST = 'guest'; +const ACTOR_TYPE_KEY_PROJECT = 'keyProject'; +const ACTOR_TYPE_KEY_ACCOUNT = 'keyAccount'; +const ACTOR_TYPE_KEY_ORGANIZATION = 'keyOrganization'; /** * MFA diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index f6b0345381..07d91ce009 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -91,7 +91,7 @@ class Audits extends Action $actorUserEmail = $impersonatorUserId ? $user->getAttribute('impersonatorUserEmail', '') : $user->getAttribute('email', ''); - $userType = $user->getAttribute('type', ACTIVITY_TYPE_USER); + $userType = $user->getAttribute('type', ACTOR_TYPE_USER); // Create event data $eventData = [ From 5f1e537e5355f17239d03bb4c1772acb94fa15c6 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 18 May 2026 04:55:01 +0000 Subject: [PATCH 2/5] chore: bump utopia-php/audit to ^2.4 --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 082063bb32..3ddd6ae119 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,7 @@ "utopia-php/abuse": "1.3.*", "utopia-php/agents": "1.2.*", "utopia-php/analytics": "0.15.*", - "utopia-php/audit": "2.3.*", + "utopia-php/audit": "^2.4", "utopia-php/auth": "0.5.*", "utopia-php/cache": "^3.0", "utopia-php/cli": "0.23.*", diff --git a/composer.lock b/composer.lock index 79b7db5389..661558b63c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fafd8dc07538185b1753e9c16b622002", + "content-hash": "b092fffec11494aea10b0c823b7837b8", "packages": [ { "name": "adhocore/jwt", @@ -3510,16 +3510,16 @@ }, { "name": "utopia-php/audit", - "version": "2.3.2", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "e7b4049fc2ee9be34bcc18771fa593db3b0e9fe3" + "reference": "eddd79d93f23ed2851c0df2b1e2e2dfb25ba06c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/e7b4049fc2ee9be34bcc18771fa593db3b0e9fe3", - "reference": "e7b4049fc2ee9be34bcc18771fa593db3b0e9fe3", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/eddd79d93f23ed2851c0df2b1e2e2dfb25ba06c6", + "reference": "eddd79d93f23ed2851c0df2b1e2e2dfb25ba06c6", "shasum": "" }, "require": { @@ -3554,9 +3554,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/2.3.2" + "source": "https://github.com/utopia-php/audit/tree/2.4.1" }, - "time": "2026-05-14T04:00:37+00:00" + "time": "2026-05-20T06:25:45+00:00" }, { "name": "utopia-php/auth", From ce31a4f33621b5cc947be482976fdddb1a344eb0 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 18 May 2026 05:34:54 +0000 Subject: [PATCH 3/5] feat!: rename User::ROLE_APPS to ROLE_KEYS and isApp() to isKey() --- app/config/roles.php | 2 +- app/controllers/api/graphql.php | 2 +- app/controllers/shared/api.php | 12 +++---- app/controllers/shared/api/auth.php | 2 +- app/realtime.php | 2 +- src/Appwrite/Auth/Key.php | 6 ++-- .../Documents/Attribute/Decrement.php | 2 +- .../Documents/Attribute/Increment.php | 2 +- .../Collections/Documents/Create.php | 2 +- .../Collections/Documents/Delete.php | 2 +- .../Databases/Collections/Documents/Get.php | 2 +- .../Collections/Documents/Update.php | 2 +- .../Collections/Documents/Upsert.php | 2 +- .../Databases/Collections/Documents/XList.php | 2 +- .../Transactions/Operations/Create.php | 2 +- .../Http/Databases/Transactions/Update.php | 2 +- .../Functions/Http/Executions/Create.php | 2 +- .../Modules/Functions/Http/Executions/Get.php | 2 +- .../Functions/Http/Executions/XList.php | 2 +- .../Storage/Http/Buckets/Files/Create.php | 2 +- .../Storage/Http/Buckets/Files/Delete.php | 2 +- .../Http/Buckets/Files/Download/Get.php | 2 +- .../Storage/Http/Buckets/Files/Get.php | 2 +- .../Http/Buckets/Files/Preview/Get.php | 2 +- .../Storage/Http/Buckets/Files/Push/Get.php | 2 +- .../Storage/Http/Buckets/Files/Update.php | 4 +-- .../Storage/Http/Buckets/Files/View/Get.php | 2 +- .../Storage/Http/Buckets/Files/XList.php | 2 +- .../Modules/Teams/Http/Memberships/Create.php | 2 +- .../Modules/Teams/Http/Memberships/Get.php | 2 +- .../Modules/Teams/Http/Memberships/Update.php | 2 +- .../Modules/Teams/Http/Memberships/XList.php | 2 +- .../Modules/Teams/Http/Teams/Create.php | 2 +- .../Http/Tokens/Buckets/Files/Action.php | 2 +- .../Utopia/Database/Documents/User.php | 10 +++--- src/Appwrite/Utopia/Request.php | 2 +- src/Appwrite/Utopia/Response.php | 2 +- tests/unit/Auth/KeyTest.php | 16 +++++----- .../Utopia/Database/Documents/UserTest.php | 32 +++++++++---------- 39 files changed, 73 insertions(+), 73 deletions(-) diff --git a/app/config/roles.php b/app/config/roles.php index abb8d4481f..d5ae7c1331 100644 --- a/app/config/roles.php +++ b/app/config/roles.php @@ -150,7 +150,7 @@ return [ 'label' => 'Owner', 'scopes' => \array_merge($member, $admins), ], - User::ROLE_APPS => [ + User::ROLE_KEYS => [ 'label' => 'Applications', 'scopes' => ['global', 'health.read', 'graphql'], ], diff --git a/app/controllers/api/graphql.php b/app/controllers/api/graphql.php index 9ec2479749..4a509aefdd 100644 --- a/app/controllers/api/graphql.php +++ b/app/controllers/api/graphql.php @@ -39,7 +39,7 @@ Http::init() if ( array_key_exists('graphql', $project->getAttribute('apis', [])) && !$project->getAttribute('apis', [])['graphql'] - && !($user->isPrivileged($authorization->getRoles()) || $user->isApp($authorization->getRoles())) + && !($user->isPrivileged($authorization->getRoles()) || $user->isKey($authorization->getRoles())) ) { throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED); } diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 2ee601f685..494bd3da28 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -175,8 +175,8 @@ Http::init() $role = $apiKey->getRole(); $scopes = $apiKey->getScopes(); - // Handle special app role case - if ($apiKey->getRole() === User::ROLE_APPS) { + // Handle special key role case + if ($apiKey->getRole() === User::ROLE_KEYS) { // Disable authorization checks for project API keys // Dynamic supported for backwards compatibility if (($apiKey->getType() === API_KEY_STANDARD || $apiKey->getType() === API_KEY_EPHEMERAL || $apiKey->getType() === 'dynamic') && $apiKey->getProjectId() === $project->getId()) { @@ -425,7 +425,7 @@ Http::init() if ( array_key_exists($namespace, $project->getAttribute('services', [])) && ! $project->getAttribute('services', [])[$namespace] - && ! ($user->isPrivileged($authorization->getRoles()) || $user->isApp($authorization->getRoles())) + && ! ($user->isPrivileged($authorization->getRoles()) || $user->isKey($authorization->getRoles())) ) { throw new Exception(Exception::GENERAL_SERVICE_DISABLED); } @@ -435,7 +435,7 @@ Http::init() if ( array_key_exists('rest', $project->getAttribute('apis', [])) && ! $project->getAttribute('apis', [])['rest'] - && ! ($user->isPrivileged($authorization->getRoles()) || $user->isApp($authorization->getRoles())) + && ! ($user->isPrivileged($authorization->getRoles()) || $user->isKey($authorization->getRoles())) ) { throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED); } @@ -488,7 +488,7 @@ Http::init() $roles = $authorization->getRoles(); $shouldCheckAbuse = System::getEnv('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled' - && ! $user->isApp($roles) + && ! $user->isKey($roles) && ! $user->isPrivileged($roles) && $devKey->isEmpty(); @@ -611,7 +611,7 @@ Http::init() $storageCacheOperationsCounter = $telemetry->createCounter('storage.cache.operations.load'); if ($useCache) { $roles = $authorization->getRoles(); - $isAppUser = $user->isApp($roles); + $isAppUser = $user->isKey($roles); $isImageTransformation = $route->getPath() === '/v1/storage/buckets/:bucketId/files/:fileId/preview'; $isDisabled = isset($plan['imageTransformations']) && $plan['imageTransformations'] === -1 && ! $user->isPrivileged($roles); diff --git a/app/controllers/shared/api/auth.php b/app/controllers/shared/api/auth.php index 4fda054fd6..dfb384f893 100644 --- a/app/controllers/shared/api/auth.php +++ b/app/controllers/shared/api/auth.php @@ -51,7 +51,7 @@ Http::init() } $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); - $isAppUser = $user->isApp($authorization->getRoles()); + $isAppUser = $user->isKey($authorization->getRoles()); if ($isAppUser || $isPrivilegedUser) { // Skip limits for app and console devs return; diff --git a/app/realtime.php b/app/realtime.php index d8b70960b8..ce2dc41e54 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -858,7 +858,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $websocketEnabled = $apis['websocket'] ?? $apis['realtime'] ?? true; if ( !$websocketEnabled - && !($user->isPrivileged($authorization->getRoles()) || $user->isApp($authorization->getRoles())) + && !($user->isPrivileged($authorization->getRoles()) || $user->isKey($authorization->getRoles())) ) { throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED); } diff --git a/src/Appwrite/Auth/Key.php b/src/Appwrite/Auth/Key.php index 0cbaefa4b3..f33f591d52 100644 --- a/src/Appwrite/Auth/Key.php +++ b/src/Appwrite/Auth/Key.php @@ -122,9 +122,9 @@ class Key $secret = $key; } - $role = User::ROLE_APPS; + $role = User::ROLE_KEYS; $roles = Config::getParam('roles', []); - $scopes = $roles[User::ROLE_APPS]['scopes'] ?? []; + $scopes = $roles[User::ROLE_KEYS]['scopes'] ?? []; $expired = false; $guestKey = new Key( @@ -270,7 +270,7 @@ class Key $name = $key->getAttribute('name', 'UNKNOWN'); - $role = User::ROLE_APPS; + $role = User::ROLE_KEYS; $scopes = $key->getAttribute('scopes', []); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php index e0464f7e52..9319cffc57 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php @@ -93,7 +93,7 @@ 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, callable $getDatabasesDB, Event $queueForEvents, Context $usage, array $plan, Authorization $authorization, User $user): void { - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php index de090f9882..ba74545342 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php @@ -93,7 +93,7 @@ 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, callable $getDatabasesDB, Event $queueForEvents, Context $usage, array $plan, Authorization $authorization, User $user): void { - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php index 2ade0b2b79..2e861dfcce 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php @@ -201,7 +201,7 @@ class Create extends Action $documents = [$data]; } - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($isBulk && !$isAPIKey && !$isPrivilegedUser) { diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php index ecc5b152ec..e0863b8ac7 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php @@ -107,7 +107,7 @@ class Delete extends Action ): void { $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php index 06f0e9cf1c..c40e70d667 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php @@ -78,7 +78,7 @@ class Get extends Action public function action(string $databaseId, string $collectionId, string $documentId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, callable $getDatabasesDB, Context $usage, TransactionState $transactionState, Authorization $authorization, User $user): void { - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php index b86d934ffb..4a675615da 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php @@ -103,7 +103,7 @@ class Update extends Action $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php index fb3d414097..ae940456f0 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php @@ -108,7 +108,7 @@ class Upsert extends Action throw new Exception($this->getMissingPayloadException()); } - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php index fdcbced6f3..afde3d0baa 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php @@ -88,7 +88,7 @@ class XList extends Action public function action(string $databaseId, string $collectionId, array $queries, ?string $transactionId, bool $includeTotal, int $ttl, UtopiaResponse $response, Database $dbForProject, User $user, callable $getDatabasesDB, Context $usage, TransactionState $transactionState, Authorization $authorization, ?Http $utopia = null): void { - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Operations/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Operations/Create.php index f06feccdee..8e085a9481 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Operations/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Operations/Create.php @@ -75,7 +75,7 @@ class Create extends Action throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Operations array cannot be empty'); } - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); // API keys and admins can read any transaction, regular users need permissions diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php index fe2ad8dbae..de057ae15e 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php @@ -120,7 +120,7 @@ class Update extends Action throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Cannot commit and rollback at the same time'); } - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $transaction = ($isAPIKey || $isPrivilegedUser) diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php index 35264730f8..1089d815b5 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php @@ -161,7 +161,7 @@ class Create extends Base /* @var Document $function */ $function = $authorization->skip(fn () => $dbForProject->getDocument('functions', $functionId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Get.php b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Get.php index 0a9dd01b7e..9908669f84 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Get.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Get.php @@ -67,7 +67,7 @@ class Get extends Base ) { $function = $authorization->skip(fn () => $dbForProject->getDocument('functions', $functionId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Executions/XList.php b/src/Appwrite/Platform/Modules/Functions/Http/Executions/XList.php index 6ad2a5ae55..bf31fa0ced 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Executions/XList.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Executions/XList.php @@ -77,7 +77,7 @@ class XList extends Base ) { $function = $authorization->skip(fn () => $dbForProject->getDocument('functions', $functionId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Create.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Create.php index 8530475f0c..95ef2cbe28 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Create.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Create.php @@ -115,7 +115,7 @@ class Create extends Action ) { $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Delete.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Delete.php index 6d8781d484..c16b374c78 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Delete.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Delete.php @@ -84,7 +84,7 @@ class Delete extends Action ) { $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Download/Get.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Download/Get.php index c876004319..7e5d7d6879 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Download/Get.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Download/Get.php @@ -90,7 +90,7 @@ class Get extends Action /* @type Document $bucket */ $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Get.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Get.php index c9ce5796eb..d997fe3cc0 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Get.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Get.php @@ -65,7 +65,7 @@ class Get extends Action ) { $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Preview/Get.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Preview/Get.php index 68bc2cabae..0cca87c646 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Preview/Get.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Preview/Get.php @@ -133,7 +133,7 @@ class Get extends Action $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Push/Get.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Push/Get.php index 5b3fd02370..f069b1cc2a 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Push/Get.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Push/Get.php @@ -90,7 +90,7 @@ class Get extends Action $disposition = $decoded['disposition'] ?? 'inline'; $dbForProject = $isInternal ? $dbForPlatform : $dbForProject; - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Update.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Update.php index 407f3766df..fb1245d29c 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Update.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/Update.php @@ -81,7 +81,7 @@ class Update extends Action ) { $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { @@ -110,7 +110,7 @@ class Update extends Action // Users can only manage their own roles, API keys and Admin users can manage any $roles = $authorization->getRoles(); - if (!$user->isApp($roles) && !$user->isPrivileged($roles) && !\is_null($permissions)) { + if (!$user->isKey($roles) && !$user->isPrivileged($roles) && !\is_null($permissions)) { foreach (Database::PERMISSIONS as $type) { foreach ($permissions as $permission) { $permission = Permission::parse($permission); diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/View/Get.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/View/Get.php index b2f00da6d2..b78d582c47 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/View/Get.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/View/Get.php @@ -91,7 +91,7 @@ class Get extends Action /* @type Document $bucket */ $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/XList.php b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/XList.php index 945c4bfd7c..28dfa87c5d 100644 --- a/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/XList.php +++ b/src/Appwrite/Platform/Modules/Storage/Http/Buckets/Files/XList.php @@ -80,7 +80,7 @@ class XList extends Action ) { $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php index 5500a56cbc..3bffb091ba 100644 --- a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php +++ b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php @@ -103,7 +103,7 @@ class Create extends Action public function action(string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, User $user, Database $dbForProject, Authorization $authorization, Locale $locale, MailPublisher $publisherForMails, MessagingPublisher $publisherForMessaging, Event $queueForEvents, callable $timelimit, Context $usage, array $plan, array $platform, Password $proofForPassword, Token $proofForToken) { - $isAppUser = $user->isApp($authorization->getRoles()); + $isAppUser = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $invitee = new Document(); $hash = ''; diff --git a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Get.php b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Get.php index ef8d130855..556f6de52c 100644 --- a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Get.php +++ b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Get.php @@ -81,7 +81,7 @@ class Get extends Action $roles = $authorization->getRoles(); $isPrivilegedUser = $user->isPrivileged($roles); - $isAppUser = $user->isApp($roles); + $isAppUser = $user->isKey($roles); $membershipsPrivacy = array_map(function ($privacy) use ($isPrivilegedUser, $isAppUser) { return $privacy || $isPrivilegedUser || $isAppUser; diff --git a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Update.php b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Update.php index 540dc8a871..2198531e64 100644 --- a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Update.php +++ b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Update.php @@ -84,7 +84,7 @@ class Update extends Action } $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); - $isAppUser = $user->isApp($authorization->getRoles()); + $isAppUser = $user->isKey($authorization->getRoles()); $isOwner = $authorization->hasRole('team:' . $team->getId() . '/owner'); if ($project->getId() === 'console') { diff --git a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/XList.php b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/XList.php index 7835c8051f..45f7eb33aa 100644 --- a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/XList.php +++ b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/XList.php @@ -134,7 +134,7 @@ class XList extends Action $roles = $authorization->getRoles(); $isPrivilegedUser = $user->isPrivileged($roles); - $isAppUser = $user->isApp($roles); + $isAppUser = $user->isKey($roles); $membershipsPrivacy = array_map(function ($privacy) use ($isPrivilegedUser, $isAppUser) { return $privacy || $isPrivilegedUser || $isAppUser; diff --git a/src/Appwrite/Platform/Modules/Teams/Http/Teams/Create.php b/src/Appwrite/Platform/Modules/Teams/Http/Teams/Create.php index 0d20a58b6b..222b0968be 100644 --- a/src/Appwrite/Platform/Modules/Teams/Http/Teams/Create.php +++ b/src/Appwrite/Platform/Modules/Teams/Http/Teams/Create.php @@ -71,7 +71,7 @@ class Create extends Action public function action(string $teamId, string $name, array $roles, Response $response, User $user, Database $dbForProject, Authorization $authorization, Event $queueForEvents) { $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); - $isAppUser = $user->isApp($authorization->getRoles()); + $isAppUser = $user->isKey($authorization->getRoles()); $teamId = $teamId == 'unique()' ? ID::unique() : $teamId; diff --git a/src/Appwrite/Platform/Modules/Tokens/Http/Tokens/Buckets/Files/Action.php b/src/Appwrite/Platform/Modules/Tokens/Http/Tokens/Buckets/Files/Action.php index 934074d3c2..85247678f8 100644 --- a/src/Appwrite/Platform/Modules/Tokens/Http/Tokens/Buckets/Files/Action.php +++ b/src/Appwrite/Platform/Modules/Tokens/Http/Tokens/Buckets/Files/Action.php @@ -15,7 +15,7 @@ class Action extends UtopiaAction { $bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { diff --git a/src/Appwrite/Utopia/Database/Documents/User.php b/src/Appwrite/Utopia/Database/Documents/User.php index 211c6449dc..3004efe382 100644 --- a/src/Appwrite/Utopia/Database/Documents/User.php +++ b/src/Appwrite/Utopia/Database/Documents/User.php @@ -17,7 +17,7 @@ class User extends Document public const ROLE_ADMIN = 'admin'; public const ROLE_DEVELOPER = 'developer'; public const ROLE_OWNER = 'owner'; - public const ROLE_APPS = 'apps'; + public const ROLE_KEYS = 'keys'; public const ROLE_SYSTEM = 'system'; public function getEmail(): ?string @@ -39,7 +39,7 @@ class User extends Document { $roles = []; - if (!$this->isApp($authorization->getRoles())) { + if (!$this->isKey($authorization->getRoles())) { if ($this->getId()) { $roles[] = Role::user($this->getId())->toString(); $roles[] = Role::users()->toString(); @@ -115,15 +115,15 @@ class User extends Document } /** - * Is App User? + * Is Key User? * * @param array $roles * * @return bool */ - public function isApp(array $roles): bool + public function isKey(array $roles): bool { - if (in_array(self::ROLE_APPS, $roles)) { + if (in_array(self::ROLE_KEYS, $roles)) { return true; } diff --git a/src/Appwrite/Utopia/Request.php b/src/Appwrite/Utopia/Request.php index 24803eeaa7..1070d993c8 100644 --- a/src/Appwrite/Utopia/Request.php +++ b/src/Appwrite/Utopia/Request.php @@ -240,7 +240,7 @@ class Request extends UtopiaRequest $forwardedUserAgent = $this->getHeader('x-forwarded-user-agent'); if (!empty($forwardedUserAgent)) { $roles = $this->authorization->getRoles(); - $isAppUser = $this->user?->isApp($roles) ?? false; + $isAppUser = $this->user?->isKey($roles) ?? false; if ($isAppUser) { return $forwardedUserAgent; diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 66e4a5f4ae..c8b573fc49 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -591,7 +591,7 @@ class Response extends SwooleResponse $roles = $this->authorization->getRoles(); $user = $this->user ?? new DBUser(); $isPrivilegedUser = $user->isPrivileged($roles); - $isAppUser = $user->isApp($roles); + $isAppUser = $user->isKey($roles); if ((!$isPrivilegedUser && !$isAppUser) && !$this->showSensitive) { $data->setAttribute($key, ''); diff --git a/tests/unit/Auth/KeyTest.php b/tests/unit/Auth/KeyTest.php index bcdb46180f..674fdf09aa 100644 --- a/tests/unit/Auth/KeyTest.php +++ b/tests/unit/Auth/KeyTest.php @@ -22,7 +22,7 @@ class KeyTest extends TestCase 'collections.read', 'documents.read', ]; - $roleScopes = Config::getParam('roles', [])[User::ROLE_APPS]['scopes']; + $roleScopes = Config::getParam('roles', [])[User::ROLE_KEYS]['scopes']; $guestRoleScopes = Config::getParam('roles', [])[User::ROLE_GUESTS]['scopes']; $key = self::generateKey($projectId, $usage, $scopes); @@ -37,7 +37,7 @@ class KeyTest extends TestCase $this->assertEquals('', $decoded->getTeamId()); $this->assertEquals('', $decoded->getUserId()); $this->assertEquals(API_KEY_EPHEMERAL, $decoded->getType()); - $this->assertEquals(User::ROLE_APPS, $decoded->getRole()); + $this->assertEquals(User::ROLE_KEYS, $decoded->getRole()); $this->assertEquals(\array_merge($scopes, $roleScopes), $decoded->getScopes()); $this->assertEquals('Ephemeral Key', $decoded->getName()); @@ -61,7 +61,7 @@ class KeyTest extends TestCase $this->assertEquals('', $decoded->getTeamId()); $this->assertEquals('', $decoded->getUserId()); $this->assertEquals(API_KEY_EPHEMERAL, $decoded->getType()); - $this->assertEquals(User::ROLE_APPS, $decoded->getRole()); + $this->assertEquals(User::ROLE_KEYS, $decoded->getRole()); $this->assertEquals(\array_merge($scopes, $roleScopes), $decoded->getScopes()); $this->assertEquals('Ephemeral Key', $decoded->getName()); $this->assertEquals(['metric123'], $decoded->getDisabledMetrics()); @@ -123,7 +123,7 @@ class KeyTest extends TestCase $this->assertEquals('', $decoded->getTeamId()); $this->assertEquals('', $decoded->getUserId()); $this->assertEquals(API_KEY_STANDARD, $decoded->getType()); - $this->assertEquals(User::ROLE_APPS, $decoded->getRole()); + $this->assertEquals(User::ROLE_KEYS, $decoded->getRole()); $this->assertEquals(\array_merge($scopes, $roleScopes), $decoded->getScopes()); $this->assertEquals('Standard key', $decoded->getName()); @@ -146,7 +146,7 @@ class KeyTest extends TestCase $this->assertEquals('', $decoded->getTeamId()); $this->assertEquals('', $decoded->getUserId()); $this->assertEquals(API_KEY_STANDARD, $decoded->getType()); - $this->assertEquals(User::ROLE_APPS, $decoded->getRole()); + $this->assertEquals(User::ROLE_KEYS, $decoded->getRole()); $this->assertEquals(\array_merge($scopes, $roleScopes), $decoded->getScopes()); $this->assertEquals('Standard key', $decoded->getName()); @@ -194,7 +194,7 @@ class KeyTest extends TestCase $this->assertEquals('', $decoded->getTeamId()); $this->assertEquals('', $decoded->getUserId()); $this->assertEquals(API_KEY_STANDARD, $decoded->getType()); - $this->assertEquals(User::ROLE_APPS, $decoded->getRole()); + $this->assertEquals(User::ROLE_KEYS, $decoded->getRole()); $this->assertEquals(\array_merge($scopes, $roleScopes), $decoded->getScopes()); $this->assertEquals('Standard key', $decoded->getName()); @@ -289,7 +289,7 @@ class KeyTest extends TestCase $this->assertEquals($teamId, $decoded->getTeamId()); $this->assertEquals('', $decoded->getUserId()); $this->assertEquals(API_KEY_ORGANIZATION, $decoded->getType()); - $this->assertEquals(User::ROLE_APPS, $decoded->getRole()); + $this->assertEquals(User::ROLE_KEYS, $decoded->getRole()); $this->assertEquals($scopes, $decoded->getScopes()); $this->assertEquals('Organization key', $decoded->getName()); @@ -336,7 +336,7 @@ class KeyTest extends TestCase $this->assertEquals($teamId, $decoded->getTeamId()); $this->assertEquals('', $decoded->getUserId()); $this->assertEquals(API_KEY_ORGANIZATION, $decoded->getType()); - $this->assertEquals(User::ROLE_APPS, $decoded->getRole()); + $this->assertEquals(User::ROLE_KEYS, $decoded->getRole()); $this->assertEquals($scopes, $decoded->getScopes()); $this->assertEquals('Organization key', $decoded->getName()); } diff --git a/tests/unit/Utopia/Database/Documents/UserTest.php b/tests/unit/Utopia/Database/Documents/UserTest.php index b3638e7d3a..5bd73db132 100644 --- a/tests/unit/Utopia/Database/Documents/UserTest.php +++ b/tests/unit/Utopia/Database/Documents/UserTest.php @@ -179,11 +179,11 @@ class UserTest extends TestCase $this->assertEquals(true, $user->isPrivileged([User::ROLE_ADMIN])); $this->assertEquals(true, $user->isPrivileged([User::ROLE_DEVELOPER])); $this->assertEquals(true, $user->isPrivileged([User::ROLE_OWNER])); - $this->assertEquals(false, $user->isPrivileged([User::ROLE_APPS])); + $this->assertEquals(false, $user->isPrivileged([User::ROLE_KEYS])); $this->assertEquals(false, $user->isPrivileged([User::ROLE_SYSTEM])); - $this->assertEquals(false, $user->isPrivileged([User::ROLE_APPS, User::ROLE_APPS])); - $this->assertEquals(false, $user->isPrivileged([User::ROLE_APPS, Role::guests()->toString()])); + $this->assertEquals(false, $user->isPrivileged([User::ROLE_KEYS, User::ROLE_KEYS])); + $this->assertEquals(false, $user->isPrivileged([User::ROLE_KEYS, Role::guests()->toString()])); $this->assertEquals(true, $user->isPrivileged([User::ROLE_OWNER, Role::guests()->toString()])); $this->assertEquals(true, $user->isPrivileged([User::ROLE_OWNER, User::ROLE_ADMIN, User::ROLE_DEVELOPER])); } @@ -192,19 +192,19 @@ class UserTest extends TestCase { $user = new User(); - $this->assertEquals(false, $user->isApp([])); - $this->assertEquals(false, $user->isApp([Role::guests()->toString()])); - $this->assertEquals(false, $user->isApp([Role::users()->toString()])); - $this->assertEquals(false, $user->isApp([User::ROLE_ADMIN])); - $this->assertEquals(false, $user->isApp([User::ROLE_DEVELOPER])); - $this->assertEquals(false, $user->isApp([User::ROLE_OWNER])); - $this->assertEquals(true, $user->isApp([User::ROLE_APPS])); - $this->assertEquals(false, $user->isApp([User::ROLE_SYSTEM])); + $this->assertEquals(false, $user->isKey([])); + $this->assertEquals(false, $user->isKey([Role::guests()->toString()])); + $this->assertEquals(false, $user->isKey([Role::users()->toString()])); + $this->assertEquals(false, $user->isKey([User::ROLE_ADMIN])); + $this->assertEquals(false, $user->isKey([User::ROLE_DEVELOPER])); + $this->assertEquals(false, $user->isKey([User::ROLE_OWNER])); + $this->assertEquals(true, $user->isKey([User::ROLE_KEYS])); + $this->assertEquals(false, $user->isKey([User::ROLE_SYSTEM])); - $this->assertEquals(true, $user->isApp([User::ROLE_APPS, User::ROLE_APPS])); - $this->assertEquals(true, $user->isApp([User::ROLE_APPS, Role::guests()->toString()])); - $this->assertEquals(false, $user->isApp([User::ROLE_OWNER, Role::guests()->toString()])); - $this->assertEquals(false, $user->isApp([User::ROLE_OWNER, User::ROLE_ADMIN, User::ROLE_DEVELOPER])); + $this->assertEquals(true, $user->isKey([User::ROLE_KEYS, User::ROLE_KEYS])); + $this->assertEquals(true, $user->isKey([User::ROLE_KEYS, Role::guests()->toString()])); + $this->assertEquals(false, $user->isKey([User::ROLE_OWNER, Role::guests()->toString()])); + $this->assertEquals(false, $user->isKey([User::ROLE_OWNER, User::ROLE_ADMIN, User::ROLE_DEVELOPER])); } public function testGuestRoles(): void @@ -327,7 +327,7 @@ class UserTest extends TestCase public function testAppUserRoles(): void { - $this->getAuthorization()->addRole(User::ROLE_APPS); + $this->getAuthorization()->addRole(User::ROLE_KEYS); $user = new User([ '$id' => ID::custom('123'), 'memberships' => [ From 39aeecc58cd48fe5195b40d28e888f1b1d033f2f Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 18 May 2026 05:52:24 +0000 Subject: [PATCH 4/5] fix(audits): drop removed 'location' field from event payload (utopia-php/audit 2.4 schema) --- src/Appwrite/Platform/Workers/Audits.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 07d91ce009..09863b8626 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -100,7 +100,6 @@ class Audits extends Action 'resource' => $resource, 'userAgent' => $userAgent, 'ip' => $ip, - 'location' => '', 'data' => [ 'userId' => $actorUserId, 'userName' => $actorUserName, From 5f63100f4c639ef246b0a40793eafd5144422501 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Wed, 20 May 2026 05:16:37 +0000 Subject: [PATCH 5/5] fix(presences): rename isApp() callers to isKey() (new files from upstream 1.9.x merge) --- src/Appwrite/Platform/Modules/Presences/HTTP/Update.php | 2 +- src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php | 2 +- src/Appwrite/Presences/State.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Presences/HTTP/Update.php b/src/Appwrite/Platform/Modules/Presences/HTTP/Update.php index 5387d3a91e..376359717b 100644 --- a/src/Appwrite/Platform/Modules/Presences/HTTP/Update.php +++ b/src/Appwrite/Platform/Modules/Presences/HTTP/Update.php @@ -128,7 +128,7 @@ class Update extends PlatformAction Event $queueForEvents ): void { $presenceState = new PresenceState(); - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($userId && !$isAPIKey && !$isPrivilegedUser) { diff --git a/src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php b/src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php index c85cb15f17..be658adbd1 100644 --- a/src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php +++ b/src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php @@ -128,7 +128,7 @@ class Upsert extends PlatformAction Event $queueForEvents, Context $usage ): void { - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); if ($userId && !$isAPIKey && !$isPrivilegedUser) { throw new Exception(Exception::GENERAL_UNAUTHORIZED_SCOPE, "userId is not allowed for non-API key and non-privileged users"); diff --git a/src/Appwrite/Presences/State.php b/src/Appwrite/Presences/State.php index 19e7dc98b7..e7c51dec87 100644 --- a/src/Appwrite/Presences/State.php +++ b/src/Appwrite/Presences/State.php @@ -48,7 +48,7 @@ class State $permissions[] = (new Permission($permission, 'user', $ownerOverride))->toString(); } } else { - $isAPIKey = $user->isApp($authorization->getRoles()); + $isAPIKey = $user->isKey($authorization->getRoles()); $isPrivilegedUser = $user->isPrivileged($authorization->getRoles()); $permissions = Permission::aggregate($permissions, $allowedPermissions);