1
0
Fork 0
mirror of synced 2024-05-21 05:02:37 +12:00

Update V15 request filters for storage, teams, and users

This commit is contained in:
Steven Nguyen 2022-09-09 17:44:57 +00:00
parent ddd15921a3
commit 668ebe4f41
4 changed files with 274 additions and 68 deletions

View file

@ -45,13 +45,13 @@
"appwrite/php-runtimes": "0.11.*",
"utopia-php/framework": "0.21.*",
"utopia-php/logger": "0.3.*",
"utopia-php/abuse": "0.12.*",
"utopia-php/abuse": "0.13.*",
"utopia-php/analytics": "0.2.*",
"utopia-php/audit": "0.13.*",
"utopia-php/audit": "0.14.*",
"utopia-php/cache": "0.6.*",
"utopia-php/cli": "0.13.*",
"utopia-php/config": "0.2.*",
"utopia-php/database": "0.24.*",
"utopia-php/database": "0.25.*",
"utopia-php/locale": "0.4.*",
"utopia-php/registry": "0.5.*",
"utopia-php/preloader": "0.2.*",
@ -77,7 +77,7 @@
}
],
"require-dev": {
"appwrite/sdk-generator": "0.23.0",
"appwrite/sdk-generator": "0.25.0",
"ext-fileinfo": "*",
"phpunit/phpunit": "9.5.20",
"squizlabs/php_codesniffer": "^3.6",

92
composer.lock generated
View file

@ -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": "39c0ee0169b4681e5c07889d2a285d01",
"content-hash": "6194919aa35d896dc3dfdb846936cba4",
"packages": [
{
"name": "adhocore/jwt",
@ -1591,25 +1591,25 @@
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.1.1",
"version": "v2.5.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918"
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
"reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
"shasum": ""
},
"require": {
"php": ">=8.1"
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.1-dev"
"dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
@ -1638,7 +1638,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1"
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2"
},
"funding": [
{
@ -1654,7 +1654,7 @@
"type": "tidelift"
}
],
"time": "2022-02-25T11:15:52+00:00"
"time": "2022-01-02T09:53:40+00:00"
},
{
"name": "symfony/polyfill-php80",
@ -1741,23 +1741,23 @@
},
{
"name": "utopia-php/abuse",
"version": "0.12.0",
"version": "0.13.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/abuse.git",
"reference": "aa1e1aae163ecf8ea81d48857ff55c241dcb695f"
"reference": "4c1b8fe742f17158c59550cdfd9074a94bf474ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/aa1e1aae163ecf8ea81d48857ff55c241dcb695f",
"reference": "aa1e1aae163ecf8ea81d48857ff55c241dcb695f",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/4c1b8fe742f17158c59550cdfd9074a94bf474ac",
"reference": "4c1b8fe742f17158c59550cdfd9074a94bf474ac",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-pdo": "*",
"php": ">=8.0",
"utopia-php/database": "0.24.0"
"utopia-php/database": "0.25.*"
},
"require-dev": {
"phpunit/phpunit": "^9.4",
@ -1789,9 +1789,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/abuse/issues",
"source": "https://github.com/utopia-php/abuse/tree/0.12.0"
"source": "https://github.com/utopia-php/abuse/tree/0.13.1"
},
"time": "2022-08-27T09:50:09+00:00"
"time": "2022-09-07T16:02:58+00:00"
},
{
"name": "utopia-php/analytics",
@ -1850,22 +1850,22 @@
},
{
"name": "utopia-php/audit",
"version": "0.13.0",
"version": "0.14.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/audit.git",
"reference": "a2f30ccfba7a61b1718b9ebd4557ed0d8a4dcb5b"
"reference": "b011224ed9bfef7e5c849938e65619af28f7cf41"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/a2f30ccfba7a61b1718b9ebd4557ed0d8a4dcb5b",
"reference": "a2f30ccfba7a61b1718b9ebd4557ed0d8a4dcb5b",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/b011224ed9bfef7e5c849938e65619af28f7cf41",
"reference": "b011224ed9bfef7e5c849938e65619af28f7cf41",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"php": ">=8.0",
"utopia-php/database": "0.24.0"
"utopia-php/database": "0.25.*"
},
"require-dev": {
"phpunit/phpunit": "^9.3",
@ -1897,9 +1897,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/audit/issues",
"source": "https://github.com/utopia-php/audit/tree/0.13.0"
"source": "https://github.com/utopia-php/audit/tree/0.14.1"
},
"time": "2022-08-27T09:18:57+00:00"
"time": "2022-09-07T16:03:16+00:00"
},
{
"name": "utopia-php/cache",
@ -2060,16 +2060,16 @@
},
{
"name": "utopia-php/database",
"version": "0.24.0",
"version": "0.25.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "7da841d65d87e9f2c242589e58c38880def44dd8"
"reference": "140bbedf1c4d622990fb94d26681fcca235cd5b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/7da841d65d87e9f2c242589e58c38880def44dd8",
"reference": "7da841d65d87e9f2c242589e58c38880def44dd8",
"url": "https://api.github.com/repos/utopia-php/database/zipball/140bbedf1c4d622990fb94d26681fcca235cd5b9",
"reference": "140bbedf1c4d622990fb94d26681fcca235cd5b9",
"shasum": ""
},
"require": {
@ -2118,9 +2118,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.24.0"
"source": "https://github.com/utopia-php/database/tree/0.25.2"
},
"time": "2022-08-27T09:16:05+00:00"
"time": "2022-09-09T03:58:01+00:00"
},
{
"name": "utopia-php/domains",
@ -2178,16 +2178,16 @@
},
{
"name": "utopia-php/framework",
"version": "0.21.0",
"version": "0.21.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/framework.git",
"reference": "5aa5431788460a782065e42b0e8a35e7f139af2f"
"reference": "c81789b87a917da2daf336738170ebe01f50ea18"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/framework/zipball/5aa5431788460a782065e42b0e8a35e7f139af2f",
"reference": "5aa5431788460a782065e42b0e8a35e7f139af2f",
"url": "https://api.github.com/repos/utopia-php/framework/zipball/c81789b87a917da2daf336738170ebe01f50ea18",
"reference": "c81789b87a917da2daf336738170ebe01f50ea18",
"shasum": ""
},
"require": {
@ -2221,9 +2221,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/framework/issues",
"source": "https://github.com/utopia-php/framework/tree/0.21.0"
"source": "https://github.com/utopia-php/framework/tree/0.21.1"
},
"time": "2022-08-12T11:37:21+00:00"
"time": "2022-09-07T09:56:28+00:00"
},
{
"name": "utopia-php/image",
@ -2840,16 +2840,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.23.0",
"version": "0.25.0",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "efadccb9abd6263d045ef157881143d3a59dc710"
"reference": "91e2b9bfb06521faabd610935cbfc1825110666a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/efadccb9abd6263d045ef157881143d3a59dc710",
"reference": "efadccb9abd6263d045ef157881143d3a59dc710",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/91e2b9bfb06521faabd610935cbfc1825110666a",
"reference": "91e2b9bfb06521faabd610935cbfc1825110666a",
"shasum": ""
},
"require": {
@ -2884,9 +2884,9 @@
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
"support": {
"issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/0.23.0"
"source": "https://github.com/appwrite/sdk-generator/tree/0.25.0"
},
"time": "2022-09-04T17:29:33+00:00"
"time": "2022-09-06T16:32:52+00:00"
},
{
"name": "doctrine/instantiator",
@ -5382,7 +5382,13 @@
"ext-fileinfo": "*"
},
"platform-overrides": {
"php": "8.0"
"php": "8.0",
"ext-imagick": "3.7.0",
"ext-yaml": "2.2.2",
"ext-redis": "5.3.7",
"ext-swoole": "4.8.10",
"ext-zstd": "0.11.0",
"ext-mongodb": "1.13.0"
},
"plugin-api-version": "2.3.0"
"plugin-api-version": "2.2.0"
}

