Skip to content

Commit b3a995c

Browse files
authoredOct 29, 2021
Option for custom logic for checking permissions (spatie#1891)
* option for custom logic for checking permissions added * tests * docs for Custom Permission Check added
1 parent fb4f027 commit b3a995c

10 files changed

+81
-7
lines changed
 

‎config/permission.php

+7
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@
9696
'team_foreign_key' => 'team_id',
9797
],
9898

99+
/*
100+
* When set to true, the method for checking permissions will be registered on the gate.
101+
* Set this to false, if you want to implement custom logic for checking permissions.
102+
*/
103+
104+
'register_permission_check_method' => true,
105+
99106
/*
100107
* When set to true the package implements teams using the 'team_foreign_key'. If you want
101108
* the migrations to register the 'team_foreign_key', you must set this to true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
title: Custom Permission Check
3+
weight: 6
4+
---
5+
6+
By default, a method is registered on [Laravel's gate](https://laravel.com/docs/authorization). This method is responsible for checking if the user has the required permission or not. Whether a user has a permission or not is determined by checking the user's permissions stored in the database.
7+
8+
However, in some cases, you might want to implement custom logic for checking if the user has a permission or not.
9+
10+
Let's say that your application uses access tokens for authentication and when issuing the tokens, you add a custom claim containing all the permissions the user has. In this case, if you want to check whether the user has the required permission or not based on the permissions in your custom claim in the access token, then you need to implement your own logic for handling this.
11+
12+
You could, for example, create a `before` method to handle this:
13+
14+
**app/Providers/AuthServiceProvider.php**
15+
```php
16+
public function boot()
17+
{
18+
...
19+
20+
Gate::before(function ($user, $ability) {
21+
return $user->hasTokenPermission($ability) ?: null;
22+
});
23+
}
24+
```
25+
Here `hasTokenPermission` is a custom method you need to implement yourself.
26+
27+
### Register Permission Check Method
28+
By default, `register_permission_check_method` is set to `true`.
29+
Only set this to false if you want to implement custom logic for checking permissions.

‎docs/advanced-usage/other.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Other
3-
weight: 8
3+
weight: 9
44
---
55

66
Schema Diagram:

‎docs/advanced-usage/phpstorm.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: PhpStorm Interaction
3-
weight: 7
3+
weight: 8
44
---
55

66
# Extending PhpStorm

‎docs/advanced-usage/timestamps.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Timestamps
3-
weight: 8
3+
weight: 10
44
---
55

66
### Excluding Timestamps from JSON

‎docs/advanced-usage/ui-options.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: UI Options
3-
weight: 10
3+
weight: 11
44
---
55

66
## Need a UI?

‎docs/advanced-usage/uuid.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: UUID
3-
weight: 6
3+
weight: 7
44
---
55

66
If you're using UUIDs or GUIDs for your User models there are a few considerations to note.

‎src/PermissionServiceProvider.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ public function boot(PermissionRegistrar $permissionLoader)
2222

2323
$this->registerModelBindings();
2424

25-
$permissionLoader->clearClassPermissions();
26-
$permissionLoader->registerPermissions();
25+
if ($this->app->config['permission.register_permission_check_method']) {
26+
$permissionLoader->clearClassPermissions();
27+
$permissionLoader->registerPermissions();
28+
}
2729

2830
$this->app->singleton(PermissionRegistrar::class, function ($app) use ($permissionLoader) {
2931
return $permissionLoader;

‎tests/CustomGateTest.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Spatie\Permission\Test;
4+
5+
use Illuminate\Contracts\Auth\Access\Gate;
6+
7+
class CustomGateTest extends TestCase
8+
{
9+
protected function getEnvironmentSetUp($app)
10+
{
11+
parent::getEnvironmentSetUp($app);
12+
13+
$app['config']->set('permission.register_permission_check_method', false);
14+
}
15+
16+
/** @test */
17+
public function it_doesnt_register_the_method_for_checking_permissions_on_the_gate()
18+
{
19+
$this->testUser->givePermissionTo('edit-articles');
20+
21+
$this->assertEmpty(app(Gate::class)->abilities());
22+
$this->assertFalse($this->testUser->can('edit-articles'));
23+
}
24+
25+
/** @test */
26+
public function it_can_authorize_using_custom_method_for_checking_permissions()
27+
{
28+
app(Gate::class)->define('edit-articles', function () {
29+
return true;
30+
});
31+
32+
$this->assertArrayHasKey('edit-articles', app(Gate::class)->abilities());
33+
$this->assertTrue($this->testUser->can('edit-articles'));
34+
}
35+
}

‎tests/TestCase.php

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ protected function getPackageProviders($app)
7979
*/
8080
protected function getEnvironmentSetUp($app)
8181
{
82+
$app['config']->set('permission.register_permission_check_method', true);
8283
$app['config']->set('permission.teams', $this->hasTeams);
8384
$app['config']->set('permission.testing', true); //fix sqlite
8485
$app['config']->set('permission.column_names.model_morph_key', 'model_test_id');

0 commit comments

Comments
 (0)
Please sign in to comment.