[jifty-devel] RFC: Access considerations for models

Andrew Sterling Hanenkamp andrew.hanenkamp at boomer.com
Tue May 8 17:09:47 EDT 2007

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


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

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

*         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


    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


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


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.






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



andrew.hanenkamp at boomer.com <mailto:andrew.hanenkamp at boomer.com> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.bestpractical.com/pipermail/jifty-devel/attachments/20070508/721d1683/attachment.htm

More information about the jifty-devel mailing list