Jifty::Manual::AccessControl - Using Jifty's default ACL system
Out of the box Jifty-based applications have an ACL system. The system automatically validates ACLs on Jifty::Record objects by calling the method current_user_can before any create, read, update, or delete operation. In all cases, the arguments passed to the CRUD operation are passed as extra arguments to current_user_can.
current_user_can
On create(), we reject the operation if current_user_can('create') returns FALSE.
create()
current_user_can('create')
On _value() or somefieldname, we reject the operation if current_user_can('read') returns false.
_value()
somefieldname
current_user_can('read')
On _set() or set_somefieldname, we reject the operation if current_user_can('update') returns false.
_set()
set_somefieldname
current_user_can('update')
On delete(), we reject the operation if current_user_can('delete') returns false.
delete()
current_user_can('delete')
Out of the box, current_user_can returns 1. When you want to actually check ACLs, you'll need to override current_user_can() in your Jifty::Record subclass.
current_user_can()
Jifty::Record
It's likely that at some point, you'll decide you want to ask other questions on certain types of operations. Say, you only want to let administrators update the paid_account field. In that case, you'd override check_update_rights() to look for the admin right rather than the update right, if the FIELD is paid_account.
paid_account
check_update_rights()
admin
update
FIELD
To painlessly enable the AccessControl subsystem, a User plugin is available with an authentication plugin, the Authentication::Password plugin may get enabled. This is done in the etc/config.yml configuration file.
Authentication::Password
Plugins: - Authentication::Password: {}
Then, create an App::Model::User class that will be override with Jifty::Plugin::User::Mixin::Model::User and an authentication plugin Jifty::Plugin::Authentication::Password::Mixin::Model::User , for example:
App::Model::User
Jifty::Plugin::User::Mixin::Model::User
Jifty::Plugin::Authentication::Password::Mixin::Model::User
use strict; use warnings; package App::Model::User; use Jifty::DBI::Schema; use App::Record schema { }; use Jifty::Plugin::User::Mixin::Model::User; use Jifty::Plugin::Authentication::Password::Mixin::Model::User; # Your model-specific methods go here. 1;
Next, create the table in your database using the jifty executable like ./bin/jifty schema --setup.
./bin/jifty schema --setup
The model that manages User Records is not limited to the plugin's definition. It can be expanded by providing an additional schema definition. Every column here will be added to the plugin's columns. Simply add a schema definition block like this:
User
use Jifty::DBI::Schema; use App::Record schema { column 'extra_column_name'; column 'mygroup' => valid_values are qw/admin moderator user/, default is 'user'; # more columns if necessary };
The full syntax for defining a schema can be found in Jifty::Manual::Models or in Jifty::DBI::Schema.
If you want to manage an admin group, you must protect the group column as only a superuser can change it. Then, you override current_user_can in App::Model::User
sub current_user_can { my $self = shift; my $type = shift; my %args = (@_); return 0 if ( $type eq 'update' and !$self->current_user->is_superuser and $args{'column'} eq 'mygroup' ); return 1; }
Defining a method _init in your App::CurrentUser class gives you a chance to add more data to the CurrentUser object. This method will automatically get called after the Plugin's _init is done.
_init
App::CurrentUser
CurrentUser
package App::CurrentUser; use strict; use warnings; use base qw(Jifty::CurrentUser); __PACKAGE__->mk_accessors(qw(group)); sub _init { my $self = shift; my %args = (@_); if (keys %args) { $self->user_object(App::Model::User->new(current_user => $self)); $self->user_object->load_by_cols(%args); if ( $self->user_object->mygroup eq 'admin') { $self->is_superuser(1); }; $self->group($self->user_object->mygroup); }; $self->SUPER::_init(%args); };
With your App::CurrentUser, users in group admin are superuser and you can use Jifty->web->current_user->group in your application.
Jifty->web->current_user->group
To avoid the need for repetitive work, the Authentication::Password plugin already defines a couple of usable templates:
provides a login screen with a signup option. After successful login, the current continuation is called. If no continuation exists, the template sitting at the base URL (/) is called.
logs out the current user.
allows a user to sign up himself/herself. By default a confirmation mail is sent out that has to get followed by the user.
after entering his/her mail address, the user will receive a mail that contains a link to /let/reset_lost_password.
is called in the mail and results in accepting the user.
enabled by the passwordreminder template, this template allows a user to reenter a password for future use.
If you need to check more than Model-based record operations you will have to do some coding on your own. Jifty->web->current_user provides a App::CurrentUser object that can get queried about the current user. This object provides some convenience methods:
Jifty->web->current_user
username
returns the name of the current user or undef if not logged in.
undef
id
returns the id of the current user or undef if not logged in.
Jifty::CurrentUser, Jifty::Record, Jifty::RightsFrom, Jifty::Plugin::Authentication::Ldap, Jifty::Plugin::Authentication::CAS
To install Jifty, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Jifty
CPAN shell
perl -MCPAN -e shell install Jifty
For more information on module installation, please visit the detailed CPAN module installation guide.