I'm still in need of help. Here's what I've managed to find.
My problem is that if I don't use good credentials in the command line
I get an exception because web2py is replying with the login_url. This
suggests that the failedAuthHandler I'm using in
auth.settings.on_failed_authorization is not working.
[in models/db.py]
def failedAuthHandler():
if request.function == 'private_call':
redirect(URL(f='failed_login')) # just a regular action
# or alternatively:
redirect(URL(f='public_call', args=['jsonrpc', 'failed_login']))
else:
redirect(URL(request))
auth.settings.on_failed_authorization = failedAuthHandler
Since using "failed_login" as a regular action or as a public_call
makes no difference. is this the correct way to use
auth.settings.on_failed_authorization = function ?
Txs for the help,
Miguel
On Sun, Jan 30, 2011 at 10:55 AM, Miguel Lopes <[email protected]> wrote:
> on_failed_authorization can be a URL or a function.
> I'm think I could use this to achieve conditional login redirection.
> A use case would be service calls returning a simple string (or a JSON
> or an XML reply to non-validated requests), while still allowing for
> regular (non-service requests) to be redirected to a login page.
> This is useful for command-line clients (as a recent post argues) and
> desktops clients, but also to browser based RIA apps (e.g. Pyjamas
> based, Flex,...) where session expiration could lead to wanted
> redirections (as is mentioned in
> http://www.web2pyslices.com/main/slices/take_slice/48 ).
>
> I would see this as something as simple as:
>
> [in models/db.py]
> private_service = Service(globals()) # PRIVATE - for json,
> xml, jsonrpc, xmlrpc, amfrpc
> public_service = Service(globals()) # PUBLIC - for json,
> xml, jsonrpc, xmlrpc, amfrpc
> ...
> auth.settings.allow_basic_login = True
> def failedAuthHandler():
> if request.function == 'private_call':
> redirect(URL(f='public_call', args='failed_login'))
> else:
> redirect(URL(request))
> auth.settings.on_failed_authorization = failedAuthHandlerandler
>
> [in controllers/default]
> @private_service.jsonrpc
> def jsoncount():
> return dict(response=response.session_id_name, now=request.now)
>
> @public_service.jsonrpc
> def failed_login():
> return dict(error='Failed login')
>
> def public_call():
> return public_service()
>
> @auth.requires_login()
> def private_call():
> return private_service()
>
> However, I'm unable to make this code work.
> From the command line, if I issue a call with basic auth, with good
> credentials, such as:
>>>> import jsonrpc
>>>> sv =
>>>> jsonrpc.ServiceProxy("http://GOOD_USER:[email protected]:8080/json_auth_test/default/private_call/jsonrpc")
>>>> sv.jsoncount()
>>>> {'now': '2011-01-30 10:31:21', 'response': 'session_id_json_auth_test'}
>
> But bad credentials don't work as expected:
>>>> import jsonrpc
>>>> sv =
>>>> jsonrpc.ServiceProxy("http://GOOD_USER:[email protected]:8080/json_auth_test/default/private_call/jsonrpc")
>>>> sv.jsoncount()
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File
> "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/jsonrpc/proxy.py",
> line 43, in __call__
> resp = loads(respdata)
> File
> "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/jsonrpc/json.py",
> line 211, in loads
> raise JSONDecodeException('Expected []{}," or Number, Null, False or True')
> jsonrpc.json.JSONDecodeException: Expected []{}," or Number, Null, False or
> True
>>>>
>
> From the browser using an url with or without credentials, for both:
> .../default/private_call/jsoncount
> .../default/public_call/failed_login
>
> I get:
> Object does not exist with a Status 404 content header
>
> Am I on the right track?
> How could this be achieved?
> Txs,
> Miguel
>