@auth.requires_membership() was changed so it only does its query when the 
decorated function is actually called. However, you are using the more 
generic @auth.requires(), which can take any condition. There's no way to 
automatically make the evaluation of that condition lazy, so you are 
responsible for putting it inside a callable (e.g., a lambda) yourself.

On Friday, April 12, 2013 10:08:35 AM UTC-4, SimonD wrote:
>
> Anthony,
> Thanks so much for sharing the expertise, and so quickly.
>
> I had completely misunderstood about the decorators. Actually stacking 
> them is the simplest and easiest answer, given that it is a valid thing to 
> do. 
>
> I hear what you say about the unnecessary database hits and the lambda. I 
> had read the other string about this: "Authorization decorators always 
> generate db queries" that you had kindly posted to. This was something else 
> I misunderstood as I thought an update was applied to this on 11/18/11. 
> Oops sorry, I will be sure to take your advice on this point also.
>
> So, answer is: stacking the decorators and adding lambda to 
> @auth.requires(auth.has_membership.....
>
> Thanks again
> Simon
>
>
> On Friday, April 12, 2013 2:34:06 PM UTC+1, Anthony wrote:
>>
>> @auth.requires(auth.has_membership('Approver') or 
>>> auth.has_membership('Admin'))   #allowing Admin or Approvers to access
>>
>>
>> The above will execute the has_membership queries every time the 
>> controller is called, even when not accessing the decorated function. To 
>> avoid the unnecessary database hits, you can put the condition inside a 
>> lambda (so it will only get called when the decorated function is actually 
>> accessed):
>>
>> @auth.requires(lambda: auth.has_membership('Approver') or auth.
>> has_membership('Admin'))
>>
>> 1) How do I combine these decorators to include BOTH group membership and 
>>> requires_signature() ?
>>> 2) Can I use multiple,separate decorators for a function()? (I am sure 
>>> not)
>>>
>>
>> Yes, decorators can be stacked:
>>
>> @auth.requires_signature()
>> @auth.requires(some_condition)
>> def myfunc():
>>     ...
>>  
>>
>>> 3) It is also possible to add addtional conditions to @auth.requires() 
>>> e.g. mytable.department==auth.user.department (for added security!)
>>>
>>
>> Yes, the first argument to @auth.requires() can be any expression -- its 
>> truthiness will be evaluated to determine whether access is granted. It can 
>> also be a callable, it which case, it will be called and the return value 
>> will be evaluated (hence the recommendation above to put the membership 
>> checks inside a lambda).
>>  
>>
>>> 4) Or maybe there is there is a better way to prevent manual fiddling 
>>> with the URL/ARG ?
>>>
>>
>> Digitally signing the URLs is a good method for this. The signature is 
>> actually a hash of the URL itself (minus the signature, of course). When 
>> the request is made, web2py re-hashes the requested URL and makes sure it 
>> matches the signature -- if not, that means the URL was modified, and 
>> access is denied.
>>
>> The other option would be to check for permission on the requested 
>> record, but the signature is probably the best approach, as it doesn't 
>> require another database query to check permission.
>>
>> Anthony
>>
>

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to