OAuth user sessions can be accessed through the asfquart.session component, and are encrypted to ensure authenticity.
The login and logout flow is automatically handled by asfquart, unless explicitly told not to, and sessions can be accessed and modified as needed:
@asfquart.auth.require # Implicitly require a valid (non-empty) session async def endpoint_with_session(): session = await asfquart.session.read() # Read user session dict session["foobar"] = 42 asfquart.session.write(session) # Store our changes in the user session
Session timeouts can be handled by passing the expiry_time argument to the read() call:
session = await asfquart.session.read(expiry_time=24*3600) # Require a session that has been accessed in the past 24 hours. assert session, "No session found or session expired" # If too old or not found, read() returns None
Role accounts (or regular users) can access asfquart apps by using a bearer token, so long as a personal app token (PAT) handler is declared:
async def token_handler(token): if token == "abcdefg": return { "uid": "roleaccountthing", "roleaccount": True, # For role accounts, this MUST be set to True, to distinguish from normal user PATs "committees": ["httpd", "tomcat",], # random restriction in this example "metadata": { # the optional metadata dict can be used to manage/log whatever internal information you wish "scope": ["scopeA", "scopeB"], # For instance, you can log which scopes this token can be used within }, } asfquart.APP.token_handler = token_handler
This would enable the role account to be granted a session through the bearer auth header:
curl -H "Authorization: bearer abcdefg" https://foo.apache.org/some-endpoint
If the application makes use of scopes to limit what an access token can do, you can note these scopes inside the metadata dictionary when constructing the session dict to return. The metadata dict can be used for whatever information you wish to keep about a specific session, and is accessed through session.metadata when fetched via the usual session = await asfquart.session.read() call. Thus, you can test your tokens at the endpoint:
REQUIRED_SCOPE = "admin" # some random scope required for this endpoint @app.route("/foo") @asfquart.auth.require # Require a valid session, can be through a PAT async def endpoint(): # Get session session = await asfquart.session.read() # Ensure it has the right scope, or bail if REQUIRED_SCOPE not in session.metadata.get("scope", []): raise asfquart.auth.AuthenticationFailed("Your token does not have the required scope for this endpoint") # No bail? scope must be proper, do the things.. do_scoped_stuff()