From 07cd5a7972cf5ebedc6a85493c04c603f20f7847 Mon Sep 17 00:00:00 2001 From: Bernhard Enders Date: Wed, 19 Feb 2025 11:43:04 -0300 Subject: [PATCH] feat: Support hierarchical permissions in method --- src/Authorization/Traits/Authorizable.php | 10 ++++++++-- src/Entities/Group.php | 12 ++++++++++-- tests/Authorization/GroupTest.php | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/Authorization/Traits/Authorizable.php b/src/Authorization/Traits/Authorizable.php index 6e4f4b21b..3516ee1e1 100644 --- a/src/Authorization/Traits/Authorizable.php +++ b/src/Authorization/Traits/Authorizable.php @@ -280,8 +280,14 @@ public function can(string ...$permissions): bool } // Check wildcard match - $check = substr($permission, 0, strpos($permission, '.')) . '.*'; - if (isset($matrix[$group]) && in_array($check, $matrix[$group], true)) { + $checks = []; + $parts = explode('.', $permission); + + for ($i = count($parts); $i > 0; $i--) { + $check = implode('.', array_slice($parts, 0, $i)) . '.*'; + $checks[] = $check; + } + if (isset($matrix[$group]) && array_intersect($checks, $matrix[$group]) !== []) { return true; } } diff --git a/src/Entities/Group.php b/src/Entities/Group.php index b63707929..5b417a6b2 100644 --- a/src/Entities/Group.php +++ b/src/Entities/Group.php @@ -85,9 +85,17 @@ public function can(string $permission): bool } // Check wildcard match - $check = substr($permission, 0, strpos($permission, '.')) . '.*'; + $checks = []; + $parts = explode('.', $permission); - return $this->permissions !== null && $this->permissions !== [] && in_array($check, $this->permissions, true); + for ($i = count($parts); $i > 0; $i--) { + $check = implode('.', array_slice($parts, 0, $i)) . '.*'; + $checks[] = $check; + } + + return $this->permissions !== null + && $this->permissions !== [] + && array_intersect($checks, $this->permissions) !== []; } /** diff --git a/tests/Authorization/GroupTest.php b/tests/Authorization/GroupTest.php index 68c190be8..baa03c07c 100644 --- a/tests/Authorization/GroupTest.php +++ b/tests/Authorization/GroupTest.php @@ -87,4 +87,26 @@ public function testCan(): void $this->assertTrue($group2->can('users.edit')); $this->assertFalse($group2->can('foo.bar')); } + + public function testCanNestedPerms(): void + { + $group = $this->groups->info('user'); + $group->addPermission('foo.bar.*'); + $group->addPermission('foo.biz.buz.*'); + $this->assertTrue($group->can('foo.bar')); + $this->assertTrue($group->can('foo.bar.*')); + $this->assertTrue($group->can('foo.bar.baz')); + $this->assertTrue($group->can('foo.bar.buz')); + $this->assertTrue($group->can('foo.bar.buz.biz')); + $this->assertTrue($group->can('foo.biz.buz')); + $this->assertTrue($group->can('foo.biz.buz.*')); + $this->assertTrue($group->can('foo.biz.buz.bar')); + $this->assertFalse($group->can('foo')); + $this->assertFalse($group->can('foo.*')); + $this->assertFalse($group->can('foo.biz')); + $this->assertFalse($group->can('foo.buz')); + $this->assertFalse($group->can('foo.biz.*')); + $this->assertFalse($group->can('foo.biz.bar')); + $this->assertFalse($group->can('foo.biz.bar.buz')); + } }