ACL and Reflection

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: ACL and Reflection

Post by Luke »

What I would do is define those two groups as roles:

Code: Select all

$myAcl = new Zend_Acl();
 
$myAcl->addRole(new Zend_Acl_Role('standard')) // standard access
      ->addRole(new Zend_Acl_Role('pro'), 'standard'); // pro inherits standard

Code: Select all

<?php
class PostsController extends BaseController {
 
    public function indexAction() {
 
        switch($this->_user->role) {
            case 'pro':
                $posts = $posts->select()->where('1')->order('post_date', 'asc');
                break;
            default:
                $posts = $posts->select()->where('pro <> 1')->order('post_date', 'asc');
                break;
        }
        $this->view->posts = $posts;
 
    }
 
}
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: ACL and Reflection

Post by VladSun »

VladSun wrote:... I don't think a Controller, or a Model or a View should have any knowledge of what the current user is permitted to do or not. It's simply out of their scope...
... That's why I think I need the Reflection and a MVC provider class...
RANDOM THOUGHTS ;)

So, I imagine that like having a top level ACL object, which owns ModelProvider, ControllerProvider and ViewProvider objects. Every M-V-C class is instantiated by using these providers, so ACL rules are applied even before creation of M-V-C objects.

A Model should consist of one or more objects (i.e. objUser, objProfile). These objects has some "editable" properties. These properties are ACL-protected by having them in a ProtectedPropertyObject. A ProtectedPropertyObject should deny/allow write/read access to the "real" property according to the ACL.

A View should be a hierarchy of Subview objects created by the ACL ViewProvider. If a subview shouldn't be displayed it's simply not created by the ViewProvider (hm... we need a ViewLayoutManager?).

I think it's needed a user-role-group-everybody schema for defining ACL.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: ACL and Reflection

Post by VladSun »

Linux sudo command with its configuration file is much closer to what I'm looking for than the Zend ACL approach.
In sudo config file one can define permission to a specific user(s) to run a command, while keeping control over the arguments passed to this command. The command itself, doesn't know about sudo :)
Also, the setuid() and setgid() functions are in interest for defining temporary role to a user according to some specific data.

The final result, I want to get, is to have M-V-C classes free of "ACL related IFs/SWITCHs" and the whole ACL should be managed only by using the storage layer, without even a single touch to the application layer.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: ACL and Reflection

Post by Luke »

I agree that that would be very nice. I just haven't ever been able to accomplish it. I tried pulling out all the ACL and putting it into a plugin, but I failed. This was a compromise I was willing to make.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: ACL and Reflection

Post by josh »

http://framework.zend.com/wiki/pages/vi ... geId=39025
may be of interest, I've tried it out and it seems to do everything you mentioned.

Another article on doing more with ACL, http://www.xaprb.com/blog/2006/08/16/ho ... ol-in-sql/
webaddict
Forum Commoner
Posts: 60
Joined: Wed Mar 14, 2007 6:55 am
Location: The Netherlands

Re: ACL and Reflection

Post by webaddict »

VladSun wrote:The final result, I want to get, is to have M-V-C classes free of "ACL related IFs/SWITCHs" and the whole ACL should be managed only by using the storage layer, without even a single touch to the application layer.
That would be great, except that it can not be done. ACL is a cross-cutting concern, which has to interfere in each layer of your application. When saying it's cross-cutting, it means that you'd have to be able to show or hide certain buttons (View), you should block access to certain actions (Controller), and you should not include some results in the resultset (Model).

It's noble to try, but impossible from my point of view.
User avatar
inghamn
Forum Contributor
Posts: 174
Joined: Mon Apr 16, 2007 10:33 am
Location: Bloomington, IN, USA

Re: ACL and Reflection

Post by inghamn »

I'd be interested in seeing a way to ACL with per-field permissions. So far, I'm having to hard code Roles into my controllers and views. Otherwise, asking permitsEditing() on each and every field of a form gets quite tedious.

Here's the code I'm using for a Page Controller for Updating Users

Code: Select all

 
verifyUser(array('Administrator','Clerk'));
 
$user = new User($_REQUEST['user_id']);
 
if (isset($_POST['user']))
{
    # Both clerk and admin can edit these fields
    $fields = array('gender','firstname','lastname','email','address','city',
                    'zipcode','about','race_id','birthdate','phoneNumbers');
 
    # Only the Administrator can edit these fields
    if (userHasRole('Administrator'))
    {
        $fields[] = 'authenticationMethod';
        $fields[] = 'username';
        $fields[] = 'password';
        $fields[] = 'roles';
    }
 
    # Set all the fields they're allowed to edit
    foreach($fields as $field)
    {
        if (isset($_POST['user'][$field]))
        {
            $set = 'set'.ucfirst($field);
            $user->$set($_POST['user'][$field]);
        }
    }
 
    try
    {
        $user->save();
        Header('Location: home.php');
        exit();
    }
    catch (Exception $e) { $_SESSION['errorMessages'][] = $e; }
}
 
$template = new Template();
 
$form = new Block('users/updateUserForm.inc');
$form->user = $user;
$form->return_url = $_REQUEST['return_url'];
$template->blocks[] = $form;
 
echo $template->render();
 
And the top level view:

Code: Select all

 
<h1>Edit <?php echo $this->user->getUsername(); ?></h1>
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
 
