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

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: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.
Okay, I'm grinding my brains here, but I really don't get how you see DI could solve your problems with access control. Now, I like to think I've read enough on dependency injection to get what it's about, but this I don't really understand. Care to elaborate on how you would use DI to accomplish ACL (or rather RBAC)?
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: ACL and Reflection

Post by josh »

arborint wrote: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.
When I say data gateway, I mean an object that represents each of my models properties. I'm saying there seems to be opportunity for a pattern, that sits between the model and it's properties and fires off event triggers. It doesn't necessarily have to implement RBAC. I'm saying I'd write an abstract data access object that defines an interface for preAccess() and postAccess(), etc.. methods. RBAC would then be implemented and "hooked"* into the data access. The "property access gateway" ( the pattern I'm proposing, which I'm not sure if its an existing pattern so I'm using made up words, if you have a better term let me know ) would have no direct knowledge of which fields were allowed disallowed, and certainly would not be limited to allowing / disallowing access, it could be extended to modify the data, return a different property than what was asked for, etc.. depending on which plugins were loaded for the given property. An infastructure like this could prove useful as a central place to implement your RBAC on a field per field basis, without hard-coding anything in your models / controllers or limiting you to the concept of RBAC.

This "data access pattern" could just be called thru magic methods so you could access your properties with pure semantics, and separate out the "law and methods of access" ( Cross cutting concerns, or actual delegation ), from the "logic of access" ( core concerns, or actual business based logic )

For instance if a model should show a user one property if he is a guest, and another if he is "super admin type A", should a model necessarily know "super admin type A" exists? If not then should it even know the privilege exists? Why should it know about the privilege rule itself, it should only define business logic. A controller would be better then putting it in the model but still not perfect, as a controller tends to end up acting as a procedural transaction script. Its a fine line, and I'm not proposing separating the actual business logic from the model, just certain rules of property access that wouldn't make sense to put in the model. The pattern just like any other pattern would have the ability to be misused, but used semantically I think it has value

