added the cases of null permissions in the upsert route and update the e2e test

This commit is contained in:
ArnabChatterjee20k
2025-07-21 19:32:27 +05:30
parent 1d9aac5a49
commit 8b88a09374
2 changed files with 96 additions and 10 deletions
+24 -4
View File
@@ -4257,10 +4257,11 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
->inject('requestTimestamp')
->inject('response')
->inject('user')
->inject('dbForProject')
->inject('queueForEvents')
->inject('queueForStatsUsage')
->action(function (string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage) {
->action(function (string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage) {
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
if (empty($data) && \is_null($permissions)) {
@@ -4280,12 +4281,31 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
// Map aggregate permissions into the multiple permissions they represent.
$permissions = Permission::aggregate($permissions, [
$allowedPermissions = [
Database::PERMISSION_READ,
Database::PERMISSION_UPDATE,
Database::PERMISSION_DELETE,
]);
];
$permissions = Permission::aggregate($permissions, $allowedPermissions);
// if no permission , upsert permission from the old document if present(update scenario) else add default permission(create scenario)
if (\is_null($permissions)) {
$oldDocument = Authorization::skip(
fn () =>
$dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId)
);
if ($oldDocument->isEmpty()) {
if (!empty($user->getId())) {
$defaultPermissions = [];
foreach ($allowedPermissions as $permission) {
$defaultPermissions[] = (new Permission($permission, 'user', $user->getId()))->toString();
}
$permissions = $defaultPermissions;
}
} else {
$permissions = $oldDocument->getPermissions();
}
}
// Users can only manage their own roles, API keys and Admin users can manage any
$roles = Authorization::getRoles();
+72 -6
View File
@@ -2010,20 +2010,86 @@ trait DatabasesBase
$this->assertEquals(200, $document['headers']['status-code']);
$this->assertEquals('Thor: Ragnarok', $document['body']['title']);
$this->assertCount(3, $document['body']['$permissions']);
$permissionsCreated = $document['body']['$permissions'];
// checking the default created permission
$defaultPermission = [Permission::read(Role::user($this->getUser()['$id'])),
Permission::update(Role::user($this->getUser()['$id'])),
Permission::delete(Role::user($this->getUser()['$id'])),];
// ignoring the order of the permission and checking the permissions
$this->assertEqualsCanonicalizing($defaultPermission, $permissionsCreated);
$document = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $documentId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]));
'x-appwrite-project' => $this->getProject()['$id']
], $this->getHeaders()));
$this->assertEquals(200, $document['headers']['status-code']);
$deleteResponse = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $documentId, array_merge([
// updating the created doc
$document = $this->client->call(Client::METHOD_PUT, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $documentId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]));
], $this->getHeaders()), [
'data' => [
'title' => 'Thor: Ragnarok',
'releaseYear' => 2002
]
]);
$this->assertEquals(200, $document['headers']['status-code']);
$this->assertEquals('Thor: Ragnarok', $document['body']['title']);
$this->assertEquals(2002, $document['body']['releaseYear']);
$this->assertCount(3, $document['body']['$permissions']);
$this->assertEquals($permissionsCreated, $document['body']['$permissions']);
// removing the delete permission
$document = $this->client->call(Client::METHOD_PUT, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $documentId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'data' => [
'title' => 'Thor: Ragnarok',
'releaseYear' => 2002
],
'permissions' => [
Permission::update(Role::user($this->getUser()['$id']))
]
]);
$this->assertEquals(200, $document['headers']['status-code']);
$this->assertEquals('Thor: Ragnarok', $document['body']['title']);
$this->assertEquals(2002, $document['body']['releaseYear']);
$this->assertCount(1, $document['body']['$permissions']);
$deleteResponse = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $documentId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id']
], $this->getHeaders()));
$this->assertEquals(401, $deleteResponse['headers']['status-code']);
// giving the delete permission
$document = $this->client->call(Client::METHOD_PUT, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $documentId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'data' => [
'title' => 'Thor: Ragnarok',
'releaseYear' => 2002
],
'permissions' => [
Permission::update(Role::user($this->getUser()['$id'])),
Permission::delete(Role::user($this->getUser()['$id']))
]
]);
$this->assertEquals(200, $document['headers']['status-code']);
$this->assertEquals('Thor: Ragnarok', $document['body']['title']);
$this->assertEquals(2002, $document['body']['releaseYear']);
$this->assertCount(2, $document['body']['$permissions']);
$deleteResponse = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $documentId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id']
], $this->getHeaders()));
$this->assertEquals(204, $deleteResponse['headers']['status-code']);
}