You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(auth): support hierarchical permission wildcards
Add hierarchical wildcard matching for Shield permissions.
- Support nested trailing wildcards like forum.posts.*
- Support middle-segment wildcards like forum.*.create
- Share wildcard matching between user and group permission checks
- Document wildcard semantics and direct user wildcard assignment
- Cover matcher behavior and public authorization paths
Co-authored-by: bgeneto <bgeneto@duck.com>
Co-authored-by: christianberkman <christianberkman@users.noreply.github.com>
Signed-off-by: memleakd <121398829+memleakd@users.noreply.github.com>
Copy file name to clipboardExpand all lines: docs/quick_start_guide/using_authorization.md
+18-2Lines changed: 18 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,7 @@ When a user registers on your site, they are assigned the group specified at `Co
22
22
23
23
### Change Available Permissions
24
24
25
-
The permissions on the site are stored in the `AuthGroups` config file also. Each one is defined by a string that represents a context and a permission, joined with a decimal point.
25
+
The permissions on the site are stored in the `AuthGroups` config file also. Each one is defined by a string with dot-separated segments, like `users.create` or `forum.posts.create`.
26
26
27
27
```php
28
28
public array $permissions = [
@@ -42,19 +42,24 @@ public array $permissions = [
42
42
43
43
### Assign Permissions to a Group
44
44
45
-
Each group can have its own specific set of permissions. These are defined in `Config\AuthGroups::$matrix`. You can specify each permission by it's full name, or using the context and an asterisk (*) to specify all permissions within that context.
45
+
Each group can have its own specific set of permissions. These are defined in `Config\AuthGroups::$matrix`. You can specify each permission by its full name, or use `*` as a wildcard segment.
46
46
47
47
```php
48
48
public array $matrix = [
49
49
'superadmin' => [
50
50
'admin.*',
51
+
'forum.posts.*',
51
52
'users.*',
52
53
'beta.access',
53
54
],
54
55
//
55
56
];
56
57
```
57
58
59
+
A trailing `*` wildcard on a dotted scope matches the scope itself and all child permission segments. For example, `forum.posts.*` matches `forum.posts`, `forum.posts.create`, and `forum.posts.comments.delete`.
60
+
When `*` appears between segments, it matches exactly one segment. For example, `forum.*.create` matches `forum.posts.create`.
61
+
Parent matching applies to dotted scopes like `forum.posts`, not root labels like `forum`. The first segment cannot be `*`, and a standalone `*` permission does not grant all permissions.
62
+
58
63
## Assign Permissions to a User
59
64
60
65
Permissions can also be assigned directly to a user, regardless of what groups they belong to. This is done programatically on the `User` Entity.
Wildcard permissions can also be assigned directly to a user, but they must be listed in `Config\AuthGroups::$permissions`
74
+
before they can be assigned.
75
+
76
+
```php
77
+
public array $permissions = [
78
+
'forum.posts.*' => 'Can manage forum posts',
79
+
];
80
+
81
+
$user->addPermission('forum.posts.*');
82
+
```
83
+
68
84
This will add all new permissions. You can also sync permissions so that the user ONLY has the given permissions directly assigned to them. Any not in the provided list are removed from the user.
Copy file name to clipboardExpand all lines: docs/references/authorization.md
+38-7Lines changed: 38 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,9 +35,9 @@ public string $defaultGroup = 'user';
35
35
36
36
## Defining Available Permissions
37
37
38
-
All permissions must be added to the `AuthGroups` config file, also. A permission is simply a string consisting of
39
-
a scope and action, like `users.create`. The scope would be`users` and the action would be `create`. Each permission
40
-
can have a description for display within UIs if needed.
38
+
Permissions that can be assigned directly to users must be added to the `AuthGroups` config file.
39
+
A permission is a string consisting of dot-separated segments, like`users.create` or
40
+
`forum.posts.create`. Each permission can have a description for display within UIs if needed.
41
41
42
42
```php
43
43
public array $permissions = [
@@ -58,7 +58,7 @@ config file, under the `$matrix` property.
58
58
59
59
!!! note
60
60
61
-
This defines **group-level permissons**.
61
+
This defines **group-level permissions**.
62
62
63
63
The matrix is an associative array with the group name as the key,
64
64
and an array of permissions that should be applied to that group.
@@ -73,23 +73,43 @@ public array $matrix = [
73
73
];
74
74
```
75
75
76
-
You can use a wildcard within a scope to allow all actions within that scope, by using a `*` in place of the action.
76
+
You can use `*` as a wildcard segment to allow permissions under a scope. A wildcard matches one full segment.
77
+
When the wildcard is trailing on a dotted scope, it also grants the parent scope itself and all descendant permissions.
78
+
The first segment cannot be `*`, and a standalone `*` permission does not grant all permissions.
77
79
78
80
```php
79
81
public array $matrix = [
80
82
'superadmin' => ['admin.*', 'users.*', 'beta.*'],
81
83
];
82
84
```
83
85
86
+
For example, `forum.posts.*` matches `forum.posts`, `forum.posts.create`, and `forum.posts.comments.delete`.
87
+
Wildcards can also appear between segments: `forum.*.create` matches `forum.posts.create` and
88
+
`forum.comments.create`, but does not match `forum.create` or `forum.posts.comments.create`.
89
+
Since `$user->can()` expects dot-separated permissions like `scope.action`, parent matching applies to dotted
90
+
permission scopes like `forum.posts`, not to root labels like `forum`.
91
+
92
+
Exact child permissions do not grant their parent permission. For example, `forum.posts.create` does not grant
93
+
`forum.posts`.
94
+
95
+
Wildcard matching is used by `$user->can()` and `$group->can()` for both user-level and group-level permissions.
96
+
97
+
!!! warning
98
+
99
+
Wildcard permissions can grant access to the parent scope and to future child permissions added under the
100
+
same scope. Use broad wildcards like `admin.*` carefully, and prefer literal permissions for highly sensitive
101
+
access.
102
+
84
103
## Authorizing Users
85
104
86
105
The `Authorizable` trait on the `User` entity provides the following methods to authorize your users.
87
106
88
107
#### can()
89
108
90
-
Allows you to check if a user is permitted to do a specific action or group or actions. The permission string(s) should be passed as the argument(s). Returns
109
+
Allows you to check if a user has one or more permissions. The permission string(s) should be passed as the argument(s). Returns
91
110
boolean `true`/`false`. Will check the user's direct permissions (**user-level permissions**) first, and then check against all of the user's groups
92
-
permissions (**group-level permissions**) to determine if they are allowed.
111
+
permissions (**group-level permissions**) to determine if they are allowed. Wildcard permissions are supported for both
0 commit comments