Sorry, forgot login_bare adds the user to auth, so it's simpler:

auth.settings.allow_basic_login = True
auth.basic()
if auth.user:
    etc.

Anthony

On Thursday, May 31, 2012 10:49:04 PM UTC-4, Anthony wrote:
>
> If you can confirm that this works, I'll add it to the book.
>
> On Thursday, May 31, 2012 10:48:21 PM UTC-4, Anthony wrote:
>>
>> Looks like you can do:
>>
>> auth.settings.allow_basic_login = True
>> auth.user = auth.basic()[2]
>> if auth.user:
>>     etc.
>>
>> But this doesn't appear to be documented. Perhaps auth.basic() should 
>> automatically populate auth.user rather than simply returning it as part of 
>> a tuple.
>>
>> Anthony
>>
>> On Thursday, May 31, 2012 10:12:14 PM UTC-4, G. Clifford Williams wrote:
>>>
>>> Given the following code snippet in a controller (default or any other): 
>>>
>>> auth.settings.allow_basic_login = True
>>> def howdy():
>>>     auth.settings.allow_basic_login = True
>>>     response.view = 'generic.json'
>>>     if auth.user:
>>>         this_user = auth.user.id
>>>     else:
>>>         this_user = "unset"
>>>     return dict(user=this_user)
>>> if the controller action is called as such:
>>> % curl --user '[email protected]:supersecretpassword' 
>>> http://127.0.0.1:8000/myapp/controller/howdy                      
>>>
>>> this response you'll get it this: 
>>> {"user": "unset"} 
>>>
>>> The same goes for using auth.is_logged_in(): 
>>>
>>> The result is different, however, when you use one of the 'requires' 
>>> decorators:                                                             
>>>
>>> auth.settings.allow_basic_login = True
>>>
>>> def howdy():
>>>     auth.settings.allow_basic_login = True
>>>     @auth.requires_login()
>>>     def proforma():
>>>         pass #empty function just to invoke auth.requires
>>>     proforma() #call empty function
>>>     response.view = 'generic.json'
>>>     if auth.user:
>>>         this_user = auth.user.id
>>>     else:
>>>         this_user = "unset"
>>>     return dict(user=this_user)
>>> this results in:
>>> % curl --user '[email protected]:supersecretpassword' 
>>> http://127.0.0.1:8000/myapp/controller/howdy                      
>>> {"user": 1}  
>>>
>>> After some digging I discovered that in tools.py auth.requires_* ends up 
>>> calling login_bare which is why the second one works. I realize that 
>>> according to the book (
>>> http://web2py.com/books/default/chapter/29/9?search=login_bare) 
>>>  login_bare() can be called to login the user "manually". Unfortunately the 
>>> examples for auth.settings.allow_basic_login in the manual/book (
>>> http://web2py.com/books/default/chapter/29/9#Access-Control-and-Basic-Authentication,
>>>  
>>> http://web2py.com/books/default/chapter/29/9#Settings-and-messages , & 
>>> http://web2py.com/books/default/chapter/29/10#Access-Control) don't 
>>> address the fact that no login is actually executed without the decorators. 
>>> With the last example if someone wanted to use that as a guide they might 
>>> think that changing: 
>>>
>>> @auth.requires_login()
>>> @request.restful()
>>> def api():
>>>    def GET(s):
>>>        return 'access granted, you said %s' % s
>>>    return locals()
>>>
>>> to: 
>>>
>>>
>>> @request.restful()
>>> def api():
>>>    def GET(s):
>>>
>>>        if auth.is_logged_in():
>>>            return 'access granted, you said %s' % s
>>>
>>>        else:
>>>
>>>            return 'access denied'
>>>    return locals()
>>>
>>>
>>> Should work, but they would be mistaken (and likely to spend much time 
>>> trying to figure out why one worked and the other did not). I don't know 
>>> whether it was the intention that using basic auth prevent a call to log 
>>> the user in by default. It seems that either the code should be fixed or we 
>>> should update the documentation to clarify that login_bare() should be 
>>> called explicitly (directly or indirectly) to actually execute the login 
>>> process. 
>>>
>>>

Reply via email to