diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index e9f280eaef..a00d485bec 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1491,7 +1491,7 @@ App::patch('/v1/account/password') ->action(function (string $password, string $oldPassword, Response $response, Document $user, Database $dbForProject, Event $events) { // Check old password only if its an existing user. - if ($user->getAttribute('passwordUpdate') !== null && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'), $user->getAttribute('hash'), $user->getAttribute('hashOptions'))) { // Double check user password + if (!empty($user->getAttribute('passwordUpdate')) && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'), $user->getAttribute('hash'), $user->getAttribute('hashOptions'))) { // Double check user password throw new Exception(Exception::USER_INVALID_CREDENTIALS); } diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index f22fb7d1c9..861766df8a 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -493,8 +493,8 @@ App::post('/v1/databases/:databaseId/collections') ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new CustomId(), 'Unique Id. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') ->param('name', '', new Text(128), 'Collection name. Max length: 128 chars.') - ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permissions strings. By default no user is granted with any permissions. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.') - ->param('documentSecurity', false, new Boolean(true), 'Whether to enable document-level permissions, where each document\'s permissions will be merged with the collection\'s permissions to determine who has access to each document individually. [Learn more about permissions](/docs/permissions).') + ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permissions strings. By default no user is granted with any permissions. [Learn more about permissions](/docs/permissions).') + ->param('documentSecurity', false, new Boolean(true), 'Enables configuring permissions for individual documents. A user needs one of document or collection level permissions to access a document. [Learn more about permissions](/docs/permissions).') ->inject('response') ->inject('dbForProject') ->inject('events') @@ -748,8 +748,8 @@ App::put('/v1/databases/:databaseId/collections/:collectionId') ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID.') ->param('name', null, new Text(128), 'Collection name. Max length: 128 chars.') - ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default the current permission are inherited. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', true) - ->param('documentSecurity', false, new Boolean(true), 'Whether to enable document-level permissions, where each document\'s permissions will be merged with the collection\'s permissions to determine who has access to each document individually. [Learn more about permissions](/docs/permissions).') + ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default the current permission are inherited. [Learn more about permissions](/docs/permissions).', true) + ->param('documentSecurity', false, new Boolean(true), 'Enables configuring permissions for individual documents. A user needs one of document or collection level permissions to access a document. [Learn more about permissions](/docs/permissions).') ->param('enabled', true, new Boolean(), 'Is collection enabled?', true) ->inject('response') ->inject('dbForProject') @@ -1833,7 +1833,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') ->param('documentId', '', new CustomId(), 'Document ID. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') ->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents.') ->param('data', [], new JSON(), 'Document data as JSON object.') - ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE]), 'An array of permissions strings. By default the current user is granted with all permissions. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', true) + ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE]), 'An array of permissions strings. By default the current user is granted with all permissions. [Learn more about permissions](/docs/permissions).', true) ->inject('response') ->inject('dbForProject') ->inject('user') @@ -2212,7 +2212,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum ->param('collectionId', null, new UID(), 'Collection ID.') ->param('documentId', null, new UID(), 'Document ID.') ->param('data', [], new JSON(), 'Document data as JSON object. Include only attribute and value pairs to be updated.', true) - ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permissions strings. By default the current permissions are inherited. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', true) + ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permissions strings. By default the current permissions are inherited. [Learn more about permissions](/docs/permissions).', true) ->inject('response') ->inject('dbForProject') ->inject('events') diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 4db73b9acf..a32615161f 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -62,7 +62,7 @@ App::post('/v1/functions') ->label('sdk.response.model', Response::MODEL_FUNCTION) ->param('functionId', '', new CustomId(), 'Function ID. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') ->param('name', '', new Text(128), 'Function name. Max length: 128 chars.') - ->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed, each 64 characters long.') + ->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.') ->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.') ->param('events', [], new ArrayList(new ValidatorEvent(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.', true) ->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true) @@ -420,7 +420,7 @@ App::put('/v1/functions/:functionId') ->label('sdk.response.model', Response::MODEL_FUNCTION) ->param('functionId', '', new UID(), 'Function ID.') ->param('name', '', new Text(128), 'Function name. Max length: 128 chars.') - ->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed, each 64 characters long.') + ->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with execution roles. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.') ->param('events', [], new ArrayList(new ValidatorEvent(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.', true) ->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true) ->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Maximum execution time in seconds.', true) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index dbdfccedc2..5ab2e8450b 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -61,8 +61,8 @@ App::post('/v1/storage/buckets') ->label('sdk.response.model', Response::MODEL_BUCKET) ->param('bucketId', '', new CustomId(), 'Unique Id. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') ->param('name', '', new Text(128), 'Bucket name') - ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default no user is granted with any permissions. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', true) - ->param('fileSecurity', false, new Boolean(true), 'Whether to enable file-level permissions, where each file\'s permissions will be merged with the bucket\'s permissions to determine who has access to each file individually. [Learn more about permissions](/docs/permissions).') + ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default no user is granted with any permissions. [Learn more about permissions](/docs/permissions).', true) + ->param('fileSecurity', false, new Boolean(true), 'Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](/docs/permissions).') ->param('enabled', true, new Boolean(true), 'Is bucket enabled?', true) ->param('maximumFileSize', (int) App::getEnv('_APP_STORAGE_LIMIT', 0), new Range(1, (int) App::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(App::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '. For self-hosted setups you can change the max limit by changing the `_APP_STORAGE_LIMIT` environment variable. [Learn more about storage environment variables](docs/environment-variables#storage)', true) ->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true) @@ -118,10 +118,10 @@ App::post('/v1/storage/buckets') 'name' => $name, 'maximumFileSize' => $maximumFileSize, 'allowedFileExtensions' => $allowedFileExtensions, - 'fileSecurity' => (bool) filter_var($fileSecurity, FILTER_VALIDATE_BOOLEAN), - 'enabled' => (bool) filter_var($enabled, FILTER_VALIDATE_BOOLEAN), - 'encryption' => (bool) filter_var($encryption, FILTER_VALIDATE_BOOLEAN), - 'antivirus' => (bool) filter_var($antivirus, FILTER_VALIDATE_BOOLEAN), + 'fileSecurity' => $fileSecurity, + 'enabled' => $enabled, + 'encryption' => $encryption, + 'antivirus' => $antivirus, 'search' => implode(' ', [$bucketId, $name]), ])); @@ -231,8 +231,8 @@ App::put('/v1/storage/buckets/:bucketId') ->label('sdk.response.model', Response::MODEL_BUCKET) ->param('bucketId', '', new UID(), 'Bucket unique ID.') ->param('name', null, new Text(128), 'Bucket name', false) - ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default the current permissions are inherited. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', true) - ->param('fileSecurity', false, new Boolean(true), 'Whether to enable file-level permissions, where each file\'s permissions will be merged with the bucket\'s permissions to determine who has access to each file individually. [Learn more about permissions](/docs/permissions).') + ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default the current permissions are inherited. [Learn more about permissions](/docs/permissions).', true) + ->param('fileSecurity', false, new Boolean(true), 'Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](/docs/permissions).') ->param('enabled', true, new Boolean(true), 'Is bucket enabled?', true) ->param('maximumFileSize', null, new Range(1, (int) App::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human((int)App::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '. For self hosted version you can change the limit by changing _APP_STORAGE_LIMIT environment variable. [Learn more about storage environment variables](docs/environment-variables#storage)', true) ->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true) @@ -267,10 +267,10 @@ App::put('/v1/storage/buckets/:bucketId') ->setAttribute('$permissions', $permissions) ->setAttribute('maximumFileSize', $maximumFileSize) ->setAttribute('allowedFileExtensions', $allowedFileExtensions) - ->setAttribute('fileSecurity', (bool) filter_var($fileSecurity, FILTER_VALIDATE_BOOLEAN)) - ->setAttribute('enabled', (bool) filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) - ->setAttribute('encryption', (bool) filter_var($encryption, FILTER_VALIDATE_BOOLEAN)) - ->setAttribute('antivirus', (bool) filter_var($antivirus, FILTER_VALIDATE_BOOLEAN))); + ->setAttribute('fileSecurity', $fileSecurity) + ->setAttribute('enabled', $enabled) + ->setAttribute('encryption', $encryption) + ->setAttribute('antivirus', $antivirus)); $events ->setParam('bucketId', $bucket->getId()) @@ -341,7 +341,7 @@ App::post('/v1/storage/buckets/:bucketId/files') ->param('bucketId', null, new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).') ->param('fileId', '', new CustomId(), 'File ID. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') ->param('file', [], new File(), 'Binary file.', false) - ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE]), 'An array of permission strings. By default the current user is granted with all permissions. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', true) + ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE]), 'An array of permission strings. By default the current user is granted with all permissions. [Learn more about permissions](/docs/permissions).', true) ->inject('request') ->inject('response') ->inject('dbForProject') @@ -1218,7 +1218,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId') ->label('sdk.response.model', Response::MODEL_FILE) ->param('bucketId', null, new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).') ->param('fileId', '', new UID(), 'File unique ID.') - ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission string. By default the current permissions are inherited. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', true) + ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission string. By default the current permissions are inherited. [Learn more about permissions](/docs/permissions).', true) ->inject('response') ->inject('dbForProject') ->inject('user') diff --git a/app/views/console/settings/index.phtml b/app/views/console/settings/index.phtml index 9b355a7e60..44daa33bb7 100644 --- a/app/views/console/settings/index.phtml +++ b/app/views/console/settings/index.phtml @@ -1,4 +1,8 @@ getParam('services', []); $customDomainsEnabled = $this->getParam('customDomainsEnabled', false); $customDomainsTarget = $this->getParam('customDomainsTarget', false); @@ -57,24 +61,11 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
- +

- - - @@ -144,57 +135,7 @@ $smtpEnabled = $this->getParam('smtpEnabled', false); -
  • Services

    diff --git a/composer.json b/composer.json index 40027ab0f7..2b9aa2d067 100644 --- a/composer.json +++ b/composer.json @@ -45,13 +45,13 @@ "appwrite/php-runtimes": "0.11.*", "utopia-php/framework": "0.21.*", "utopia-php/logger": "0.3.*", - "utopia-php/abuse": "0.11.*", + "utopia-php/abuse": "0.12.*", "utopia-php/analytics": "0.2.*", - "utopia-php/audit": "0.12.*", + "utopia-php/audit": "0.13.*", "utopia-php/cache": "0.6.*", "utopia-php/cli": "0.13.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "dev-refactor-permissions as 0.23.0", + "utopia-php/database": "0.24.*", "utopia-php/locale": "0.4.*", "utopia-php/registry": "0.5.*", "utopia-php/preloader": "0.2.*", diff --git a/composer.lock b/composer.lock index 149ed168ed..d2f881d7cc 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": "64351ec59c6d50023ef9f6195777709b", + "content-hash": "1145ff29befcc4aa21b5002da0b8319c", "packages": [ { "name": "adhocore/jwt", @@ -481,16 +481,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.4.5", + "version": "7.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82" + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", - "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", "shasum": "" }, "require": { @@ -505,10 +505,10 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.1", "ext-curl": "*", "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -518,8 +518,12 @@ }, "type": "library", "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, "branch-alias": { - "dev-master": "7.4-dev" + "dev-master": "7.5-dev" } }, "autoload": { @@ -585,7 +589,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.5" + "source": "https://github.com/guzzle/guzzle/tree/7.5.0" }, "funding": [ { @@ -601,20 +605,20 @@ "type": "tidelift" } ], - "time": "2022-06-20T22:16:13+00:00" + "time": "2022-08-28T15:39:27+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.1", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" + "reference": "b94b2807d85443f9719887892882d0329d1e2598" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", - "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", "shasum": "" }, "require": { @@ -669,7 +673,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.1" + "source": "https://github.com/guzzle/promises/tree/1.5.2" }, "funding": [ { @@ -685,20 +689,20 @@ "type": "tidelift" } ], - "time": "2021-10-22T20:56:57+00:00" + "time": "2022-08-28T14:55:35+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.4.0", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "13388f00956b1503577598873fffb5ae994b5737" + "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/13388f00956b1503577598873fffb5ae994b5737", - "reference": "13388f00956b1503577598873fffb5ae994b5737", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", + "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", "shasum": "" }, "require": { @@ -712,15 +716,19 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.1", "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.8 || ^9.3.10" + "phpunit/phpunit": "^8.5.29 || ^9.5.23" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, "branch-alias": { "dev-master": "2.4-dev" } @@ -784,7 +792,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.0" + "source": "https://github.com/guzzle/psr7/tree/2.4.1" }, "funding": [ { @@ -800,7 +808,7 @@ "type": "tidelift" } ], - "time": "2022-06-20T21:43:11+00:00" + "time": "2022-08-28T14:45:39+00:00" }, { "name": "influxdb/influxdb-php", @@ -1733,23 +1741,23 @@ }, { "name": "utopia-php/abuse", - "version": "0.11.0", + "version": "0.12.0", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "f1096b92a8c47b19b0c55096775c186cab0b0a97" + "reference": "aa1e1aae163ecf8ea81d48857ff55c241dcb695f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/f1096b92a8c47b19b0c55096775c186cab0b0a97", - "reference": "f1096b92a8c47b19b0c55096775c186cab0b0a97", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/aa1e1aae163ecf8ea81d48857ff55c241dcb695f", + "reference": "aa1e1aae163ecf8ea81d48857ff55c241dcb695f", "shasum": "" }, "require": { "ext-curl": "*", "ext-pdo": "*", "php": ">=8.0", - "utopia-php/database": "0.23.0" + "utopia-php/database": "0.24.0" }, "require-dev": { "phpunit/phpunit": "^9.4", @@ -1781,9 +1789,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.11.0" + "source": "https://github.com/utopia-php/abuse/tree/0.12.0" }, - "time": "2022-08-19T08:47:17+00:00" + "time": "2022-08-27T09:50:09+00:00" }, { "name": "utopia-php/analytics", @@ -1842,22 +1850,22 @@ }, { "name": "utopia-php/audit", - "version": "0.12.0", + "version": "0.13.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "fe5d2372d9c7f0e1abcf85eaf59ebeaa6f572168" + "reference": "a2f30ccfba7a61b1718b9ebd4557ed0d8a4dcb5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/fe5d2372d9c7f0e1abcf85eaf59ebeaa6f572168", - "reference": "fe5d2372d9c7f0e1abcf85eaf59ebeaa6f572168", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/a2f30ccfba7a61b1718b9ebd4557ed0d8a4dcb5b", + "reference": "a2f30ccfba7a61b1718b9ebd4557ed0d8a4dcb5b", "shasum": "" }, "require": { "ext-pdo": "*", "php": ">=8.0", - "utopia-php/database": "0.23.0" + "utopia-php/database": "0.24.0" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -1889,9 +1897,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.12.0" + "source": "https://github.com/utopia-php/audit/tree/0.13.0" }, - "time": "2022-08-19T08:47:16+00:00" + "time": "2022-08-27T09:18:57+00:00" }, { "name": "utopia-php/cache", @@ -2052,16 +2060,16 @@ }, { "name": "utopia-php/database", - "version": "dev-refactor-permissions", + "version": "0.24.0", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "a3b291456b0d73ea6b0de1a1bb8fc6713472575e" + "reference": "7da841d65d87e9f2c242589e58c38880def44dd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/a3b291456b0d73ea6b0de1a1bb8fc6713472575e", - "reference": "a3b291456b0d73ea6b0de1a1bb8fc6713472575e", + "url": "https://api.github.com/repos/utopia-php/database/zipball/7da841d65d87e9f2c242589e58c38880def44dd8", + "reference": "7da841d65d87e9f2c242589e58c38880def44dd8", "shasum": "" }, "require": { @@ -2110,9 +2118,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/refactor-permissions" + "source": "https://github.com/utopia-php/database/tree/0.24.0" }, - "time": "2022-08-26T09:03:29+00:00" + "time": "2022-08-27T09:16:05+00:00" }, { "name": "utopia-php/domains", @@ -2833,12 +2841,12 @@ "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "1a67d9dcd2884a6a708176955f83e319ac53059e" + "reference": "bf05fc00755b9d27dac530669ca834f3ceb655ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/1a67d9dcd2884a6a708176955f83e319ac53059e", - "reference": "1a67d9dcd2884a6a708176955f83e319ac53059e", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/bf05fc00755b9d27dac530669ca834f3ceb655ec", + "reference": "bf05fc00755b9d27dac530669ca834f3ceb655ec", "shasum": "" }, "require": { @@ -2876,7 +2884,7 @@ "issues": "https://github.com/appwrite/sdk-generator/issues", "source": "https://github.com/appwrite/sdk-generator/tree/master" }, - "time": "2022-08-19T10:03:22+00:00" + "time": "2022-08-28T04:14:32+00:00" }, { "name": "doctrine/instantiator", @@ -4802,16 +4810,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "fb44e1cc6e557418387ad815780360057e40753e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb44e1cc6e557418387ad815780360057e40753e", + "reference": "fb44e1cc6e557418387ad815780360057e40753e", "shasum": "" }, "require": { @@ -4823,7 +4831,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -4846,7 +4854,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.1.0" }, "funding": [ { @@ -4854,7 +4862,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2022-08-29T06:55:37+00:00" }, { "name": "sebastian/version", @@ -5354,17 +5362,10 @@ "version": "9999999-dev", "alias": "0.19.5", "alias_normalized": "0.19.5.0" - }, - { - "package": "utopia-php/database", - "version": "dev-refactor-permissions", - "alias": "0.23.0", - "alias_normalized": "0.23.0.0" } ], "minimum-stability": "stable", "stability-flags": { - "utopia-php/database": 20, "appwrite/sdk-generator": 20 }, "prefer-stable": false, diff --git a/phpunit.xml b/phpunit.xml index 02e62794cc..fd59a8f236 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -13,7 +13,7 @@ - ./tests/unit/ + ./tests/unit ./tests/e2e/Client.php diff --git a/src/Appwrite/Utopia/Response/Model/Bucket.php b/src/Appwrite/Utopia/Response/Model/Bucket.php index 03e08478bc..18a2d5d685 100644 --- a/src/Appwrite/Utopia/Response/Model/Bucket.php +++ b/src/Appwrite/Utopia/Response/Model/Bucket.php @@ -30,7 +30,7 @@ class Bucket extends Model ]) ->addRule('$permissions', [ 'type' => self::TYPE_STRING, - 'description' => 'File permissions. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', + 'description' => 'Bucket permissions. [Learn more about permissions](/docs/permissions).', 'default' => [], 'example' => ['read("any")'], 'array' => true, diff --git a/src/Appwrite/Utopia/Response/Model/Collection.php b/src/Appwrite/Utopia/Response/Model/Collection.php index 899c93cb90..5d1e88d521 100644 --- a/src/Appwrite/Utopia/Response/Model/Collection.php +++ b/src/Appwrite/Utopia/Response/Model/Collection.php @@ -30,7 +30,7 @@ class Collection extends Model ]) ->addRule('$permissions', [ 'type' => self::TYPE_STRING, - 'description' => 'Collection permissions. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', + 'description' => 'Collection permissions. [Learn more about permissions](/docs/permissions).', 'default' => '', 'example' => ['read("any")'], 'array' => true diff --git a/src/Appwrite/Utopia/Response/Model/Document.php b/src/Appwrite/Utopia/Response/Model/Document.php index 2c2bc02410..3b69d38a30 100644 --- a/src/Appwrite/Utopia/Response/Model/Document.php +++ b/src/Appwrite/Utopia/Response/Model/Document.php @@ -56,7 +56,7 @@ class Document extends Any ]) ->addRule('$permissions', [ 'type' => self::TYPE_STRING, - 'description' => 'Document permissions. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', + 'description' => 'Document permissions. [Learn more about permissions](/docs/permissions).', 'default' => '', 'example' => ['read("any")'], 'array' => true, diff --git a/src/Appwrite/Utopia/Response/Model/File.php b/src/Appwrite/Utopia/Response/Model/File.php index 23ef620c75..6d82928713 100644 --- a/src/Appwrite/Utopia/Response/Model/File.php +++ b/src/Appwrite/Utopia/Response/Model/File.php @@ -36,7 +36,7 @@ class File extends Model ]) ->addRule('$permissions', [ 'type' => self::TYPE_STRING, - 'description' => 'File permissions. [Learn more about permissions](/docs/permissions) and get a full list of available permissions.', + 'description' => 'File permissions. [Learn more about permissions](/docs/permissions).', 'default' => [], 'example' => ['read("any")'], 'array' => true, diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 5d31250205..114a80dd3b 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -50,10 +50,7 @@ trait DatabasesBase 'name' => 'Movies', 'documentSecurity' => true, 'permissions' => [ - Permission::read(Role::any()), - Permission::create(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()), + Permission::create(Role::user($this->getUser()['$id'])), ], ]); @@ -1581,8 +1578,8 @@ trait DatabasesBase ], 'permissions' => [ Permission::read(Role::user($this->getUser()['$id'])), - Permission::update(Role::user(ID::custom($this->getUser()['$id']))), - Permission::delete(Role::user(ID::custom($this->getUser()['$id']))), + Permission::update(Role::user($this->getUser()['$id'])), + Permission::delete(Role::user($this->getUser()['$id'])), ] ]); @@ -2266,13 +2263,20 @@ trait DatabasesBase $this->assertCount(0, $document['body']['$permissions']); $this->assertEquals([], $document['body']['$permissions']); - // Check user can still read document due to collection permissions of read("any") + // Check client side can no longer read the document. $document = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents/' . $id, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); - $this->assertEquals(200, $document['headers']['status-code']); + switch ($this->getSide()) { + case 'client': + $this->assertEquals(404, $document['headers']['status-code']); + break; + case 'server': + $this->assertEquals(200, $document['headers']['status-code']); + break; + } return $data; } diff --git a/tests/e2e/Services/Databases/DatabasesPermissionsMemberTest.php b/tests/e2e/Services/Databases/DatabasesPermissionsMemberTest.php index aedc53854a..59091956b0 100644 --- a/tests/e2e/Services/Databases/DatabasesPermissionsMemberTest.php +++ b/tests/e2e/Services/Databases/DatabasesPermissionsMemberTest.php @@ -95,6 +95,12 @@ class DatabasesPermissionsMemberTest extends Scope 'users' => 11, 'doconly' => 6, ], + [ + 'permissions' => [Permission::read(Role::users()), Permission::update(Role::users()), Permission::delete(Role::users())], + 'any' => 12, + 'users' => 12, + 'doconly' => 7, + ], ]; } diff --git a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php index 1daa4ef0a0..30c3c261ab 100644 --- a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php @@ -7,7 +7,7 @@ use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Client; use Tests\E2E\Scopes\SideConsole; use Utopia\Database\ID; -use Utopia\Database\Query; +use Utopia\Database\Role; class FunctionsConsoleClientTest extends Scope { @@ -22,7 +22,7 @@ class FunctionsConsoleClientTest extends Scope ], $this->getHeaders()), [ 'functionId' => ID::unique(), 'name' => 'Test', - 'execute' => ["user:{$this->getUser()['$id']}"], + 'execute' => [Role::user($this->getUser()['$id'])->toString()], 'runtime' => 'php-8.0', 'events' => [ 'users.*.create', diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index ff69f6abc5..bdcfc66b93 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -54,7 +54,7 @@ class FunctionsCustomClientTest extends Scope ], [ 'functionId' => ID::unique(), 'name' => 'Test', - 'execute' => ["user:{$this->getUser()['$id']}"], + 'execute' => [Role::user($this->getUser()['$id'])->toString()], 'runtime' => 'php-8.0', 'events' => [ 'users.*.create', diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 1b0ee751d6..9b270c559f 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -396,7 +396,7 @@ class ProjectsConsoleClientTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'provider' => 'unknown', - 'appId' => ID::custom('AppId'), + 'appId' => 'AppId', 'secret' => 'Secret', ]); diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index ed81e843d8..1cd7cd9c90 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -648,10 +648,7 @@ class RealtimeCustomClientTest extends Scope 'collectionId' => ID::unique(), 'name' => 'Actors', 'permissions' => [ - Permission::read(Role::users()), - Permission::create(Role::users()), - Permission::update(Role::users()), - Permission::delete(Role::users()), + Permission::create(Role::user($this->getUser()['$id'])), ], 'documentSecurity' => true, ]); diff --git a/tests/unit/Auth/AuthTest.php b/tests/unit/Auth/AuthTest.php index 21436c5155..362b0ee9b4 100644 --- a/tests/unit/Auth/AuthTest.php +++ b/tests/unit/Auth/AuthTest.php @@ -371,13 +371,13 @@ class AuthTest extends TestCase $roles = Auth::getRoles($user); $this->assertCount(7, $roles); - $this->assertContains('users', $roles); - $this->assertContains('user:123', $roles); - $this->assertContains('team:abc', $roles); - $this->assertContains('team:abc/administrator', $roles); - $this->assertContains('team:abc/moderator', $roles); - $this->assertContains('team:def', $roles); - $this->assertContains('team:def/guest', $roles); + $this->assertContains(Role::users()->toString(), $roles); + $this->assertContains(Role::user(ID::custom('123'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'), 'administrator')->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'), 'moderator')->toString(), $roles); + $this->assertContains(Role::team(ID::custom('def'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('def'), 'guest')->toString(), $roles); } public function testPrivilegedUserRoles(): void @@ -405,13 +405,13 @@ class AuthTest extends TestCase $roles = Auth::getRoles($user); $this->assertCount(5, $roles); - $this->assertNotContains('users', $roles); - $this->assertNotContains('user:123', $roles); - $this->assertContains('team:abc', $roles); - $this->assertContains('team:abc/administrator', $roles); - $this->assertContains('team:abc/moderator', $roles); - $this->assertContains('team:def', $roles); - $this->assertContains('team:def/guest', $roles); + $this->assertNotContains(Role::users()->toString(), $roles); + $this->assertNotContains(Role::user(ID::custom('123'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'), 'administrator')->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'), 'moderator')->toString(), $roles); + $this->assertContains(Role::team(ID::custom('def'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('def'), 'guest')->toString(), $roles); } public function testAppUserRoles(): void @@ -439,12 +439,12 @@ class AuthTest extends TestCase $roles = Auth::getRoles($user); $this->assertCount(5, $roles); - $this->assertNotContains('users', $roles); - $this->assertNotContains('user:123', $roles); - $this->assertContains('team:abc', $roles); - $this->assertContains('team:abc/administrator', $roles); - $this->assertContains('team:abc/moderator', $roles); - $this->assertContains('team:def', $roles); - $this->assertContains('team:def/guest', $roles); + $this->assertNotContains(Role::users()->toString(), $roles); + $this->assertNotContains(Role::user(ID::custom('123'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'), 'administrator')->toString(), $roles); + $this->assertContains(Role::team(ID::custom('abc'), 'moderator')->toString(), $roles); + $this->assertContains(Role::team(ID::custom('def'))->toString(), $roles); + $this->assertContains(Role::team(ID::custom('def'), 'guest')->toString(), $roles); } } diff --git a/tests/unit/Messaging/MessagingChannelsTest.php b/tests/unit/Messaging/MessagingChannelsTest.php index 1472961281..b97df78196 100644 --- a/tests/unit/Messaging/MessagingChannelsTest.php +++ b/tests/unit/Messaging/MessagingChannelsTest.php @@ -58,7 +58,7 @@ class MessagingChannelsTest extends TestCase 'roles' => [ empty($index % 2) ? Auth::USER_ROLE_ADMIN - : Role::users()->toString(), + : 'member', ] ] ] @@ -288,7 +288,7 @@ class MessagingChannelsTest extends TestCase ID::custom('team' . $index), (empty($index % 2) ? Auth::USER_ROLE_ADMIN - : Role::users()->toString()) + : 'member') )->toString() ];