blob: 6a41f38408dc71485a22e9c34a8f2c34a9204596 [file] [view]
# Session handling
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:
~~~python
@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:
~~~python
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 account management via declared PAT handler
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:
~~~python
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:
~~~bash
curl -H "Authorization: bearer abcdefg" https://foo.apache.org/some-endpoint
~~~
## Using scopes for tokens
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:
~~~python
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()