Abilities
view release on metacpan or search on metacpan
lib/Abilities.pm view on Meta::CPAN
=head2 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. C<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 C<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 C<Abilities>
module.
=head2 (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 L<Abilities::Features> module provided
with this distribution. Read its documentation for detailed information.
=head1 REQUIRED METHODS
Classes that consume this role are required to implement the following
methods:
=head2 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.
=cut
requires 'roles';
=head2 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.
=cut
requires 'actions';
=head2 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.
=cut
requires 'is_super';
=head2 get_role( $name )
This is a method that returns the object of the role named C<$name>.
=cut
requires 'get_role';
=head1 PROVIDED METHODS
Classes that consume this role will have the following methods available
to them:
=head2 can_perform( $action, [ $constraint ] )
Receives the name of an action, and possibly a constraint, and returns a true
value if the user/role can perform the provided action.
=cut
sub can_perform {
my ($self, $action, $constraint) = @_;
# a super-user/super-role can do whatever they want
return 1 if $self->is_super;
# return false if user/role doesn't have that ability
return unless $self->abilities->{$action};
# user/role has ability, but is there a constraint?
if ($constraint && $constraint ne '_all_') {
# return true if user/role's ability is not constrained
return 1 if !ref $self->abilities->{$action};
# it is constrained (or at least it should be, let's make
# sure we have an array-ref of constraints)
if (ref $self->abilities->{$action} eq 'ARRAY') {
( run in 1.858 second using v1.01-cache-2.11-cpan-5837b0d9d2c )