<?php
    if (userHasRole('Administrator'))
    {
        include APPLICATION_HOME.'/blocks/html/users/authenticationFields.inc';
    }
    include APPLICATION_HOME.'/blocks/html/users/personalInfoFields.inc';
    include APPLICATION_HOME.'/blocks/html/users/phoneNumberFields.inc';
?>
 
<fieldset><legend>Submit</legend>
    <input name="user_id" type="hidden" value="<?php echo $this->user->getId(); ?>" />
    <input name="return_url" type="hidden" value="<?php echo View::escape($this->return_url); ?>" />
    <button type="submit" class="submit">Submit</button>
    <a class="cancel button" href="<?php echo View::escape($this->return_url); ?>">Cancel</a>
</fieldset>
</form>
 
Making sure the user can only change the specific fields they're allowed to is a bit tedious. And it seems to has to happen in both the controller and the view. I know this way is not ideal, I just haven't been able to adapt an ACL style approach without a ton more code.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: ACL and Reflection

Post by josh »

After reading some of the suggestions you guys posted the one I like best is having each property be accessed through an object that encapsulates field specific ACL rules, I'm going to toy around with the idea of doing something like this for my applications but implementing it as a generic 'data gateway' and having the field specific ACL checks register themselves as hooks to be run pre and post property access, that inverts control and also allows more access checks to be added later besides plain vanilla ACL (in case I think of something later). Not entirely necessary per se to solve the problem but it seems to be the right thing to do to me
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: ACL and Reflection

Post by Christopher »

I have to admit that I don't really understand what specifically you guys are talking about! ;)
VladSun wrote:In sudo config file one can define permission to a specific user(s) to run a command, while keeping control over the arguments passed to this command. ...
The final result, I want to get, is to have M-V-C classes free of "ACL related IFs/SWITCHs" and the whole ACL should be managed only by using the storage layer, without even a single touch to the application layer.
Vlad starts using the term 'storage' and I am still not sure what he means from the previous discussion.
jshpro2 wrote:... the one I like best is having each property be accessed through an object that encapsulates field specific ACL rules ... implementing it as a generic 'data gateway' and having the field specific ACL checks register themselves as hooks to be run pre and post property access...
The gears in my mind are grinding between 'data gateway', 'field specific ACL checks' and 'hooks to be run pre and post'.

Can you explain these ideas with the standard RBAC terms like User/Subject, Role, Permissions, and Session? I am assuming that any system would be DataSource independent.
(#10850)
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: ACL and Reflection

Post by Luke »

webaddict wrote:
VladSun wrote:The final result, I want to get, is to have M-V-C classes free of "ACL related IFs/SWITCHs" and the whole ACL should be managed only by using the storage layer, without even a single touch to the application layer.
That would be great, except that it can not be done. ACL is a cross-cutting concern, which has to interfere in each layer of your application. When saying it's cross-cutting, it means that you'd have to be able to show or hide certain buttons (View), you should block access to certain actions (Controller), and you should not include some results in the resultset (Model).

It's noble to try, but impossible from my point of view.
That's exactly the conclusion that I've come to. I have been able to extract most access control code into the controller, but even doing this requires that I make different views for different roles and select different data based on role. All this does happen in my controller though, or above it, in an action helper.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: ACL and Reflection

Post by Christopher »

The Ninja Space Goat wrote:I have been able to extract most access control code into the controller, but even doing this requires that I make different views for different roles and select different data based on role. All this does happen in my controller though, or above it, in an action helper.
If Access Control is truly a Cross Cutting Concern, then why don't the View and Model have the same access to the AC object as the Controller. Controllers use the AC info to determine program flow; Views use it to determine what to display; and Models use it to determine what to load and save.

The more I use MVC the more I find that the Model, View and Controller need to have and do most of the same things.
(#10850)
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: ACL and Reflection

Post by Luke »

I find that they have to do many of the same things, but I wouldn't say most of the same things. It is to be expected that since model, view and controller are where code is mainly separated, you'd notice these certain aspects that seem to be used by all three much more, wouldn't you think?

What specifically are you referring to? I can think of a few aspects of application development that spans all three:

* ACL
* Forms

What else is there?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: ACL and Reflection

Post by Christopher »

The Ninja Space Goat wrote:What else is there?
Well, in PHP is can be as simple as that they all need to load helper objects. They all can be part of a hierarchy. You mention Access Control -- at least they all need access to the same ACL object. Forms implies validation. You can pre-validate in the client -- so that's the View. You deep validate in the Model, but some people validate in the Controller. And the Controller might do some broad validation to see what kind of request is coming its way and if it is well formed. All might need to filter and escape (though in different ways). I am sure there are more...
(#10850)
webaddict
Forum Commoner
Posts: 60
Joined: Wed Mar 14, 2007 6:55 am
Location: The Netherlands

Re: ACL and Reflection

Post by webaddict »

arborint wrote:
The Ninja Space Goat wrote:All might need to filter and escape (though in different ways). I am sure there are more...
Well, you can add logging to the list, since that is the most common example of cross cutting concerns. Just stating the obvious here: this obviously could be solved by Aspect Oriented Programming. Too bad there isn't a native PHP implementation though.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: ACL and Reflection

Post by Christopher »

Yes, AOP is one direction. But since we are talking about MVC which is usually off a Front Controller and in a Action Controller then DI is probably the easier way to go.
(#10850)
Post Reply