View file

@ -4,6 +4,9 @@ namespace Appwrite\Utopia\Request\Filters;
use Appwrite\Utopia\Request\Filter;
use Utopia\Database\Database;
use Utopia\Database\Permission;
use Utopia\Database\Query;
use Utopia\Database\Role;
class V15 extends Filter
{
@ -15,6 +18,8 @@ class V15 extends Filter
case 'databases.listLogs':
case 'databases.listCollectionLogs':
case 'databases.listDocumentLogs':
case 'teams.listLogs':
case 'users.getLogs':
$content = $this->convertLimitAndOffset($content);
break;
case 'account.initials':
@ -25,6 +30,11 @@ class V15 extends Filter
case 'functions.list':
case 'functions.listDeployments':
case 'projects.list':
case 'storage.listBuckets':
case 'storage.listFiles':
case 'teams.list':
case 'teams.getMemberships':
case 'users.list':
$content = $this->convertLimitAndOffset($content);
$content = $this->convertCursor($content);
$content = $this->convertOrderType($content);
@ -36,6 +46,8 @@ class V15 extends Filter
break;
case 'databases.createDocument':
case 'databases.updateDocument':
case 'storage.createFile':
case 'storage.updateFile':
$content = $this->convertReadWrite($content);
break;
case 'databases.listDocuments':
@ -56,6 +68,11 @@ class V15 extends Filter
case 'projects.updateKey':
$content = $this->convertExpire($content);
break;
case 'storage.createBucket':
case 'storage.updateBucket':
$content = $this->convertBucketPermission($content);
$content = $this->convertReadWrite($content);
break;
}
return $content;
@ -145,13 +162,13 @@ class V15 extends Filter
if (isset($content['read'])) {
foreach ($content['read'] as $read) {
if ($read === 'role:all') {
$content['permissions'][] = 'read("any")';
$content['permissions'][] = Permission::read(Role::any());
} elseif ($read === 'role:guest') {
$content['permissions'][] = 'read("guests")';
$content['permissions'][] = Permission::read(Role::guests());
} elseif ($read === 'role:member') {
$content['permissions'][] = 'read("users")';
$content['permissions'][] = Permission::read(Role::users());
} elseif (str_contains($read, ':')) {
$content['permissions'][] = 'read("' . $read . '")';
$content['permissions'][] = Permission::read(Role::parse($read));
}
}
}
@ -159,12 +176,12 @@ class V15 extends Filter
if (isset($content['write'])) {
foreach ($content['write'] as $write) {
if ($write === 'role:all' || $write === 'role:member') {
$content['permissions'][] = 'write("users")';
$content['permissions'][] = Permission::write(Role::users());
} elseif ($write === 'role:guest') {
// don't add because, historically,
// role:guest for write did nothing
} elseif (str_contains($write, ':')) {
$content['permissions'][] = 'write("' . $write . '")';
$content['permissions'][] = Permission::write(Role::parse($write));
}
}
}
@ -182,13 +199,13 @@ class V15 extends Filter
}
$operations = [
'equal' => 'equal',
'notEqual' => 'notEqual',
'lesser' => 'lessThan',
'lesserEqual' => 'lessThanEqual',
'greater' => 'greaterThan',
'greaterEqual' => 'greaterThanEqual',
'search' => 'search',
'equal' => Query::TYPE_EQUAL,
'notEqual' => Query::TYPE_NOTEQUAL,
'lesser' => Query::TYPE_LESSER,
'lesserEqual' => Query::TYPE_LESSEREQUAL,
'greater' => Query::TYPE_GREATER,
'greaterEqual' => Query::TYPE_GREATEREQUAL,
'search' => Query::TYPE_SEARCH,
];
foreach ($content['queries'] as $i => $query) {
foreach ($operations as $oldOperation => $newOperation) {
@ -215,7 +232,7 @@ class V15 extends Filter
$execute = [];
foreach ($content['execute'] as $role) {
if ($role === 'role:all' || $role === 'role:member') {
$execute[] = 'users';
$execute[] = Role::users()->toString();
} elseif ($role === 'role:guest') {
// don't add because, historically,
// role:guest for write did nothing
@ -244,4 +261,15 @@ class V15 extends Filter
return $content;
}
protected function convertBucketPermission($content)
{
if (isset($content['permission'])) {
$content['fileSecurity'] = $content['permission'] === 'file';
}
unset($content['permission']);
return $content;
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace Tests\Unit\Utopia\Database\Validator;
namespace Tests\Unit\Utopia\Database\Request\Filters;
use Appwrite\Utopia\Request\Filter;
use Appwrite\Utopia\Request\Filters\V15;
@ -160,7 +160,7 @@ class V15Test extends TestCase
$this->assertEquals($expected, $result);
}
public function permissionProvider(): array
public function collectionPermissionProvider(): array
{
return [
'permission collection' => [
@ -244,7 +244,7 @@ class V15Test extends TestCase
}
/**
* @dataProvider permissionProvider
* @dataProvider collectionPermissionProvider
* @dataProvider readWriteProvider
*/
public function testCreateCollection(array $content, array $expected): void
@ -284,7 +284,7 @@ class V15Test extends TestCase
}
/**
* @dataProvider permissionProvider
* @dataProvider collectionPermissionProvider
* @dataProvider readWriteProvider
*/
public function testUpdateCollection(array $content, array $expected): void
@ -389,7 +389,7 @@ class V15Test extends TestCase
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result, 'fail');
$this->assertEquals($expected, $result);
}
/**
@ -416,7 +416,8 @@ class V15Test extends TestCase
$this->assertEquals($expected, $result);
}
public function executeProvider() : array {
public function executeProvider(): array
{
return [
'all roles' => [
[
@ -526,7 +527,7 @@ class V15Test extends TestCase
$this->assertEquals($expected, $result);
}
public function expireProvider() : array
public function expireProvider(): array
{
return [
'empty' => [
@ -567,4 +568,175 @@ class V15Test extends TestCase
$this->assertEquals($expected, $result);
}
public function bucketPermissionProvider(): array
{
return [
'permission bucket' => [
['permission' => 'bucket'],
['fileSecurity' => false],
],
'permission document' => [
['permission' => 'file'],
['fileSecurity' => true],
],
'permission empty' => [
[],
[],
],
'permission invalid' => [
['permission' => 'invalid'],
['fileSecurity' => false],
],
];
}
/**
* @dataProvider bucketPermissionProvider
* @dataProvider readWriteProvider
*/
public function testCreateBucket(array $content, array $expected)
{
$model = 'storage.createBucket';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider limitOffsetCursorOrderTypeProvider
* @dataProvider limitOffsetProvider
* @dataProvider cursorProvider
* @dataProvider orderTypeProvider
*/
public function testListBuckets(array $content, array $expected): void
{
$model = 'storage.listBuckets';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider bucketPermissionProvider
* @dataProvider readWriteProvider
*/
public function testUpdateBucket(array $content, array $expected)
{
$model = 'storage.updateBucket';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider readWriteProvider
*/
public function testCreateFile(array $content, array $expected)
{
$model = 'storage.createFile';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider limitOffsetCursorOrderTypeProvider
* @dataProvider limitOffsetProvider
* @dataProvider cursorProvider
* @dataProvider orderTypeProvider
*/
public function testListFiles(array $content, array $expected): void
{
$model = 'storage.listFiles';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider readWriteProvider
*/
public function testUpdateFile(array $content, array $expected)
{
$model = 'storage.updateFile';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider limitOffsetCursorOrderTypeProvider
* @dataProvider limitOffsetProvider
* @dataProvider cursorProvider
* @dataProvider orderTypeProvider
*/
public function testListTeams(array $content, array $expected): void
{
$model = 'teams.list';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider limitOffsetCursorOrderTypeProvider
* @dataProvider limitOffsetProvider
* @dataProvider cursorProvider
* @dataProvider orderTypeProvider
*/
public function testGetTeamMemberships(array $content, array $expected): void
{
$model = 'teams.getMemberships';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider limitOffsetProvider
*/
public function testListTeamLogs(array $content, array $expected): void
{
$model = 'teams.listLogs';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider limitOffsetCursorOrderTypeProvider
* @dataProvider limitOffsetProvider
* @dataProvider cursorProvider
* @dataProvider orderTypeProvider
*/
public function testListUsers(array $content, array $expected): void
{
$model = 'users.list';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider limitOffsetProvider
*/
public function testGetUserLogs(array $content, array $expected): void
{
$model = 'users.getLogs';
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
}