Skip to content
This repository has been archived by the owner on Jul 3, 2020. It is now read-only.

Commit

Permalink
Merge pull request #268 from davidwindell/issue-262
Browse files Browse the repository at this point in the history
Conditions for Guards
  • Loading branch information
bakura10 committed Mar 31, 2015
2 parents 937f89b + f56b0b8 commit e89cba0
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 8 deletions.
23 changes: 20 additions & 3 deletions docs/04. Guards.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,17 +177,34 @@ return [
'guards' => [
'ZfcRbac\Guard\RoutePermissionsGuard' => [
'admin*' => ['admin'],
'post/manage' => ['post.update', 'post.delete']
'post/manage' => ['post.update', 'post.delete']
]
]
]
];
```

> All permissions in a rule must be matched (it is an AND condition).
> By default, all permissions in a rule must be matched (an AND condition).
In the previous example, one must have ```post.update``` **AND** ```post.delete``` permissions
to access the ```post/manage``` route.
to access the ```post/manage``` route. You can also specify an OR condition like so:

```php
use ZfcRbac\Guard\GuardInterface;

return [
'zfc_rbac' => [
'guards' => [
'ZfcRbac\Guard\RoutePermissionsGuard' => [
'post/manage' => [
'permissions' => ['post.update', 'post.delete'],
'condition' => GuardInterface::CONDITION_OR
]
]
]
]
];
```

> Permissions are linked to roles, not to users
Expand Down
6 changes: 6 additions & 0 deletions src/ZfcRbac/Guard/GuardInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ interface GuardInterface extends ListenerAggregateInterface
const POLICY_DENY = 'deny';
const POLICY_ALLOW = 'allow';

/**
* Condition constants
*/
const CONDITION_OR = 'OR';
const CONDITION_AND = 'AND';

/**
* @param MvcEvent $event
* @return bool
Expand Down
34 changes: 29 additions & 5 deletions src/ZfcRbac/Guard/RoutePermissionsGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
namespace ZfcRbac\Guard;

use Zend\Mvc\MvcEvent;
use ZfcRbac\Exception;
use ZfcRbac\Service\AuthorizationServiceInterface;

/**
Expand Down Expand Up @@ -101,12 +100,37 @@ public function isGranted(MvcEvent $event)
return true;
}

foreach ($allowedPermissions as $permission) {
if (!$this->authorizationService->isGranted($permission)) {
return false;
$permissions = isset($allowedPermissions['permissions'])
? $allowedPermissions['permissions']
: $allowedPermissions;

$condition = isset($allowedPermissions['condition'])
? $allowedPermissions['condition']
: GuardInterface::CONDITION_AND;

if (GuardInterface::CONDITION_AND === $condition) {
foreach ($permissions as $permission) {
if (!$this->authorizationService->isGranted($permission)) {
return false;
}
}

return true;
}

if (GuardInterface::CONDITION_OR === $condition) {
foreach ($permissions as $permission) {
if ($this->authorizationService->isGranted($permission)) {
return true;
}
}

return false;
}

return true;
throw new InvalidArgumentException(sprintf(
'Condition must be either "AND" or "OR", %s given',
is_object($condition) ? get_class($condition) : gettype($condition)
));
}
}
20 changes: 20 additions & 0 deletions tests/ZfcRbacTest/Guard/RoutePermissionsGuardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,26 @@ public function routeDataProvider()
'isGranted' => true,
'policy' => GuardInterface::POLICY_DENY
],
[
'rules' => ['route' => [
'permissions' => ['post.edit', 'post.read'],
'condition' => GuardInterface::CONDITION_OR
]],
'matchedRouteName' => 'route',
'identityPermissions' => [['post.edit', null, true]],
'isGranted' => true,
'policy' => GuardInterface::POLICY_DENY
],
[
'rules' => ['route' => [
'permissions' => ['post.edit', 'post.read'],
'condition' => GuardInterface::CONDITION_AND
]],
'matchedRouteName' => 'route',
'identityPermissions' => [['post.edit', null, true]],
'isGranted' => false,
'policy' => GuardInterface::POLICY_DENY
]
];
}

Expand Down

0 comments on commit e89cba0

Please sign in to comment.