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

Conditions for Guards #268

Merged
merged 8 commits into from
Mar 31, 2015
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
23 changes: 20 additions & 3 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,30 @@ public function isGranted(MvcEvent $event)
return true;
}

foreach ($allowedPermissions as $permission) {
if (!$this->authorizationService->isGranted($permission)) {
$permissions = isset($allowedPermissions['permissions'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably happen before the wildcard check

? $allowedPermissions['permissions']
: $allowedPermissions;

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

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

if ($condition === GuardInterface::CONDITION_OR) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm I'm trying to read the code and I'm not sure to understand this.

return false;
}

return true;
}
}
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' => [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to align when the value is array

'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