Thursday, January 27, 2011

Re: Need advice for custom ACL

Hi ShadowCross.

thx for your suggestions.

i'll surely try them


On 27 Gen, 20:31, ShadowCross <adri...@jps.net> wrote:
> Ernesto:
>
> Some things to try:
>
> For your first example: ignore some validation rules if the user has
> "authorization X".
> - validate the data from the controller, using the $options parameter
> to specify which subset of the validation rules to apply.  There is a
> (albeit simplistic) example in the Cookbook (http://book.cakephp.org/
> view/1182/Validating-Data-from-the-Controller), where only a couple of
> the fields are validated.  If you have multiple rules for a field, and
> you want only some, not all, those rules checked on that field, you
> can adjust rules array for that field in the Model's beforeValidate()
> function (or an attached Behavior's beforeValidate()) -- the
> $optionsparameter of Model::validates() is passed to the
> Model::beforeValidate(), and only the 'fieldList' key is reserved.
> Unfortunately, if you have to resort to the beforeValidate(), your
> permissions logic will not be confined to your controller.
> - if no errors, call the Model::save() or Model::saveAll(), but set
> the validate parameter to false to avoid using the model's full
> validation
>
> =====
> For your second example: hide or modify some form fields if user
> hasn't "authorization Y".
> - in your controller, you can create an array of what authorizations
> the user has and save that to a view variable.
> - in your view, use that array to determine whether a form field
> should be hidden or adjusted.
>
> example:
> foo_controller.php:
>
>         function edit($id = null) {
>                 ...
>                 $aro = 'user/' . $this->Auth->user('id');
>
>                 // Create list of authorizations that user has
>                 $authorizations = array();
>                 foreach(array('Bar/Y_1', 'Bar/Y_2', 'Bar/Y_3') as $aco) {
>                         if ($this->Acl->check($aro, $aco) {
>                                 $authorizations[] = $aco;
>                         }
>                 }
>                 $this->set(compact('authorizations'));
>         }
>
> foo/edit.ctp:
>
>         ...
>
>         if (in_array('Bar/Y_2', $authorizations)) {
>                 echo $this->Form->input('fieldX1');
>         } else {
>                 echo $this->Form->hidden('fieldX1');
>         }
>         if (in_array('Bar/Y_3', $authorizations)) {
>                 echo $this->Form->input('fieldX2', array(
>                         'options' => array('1', '2', '3')
>                 ));
>         } else {
>                 echo $this->Form->input('fieldX2', array(
>                         'options' => array('4', '5', '6')
>                 ));
>         }
>
> Note that in Cake's built-in ACL, the ACO (Access Control Object)
> nodes do not have to correspond to controllers or actions. ACO nodes
> that correspond to actions is just one of the built-in behaviors.  You
> can also define arbitrary ACO nodes.  To extend my example above, I
> can have the following ACO nodes defined:
>
>         controllers/Foo/add
>         controllers/Foo/edit
>         controllers/Foo/index
>         controllers/Foo/view
>         Bar/Y_1
>         Bar/Y_2
>         Bar/Y_3
>
> and in app_controller.php:
>
>         var $components = array('Auth' => array(
>                 'authorize' => 'actions',
>                 'actionPath' => 'controllers/'
>         ));
>
> Note the 'actionPath' AuthComponent variable; any ACO nodes NOT nested
> under the 'controllers' (or whatever you specify as the actionPath)
> node are ignored for the purposes of the "standard Cake ACL".  To
> check permissions manually for everything else, you can use the
> check($aro, $aco, $action = '*') function of the AclComponent.
>
> There may be some advantages of using Cake's AclComponent in this way
> instead of your custom CheckAuthorizations class, including:
> - using existing tables (aros, acos, aros_acos, and not having to add
> the authorizations and authorizations_users tables)
> - "inheritance".  ARO nodes can refer to groups and/or users -- if a
> UserX is part of GroupA and GroupA has access to AuthB, UserX also has
> AuthB (unless access to AuthB is explicitly revoked from UserX.  And
> if groups are defined as heirarchical (i.e. TreeBehavior), GroupA can
> inherit access rights from it's parents and ancestors.  The same
> applies to ACO nodes.  In fact, you *could*, in theory, define field-
> level access in the following manner:
>
> ARO:
>         Group 1 (all users)
>         Group 2 (admin)
>
> ACO:
>         controllers/Foo/edit
>         controllers/Foo/edit/name
>         controllers/Foo/edit/fieldX1
>         controllers/Foo/edit/fieldX2
>
> ARO/ACO:
>
>         // All users can access the edit page for Foo
>         $this->Acl->allow('Group 1', 'controllers/Foo/edit');
>
>         // Revoke access to fieldX1 and fieldX2 from the public at large
>         $this->Acl->deny('Group 1', 'controllers/Foo/edit/fieldX1');
>         $this->Acl->deny('Group 1', 'controllers/Foo/edit/fieldX2');
>
>         // Grant access to fieldX1 and fieldX2 to the admins
>         $this->Acl->allow('Group 2', 'controllers/Foo/edit/fieldX1');
>         $this->Acl->allow('Group 2', 'controllers/Foo/edit/fieldX1');
>
> then adjust the controller and view to accommodate the results of the
> permission check.
>
> - There is at least one plugin that facilitates maintenance of Cake's
> ACL tables, so you don't have create your own.  The one I use can be
> found on  http://github.com/interlock/acl_plugin/

--
Our newest site for the community: CakePHP Video Tutorials http://tv.cakephp.org
Check out the new CakePHP Questions site http://ask.cakephp.org and help others with their CakePHP related questions.


To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php

No comments: