diff --git a/phpunit.xml b/phpunit.xml index 55995070..5474f9fb 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,4 +16,4 @@ ./tests/ - \ No newline at end of file + diff --git a/src/Middleware/LaratrustAbility.php b/src/Middleware/LaratrustAbility.php index 7c8ac2c9..8414d3ce 100644 --- a/src/Middleware/LaratrustAbility.php +++ b/src/Middleware/LaratrustAbility.php @@ -21,7 +21,7 @@ class LaratrustAbility extends LaratrustMiddleware */ public function handle($request, Closure $next, $roles, $permissions, $team = null, $options = '') { - list($team, $validateAll, $guard) = $this->assignRealValuesTo($team, $options); + [$team, $validateAll, $guards] = $this->assignRealValuesTo($team, $options); if (!is_array($roles)) { $roles = explode(self::DELIMITER, $roles); @@ -31,16 +31,14 @@ public function handle($request, Closure $next, $roles, $permissions, $team = nu $permissions = explode(self::DELIMITER, $permissions); } - if ( - Auth::guard($guard)->guest() - || !Auth::guard($guard)->user() - ->ability($roles, $permissions, $team, [ + foreach ($guards as $guard) { + if (!Auth::guard($guard)->guest() && Auth::guard($guard)->user()->ability($roles, $permissions, $team, [ 'validate_all' => $validateAll - ]) - ) { - return $this->unauthorized(); + ])) { + return $next($request); + } } - return $next($request); + return $this->unauthorized(); } } diff --git a/src/Middleware/LaratrustMiddleware.php b/src/Middleware/LaratrustMiddleware.php index 7fb3977e..a2f903f7 100644 --- a/src/Middleware/LaratrustMiddleware.php +++ b/src/Middleware/LaratrustMiddleware.php @@ -24,15 +24,23 @@ class LaratrustMiddleware */ protected function authorization($type, $rolesPermissions, $team, $options) { - list($team, $requireAll, $guard) = $this->assignRealValuesTo($team, $options); + [$team, $requireAll, $guards] = $this->assignRealValuesTo($team, $options); $method = $type == 'roles' ? 'hasRole' : 'hasPermission'; if (!is_array($rolesPermissions)) { $rolesPermissions = explode(self::DELIMITER, $rolesPermissions); } - return !Auth::guard($guard)->guest() - && Auth::guard($guard)->user()->$method($rolesPermissions, $team, $requireAll); + foreach ($guards as $guard) { + if (!Auth::guard($guard)->guest() && Auth::guard($guard)->user()->$method( + $rolesPermissions, + $team, + $requireAll + )) { + return true; + } + } + return false; } /** @@ -70,10 +78,10 @@ protected function assignRealValuesTo($team, $options) return [ (Str::contains($team, ['require_all', 'guard:']) ? null : $team), (Str::contains($team, 'require_all') ?: Str::contains($options, 'require_all')), - (Str::contains($team, 'guard:') ? $this->extractGuard($team) : ( + (Str::contains($team, 'guard:') ? $this->extractGuards($team) : ( Str::contains($options, 'guard:') - ? $this->extractGuard($options) - : Config::get('auth.defaults.guard') + ? $this->extractGuards($options) + : [Config::get('auth.defaults.guard')] )), ]; } @@ -84,7 +92,7 @@ protected function assignRealValuesTo($team, $options) * @param string $string * @return string */ - protected function extractGuard($string) + protected function extractGuards($string) { $options = Collection::make(explode('|', $string)); @@ -92,6 +100,6 @@ protected function extractGuard($string) return strpos($option, 'guard:') === false; })->map(function ($option) { return explode(':', $option)[1]; - })->first(); + }); } } diff --git a/tests/Checkers/User/LaratrustUserCanCheckerTestCase.php b/tests/Checkers/User/LaratrustUserCanCheckerTestCase.php index ec298278..d3bc355a 100644 --- a/tests/Checkers/User/LaratrustUserCanCheckerTestCase.php +++ b/tests/Checkers/User/LaratrustUserCanCheckerTestCase.php @@ -7,7 +7,7 @@ use Laratrust\Tests\LaratrustTestCase; use Laratrust\Tests\Models\Permission; -class LaratrustUserCanCheckerTestCase extends LaratrustTestCase +abstract class LaratrustUserCanCheckerTestCase extends LaratrustTestCase { protected $user; diff --git a/tests/Middleware/LaratrustPermissionTest.php b/tests/Middleware/LaratrustPermissionTest.php index 74866bfd..4f870cdb 100644 --- a/tests/Middleware/LaratrustPermissionTest.php +++ b/tests/Middleware/LaratrustPermissionTest.php @@ -143,6 +143,59 @@ public function testHandle_IsLoggedInWithPermission_ShouldNotAbort() }, 'users-create|users-update', 'TeamA', 'guard:api|require_all')); } + public function testHandle_IsLoggedInWithPermissionAndMultipleGuards_ShouldNotAbort() + { + /* + |------------------------------------------------------------ + | Set + |------------------------------------------------------------ + */ + $guard2 = m::mock('Illuminate\Contracts\Auth\Guard'); + $user = m::mock('Laratrust\Tests\Models\User')->makePartial(); + $middleware = new LaratrustPermission($this->guard); + + /* + |------------------------------------------------------------ + | Expectation + |------------------------------------------------------------ + */ + Auth::shouldReceive('guard')->with('api')->andReturn($this->guard); + Auth::shouldReceive('guard')->with('web')->andReturn($guard2); + $this->guard->shouldReceive('guest')->andReturn(true); + $guard2->shouldReceive('guest')->andReturn(false); + $guard2->shouldReceive('user')->andReturn($user); + $user->shouldReceive('hasPermission') + ->with( + ['users-create', 'users-update'], + m::anyOf(null, 'TeamA'), + m::anyOf(true, false) + ) + ->andReturn(true); + + /* + |------------------------------------------------------------ + | Assertion + |------------------------------------------------------------ + */ + $this->assertNull($middleware->handle($this->request, function () { + }, 'users-create|users-update')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'users-create|users-update', 'guard:api|guard:web')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'users-create|users-update', 'require_all')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'users-create|users-update', 'guard:api|guard:web|require_all')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'users-create|users-update', 'TeamA', 'require_all')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'users-create|users-update', 'TeamA', 'guard:api|guard:web|require_all')); + } + public function testHandle_IsLoggedInWithNoPermission_ShouldRedirectWithError() { /* diff --git a/tests/Middleware/MiddlewareLaratrustAbilityTest.php b/tests/Middleware/MiddlewareLaratrustAbilityTest.php index 2cb90540..c484e89c 100644 --- a/tests/Middleware/MiddlewareLaratrustAbilityTest.php +++ b/tests/Middleware/MiddlewareLaratrustAbilityTest.php @@ -143,4 +143,59 @@ public function testHandle_IsLoggedInWithAbility_ShouldNotAbort() $this->assertNull($middleware->handle($this->request, function () { }, 'admin|user', 'edit-users|update-users', 'TeamA', 'require_all|guard:api')); } + + + public function testHandle_IsLoggedInWithAbilityAndMultipleGuards_ShouldNotAbort() + { + /* + |------------------------------------------------------------ + | Set + |------------------------------------------------------------ + */ + $guard2 = m::mock('Illuminate\Contracts\Auth\Guard'); + $user = m::mock('Laratrust\Tests\Models\User')->makePartial(); + $middleware = new LaratrustAbility($this->guard); + + /* + |------------------------------------------------------------ + | Expectation + |------------------------------------------------------------ + */ + Auth::shouldReceive('guard')->with('api')->andReturn($this->guard); + Auth::shouldReceive('guard')->with('web')->andReturn($guard2); + $this->guard->shouldReceive('guest')->andReturn(true); + $guard2->shouldReceive('guest')->andReturn(false); + $guard2->shouldReceive('user')->andReturn($user); + $user->shouldReceive('ability') + ->with( + ['admin', 'user'], + ['edit-users', 'update-users'], + m::anyOf(null, 'TeamA'), + m::anyOf(['validate_all' => true], ['validate_all' => false]) + ) + ->andReturn(true); + + /* + |------------------------------------------------------------ + | Assertion + |------------------------------------------------------------ + */ + $this->assertNull($middleware->handle($this->request, function () { + }, 'admin|user', 'edit-users|update-users')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'admin|user', 'edit-users|update-users', 'guard:api|guard:web')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'admin|user', 'edit-users|update-users', 'require_all')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'admin|user', 'edit-users|update-users', 'guard:api|guard:web|require_all')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'admin|user', 'edit-users|update-users', 'TeamA', 'require_all')); + + $this->assertNull($middleware->handle($this->request, function () { + }, 'admin|user', 'edit-users|update-users', 'TeamA', 'require_all|guard:api|guard:web')); + } }