I thought of another solution to this issue this morning in the shower. Rather than creating an additional master can_access() method in CurrentUser, this could be handled with model hooks. JDBI uses hooks to perform processing before_create, after_create, etc. We could add an additional set of hooks called to do access checking, such as before_access() (and/or before_read, before_write, etc.).
This would allow the user of a class to arbitrarily associate additional checks for access. The weakness I see immediately though is if the system should be operated as an AND or an OR or if there could be a way to give it enough power to do both. That is, if multiple hooks are assigned, do all have to return true in order to gain access or does just one have to return true? Other than answering that question, the implementation should be relatively simple and provide additional power in a very straightforward manner. I still like the idea of having the can_access() mechanism on CurrentUser, but I don't know how anyone else feels about it. It would actually be possible to have both the can_access() method and the before_access() hooks, but that might just be over-complicating things. -- Andrew Sterling Hanenkamp Interaction Developer Boomer Consulting, Inc. 1.785.537.2358 ext. 17 1.888.266.6375 ext. 17 1.785.537.4545 (fax) 610 Humboldt Manhattan, KS 66502 http://www.boomer.com/about/team/andrew-hanenkamp.html <http://www.boomer.com/about/team/andrew-hanenkamp.html> [EMAIL PROTECTED] From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Andrew Sterling Hanenkamp Sent: Tuesday, May 08, 2007 4:10 PM To: [email protected] Subject: [jifty-devel] RFC: Access considerations for models I've been doing some work with the virtual-models branch (i.e., Jifty with models stored in the database rather than built in Perl modules). Part of this work has led to a dilemma on how best to deal with access to the models tables. The issue is that there is no obvious mechanism for overriding access control to built-in Jifty classes, such as ModelClass and ModelClassColumn in the virtual-models branch. The additional problem of access to the tables that are created "on the fly" by ModelClass rows is also problematic. I hesitate to store code in the database as the primary method of access control, but that's probably an option to consider for the future. An additional ACL system of some kind might be desirable at some point, but I don't think I'm ready for that proposal yet. However, this proposal could offer a good stop-gap for gaining control over access to both of the built-in Jifty models and custom models stored in ModelClass. This would also provide a mechanism for implementing custom ACL systems per-application. The key components of the current access control system are: * current_user_can() - each model may implement this method to provide per-model access control * App::CurrentUser - the CurrentUser object is used to represent information about the current user that may be used by current_user_can() implementations to determine if the current model is permitted o is_bootstrap_user() - the built-in implementation of current_user_can() allows the user that isn't logged when administration mode is enabled and during the run of Jifty::Bootstrap to have unrestricted access o is_superuser() - the built-in implementation of current_user_can() allows any current user with this set to true to have unrestricted access * Jifty::RightsFrom - this is a helper that is used to import a method named delegate_current_user_can() into the model it is applied to, this method is called by the default current_user_can() implementation to cause the checked model to inherit the current_user_can() method of another model based upon a related column... for example, if you delegate based upon the "owner" column, then the current user can create, read, write, or delete the current model if the current user could do the same operation on owner object Unless I'm mistaken, this pretty much sums up the current system. All the other methods and objects related to security are just additional helpers or checks based upon these pieces. In order to increase the flexibility of the system one more level, I propose the addition of a single new method to CurrentUser. Right now the Jifty::Record::current_user_can() implementation contains this snippet: if ( $self->current_user->is_bootstrap_user or $self->current_user->is_superuser ) { return (1); } I would suggest modifying this to read as follows: if ($self->current_user->can_access($model, $right, @_)) { return (1); } Then, the default Jifty::CurrentUser implementation would add this new method: sub can_access { my $self = shift; return $self->is_bootstrap_user || $self->is_superuser; } This has the advantage of not breaking any existing code, but granting ultimate authority on access control to the current user object. Alternatively, the previous if-statement could stand as before and the default can_access() implementation just returns false and is checked in addition to is_bootstrap_user() and is_superuser(). It makes little difference to me. I see this as having the following advantages: * Allows a single method implementation to control access to all models, which would allow really simple sites to create a single simple access control implementation for all models in one place. * Allows a complex application that needs fine-grained user-level control of access to do so by adding an ACL or other global access control system in the single method, can_access(). * Allows the implementations using virtual-models to apply application specific control to database-backed models via a custom CurrentUser object rather than some particular ACL system or code stored in the database. * Allows the implementation of can_access() to apply application specific control to all built-in Jifty models, such as ModelClass, ModelClassColumn, Metadata, and Session * It's pretty simple to understand and document. * It requires a very small patch. The disadvantages I see are: * App::CurrentUser::can_access() becomes holy-crap-powerful and has the potential to rip your site wide open if you aren't very careful with the implementation. * One might consider this a violation of the Separation of Concerns since it pulls access control of models into another object. However, one might also see it as allowing both objects involved in access control (model and CurrentUser) having a voice in the control. If you don't want to delegate this authority to CurrentUser, your model's current_user_can() just won't use it or the default Jifty::Record implementation. Built-in models don't have this possibility, but at least the developer has the option of controlling them at all. * Technically, you can already (mostly) provide this functionality without any change to Jifty core by overriding App::Record. However, this doesn't allow the application to control access to any modules that are part of Jifty itself, such as ModelClass, ModelClassColumn, Metadata, and Session. The only other alternative I can think of to handling this is to unshift App::Record into the Jifty::Model::* models you want to control access to and then implement a new default implementation of current_user_can() that has your application-wide access checks. As a modified version of that altnerative, I could see changing the implementation of the built-in Jifty models to inherit from App::Record automagically allowing this kind of tweak to actually succeed with the hack. However, that's not nearly so simple, so I think my proposal still stands. If we went with this latter suggestion, I would add an extra section to the AccessControl manual describing the technique with a possible reference in the Cookbook too. Please critique. Cheers, Sterling -- Andrew Sterling Hanenkamp Interaction Developer Boomer Consulting, Inc. 1.785.537.2358 ext. 17 1.888.266.6375 ext. 17 1.785.537.4545 (fax) 610 Humboldt Manhattan, KS 66502 http://www.boomer.com/about/team/andrew-hanenkamp.html <http://www.boomer.com/about/team/andrew-hanenkamp.html> [EMAIL PROTECTED]
_______________________________________________ jifty-devel mailing list [email protected] http://lists.jifty.org/cgi-bin/mailman/listinfo/jifty-devel
