.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Jifty::Manual::AccessControl 3pm" .TH Jifty::Manual::AccessControl 3pm "2010-12-08" "perl v5.14.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Jifty::Manual::AccessControl \- Using Jifty's default ACL system .SH "DESCRIPTION" .IX Header "DESCRIPTION" Out of the box Jifty-based applications have an \s-1ACL\s0 system. The system automatically validates ACLs on Jifty::Record objects by calling the method \&\f(CW\*(C`current_user_can\*(C'\fR before any create, read, update, or delete operation. In all cases, the arguments passed to the \s-1CRUD\s0 operation are passed as extra arguments to \f(CW\*(C`current_user_can\*(C'\fR. .PP On \f(CW\*(C`create()\*(C'\fR, we reject the operation if \f(CW\*(C`current_user_can(\*(Aqcreate\*(Aq)\*(C'\fR returns \s-1FALSE\s0. .PP On \f(CW\*(C`_value()\*(C'\fR or \f(CW\*(C`\f(CIsomefieldname\f(CW\*(C'\fR, we reject the operation if \f(CW\*(C`current_user_can(\*(Aqread\*(Aq)\*(C'\fR returns false. .PP On \f(CW\*(C`_set()\*(C'\fR or \f(CW\*(C`\f(CIset_somefieldname\f(CW\*(C'\fR, we reject the operation if \f(CW\*(C`current_user_can(\*(Aqupdate\*(Aq)\*(C'\fR returns false. .PP On \f(CW\*(C`delete()\*(C'\fR, we reject the operation if \f(CW\*(C`current_user_can(\*(Aqdelete\*(Aq)\*(C'\fR returns false. .PP Out of the box, \f(CW\*(C`current_user_can\*(C'\fR returns 1. When you want to actually check ACLs, you'll need to override \f(CW\*(C`current_user_can()\*(C'\fR in your \&\f(CW\*(C`Jifty::Record\*(C'\fR subclass. .PP 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 \f(CW\*(C`paid_account\*(C'\fR field. In that case, you'd override \&\f(CW\*(C`check_update_rights()\*(C'\fR to look for the \f(CW\*(C`admin\*(C'\fR right rather than the \&\f(CW\*(C`update\*(C'\fR right, if the \f(CW\*(C`FIELD\*(C'\fR is \f(CW\*(C`paid_account\*(C'\fR. .SH "ENABLING ACCESS CONTROL USING THE USER PLUGIN" .IX Header "ENABLING ACCESS CONTROL USING THE USER PLUGIN" To painlessly enable the AccessControl subsystem, a User plugin is available with an authentication plugin, the \f(CW\*(C`Authentication::Password\*(C'\fR plugin may get enabled. This is done in the \fIetc/config.yml\fR configuration file. .PP .Vb 2 \& Plugins: \& \- Authentication::Password: {} .Ve .PP Then, create an \f(CW\*(C`App::Model::User\*(C'\fR class that will be override with \&\f(CW\*(C`Jifty::Plugin::User::Mixin::Model::User\*(C'\fR and an authentication plugin \&\f(CW\*(C`Jifty::Plugin::Authentication::Password::Mixin::Model::User\*(C'\fR , for example: .PP .Vb 2 \& 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; .Ve .PP Next, create the table in your database using the \fIjifty\fR executable like \f(CW\*(C`./bin/jifty schema \-\-setup\*(C'\fR. .SS "Expanding the Model" .IX Subsection "Expanding the Model" The model that manages \f(CW\*(C`User\*(C'\fR 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: .PP .Vb 3 \& use Jifty::DBI::Schema; \& use App::Record schema { \& column \*(Aqextra_column_name\*(Aq; \& \& column \*(Aqmygroup\*(Aq => \& valid_values are qw/admin moderator user/, \& default is \*(Aquser\*(Aq; \& \& # more columns if necessary \& }; .Ve .PP The full syntax for defining a schema can be found in Jifty::Manual::Models or in Jifty::DBI::Schema. .PP If you want to manage an admin group, you must protect the group column as only a superuser can change it. Then, you override \f(CW\*(C`current_user_can\*(C'\fR in \f(CW\*(C`App::Model::User\*(C'\fR .PP .Vb 4 \& sub current_user_can { \& my $self = shift; \& my $type = shift; \& my %args = (@_); \& \& return 0 \& if ( $type eq \*(Aqupdate\*(Aq \& and !$self\->current_user\->is_superuser \& and $args{\*(Aqcolumn\*(Aq} eq \*(Aqmygroup\*(Aq ); \& \& \& return 1; \& } .Ve .PP Defining a method \f(CW\*(C`_init\*(C'\fR in your \f(CW\*(C`App::CurrentUser\*(C'\fR class gives you a chance to add more data to the \f(CW\*(C`CurrentUser\*(C'\fR object. This method will automatically get called after the Plugin's \f(CW\*(C`_init\*(C'\fR is done. .PP .Vb 1 \& 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 \*(Aqadmin\*(Aq) { \& $self\->is_superuser(1); \& }; \& \& $self\->group($self\->user_object\->mygroup); \& }; \& $self\->SUPER::_init(%args); \& }; .Ve .PP With your \f(CW\*(C`App::CurrentUser\*(C'\fR, users in group admin are superuser and you can use \f(CW\*(C`Jifty\->web\->current_user\->group\*(C'\fR in your application. .ie n .SS "Templates defined by the ""Authentication::Password"" plugin" .el .SS "Templates defined by the \f(CWAuthentication::Password\fP plugin" .IX Subsection "Templates defined by the Authentication::Password plugin" To avoid the need for repetitive work, the \f(CW\*(C`Authentication::Password\*(C'\fR plugin already defines a couple of usable templates: .IP "\fI/login\fR" 4 .IX Item "/login" 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 \s-1URL\s0 (\fI/\fR) is called. .IP "\fI/logout\fR" 4 .IX Item "/logout" logs out the current user. .IP "\fI/signup\fR" 4 .IX Item "/signup" allows a user to sign up himself/herself. By default a confirmation mail is sent out that has to get followed by the user. .IP "\fI/passwordreminder\fR" 4 .IX Item "/passwordreminder" after entering his/her mail address, the user will receive a mail that contains a link to \fI/let/reset_lost_password\fR. .IP "\fI/let/confirm_email\fR" 4 .IX Item "/let/confirm_email" is called in the mail and results in accepting the user. .IP "\fI/let/reset_lost_password\fR" 4 .IX Item "/let/reset_lost_password" enabled by the \fI/passwordreminder\fR template, this template allows a user to reenter a password for future use. .SS "Doing checks at other places in your code" .IX Subsection "Doing checks at other places in your code" If you need to check more than Model-based record operations you will have to do some coding on your own. \f(CW\*(C`Jifty\->web\->current_user\*(C'\fR provides a \&\f(CW\*(C`App::CurrentUser\*(C'\fR object that can get queried about the current user. This object provides some convenience methods: .ie n .IP """username""" 4 .el .IP "\f(CWusername\fR" 4 .IX Item "username" returns the name of the current user or \f(CW\*(C`undef\*(C'\fR if not logged in. .ie n .IP """id""" 4 .el .IP "\f(CWid\fR" 4 .IX Item "id" returns the id of the current user or \f(CW\*(C`undef\*(C'\fR if not logged in. .SH "SEE ALSO" .IX Header "SEE ALSO" Jifty::CurrentUser, Jifty::Record, Jifty::RightsFrom, Jifty::Plugin::Authentication::Ldap, Jifty::Plugin::Authentication::CAS