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

Reply via email to