* I'm using the term "hooked" to describe any event that gets triggered, I'm using the term from svn hook scripts that can run post-commit and pre-commit, etc.. For instance on my development servers I have hook scripts to update my working copy, which happens to be the htdocs folder for apache ( so when I run a commit from my workstation the code gets pushed to a staging area on my network.. since apache cant directly serve files from a repository, and since there's no reason to keep running "svn update" to stage my code ), similarly a developer might want to run some procedure(s) before / after data access that allowed or disallowed access, redirected program flow, modified the data being passed thru, mapped data to other objects, etc.. ( possibilities would be unlimited )

Edit: I guess what I'm thinking of is basically a mix AOP and the decorator pattern? I don't know..
AOP attempts to solve this problem by allowing the programmer to express cross-cutting concerns in stand-alone modules called aspects. Aspects can contain advice (code joined to specified points in the program) and inter-type declarations (structural members added to other classes). For example, a security module can include advice that performs a security check before accessing a bank account.
http://en.wikipedia.org/wiki/Aspect-ori ... rogramming
Another good example of where a decorator can be desired is when there is a need to restrict access to an object's properties or methods according to some set of rules or perhaps several parallel sets of rules (different user credentials, etc). In this case instead of implementing the access control in the original object it is left unchanged and unaware of any restrictions on its use, and it is wrapped in an access control decorator object, which can then serve only the permitted subset of the original object's interface.
(taken from http://en.wikipedia.org/wiki/Decorator_pattern)
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 »

Interesting discussion guys, thanks. I'm trying to follow you ;)
Keep going :)

// offtopic - I do love prototype based OOP languages (JS in particular), I wish PHP was prototype based :) :)
There are 10 types of people in this world, those who understand binary and those who don't
webaddict
Forum Commoner
Posts: 60
Joined: Wed Mar 14, 2007 6:55 am
Location: The Netherlands

Re: ACL and Reflection

Post by webaddict »

jshpro2 wrote:Edit: I guess what I'm thinking of is basically a mix AOP and the decorator pattern? I don't know..
Well, it sounds like you're proposing "faking" aspect oriented programming in PHP using decorators and magic methods, which isn't a really bad idea per se. I've tried faking AOP in PHP before, using a similar method but discontinued due to a lack of time. I ran into a few problems with my own half implementation, so here's a list that you might find useful:
  • - When using an IDE and an object that has only magic methods (the Decarator in this case), the IDE doesn't know what methods belong to the "inner object", so it won't be able to hint you about the methods. Obviously, you could work around this using specific decorators for each object you wish to "secure" using the Decorator, but note that your design will become unclear and it is considered a code smell to have a parallel inheretance structure. Not having code hints may a price worth paying if it clears up your design and application though.

    - Due to the fact that PHP doesn't have a native AOP implementation, there will always be objects "in the know" of your implementation. That is to say: each and every object that is able to instantiate objects that should be "secured" by your Decorator, has to know it'll have to instantiate that Decorator before instantiating the actual object.
While writing the above text, I get how arborint thinks DI could help to implement ACL: by letting the DIC instantiate everything, the DIC is - in effect - the only object that has to know about your little trick. Arborint: if I'm still off course, please enlighten me :) I'll think this theory over again, see if it's worth the trouble. If anyone has thoughts on how to actually implement this, I for one would love to hear about it :)
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: ACL and Reflection

Post by allspiritseve »

webaddict wrote:
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.
I remember a couple of weeks back I found two AOP projects that were extending PHP to add aspects... its a cool idea, but I don't know how I feel about something that's so different that the language has to be extended in order to incorporate it.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: ACL and Reflection

Post by allspiritseve »

jshpro2 wrote: there seems to be opportunity for a pattern, that sits between the model and it's properties and fires off event triggers.
I think the decorator would be more useful sitting between the model and its client code, instead of between the model and its properties. That would work especially well with the DI webaddict and arborint were talking about, where you could instantiate the model using DI and decorate it with an ACL wrapper that would restrict access to methods, not properties.
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 »

Are you talking about using getters in the Model, with DI, then? Something like:

Code: Select all

 
class User
{
    private $email;
    private $privateFields = array();
 
    public function isPrivate($field)
    {
        return in_array($field,$this->privateFields);
    }
 
    /**
     * @param User $user The person asking for this user's name
     */
    public function getEmail(User $user=null)
    {
        if ($user)
        {
            if ( $user->hasRole(array('Administrator','Clerk')) ||
                 !$this->isPrivate('email') )
            {
                return $this->email;
            }
            else
            {
                return 'Anonymous';
            }
    }
}
 
This would mean we always must remember to pass in the current User of the system
whenever we want to display someone's email anywhere in the system. In
applications, there's a ton of places where we're displaying someone's email address.
webaddict
Forum Commoner
Posts: 60
Joined: Wed Mar 14, 2007 6:55 am
Location: The Netherlands

Re: ACL and Reflection

Post by webaddict »

inghamn wrote:Are you talking about using getters in the Model, with DI, then? Something like:

Code: Select all

<?php 
// snip;
?>
This would mean we always must remember to pass in the current User of the system whenever we want to display someone's email anywhere in the system. In applications, there's a ton of places where we're displaying someone's email address.
Well, obviously I can't speak for jshpro2, but in my opinion, it's the thing you're displaying (doing the check whether or not someone can do a certain thing in the method itself) that you want to get rid of.
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 »

webaddict wrote:Well, obviously I can't speak for jshpro2, but in my opinion, it's the thing you're displaying (doing the check whether or not someone can do a certain thing in the method itself) that you want to get rid of.
I agree, doing the ACL checks inside the model seems wrong. However, absent an actual AOP implentation in PHP, we're left with needing to add extra code throughout the application. Like you said before:
webaddict wrote: Due to the fact that PHP doesn't have a native AOP implementation, there will always be objects "in the know" of your implementation. That is to say: each and every object that is able to instantiate objects that should be "secured" by your Decorator, has to know it'll have to instantiate that Decorator before instantiating the actual object.
My problem with it is: if we having to go into all our Controllers and/or Views that interact with a Model and make sure they're loading some Decorator or whatnot instead of the Model itself....with a large application, that gets to be a lot of code, and a lot for a developer to remember when trying to work on the application.

Without an AOP implementation, doing the ACL checks in the model starts to look, well, not *too* bad. One single place to put the checks, and nothing to try and remember to do when writing Controllers or Views.

Then, it's just a question of how to get the ACL information into the Model. Dare I even suggest we make the ACL information globally available (as opposed to trying to remember to DI it everywhere?)
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: ACL and Reflection

Post by allspiritseve »

inghamn wrote:My problem with it is: if we having to go into all our Controllers and/or Views that interact with a Model and make sure they're loading some Decorator or whatnot instead of the Model itself....with a large application, that gets to be a lot of code, and a lot for a developer to remember when trying to work on the application.
That's what the DI idea solves. The idea is that some DI factory instantiates your classes through its methods, and decorates the objects behind the scenes. All your code has to do is use the DI factory, and proceed as usual. I'm sure someone could give you a good example, as I am somewhat familiar with the theory behind DI factories, but I have never actually implemented it.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: ACL and Reflection

Post by josh »

What is DI / DIC? and what is the benefit over AOP and "weaving" vs decorators? Not to go off topic but I'm not familiar with DI. And basically the way I envision it you'd define properties normally and set and get them normally ( $this->property ), PHP would then invoke a chain of commands with magic methods, you'd be able to get rid of the magic methods and the class should still pass unit tests, code completion would not be broken ( based on my self admittedly very ignorant understanding of AOP it would break code completion and is aimed at more general logic then "laws of access".. by laws of access I don't necessarily mean limited to RBAC like I said before, but would not include any "weaving" of functionality, it would work more like a strategy pattern / decorator then AOP.. honestly I didn't even know what AOP was until I saw the acronym in arboints post and googled it )

But yeah if anyone can tell me what DI is since I don't know what the acronym stands for and therefore cannot look it up and make a conclusion on it.

Also I agree these access decorators should not be loaded by the view or the model, maybe at the controller or boostrap level as it's own separate component. No coupling. There would be a table of decorators somewhere that exists independently of the models, that says which decorators should be loaded for which "types" of domain models, domain models would only know info about their type. Decorators would only know what types they should decorate. If a view had to be dependent on a role, a variable should be sent to the view, a configuration variable if you will, the configuration variable would be set by an object that was aware of roles. Instead of
if( $this->role=='user') echo 'left column';
you'd write something like
if( $this->hasLeftColumn ) echo 'left column';

That's just my 2 cents, of course I've never implemented this yet so I'm not really basing this on anything scientific per se
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: ACL and Reflection

Post by allspiritseve »

jshpro2 wrote:What is DI / DIC?
Dependency Injection/ Dependency Injection Container

There's a recent thread on sitepoint right now that talks about it.
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 »

There are really two conversations about Cross-Cutting Concerns: one about the AOP solution, and the other about making objects available in places where they are not structurally required to be. Logging and Access Control are common examples because you want them when you want them, but not always enough to build some structure to put them everywhere. AOP adds some almost-language level functionality to make things available as needed.

However as I mentioned above, MVC-like systems provide a structure to make a lot of things optionally available because there is a clear hierarchy of objects in these systems. So you can fairly easily inject these objects that are needed many different places -- making them available almost everywhere.


PS - it is interesting to see that Jeff has come to a very similar Registry/Config solution in WACT that I came to in Skeleton. It is a big trade-off (and unacceptable to many ;)) but I think on balance it produces the best mix of functionality.

PPS - yes I am avoiding static solutions and no I'm not going to go there... ;)
(#10850)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: ACL and Reflection

Post by josh »

allspiritseve wrote:
jshpro2 wrote:What is DI / DIC?
Dependency Injection/ Dependency Injection Container

There's a recent thread on sitepoint right now that talks about it.
damn acronyms, thanks yeah I had been reading up on DI, just never came across the abbreviations ( and it didn't click in my head ).

Also interesting synopsis arborint, I like the idea of it being almost a language like construct, doesn't sound like hacking a run-time solution would be best, I guess I was just suggesting even driven property access control for models, not really anything to do with AOP, which seems like an entirely different topic
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 »

jshpro2 wrote:I like the idea of it being almost a language like construct, doesn't sound like hacking a run-time solution would be best,
You may like a language level solution, but unfortunately a run-time solution is really the only thing possible. I also get the sense with subject that there are diminishing returns for more effort. What you really want is well designed objects available when you need them. That can be done now...
(#10850)
Post Reply