How this basically works is:
1. A fernet key is established which is shared between all services
2. For website logins, a cookie with the user's meta.sr.ht profile info
is encrypted with the fernet key and placed on the global domain
3. For API access, the fernet key is used to sign and encrypt a header
with a short JSON payload specifying the username the request is made
on behalf of, as well as the client ID for the requesting service. A
synthetic OAuth token is generated on the fly at the other end.
Problems this solves:
- Single sign-on/sign-off
- API authentication prior to first log-in at each service
- Referencing unknown users will fetch their info and make them known
(e.g. adding new users to an ACL before their first log-in)
Future improvements:
- Drop the core.sr.ht flask.session wrapper
- Use session IDs from the database to allow session revocation
- Add a version number to the user info cookie so we can go back and
update our webhooks et al when necessary
I have attempted to leave the OAuth path in place, so that third-parties
can run *.sr.ht services with upstream meta.sr.ht handling logins, but I
have not tested this code.