From 88d45bb191b929eca7178088362e0339b4108671 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Wed, 10 Mar 2021 02:36:38 -0600 Subject: [PATCH] Add aliasing support to AuthManager permission registration and fixed an issue where the permission cache wasn't cleared after changing the available permissions --- composer.json | 2 +- modules/backend/classes/AuthManager.php | 28 ++++++++++++++++++- tests/UiTestCase.php | 2 +- .../unit/backend/classes/AuthManagerTest.php | 16 +++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 6014801401..226ef8d5c5 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ "require-dev": { "fzaninotto/faker": "~1.7", "phpunit/phpunit": "~6.5", - "phpunit/phpunit-selenium": "~1.2", + "phpunit/phpunit-selenium": "~4.1.0", "meyfa/phpunit-assert-gd": "1.1.0", "squizlabs/php_codesniffer": "3.*", "php-parallel-lint/php-parallel-lint": "^1.0", diff --git a/modules/backend/classes/AuthManager.php b/modules/backend/classes/AuthManager.php index 694ef8ed7b..c0a9247ccf 100644 --- a/modules/backend/classes/AuthManager.php +++ b/modules/backend/classes/AuthManager.php @@ -47,6 +47,11 @@ class AuthManager extends StormAuthManager */ protected $permissions = []; + /** + * @var array List of owner aliases. ['Aliased.Owner' => 'Real.Owner'] + */ + protected $aliases = []; + /** * @var array List of registered permission roles. */ @@ -94,8 +99,11 @@ public function registerCallback(callable $callback) */ public function registerPermissions($owner, array $definitions) { + // Resolve alias + $owner = $this->aliases[$owner] ?? $owner; + foreach ($definitions as $code => $definition) { - $permission = (object)array_merge(self::$permissionDefaults, array_merge($definition, [ + $permission = (object) array_merge(self::$permissionDefaults, array_merge($definition, [ 'code' => $code, 'owner' => $owner ])); @@ -104,6 +112,18 @@ public function registerPermissions($owner, array $definitions) } } + /** + * Register a permission owner alias + * + * @param string $owner The owner to register an alias for. Example: Real.Owner + * @param string $alias The alias to register. Example: Aliased.Owner + * @return void + */ + public function registerPermissionOwnerAlias(string $owner, string $alias) + { + $this->aliases[$alias] = $owner; + } + /** * Removes a single back-end permission * @param string $owner Specifies the permissions' owner plugin or module in the format Author.Plugin @@ -116,6 +136,9 @@ public function removePermission($owner, $code) throw new SystemException('Unable to remove permissions before they are loaded.'); } + // Resolve alias + $owner = $this->aliases[$owner] ?? $owner; + $ownerPermissions = array_filter($this->permissions, function ($permission) use ($owner) { return $permission->owner === $owner; }); @@ -125,6 +148,9 @@ public function removePermission($owner, $code) unset($this->permissions[$key]); } } + + // Clear the permission cache + $this->permissionCache = false; } /** diff --git a/tests/UiTestCase.php b/tests/UiTestCase.php index e4fc5bcafe..5b58ddaddf 100644 --- a/tests/UiTestCase.php +++ b/tests/UiTestCase.php @@ -1,6 +1,6 @@ pluck('code')->toArray()); } + public function testAliasesPermissions() + { + $this->instance->registerPermissionOwnerAlias('Winter.TestCase', 'Aliased.TestCase'); + + $permissions = $this->instance->listPermissions(); + $this->assertCount(2, $permissions); + + $this->instance->removePermission('Aliased.TestCase', 'test.permission_one'); + + $permissions = $this->instance->listPermissions(); + $this->assertCount(1, $permissions); + $this->assertEquals([ + 'test.permission_two' + ], collect($permissions)->pluck('code')->toArray()); + } + public function testRegisterPermissionsThroughCallbacks() { // Callback one