diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index f21a1413a9..4ae1f8dee8 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -98,7 +98,9 @@ App::post('/v1/account') '$id' => $userId, '$permissions' => [ 'read(any)', - 'write(user:' . $userId . ')', + 'create(user:' . $userId . ')', + 'update(user:' . $userId . ')', + 'delete(user:' . $userId . ')', ], 'email' => $email, 'emailVerification' => false, @@ -202,7 +204,9 @@ App::post('/v1/account/sessions/email') $session = $dbForProject->createDocument('sessions', $session->setAttribute('$permissions', [ 'read(user:' . $profile->getId() . ')', - 'write(user:' . $profile->getId() . ')', + 'create(user:' . $profile->getId() . ')', + 'update(user:' . $profile->getId() . ')', + 'delete(user:' . $profile->getId() . ')', ])); $dbForProject->deleteCachedDocument('users', $profile->getId()); @@ -483,7 +487,9 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') '$id' => $userId, '$permissions' => [ 'read(any)', - 'write(user:' . $userId . ')', + 'create(user:' . $userId . ')', + 'update(user:' . $userId . ')', + 'delete(user:' . $userId . ')', ], 'email' => $email, 'emailVerification' => true, @@ -549,7 +555,9 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $session = $dbForProject->createDocument('sessions', $session->setAttribute('$permissions', [ 'read(user:' . $user->getId() . ')', - 'write(user:' . $user->getId() . ')', + 'create(user:' . $user->getId() . ')', + 'update(user:' . $user->getId() . ')', + 'delete(user:' . $user->getId() . ')', ])); $dbForProject->deleteCachedDocument('users', $user->getId()); @@ -651,7 +659,9 @@ App::post('/v1/account/sessions/magic-url') '$id' => $userId, '$permissions' => [ 'read(any)', - 'write(user: ' . $userId . ')', + 'create(user: ' . $userId . ')', + 'update(user: ' . $userId . ')', + 'delete(user: ' . $userId . ')', ], 'email' => $email, 'emailVerification' => false, @@ -688,7 +698,9 @@ App::post('/v1/account/sessions/magic-url') $token = $dbForProject->createDocument('tokens', $token ->setAttribute('$permissions', [ 'read(user: ' . $user->getId() . ')', - 'write(user:' . $user->getId() . ')', + 'create(user:' . $user->getId() . ')', + 'update(user:' . $user->getId() . ')', + 'delete(user:' . $user->getId() . ')', ])); $dbForProject->deleteCachedDocument('users', $user->getId()); @@ -795,7 +807,9 @@ App::put('/v1/account/sessions/magic-url') $session = $dbForProject->createDocument('sessions', $session ->setAttribute('$permissions', [ 'read(user: ' . $user->getId() . ')', - 'write(user:' . $user->getId() . ')', + 'create(user:' . $user->getId() . ')', + 'update(user:' . $user->getId() . ')', + 'delete(user:' . $user->getId() . ')', ])); $dbForProject->deleteCachedDocument('users', $user->getId()); @@ -2002,7 +2016,9 @@ App::post('/v1/account/recovery') $recovery = $dbForProject->createDocument('tokens', $recovery ->setAttribute('$permissions', [ 'read(user: ' . $profile->getId() . ')', - 'write(user: ' . $profile->getId() . ')', + 'create(user: ' . $profile->getId() . ')', + 'update(user: ' . $profile->getId() . ')', + 'delete(user: ' . $profile->getId() . ')', ])); $dbForProject->deleteCachedDocument('users', $profile->getId()); @@ -2165,7 +2181,9 @@ App::post('/v1/account/verification') $verification = $dbForProject->createDocument('tokens', $verification ->setAttribute('$permissions', [ 'read(user: ' . $user->getId() . ')', - 'write(user: ' . $user->getId() . ')', + 'create(user: ' . $user->getId() . ')', + 'update(user: ' . $user->getId() . ')', + 'delete(user: ' . $user->getId() . ')', ])); $dbForProject->deleteCachedDocument('users', $user->getId()); @@ -2322,7 +2340,9 @@ App::post('/v1/account/verification/phone') $verification = $dbForProject->createDocument('tokens', $verification ->setAttribute('$permissions', [ 'read(user: ' . $user->getId() . ')', - 'write(user: ' . $user->getId() . ')', + 'create(user: ' . $user->getId() . ')', + 'update(user: ' . $user->getId() . ')', + 'delete(user: ' . $user->getId() . ')', ])); $dbForProject->deleteCachedDocument('users', $user->getId()); diff --git a/app/http.php b/app/http.php index 68bf3959d8..35bc3fc4de 100644 --- a/app/http.php +++ b/app/http.php @@ -170,7 +170,9 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) { 'antivirus' => true, '$permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'search' => 'buckets Default', ])); diff --git a/src/Appwrite/Permissions/PermissionsProcessor.php b/src/Appwrite/Permissions/PermissionsProcessor.php new file mode 100644 index 0000000000..075ec7037b --- /dev/null +++ b/src/Appwrite/Permissions/PermissionsProcessor.php @@ -0,0 +1,26 @@ + ['create', 'update', 'delete', 'read',], + 'write' => ['create', 'update', 'delete',], + ]; + foreach($permissions as $i => $permission) { + foreach ($aggregates as $type => $subTypes) { + if (!\str_starts_with($permission, $type)) { + continue; + } + $permissionsContents = \str_replace([$type, '(', ')', ' '], '', $permission); + foreach ($subTypes as $subType) { + $permissions[] = $subType . '(' . $permissionsContents . ')'; + } + unset($permissions[$i]); + } + } + } +} \ No newline at end of file diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 24caddb7d4..050c51fd11 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -87,7 +87,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user:' . $this->getUser()['$id'] . ')', - 'write(user:' . $this->getUser()['$id'] . ')', + 'create(user:' . $this->getUser()['$id'] . ')', + 'update(user:' . $this->getUser()['$id'] . ')', + 'delete(user:' . $this->getUser()['$id'] . ')', ], ]); @@ -787,7 +789,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -807,7 +811,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -827,7 +833,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -841,7 +849,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1419,7 +1429,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ], ]); @@ -1429,8 +1441,10 @@ trait DatabasesBase $this->assertEquals($document['body']['title'], 'Thor: Ragnaroc'); $this->assertEquals($document['body']['releaseYear'], 2017); $this->assertNotEquals($document['body']['$createdAt'], 5); - $this->assertEquals('read(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions'][0]); - $this->assertEquals('write(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions'][1]); + $this->assertContains('read(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('create(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('update(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('delete(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); $document = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $id, array_merge([ 'content-type' => 'application/json', @@ -1441,7 +1455,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(users)', - 'write(users)', + 'create(users)', + 'update(users)', + 'delete(users)', ], ]); @@ -1450,8 +1466,10 @@ trait DatabasesBase $this->assertEquals($document['body']['$collection'], $data['moviesId']); $this->assertEquals($document['body']['title'], 'Thor: Ragnarok'); $this->assertEquals($document['body']['releaseYear'], 2017); - $this->assertEquals('read(users)', $document['body']['$permissions'][0]); - $this->assertEquals('write(users)', $document['body']['$permissions'][1]); + $this->assertContains('read(users)', $document['body']['$permissions']); + $this->assertContains('create(users)', $document['body']['$permissions']); + $this->assertContains('update(users)', $document['body']['$permissions']); + $this->assertContains('delete(users)', $document['body']['$permissions']); $document = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $id, array_merge([ 'content-type' => 'application/json', @@ -1485,7 +1503,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1736,7 +1756,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1750,7 +1772,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1764,7 +1788,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1778,7 +1804,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1792,7 +1820,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1806,7 +1836,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1820,7 +1852,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1834,7 +1868,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1848,7 +1884,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1876,7 +1914,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1890,7 +1930,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1904,7 +1946,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1918,7 +1962,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1932,7 +1978,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1946,7 +1994,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1960,7 +2010,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1974,7 +2026,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -1988,7 +2042,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -2039,8 +2095,10 @@ trait DatabasesBase if ($this->getSide() == 'client') { $this->assertCount(2, $document['body']['$permissions']); - $this->assertEquals(['read(user:' . $this->getUser()['$id'] . ')'], $document['body']['$permissions']); - $this->assertEquals(['write(user:' . $this->getUser()['$id'] . ')'], $document['body']['$permissions']); + $this->assertContains('read(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('create(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('update(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('delete(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); } if ($this->getSide() == 'server') { @@ -2071,7 +2129,9 @@ trait DatabasesBase if ($this->getSide() == 'client') { $this->assertCount(2, $document['body']['$permissions']); $this->assertContains('read(any)', $document['body']['$permissions']); - $this->assertContains('write(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('create(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('update(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('delete(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); } if ($this->getSide() == 'server') { @@ -2153,7 +2213,9 @@ trait DatabasesBase 'name' => 'enforceCollectionPermissions', 'permissions' => [ 'read(' . $user . ')', - 'write(' . $user . ')', + 'create(' . $user . ')', + 'update(' . $user . ')', + 'delete(' . $user . ')', ], ]); @@ -2207,7 +2269,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(' . $user . ')', - 'write(' . $user . ')', + 'create(' . $user . ')', + 'update(' . $user . ')', + 'delete(' . $user . ')', ] ]); @@ -2222,7 +2286,9 @@ trait DatabasesBase 'attribute' => 'one', ], 'permissions' => [ - 'write(' . $user . ')', + 'create(' . $user . ')', + 'update(' . $user . ')', + 'delete(' . $user . ')', ] ]); @@ -2277,7 +2343,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(' . $user . ')', - 'write(' . $user . ')', + 'create(' . $user . ')', + 'update(' . $user . ')', + 'delete(' . $user . ')', ], ]); @@ -2345,7 +2413,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -2367,7 +2437,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -2389,7 +2461,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -2518,7 +2592,9 @@ trait DatabasesBase ], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -2527,7 +2603,9 @@ trait DatabasesBase $this->assertEquals($document['headers']['status-code'], 201); $this->assertCount(2, $document['body']['$permissions']); $this->assertContains('read(any)', $document['body']['$permissions']); - $this->assertContains('write(any)', $document['body']['$permissions']); + $this->assertContains('create(any)', $document['body']['$permissions']); + $this->assertContains('update(any)', $document['body']['$permissions']); + $this->assertContains('delete(any)', $document['body']['$permissions']); // Send only read permission $document = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $moviesId . '/documents/' . $id, array_merge([ @@ -2547,7 +2625,9 @@ trait DatabasesBase $this->assertEquals($document['headers']['status-code'], 200); $this->assertCount(2, $document['body']['$permissions']); $this->assertContains('read(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); - $this->assertContains('write(any)', $document['body']['$permissions']); + $this->assertContains('create(any)', $document['body']['$permissions']); + $this->assertContains('update(any)', $document['body']['$permissions']); + $this->assertContains('delete(any)', $document['body']['$permissions']); } // send only write permission @@ -2556,7 +2636,9 @@ trait DatabasesBase 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'permissions' => [ - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ], ]); @@ -2564,7 +2646,9 @@ trait DatabasesBase $this->assertEquals($document['headers']['status-code'], 200); $this->assertCount(2, $document['body']['$permissions']); $this->assertContains('read(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); - $this->assertContains('write(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('create(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('update(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); + $this->assertContains('delete(user:' . $this->getUser()['$id'] . ')', $document['body']['$permissions']); } // remove collection diff --git a/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php b/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php index 240c552e3e..fa9a167c92 100644 --- a/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php +++ b/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php @@ -37,7 +37,9 @@ class DatabasesConsoleClientTest extends Scope 'name' => 'Movies', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); diff --git a/tests/e2e/Services/Databases/DatabasesCustomClientTest.php b/tests/e2e/Services/Databases/DatabasesCustomClientTest.php index 6b0c5d38f1..2d1927704d 100644 --- a/tests/e2e/Services/Databases/DatabasesCustomClientTest.php +++ b/tests/e2e/Services/Databases/DatabasesCustomClientTest.php @@ -79,7 +79,9 @@ class DatabasesCustomClientTest extends Scope ], 'permissions' => [ 'read(user:' . $userId . ', user:user2)', - 'write(user:' . $userId . ')', + 'create(user:' . $userId . ')', + 'update(user:' . $userId . ')', + 'delete(user:' . $userId . ')', ], ]); $this->assertEquals(201, $response['headers']['status-code']); diff --git a/tests/e2e/Services/Databases/DatabasesCustomServerTest.php b/tests/e2e/Services/Databases/DatabasesCustomServerTest.php index 3837366894..dbc994e657 100644 --- a/tests/e2e/Services/Databases/DatabasesCustomServerTest.php +++ b/tests/e2e/Services/Databases/DatabasesCustomServerTest.php @@ -252,7 +252,9 @@ class DatabasesCustomServerTest extends Scope 'collectionId' => 'first', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); @@ -266,7 +268,9 @@ class DatabasesCustomServerTest extends Scope 'collectionId' => 'second', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); @@ -408,7 +412,9 @@ class DatabasesCustomServerTest extends Scope 'collectionId' => 'first', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); @@ -444,7 +450,9 @@ class DatabasesCustomServerTest extends Scope 'name' => 'Actors', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); @@ -499,7 +507,9 @@ class DatabasesCustomServerTest extends Scope ], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -724,7 +734,9 @@ class DatabasesCustomServerTest extends Scope 'name' => 'TestCleanupDuplicateIndexOnDeleteAttribute', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); @@ -845,7 +857,9 @@ class DatabasesCustomServerTest extends Scope ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ], ]); @@ -860,7 +874,9 @@ class DatabasesCustomServerTest extends Scope ], 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ], ]); @@ -972,7 +988,9 @@ class DatabasesCustomServerTest extends Scope 'name' => 'attributeRowWidthLimit', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); @@ -1036,7 +1054,9 @@ class DatabasesCustomServerTest extends Scope 'name' => 'testLimitException', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); diff --git a/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php b/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php index e6da7ede82..fecaf5f0e9 100644 --- a/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php +++ b/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php @@ -32,7 +32,9 @@ class DatabasesPermissionsGuestTest extends Scope 'name' => 'Movies', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); diff --git a/tests/e2e/Services/Databases/DatabasesPermissionsMemberTest.php b/tests/e2e/Services/Databases/DatabasesPermissionsMemberTest.php index 193808fc16..01a8b16632 100644 --- a/tests/e2e/Services/Databases/DatabasesPermissionsMemberTest.php +++ b/tests/e2e/Services/Databases/DatabasesPermissionsMemberTest.php @@ -66,7 +66,9 @@ class DatabasesPermissionsMemberTest extends Scope 'name' => 'Movies', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); @@ -86,7 +88,9 @@ class DatabasesPermissionsMemberTest extends Scope 'name' => 'Private Movies', 'permissions' => [ 'read(users)', - 'write(users)', + 'create(users)', + 'update(users)', + 'delete(users)', ], 'documentSecurity' => true, ]); @@ -128,7 +132,9 @@ class DatabasesPermissionsMemberTest extends Scope ], 'permissions' => [ 'read(' . $read . ')', - 'write(' . $write . ')', + 'create(' . $write . ')', + 'update(' . $write . ')', + 'delete(' . $write . ')', ], ]); $this->assertEquals(201, $response['headers']['status-code']); @@ -140,7 +146,9 @@ class DatabasesPermissionsMemberTest extends Scope ], 'permissions' => [ 'read(' . $read . ')', - 'write(' . $write . ')', + 'create(' . $write . ')', + 'update(' . $write . ')', + 'delete(' . $write . ')', ], ]); $this->assertEquals(201, $response['headers']['status-code']); @@ -161,8 +169,10 @@ class DatabasesPermissionsMemberTest extends Scope return $carry; } foreach ($document['$permissions'] as $permission) { - if (\stripos($permission, $item) !== false - && \str_starts_with('read', $permission)) { + if ( + \stripos($permission, $item) !== false + && \str_starts_with('read', $permission) + ) { return true; } } @@ -187,8 +197,10 @@ class DatabasesPermissionsMemberTest extends Scope return $carry; } foreach ($document['$permissions'] as $permission) { - if (\stripos($permission, $item) !== false - && \str_starts_with('read', $permission)) { + if ( + \stripos($permission, $item) !== false + && \str_starts_with('read', $permission) + ) { return true; } } diff --git a/tests/e2e/Services/Databases/DatabasesPermissionsTeamTest.php b/tests/e2e/Services/Databases/DatabasesPermissionsTeamTest.php index cf391042c9..c39f3d04e2 100644 --- a/tests/e2e/Services/Databases/DatabasesPermissionsTeamTest.php +++ b/tests/e2e/Services/Databases/DatabasesPermissionsTeamTest.php @@ -46,7 +46,9 @@ class DatabasesPermissionsTeamTest extends Scope 'name' => 'Collection 1', 'permissions' => [ 'read(team: ' . $teams['team1']['$id'] . ')', - 'write(team: ' . $teams['team1']['$id'] . '/admin)', + 'create(team: ' . $teams['team1']['$id'] . '/admin)', + 'update(team: ' . $teams['team1']['$id'] . '/admin)', + 'delete(team: ' . $teams['team1']['$id'] . '/admin)', ], ]); @@ -63,7 +65,9 @@ class DatabasesPermissionsTeamTest extends Scope 'name' => 'Collection 2', 'permissions' => [ 'read(team: ' . $teams['team2']['$id'] . ')', - 'write(team: ' . $teams['team2']['$id'] . '/owner)', + 'create(team: ' . $teams['team2']['$id'] . '/owner)', + 'update(team: ' . $teams['team2']['$id'] . '/owner)', + 'delete(team: ' . $teams['team2']['$id'] . '/owner)', ] ]); diff --git a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php index 804674c0cf..9f35f3df37 100644 --- a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php @@ -161,7 +161,9 @@ class RealtimeConsoleClientTest extends Scope 'name' => 'Actors', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 941357fa47..29c7142205 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -681,7 +681,9 @@ class RealtimeCustomClientTest extends Scope ], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -726,7 +728,9 @@ class RealtimeCustomClientTest extends Scope ], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -770,7 +774,9 @@ class RealtimeCustomClientTest extends Scope ], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -861,7 +867,9 @@ class RealtimeCustomClientTest extends Scope 'name' => 'Actors', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ] ]); @@ -1069,7 +1077,9 @@ class RealtimeCustomClientTest extends Scope 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -1109,7 +1119,9 @@ class RealtimeCustomClientTest extends Scope ], $this->getHeaders()), [ 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 1650369218..be0a13f1ef 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -24,7 +24,9 @@ trait StorageBase 'allowedFileExtensions' => ["jpg", "png"], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $this->assertEquals(201, $bucket['headers']['status-code']); @@ -40,7 +42,9 @@ trait StorageBase 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $this->assertEquals(201, $file['headers']['status-code']); @@ -66,7 +70,9 @@ trait StorageBase 'fileSecurity' => true, 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $this->assertEquals(201, $bucket2['headers']['status-code']); @@ -100,7 +106,9 @@ trait StorageBase 'file' => $curlFile, 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $counter++; @@ -140,7 +148,9 @@ trait StorageBase 'file' => $curlFile, 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @fclose($handle); @@ -160,7 +170,9 @@ trait StorageBase 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $this->assertEquals(404, $res['headers']['status-code']); @@ -177,7 +189,9 @@ trait StorageBase 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/disk-b/kitten-1.png'), 'image/png', 'kitten-1.png'), 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -196,7 +210,9 @@ trait StorageBase 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/disk-a/kitten-3.gif'), 'image/gif', 'kitten-3.gif'), 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -220,7 +236,9 @@ trait StorageBase 'allowedFileExtensions' => ["jpg", "png"], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $this->assertEquals(400, $failedBucket['headers']['status-code']); @@ -473,7 +491,9 @@ trait StorageBase 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $this->assertEquals(201, $file['headers']['status-code']); @@ -518,7 +538,9 @@ trait StorageBase 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/disk-b/kitten-2.png'), 'image/png', 'logo.png'), 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $this->assertEquals(201, $file['headers']['status-code']); @@ -563,7 +585,9 @@ trait StorageBase ], $this->getHeaders()), [ 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); @@ -592,7 +616,9 @@ trait StorageBase ], $this->getHeaders()), [ 'permissions' => [ 'read(user: ' . $this->getUser()['$id'] . ')', - 'write(user: ' . $this->getUser()['$id'] . ')', + 'create(user: ' . $this->getUser()['$id'] . ')', + 'update(user: ' . $this->getUser()['$id'] . ')', + 'delete(user: ' . $this->getUser()['$id'] . ')', ] ]); diff --git a/tests/e2e/Services/Storage/StorageCustomClientTest.php b/tests/e2e/Services/Storage/StorageCustomClientTest.php index 726b0842ed..0d49aae66a 100644 --- a/tests/e2e/Services/Storage/StorageCustomClientTest.php +++ b/tests/e2e/Services/Storage/StorageCustomClientTest.php @@ -31,7 +31,9 @@ class StorageCustomClientTest extends Scope 'name' => 'Test Bucket', 'permissions' => [ 'read(any)', - 'write(users)', + 'create(users)', + 'update(users)', + 'delete(users)', ], ]); @@ -123,7 +125,9 @@ class StorageCustomClientTest extends Scope 'fileSecurity' => true, 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); $this->assertEquals(201, $bucket['headers']['status-code']); @@ -199,7 +203,9 @@ class StorageCustomClientTest extends Scope 'folderId' => 'xyz', 'permissions' => [ 'read(user:notme)', - 'write(user:notme)', + 'create(user:notme)', + 'update(user:notme)', + 'delete(user:notme)', ], ]); @@ -252,7 +258,9 @@ class StorageCustomClientTest extends Scope ], $this->getHeaders()), [ 'permissions' => [ 'read(user:notme)', - 'write(user:notme)', + 'create(user:notme)', + 'update(user:notme)', + 'delete(user:notme)', ], ]); diff --git a/tests/e2e/Services/Webhooks/WebhooksBase.php b/tests/e2e/Services/Webhooks/WebhooksBase.php index 9a9e67b876..c78b53428e 100644 --- a/tests/e2e/Services/Webhooks/WebhooksBase.php +++ b/tests/e2e/Services/Webhooks/WebhooksBase.php @@ -43,7 +43,9 @@ trait WebhooksBase 'name' => 'Actors', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); @@ -194,7 +196,9 @@ trait WebhooksBase ], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -255,7 +259,9 @@ trait WebhooksBase ], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -316,7 +322,9 @@ trait WebhooksBase ], 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -376,7 +384,9 @@ trait WebhooksBase 'name' => 'Test Bucket', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); @@ -482,7 +492,9 @@ trait WebhooksBase 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'folderId' => 'xyz', ]); @@ -542,7 +554,9 @@ trait WebhooksBase ], $this->getHeaders()), [ 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]); diff --git a/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php b/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php index b8052f2c6d..2601c1c75c 100644 --- a/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php +++ b/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php @@ -159,7 +159,9 @@ class WebhooksCustomServerTest extends Scope 'name' => 'Demo', 'permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], 'documentSecurity' => true, ]); diff --git a/tests/unit/Messaging/MessagingTest.php b/tests/unit/Messaging/MessagingTest.php index b4a7f102b9..2fdccbda72 100644 --- a/tests/unit/Messaging/MessagingTest.php +++ b/tests/unit/Messaging/MessagingTest.php @@ -208,14 +208,18 @@ class MessagingTest extends TestCase '$collection' => 'collection', '$permissions' => [ 'read(admin)', - 'write(admin)', + 'create(admin)', + 'update(admin)', + 'delete(admin)', ], ]), collection: new Document([ '$id' => 'collection', '$permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]), database: new Document([ @@ -238,14 +242,18 @@ class MessagingTest extends TestCase '$collection' => 'collection', '$permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]), collection: new Document([ '$id' => 'collection', '$permissions' => [ 'read(admin)', - 'write(admin)', + 'create(admin)', + 'update(admin)', + 'delete(admin)', ], 'documentSecurity' => true, ]), @@ -270,14 +278,18 @@ class MessagingTest extends TestCase '$collection' => 'bucket', '$permissions' => [ 'read(admin)', - 'write(admin)', + 'create(admin)', + 'update(admin)', + 'delete(admin)', ], ]), bucket: new Document([ '$id' => 'bucket', '$permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]) ); @@ -295,14 +307,18 @@ class MessagingTest extends TestCase '$collection' => 'bucket', '$permissions' => [ 'read(any)', - 'write(any)', + 'create(any)', + 'update(any)', + 'delete(any)', ], ]), bucket: new Document([ '$id' => 'bucket', '$permissions' => [ 'read(admin)', - 'write(admin)', + 'create(admin)', + 'update(admin)', + 'delete(admin)', ], 'documentSecurity' => true ])