[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