Skip to content

Commit

Permalink
Add guard parameter to can() (#2526)
Browse files Browse the repository at this point in the history
* Add guard parameter to can()

As discussed in comments on 2515: #2515 (comment)

Co-authored-by: parallels999 <parallels999@users.noreply.github.com>
  • Loading branch information
drbyte and parallels999 authored Oct 25, 2023
1 parent 669d828 commit 239abc5
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 3 deletions.
7 changes: 5 additions & 2 deletions src/PermissionRegistrar.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ public function getPermissionsTeamId()
*/
public function registerPermissions(Gate $gate): bool
{
$gate->before(function (Authorizable $user, string $ability) {
$gate->before(function (Authorizable $user, string $ability, array &$args = []) {
if (is_string($args[0] ?? null) && ! class_exists($args[0])) {
$guard = array_shift($args);
}
if (method_exists($user, 'checkPermissionTo')) {
return $user->checkPermissionTo($ability) ?: null;
return $user->checkPermissionTo($ability, $guard ?? null) ?: null;
}
});

Expand Down
30 changes: 30 additions & 0 deletions tests/BladeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,36 @@ public function all_blade_directives_will_evaluate_false_when_somebody_with_anot
$this->assertEquals('does not have any of the given roles', $this->renderView('hasAnyRole', compact('roles')));
}

/** @test */
public function the_can_directive_can_accept_a_guard_name()
{
$user = $this->getWriter();
$user->givePermissionTo('edit-articles');
auth()->setUser($user);

$permission = 'edit-articles';
$guard = 'web';
$this->assertEquals('has permission', $this->renderView('can', compact('permission', 'guard')));
$guard = 'admin';
$this->assertEquals('does not have permission', $this->renderView('can', compact('permission', 'guard')));

auth()->logout();

// log in as the Admin with the permission-via-role
$this->testAdmin->givePermissionTo($this->testAdminPermission);
$user = $this->testAdmin;
auth()->setUser($user);

$permission = 'edit-articles';
$guard = 'web';
$this->assertEquals('does not have permission', $this->renderView('can', compact('permission', 'guard')));

$permission = 'admin-permission';
$guard = 'admin';
$this->assertTrue($this->testAdmin->checkPermissionTo($permission, $guard));
$this->assertEquals('has permission', $this->renderView('can', compact('permission', 'guard')));
}

/** @test */
public function the_can_directive_will_evaluate_true_when_the_logged_in_user_has_the_permission()
{
Expand Down
42 changes: 42 additions & 0 deletions tests/MultipleGuardsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ protected function getEnvironmentSetUp($app)
'api' => ['driver' => 'token', 'provider' => 'users'],
'jwt' => ['driver' => 'token', 'provider' => 'users'],
'abc' => ['driver' => 'abc'],
'admin' => ['driver' => 'session', 'provider' => 'admins'],
]);

$this->setUpRoutes();
Expand Down Expand Up @@ -53,6 +54,47 @@ public function it_can_give_a_permission_to_a_model_that_is_used_by_multiple_gua
$this->assertFalse($this->testUser->checkPermissionTo('do_that', 'web'));
}

/** @test */
public function the_gate_can_grant_permission_to_a_user_by_passing_a_guard_name()
{
$this->testUser->givePermissionTo(app(Permission::class)::create([
'name' => 'do_this',
'guard_name' => 'web',
]));

$this->testUser->givePermissionTo(app(Permission::class)::create([
'name' => 'do_that',
'guard_name' => 'api',
]));

$this->assertTrue($this->testUser->can('do_this', 'web'));
$this->assertTrue($this->testUser->can('do_that', 'api'));
$this->assertFalse($this->testUser->can('do_that', 'web'));

$this->assertTrue($this->testUser->cannot('do_that', 'web'));
$this->assertTrue($this->testUser->canAny(['do_this', 'do_that'], 'web'));

$this->testAdminRole->givePermissionTo($this->testAdminPermission);
$this->testAdmin->assignRole($this->testAdminRole);

$this->assertTrue($this->testAdmin->hasPermissionTo($this->testAdminPermission));
$this->assertTrue($this->testAdmin->can('admin-permission'));
$this->assertTrue($this->testAdmin->can('admin-permission', 'admin'));
$this->assertTrue($this->testAdmin->cannot('admin-permission', 'web'));

$this->assertTrue($this->testAdmin->cannot('non-existing-permission'));
$this->assertTrue($this->testAdmin->cannot('non-existing-permission', 'web'));
$this->assertTrue($this->testAdmin->cannot('non-existing-permission', 'admin'));
$this->assertTrue($this->testAdmin->cannot(['admin-permission', 'non-existing-permission'], 'web'));

$this->assertFalse($this->testAdmin->can('edit-articles', 'web'));
$this->assertFalse($this->testAdmin->can('edit-articles', 'admin'));

$this->assertTrue($this->testUser->cannot('edit-articles', 'admin'));
$this->assertTrue($this->testUser->cannot('admin-permission', 'admin'));
$this->assertTrue($this->testUser->cannot('admin-permission', 'web'));
}

/** @test */
public function it_can_honour_guardName_function_on_model_for_overriding_guard_name_property()
{
Expand Down
2 changes: 1 addition & 1 deletion tests/resources/views/can.blade.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@can($permission)
@can($permission, $guard ?? null)
has permission
@else
does not have permission
Expand Down

0 comments on commit 239abc5

Please sign in to comment.