[LRUG] [Off-Topic] Authorisation
Daniel Tenner
daniel.ruby at tenner.org
Mon Jul 28 06:21:35 PDT 2008
I'll chime in with a different thought, for a somewhat different use
case...
We're building an API for a Flex RIA client, and pretty much every api
call involves some form of authorisation against some object that's
being accessed. In this case, we found it was better to separate the
authorisation logic out of the models, by creating an AccessControl
object that contains the access control logic. To find the access
level to an object, we just call something like:
access_control.check_access(:read, object)
which throws an error when the user doesn't have read access on that
object, for instance.
The advantages are:
- the models are a tad cleaner
- the access control logic is easier to test in isolation (=> fewer
authorisation logic bugs)
- because the access control is in the controller, there's no
interference from that logic when manipulating the application via the
console
- it's very straightforward to verify whether a controller method does
access control ("is there a call to check_access for the correct
object?")
- it's quite straightforward to extract most of those access control
calls out of the controller, even, via a before_filter, which makes it
all even cleaner
- it also creates a single point where access control calls can be
cached/optimised, which, when building an API that has to return a
"privilege" field on each object so the UI knows what it's allowed to
do with those objects, is quite handy
Obviously, this is for a different use case than the one Andrew asked
about, and is way over-engineered for just deciding whether to display
a checkbox :-), but for a comprehensive authorisation solution it
works pretty well, so I thought I'd throw it out there in case
someone's interested.
Daniel
On 28 Jul 2008, at 11:1528 Jul 2008, Matthew Westcott wrote:
> I've done exactly the is_editable_by? thing in my latest app and
> found it to work very well, especially with this bit of syntactic
> sugar in ApplicationController:
>
> def can_edit?(obj)
> obj.is_editable_by?(current_user)
> end
> helper_method :can_edit?
>
> # <%= link_to('edit', some_resource) if can_edit?(some_resource) %>
>
> - Matt
>
> On 28 Jul 2008, at 11:00, Steve Butterworth wrote:
>
>> I think an is_editable_by? method on Person will encapsulate the
>> logic nicely and the model doesn't have to know the current user as
>> you are passing this in as a method argument.
>>
>> >> person1.is_editable_by?(current_user)
>>
>> Sometimes I do go a step further with this kind of thing and set a
>> class attribute on Person (acutally normally User) called
>> current_user which is in a before filter in application_controller.
>> This way models can get access to the current_user via
>> User.current_user. This technique comes with a warning though
>> because once you make assumptions in models about logged in users
>> and access to them you are coupling your code (more specifically
>> layers) more tightly than perhaps you want.
>>
>> Steve
>>
>> Andrew Stewart wrote:
>>> Hola El Rug,
>>>
>>> In my current Rails project I have a screen that lists all the
>>> people who can log in. A person may update their own details, and
>>> an administrator may update anyone's details.
>>>
>>> So in the view I need to use that logic to determine whether or
>>> not to show an edit link by each person. In the controller, I use
>>> that logic to determine whether or not the current person (i.e.
>>> the person using the app) can execute the edit and update actions
>>> (because they may have typed the URL directly).
>>>
>>> Right now I have repeat the logic in the view and the controller.
>>> However I think the authorisation logic would be better off in the
>>> model, perhaps with an is_editable_by?(person) method on the
>>> Person object. But the model doesn't know anything about the
>>> current person (which is why auditing plugins resort to hijacking
>>> Rails' caching mechanism to track who does what to the models), so
>>> I can't see how to enforce the authorisation in the model layer.
>>>
>>> In a nutshell, I think that the authorisation logic should live in
>>> the model layer, and the view and the controller should query the
>>> model to find out what is allowed. However the model layer can't
>>> enforce the rules; only the controller can.
>>>
>>> Have I missed anything? Is there a better way to do this? I'd
>>> appreciate your thoughts.
>>>
>>> Regards,
>>>
>>> Andy Stewart
>>>
>>> -------
>>> AirBlade Software Ltd
>>> http://airbladesoftware.com
>>>
>>>
>>>
>>> _______________________________________________
>>> Chat mailing list
>>> Chat at lists.lrug.org
>>> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>>>
>>
>> _______________________________________________
>> Chat mailing list
>> Chat at lists.lrug.org
>> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
More information about the Chat
mailing list