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 <mig.e.lo...@gmail.com> 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:GOOD_PASS@127.0.0.1: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:BAD_PASS@127.0.0.1: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 >