Abilities
view release on metacpan or search on metacpan
}
DESCRIPTION
Abilities is a simple yet powerful mechanism for authorizing users of
web applications (or any applications) to perform certain actions in the
application. This is an extension of the familiar role-based access
control that is common in various systems and frameworks like Catalyst
(See Catalyst::Plugin::Authorization::Roles for the role-based
implementation and Catalyst::Plugin::Authorization::Abilities for the
ability-based implementation that inspired this module).
As opposed to role-based access control - where users are allowed access
to a certain feature (here called 'action') only through their
association to a certain role that is hard-coded into the program - in
ability-based acccess control, a list of actions is assigned to every
user, and they are only allowed to perform these actions. Actions are
not assigned by the developer during development, but rather by the
end-user during deployment. This allows for much more flexibility, and
also speeds up development, as you (the developer) do not need to think
about who should be allowed to perform a certain action, and can easily
grant access later-on after deployment (assuming you're also the
end-user).
Abilities to perform certain actions can be given to a user
specifically, or via roles the user can assume (as in role-based access
control). For example, if user 'user01' is a member of role 'admin', and
this user wishes to perform some action, for example 'delete_foo', then
they will only be able to do so if the 'delete_foo' ability was given to
either the user itself or the 'admin' role itself. Furthermore, roles
can recursively inherit other roles; for example, the role 'mega_mods'
can inherit the roles 'mods' and 'editors'. Users of the 'mega_mods'
role will assume all actions owned by the 'mods' and 'editors' roles.
A commonly known use-case for this type of access control is message
boards, where the administrator might wish to create roles with certain
actions and associate users with the roles (more commonly called 'user
groups'); for example, the admin can create an 'editor' role, giving
users of this role the ability to edit and delete posts, but not any
other administrative action. So in essence, this type of access control
relieves the developer of deciding who gets to do what and passes these
decisions to the end-user, which might actually be necessary in certain
situations.
The "Abilities" module is implemented as a Moo role (which makes it
compatible with Moose code). In order to be able to use this mechanism,
applications must implement a user management system that will consume
this role. More specifically, a user class and a role class must be
implemented, consuming this role. Entities is a reference implementation
that can be used by applications, or just taken as an example of an
ability-based authorization system. Entities::User and Entities::Role
are the user and role classes that consume the Abilities role in the
Entities distribution.
CONSTRAINTS
Generally, an ability is a yes/no option. Either the user can or can't
perform a specific action. At times, this might not be flexible enough,
and the user's ability to perform a certain action should be
constrained. For example, a user might be granted the ability to edit
posts in a blog, but this ability should be constrained to the user's
posts only. The user is not to be allowed to edit posts created by other
users. "Abilities" supports constraints by allowing to set a name-based
constraint when granting a user/role a certain ability. Then, checking
the user's ability to perform an action can include the constraint, for
example:
if ($post->{user_id} eq $user->id && $user->can_perform('edit_posts', 'only_his')) {
# allow
} else {
# do not allow
}
Here, the "Abilities" module allows you to check if the user's ability
is constrained, but the responsibility for making sure the constraint is
actually relevant to the case is left to you. In the above example, it
is the application that checks if the post the user is trying to edit
was created by them, not the "Abilities" module.
(PAID) SUBSCRIPTION-BASED WEB SERVICES
Apart from the scenario described above, this module also provides
optional support for subscription-based web services, such as those
where customers subscribe to a certain paid (or free, doesn't matter)
plan from a list of available plans (GitHub is an example of such a
service). This functionality is also implemented as a Moo(se) role, in
the Abilities::Features module provided with this distribution. Read its
documentation for detailed information.
REQUIRED METHODS
Classes that consume this role are required to implement the following
methods:
roles()
Returns a list of all role names that a user object belongs to, or a
role object inherits from.
Example return structure:
( 'moderator', 'supporter' )
NOTE: In previous versions, this method was required to return an array
of role objects, not a list of role names. This has been changed in
version 0.3.
actions()
Returns a list of all action names that a user object has been
explicitely granted, or that a role object has been granted. If a
certain action is constrained, then it should be added to the list as an
array reference with two items, the first being the name of the action,
the second being the name of the constraint.
Example return structure:
( 'create_posts', ['edit_posts', 'only_his'], 'comment_on_posts' )
NOTE: In previous versions, this method was required to return an array
of action objects, not a list of action names. This has been changed in
version 0.3.
is_super()
This is a boolean attribute that both user and role objects should have.
If a user/role object has a true value for this attribute, then they
will be able to perform any action, even if it wasn't granted to them.
( run in 0.367 second using v1.01-cache-2.11-cpan-fe3c2283af0 )