Skip to content

Commit 07cd5a7

Browse files
committed
feat: Support hierarchical permissions in method
1 parent e782eb0 commit 07cd5a7

3 files changed

Lines changed: 40 additions & 4 deletions

File tree

src/Authorization/Traits/Authorizable.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,14 @@ public function can(string ...$permissions): bool
280280
}
281281

282282
// Check wildcard match
283-
$check = substr($permission, 0, strpos($permission, '.')) . '.*';
284-
if (isset($matrix[$group]) && in_array($check, $matrix[$group], true)) {
283+
$checks = [];
284+
$parts = explode('.', $permission);
285+
286+
for ($i = count($parts); $i > 0; $i--) {
287+
$check = implode('.', array_slice($parts, 0, $i)) . '.*';
288+
$checks[] = $check;
289+
}
290+
if (isset($matrix[$group]) && array_intersect($checks, $matrix[$group]) !== []) {
285291
return true;
286292
}
287293
}

src/Entities/Group.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,17 @@ public function can(string $permission): bool
8585
}
8686

8787
// Check wildcard match
88-
$check = substr($permission, 0, strpos($permission, '.')) . '.*';
88+
$checks = [];
89+
$parts = explode('.', $permission);
8990

90-
return $this->permissions !== null && $this->permissions !== [] && in_array($check, $this->permissions, true);
91+
for ($i = count($parts); $i > 0; $i--) {
92+
$check = implode('.', array_slice($parts, 0, $i)) . '.*';
93+
$checks[] = $check;
94+
}
95+
96+
return $this->permissions !== null
97+
&& $this->permissions !== []
98+
&& array_intersect($checks, $this->permissions) !== [];
9199
}
92100

93101
/**

tests/Authorization/GroupTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,26 @@ public function testCan(): void
8787
$this->assertTrue($group2->can('users.edit'));
8888
$this->assertFalse($group2->can('foo.bar'));
8989
}
90+
91+
public function testCanNestedPerms(): void
92+
{
93+
$group = $this->groups->info('user');
94+
$group->addPermission('foo.bar.*');
95+
$group->addPermission('foo.biz.buz.*');
96+
$this->assertTrue($group->can('foo.bar'));
97+
$this->assertTrue($group->can('foo.bar.*'));
98+
$this->assertTrue($group->can('foo.bar.baz'));
99+
$this->assertTrue($group->can('foo.bar.buz'));
100+
$this->assertTrue($group->can('foo.bar.buz.biz'));
101+
$this->assertTrue($group->can('foo.biz.buz'));
102+
$this->assertTrue($group->can('foo.biz.buz.*'));
103+
$this->assertTrue($group->can('foo.biz.buz.bar'));
104+
$this->assertFalse($group->can('foo'));
105+
$this->assertFalse($group->can('foo.*'));
106+
$this->assertFalse($group->can('foo.biz'));
107+
$this->assertFalse($group->can('foo.buz'));
108+
$this->assertFalse($group->can('foo.biz.*'));
109+
$this->assertFalse($group->can('foo.biz.bar'));
110+
$this->assertFalse($group->can('foo.biz.bar.buz'));
111+
}
90112
}

0 commit comments

Comments
 (0)