Reputation: 1626
I would like to use Zend's ACL (Zend\Permissions\Acl
) not (only) based on static roles but also on (variable) user points.
In my application every user has points. A resource has a minimum of points needed to view it. Access to a resource should be based on the number of points the user currently has.
Example
Resources:
Users:
What would be the best way to do this?
My thoughts so far
$acl->allow()
based on points). This isn't clean.I would greatly appreciate a push in the right direction :)
Upvotes: 1
Views: 354
Reputation: 1626
Okay, I tried to implement it myself. Maybe it's not pretty, but it's the best solution I came up with myself. Is this the right direction? I would appreciate any feedback!
Solution:
Instead of strings as resources and roles i use my models (suggested here). I use PointResourceInterface
to mark resources that require a specific number of points and implement Zend\Permissions\Acl\Role\RoleInterface
in my user class. Now I create a new NeededPointsAssertion
:
class NeededPointsAssertion implements AssertionInterface
{
public function assert(Acl $acl, RoleInterface $role = null,
ResourceInterface $resource = null, $privilege = null) {
// Resource must have points, otherwise not applicable
if (!($resource instanceof PointResourceInterface)) {
throw new Exception('Resource is not an PointResourceInterface. NeededPointsAssertion is not applicable.');
}
//check if points are high enough, in my app only users have points
$hasEnoughPoints = false;
if ($role instanceof User) {
// role is User and resource is PointResourceInterface
$hasEnoughPoints = ($role->getPoints() >= $resource->getPoints());
}
return $hasEnoughPoints;
}
}
PointResourceInterface
looks like this:
use Zend\Permissions\Acl\Resource\ResourceInterface;
interface PointResourceInterface extends ResourceInterface {
public function getPoints();
}
Setup:
$acl->allow('user', $pointResource, null, new NeededPointsAssertion());
Users have access to resources that need points. But additionally the NeededPointsAssertion
is checked.
Access: I'm checking whether access is allowed like this:
$acl->isAllowed($role, $someResource);
If there's a user $role = $user
otherwise it's guest
or something else.
Inspiration is from http://www.aviblock.com/blog/2009/03/19/acl-in-zend-framework/
Update: Looking back at it now, it would have also been possible to add the needed points via the constructor and store it as an attribute. Decide for yourself and what makes sense in your application...
Upvotes: 1
Reputation: 3128
So this is not just about Zend but working with ACLs in general.
Usually when you implement access rights in an ACL you assign it to a group rather than an individual user. Then you can easily (and dynamically) add or remove users from groups.
In Zend ACL you can think of these groups as the roles. In your case you assign the access rights for a resource to a group (or role) that represent a certain number of points. Now you only have to worry about moving users between these groups based on the points they have earned.
Upvotes: 2