Download the PHP package popphp/pop-acl without Composer
On this page you can find all versions of the php package popphp/pop-acl. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download popphp/pop-acl
More information about popphp/pop-acl
Files in popphp/pop-acl
Package pop-acl
Short Description Pop ACL Component for Pop PHP Framework
License BSD-3-Clause
Homepage https://github.com/popphp/pop-acl
Informations about the package pop-acl
pop-acl
- Overview
- Install
- Quickstart
- Roles
- Resources
- Strict
- Multiple Roles
- Multi-Strict
- Inheritance
- Parent-Strict
- Removing Allow/Deny Rules
- Removing Roles and Resources
- Wildcard Permissions
- Inspecting Effective Permissions
- Assertions
- Policies
Overview
pop-acl is a full-featured component that supports ACL/RBAC user access concepts.
Beyond allowing or denying basic user access, it provides support for roles, resources,
permissions as well as assertions and policies for fine-grain access-control.
pop-acl is a component of the Pop PHP Framework.
Top
Install
Install pop-acl using Composer.
composer require popphp/pop-acl
Or, require it in your composer.json file
"require": {
"popphp/pop-acl" : "^5.0.0"
}
Top
Quickstart
The basic concepts involve role and resource objects and then defining what permissions are allowed (or denied) between them. The main ACL object will determine if the requested action by a role on a resource is permitted or not.
Without that setStrict() call, an Acl is permissive: a check for which no rule
exists returns true, so isAllowed($editor, $page, 'add') would be true rather than
false. See Strict for the full explanation.
The above also works with the string value names of the roles and resources:
Roles and resources can also be passed directly into the Acl constructor instead of (or alongside)
addRoles()/addResource() — individually, as arrays, or a mix of both, in any order:
Top
Roles
Besides being a store for a role name, a role object serves as a simple data object, should additional data need to be stored about the role or the user currently assigned to the role.
This is useful for deeper evaluations like policies.
Top
Resources
Like roles, the resource object serves as a simple data object to store additional data that may be needed.
This is useful for deeper evaluations like policies.
Top
Strict
Setting the strict flag strictly enforces any permissions that have been set and requires
permissions to be explicitly set. If the strict flag is set to false, then ACL checks may pass
as true if a rule is not explicitly set. Consider the following examples:
Both evaluations result in true, as there is no explicit rule preventing the editor from adding a page.
In order to prevent the editor from adding a page, you would either have to set a deny rule:
Or, set the ACL to strict:
Top
Multiple Roles
If a user is assigned multiple roles at one time, those roles can all be evaluated at the same time. If we wire up a similar example from above:
we can then call the isAllowedMulti() method to evaluate multiple roles at once:
If one of the roles is permitted to perform the requested action on the resource, it will
pass as true.
Multi-Strict
When evaluating multiple roles at once, if the requirement is such that all roles must be permitted
to perform the requested action on the resource, using the multi-strict flag will ensure that.
isAllowedMultiStrict() is a shorthand for the same thing — it sets the multi-strict flag on the Acl
object and then calls isAllowedMulti():
There are equivalent isDeniedMulti() and isDeniedMultiStrict() methods for checking denial across
multiple roles at once. By default (loose), it passes as true if any of the roles is denied; with
multi-strict (either via setMultiStrict(true) or the isDeniedMultiStrict() shorthand), all of the
roles must be denied:
Top
Inheritance
Roles can be constructed to inherit rules from other roles.
Parent-Strict
In strict mode, an inherited rule (one defined on a parent role, not the role being checked
directly) is treated more loosely by default: any explicit resource/permission entry on a parent is enough
to pass the check, regardless of which specific permission was requested. Setting parent-strict requires
an inherited rule to match the exact permission requested, just like a rule defined directly on the role:
Top
Removing Allow/Deny Rules
removeAllowRule() and removeDenyRule() revoke a previously-set rule without removing the role or
resource itself. Each accepts increasingly broad arguments: a specific permission, an entire resource
(every permission on it), or just a role (every rule for that role, on any resource):
removeDenyRule() works identically for deny() rules.
Note: because an empty permission list means "unrestricted" (see Wildcard Permissions), removing the last remaining rule for a role/resource pair with
removeAllowRule()/removeDenyRule()can leave that resource (or role) registered but with no explicit rules left — which, in strict mode, is indistinguishable from an intentional blanketallow($role, $resource)/deny($role, $resource). If your intent is "this role should end up with zero access," preferremoveRole()orremoveResource(), which clean up that empty state as part of the removal.
Top
Removing Roles and Resources
Roles and resources can be removed from the ACL object. Removing a role reparents any of its child roles onto its own parent (or makes them root roles if it had none), and removing either a role or a resource also purges any allow/deny rules, assertions and policies that referenced it — so a new role or resource added later with the same name starts with a clean slate.
hasRoles()/hasResources() answer "are there any roles/resources registered at all," as distinct from
hasRole($name)/hasResource($name), which check for one specific one.
Top
Wildcard Permissions
The permission '*' is reserved and means "any permission." It can be used with allow() or deny()
to grant or block everything on a resource, and is combinable with a more specific rule — deny always
takes precedence over allow, so a wildcard allow can still be narrowed by a specific deny:
Checking if the '*' permission is allowed (rather than a specific permission) still checks only whether
that permission is allowed or denied, not whether all permissions are allowed:
Top
Inspecting Effective Permissions
getAllowedPermissions() and getDeniedPermissions() report the explicit, effective permission set
for a role on a resource, merged with any inherited roles. They return ['*'] if access is
unrestricted at any level (an empty permission list or an explicit '*'), or [] if no rule exists
at all. These report the explicit rule set only — they do not apply the strict/multiStrict/parentStrict
fallback behavior, so the result can differ from what isAllowed()/isDenied() actually return for the
same role and resource. For example, on a default (non-strict) Acl, a role with no rules at all will
have getAllowedPermissions() return [] while isAllowed() returns true for any permission, because
of the permissive default:
Top
Assertions
If you want more fine-grain control over permissions and who is allowed to do what, you can use assertions.
First, define the assertion class, which implements the Pop\Acl\Assertion\AssertionInterface. In this example,
we want to check that the user "owns" the resource via a matching user ID.
Then, within the application, you can use assertions like this:
Under the hood, an assertion passed to the 4th argument of allow()/deny() is stored via createAssertion()
and keyed off the role/resource/permission it was registered against. hasAssertionKey() and getAssertionKey()
let you check whether an assertion is registered for a given combination, and deleteAssertion() removes one
directly — most applications won't need these directly, since removeAllowRule()/removeDenyRule()/removeRole()/
removeResource() already call deleteAssertion() for you as part of removing the rule it was attached to.
Top
Policies
An alternate way to achieve even more specific fine-grain control is to use policies.
Similar to assertions, you have to write the policy class and it needs to use the
Pop\Acl\Policy\PolicyTrait. Unlike assertions that are centered around the single
assert() method, policies allow you to write separate methods that will be called and
evaluated via the can() method in the PolicyTrait. Consider the following example
policy class:
It defines specific evaluations that are required for three different actions
create(), update() and delete(). Then the user role and policy can be added
to the main ACL object:
Once the polices are added to the ACL object, they will be automatically evaluated on the
isAllowed() or isDenied() method calls. Note that can() throws Pop\Acl\Policy\Exception if the
requested policy method doesn't exist or isn't callable on the role, so isAllowed(), isDenied(),
evaluatePolicy() and evaluatePolicies() can throw that exception too whenever policies are in use:
A deeper look into what is happening under the hood, the ACL object is calling the method
evaluatePolicy() to determine if the requested action is allowed:
Which, in turn, the evaluatePolicy() method calls are calling the can() method on the
actual policy objects themselves:
can() also accepts a comma-separated list of methods, evaluated in order and short-circuiting on the
first one that returns false:
Top