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+unsubscr...@googlegroups.com For more options, visit this group at 
http://groups.google.com/group/cake-php

Reply via email to