Handle aggregates per resource type at the controller level

This commit is contained in:
Jake Barnby
2022-08-16 17:54:44 +12:00
parent bf2fa212aa
commit f672269a8c
5 changed files with 135 additions and 20 deletions
+24 -1
View File
@@ -525,6 +525,12 @@ App::post('/v1/databases/:databaseId/collections')
$collectionId = $collectionId == 'unique()' ? ID::unique() : $collectionId;
/**
* Map aggregate permissions into the multiple permissions they represent,
* accounting for the resource type given that some types not allowed specific permissions.
*/
$permissions = PermissionsProcessor::aggregate($permissions, 'collection');
try {
$dbForProject->createDocument('database_' . $database->getInternalId(), new Document([
'$id' => $collectionId,
@@ -792,7 +798,12 @@ App::put('/v1/databases/:databaseId/collections/:collectionId')
}
$permissions ??= $collection->getPermissions() ?? [];
/**
* Map aggregate permissions into the multiple permissions they represent.
*/
$permissions = PermissionsProcessor::aggregate($permissions, 'collection');
$enabled ??= $collection->getAttribute('enabled', true);
try {
@@ -1933,6 +1944,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
}
/**
* Map aggregate permissions into the multiple permissions they represent,
* accounting for the resource type given that some types not allowed specific permissions.
*/
$permissions = PermissionsProcessor::aggregate($permissions, 'document');
/**
* Add permissions for current the user for any missing types
* from the allowed permissions for this resource type.
@@ -2363,6 +2380,12 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
}
}
/**
* Map aggregate permissions into the multiple permissions they represent,
* accounting for the resource type given that some types not allowed specific permissions.
*/
$permissions = PermissionsProcessor::aggregate($permissions, 'document');
if (\is_null($permissions)) {
$permissions = $document->getPermissions() ?? [];
}
+25
View File
@@ -74,6 +74,13 @@ App::post('/v1/storage/buckets')
->action(function (string $bucketId, string $name, ?array $permissions, string $fileSecurity, bool $enabled, int $maximumFileSize, array $allowedFileExtensions, bool $encryption, bool $antivirus, Response $response, Database $dbForProject, Audit $audits, Stats $usage, Event $events) {
$bucketId = $bucketId === 'unique()' ? ID::unique() : $bucketId;
/**
* Map aggregate permissions into the multiple permissions they represent,
* accounting for the resource type given that some types not allowed specific permissions.
*/
$permissions = PermissionsProcessor::aggregate($permissions, 'bucket');
try {
$files = Config::getParam('collections', [])['files'] ?? [];
if (empty($files)) {
@@ -261,6 +268,12 @@ App::put('/v1/storage/buckets/:bucketId')
$encryption ??= $bucket->getAttribute('encryption', true);
$antivirus ??= $bucket->getAttribute('antivirus', true);
/**
* Map aggregate permissions into the multiple permissions they represent,
* accounting for the resource type given that some types not allowed specific permissions.
*/
$permissions = PermissionsProcessor::aggregate($permissions, 'bucket');
$bucket = $dbForProject->updateDocument('buckets', $bucket->getId(), $bucket
->setAttribute('name', $name)
->setAttribute('$permissions', $permissions)
@@ -375,6 +388,12 @@ App::post('/v1/storage/buckets/:bucketId/files')
throw new Exception('Unauthorized permissions', 401, Exception::USER_UNAUTHORIZED);
}
/**
* Map aggregate permissions into the multiple permissions they represent,
* accounting for the resource type given that some types not allowed specific permissions.
*/
$permissions = PermissionsProcessor::aggregate($permissions, 'file');
/**
* Add permissions for current the user for any missing types
* from the allowed permissions for this resource type.
@@ -1323,6 +1342,12 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
}
}
/**
* Map aggregate permissions into the multiple permissions they represent,
* accounting for the resource type given that some types not allowed specific permissions.
*/
$permissions = PermissionsProcessor::aggregate($permissions, 'file');
$file->setAttribute('$permissions', $permissions);
$file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
+3 -3
View File
@@ -45,13 +45,13 @@
"appwrite/php-runtimes": "0.10.*",
"utopia-php/framework": "0.20.*",
"utopia-php/logger": "0.3.*",
"utopia-php/abuse": "0.9.*",
"utopia-php/abuse": "dev-refactor-permissions",
"utopia-php/analytics": "0.2.*",
"utopia-php/audit": "0.10.*",
"utopia-php/audit": "dev-refactor-permissions",
"utopia-php/cache": "0.6.*",
"utopia-php/cli": "0.13.*",
"utopia-php/config": "0.2.*",
"utopia-php/database": "0.20.*",
"utopia-php/database": "dev-refactor-permissions",
"utopia-php/locale": "0.4.*",
"utopia-php/registry": "0.5.*",
"utopia-php/preloader": "0.2.*",
Generated
+19 -16
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": "ec0e0c2072927a82fc801a757777ad73",
"content-hash": "d49d34cbdc70504ea61c5548bd60278a",
"packages": [
{
"name": "adhocore/jwt",
@@ -1733,17 +1733,17 @@
},
{
"name": "utopia-php/abuse",
"version": "0.9.0",
"version": "dev-refactor-permissions",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/abuse.git",
"reference": "34156bb5292d704bb8bc8141bb5151126ed4830a"
"reference": "496cba1f2e7f50a6faebdb77b9178a99d755b49a"
},
"require": {
"ext-curl": "*",
"ext-pdo": "*",
"php": ">=8.0",
"utopia-php/database": "0.20.0"
"utopia-php/database": "dev-refactor-permissions"
},
"require-dev": {
"phpunit/phpunit": "^9.4",
@@ -1772,7 +1772,7 @@
"upf",
"utopia"
],
"time": "2022-08-15T07:35:56+00:00"
"time": "2022-08-16T05:16:56+00:00"
},
{
"name": "utopia-php/analytics",
@@ -1831,16 +1831,16 @@
},
{
"name": "utopia-php/audit",
"version": "0.10.0",
"version": "dev-refactor-permissions",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/audit.git",
"reference": "458da3e60ea222bf9791f4891591d7f2ee16e4bb"
"reference": "cd3f0f2fd4716e32333397fedd8e7f07932361ec"
},
"require": {
"ext-pdo": "*",
"php": ">=8.0",
"utopia-php/database": "0.20.0"
"utopia-php/database": "dev-refactor-permissions"
},
"require-dev": {
"phpunit/phpunit": "^9.3",
@@ -1869,7 +1869,7 @@
"upf",
"utopia"
],
"time": "2022-08-14T19:59:21+00:00"
"time": "2022-08-16T05:16:47+00:00"
},
{
"name": "utopia-php/cache",
@@ -2030,11 +2030,11 @@
},
{
"name": "utopia-php/database",
"version": "0.20.0",
"version": "dev-refactor-permissions",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "cd89b41564223cddf7d87a41bbaf736a0c89f327"
"reference": "a1f4c0dbe387cde1d26916d6d1cfddbfe54f3e82"
},
"require": {
"ext-mongodb": "*",
@@ -2084,7 +2084,7 @@
"upf",
"utopia"
],
"time": "2022-08-14T15:22:34+00:00"
"time": "2022-08-16T05:14:16+00:00"
},
{
"name": "utopia-php/domains",
@@ -2805,12 +2805,12 @@
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "409e9a6f24a2ad4be7fd45bc424ff5d845c7eb51"
"reference": "807e7890aed597ef47e01be8ad11c3b561b7c1e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/409e9a6f24a2ad4be7fd45bc424ff5d845c7eb51",
"reference": "409e9a6f24a2ad4be7fd45bc424ff5d845c7eb51",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/807e7890aed597ef47e01be8ad11c3b561b7c1e8",
"reference": "807e7890aed597ef47e01be8ad11c3b561b7c1e8",
"shasum": ""
},
"require": {
@@ -2848,7 +2848,7 @@
"issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/master"
},
"time": "2022-08-10T12:49:03+00:00"
"time": "2022-08-15T22:33:25+00:00"
},
{
"name": "doctrine/instantiator",
@@ -5330,6 +5330,9 @@
],
"minimum-stability": "stable",
"stability-flags": {
"utopia-php/abuse": 20,
"utopia-php/audit": 20,
"utopia-php/database": 20,
"appwrite/sdk-generator": 20
},
"prefer-stable": false,
@@ -0,0 +1,64 @@
<?php
namespace Appwrite\Permissions;
use Utopia\Database\Database;
use Utopia\Database\Permission;
class PermissionsProcessor
{
public static function aggregate(?array $permissions, string $resource): ?array
{
if (\is_null($permissions)) {
return null;
}
$aggregates = self::getAggregates($resource);
foreach ($permissions as $i => $permission) {
$permission = Permission::parse($permission);
foreach ($aggregates as $type => $subTypes) {
if ($permission->getPermission() != $type) {
continue;
}
foreach ($subTypes as $subType) {
$permissions[] = (new Permission(
$subType,
$permission->getRole(),
$permission->getIdentifier(),
$permission->getDimension()
))->toString();
}
unset($permissions[$i]);
}
}
return $permissions;
}
private static function getAggregates($resource): array
{
$aggregates = [];
switch ($resource) {
case 'document':
case 'file':
$aggregates['write'] = [
Database::PERMISSION_UPDATE,
Database::PERMISSION_DELETE
];
break;
case 'collection':
case 'bucket':
$aggregates['write'] = [
Database::PERMISSION_CREATE,
Database::PERMISSION_UPDATE,
Database::PERMISSION_DELETE
];
break;
}
return $aggregates;
}
}