From 0c425dbac3e06c9f8e67132d96ee8d4e83a289c1 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 28 Dec 2025 01:48:23 +0000 Subject: [PATCH 1/2] Fix: assign user permission to files/documents only if not a previleged user --- app/controllers/api/storage.php | 4 ++-- .../Databases/Http/Databases/Collections/Documents/Create.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index e6f4394e25..ec4cc25ea3 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -461,7 +461,7 @@ App::post('/v1/storage/buckets/:bucketId/files') // Add permissions for current the user if none were provided. if (\is_null($permissions)) { $permissions = []; - if (!empty($user->getId())) { + if (!empty($user->getId()) && !$isPrivilegedUser) { foreach ($allowedPermissions as $permission) { $permissions[] = (new Permission($permission, 'user', $user->getId()))->toString(); } @@ -470,7 +470,7 @@ App::post('/v1/storage/buckets/:bucketId/files') // 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)) { + if (!$isAPIKey && !$isPrivilegedUser) { foreach (Database::PERMISSIONS as $type) { foreach ($permissions as $permission) { $permission = Permission::parse($permission); 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 7c3a06ab30..6ec06f5c8a 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 @@ -227,7 +227,7 @@ class Create extends Action // Add permissions for current the user if none were provided. if (\is_null($permissions)) { $permissions = []; - if (!empty($user->getId())) { + if (!empty($user->getId()) && !$isPrivilegedUser) { foreach ($allowedPermissions as $permission) { $permissions[] = (new Permission($permission, 'user', $user->getId()))->toString(); } From 3a983617365cd33cff4b6d130a0aa58fc1c56c5d Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 28 Dec 2025 02:02:34 +0000 Subject: [PATCH 2/2] add test --- .../Storage/StorageConsoleClientTest.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/e2e/Services/Storage/StorageConsoleClientTest.php b/tests/e2e/Services/Storage/StorageConsoleClientTest.php index 5c618d6357..2c39a12f09 100644 --- a/tests/e2e/Services/Storage/StorageConsoleClientTest.php +++ b/tests/e2e/Services/Storage/StorageConsoleClientTest.php @@ -160,4 +160,40 @@ class StorageConsoleClientTest extends Scope ], $this->getHeaders())); $this->assertEquals(204, $response['headers']['status-code']); } + + public function testFilePermissionNotAutoSetInConsole(): void + { + // Create a bucket + $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'bucketId' => ID::unique(), + 'name' => 'Test Bucket Permissions', + 'fileSecurity' => true, + ]); + $this->assertEquals(201, $bucket['headers']['status-code']); + $bucketId = $bucket['body']['$id']; + + // Create a file without providing permissions (console client should not auto-set permissions) + $file = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', array_merge([ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'fileId' => ID::unique(), + 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'test.png'), + ]); + $this->assertEquals(201, $file['headers']['status-code']); + + // Verify file permissions are empty (not auto-set for privileged console user) + $this->assertIsArray($file['body']['$permissions']); + $this->assertEmpty($file['body']['$permissions']); + + // Clean up: delete the bucket + $response = $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucketId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + $this->assertEquals(204, $response['headers']['status-code']); + } }