Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth #42

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a0e1e8d
make oauth login form actually verify creds
DavidBuchanan314 Jan 17, 2025
769a828
create session cookie on successful auth
DavidBuchanan314 Jan 17, 2025
1bc99b8
new table to track oauth grants
DavidBuchanan314 Jan 17, 2025
9a2bb78
split authz and authn into dedicated routes
DavidBuchanan314 Jan 17, 2025
9f68f9b
actually store PARs
DavidBuchanan314 Jan 17, 2025
4886ff1
pass 'next' parameter to authentication endpoint, use it to redirect …
DavidBuchanan314 Jan 17, 2025
e82f695
retreive PAR, client_id, list authz scopes in web ui
DavidBuchanan314 Jan 17, 2025
c82f705
old-python compat
DavidBuchanan314 Jan 17, 2025
991b156
old-python compat, take 2
DavidBuchanan314 Jan 17, 2025
254fa63
fix error icon alignment
DavidBuchanan314 Jan 17, 2025
8376c45
refactoring
DavidBuchanan314 Jan 19, 2025
2961123
hand out some fake tokens just so we can complete the flow
DavidBuchanan314 Jan 19, 2025
32ea4a6
send some real auth tokens
DavidBuchanan314 Jan 19, 2025
7e5de4c
implement jwk fingerprinting for dpop
DavidBuchanan314 Jan 20, 2025
4f02f5f
forbid redirects when fetching client metadata
DavidBuchanan314 Jan 20, 2025
92b4686
refactor dpop header processing into a middleware
DavidBuchanan314 Jan 20, 2025
c880469
refactor authentication into a middleware
DavidBuchanan314 Jan 22, 2025
0d39403
refactor service auth token generation, check for chat.bsky scope
DavidBuchanan314 Jan 22, 2025
ce168c0
fix inbound lxm check
DavidBuchanan314 Jan 22, 2025
53ebf02
fix service proxying
DavidBuchanan314 Jan 22, 2025
e5ba5ce
make scope grant flow work again, remember granted scopes
DavidBuchanan314 Jan 23, 2025
adc9a2b
prevent open redirects after login, clean up server metadata doc
DavidBuchanan314 Jan 23, 2025
9074f36
reuse app password api for oauth scope management
DavidBuchanan314 Jan 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/millipds/auth_oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import json
import secrets
import time
import urllib.parse

from aiohttp import web

Expand Down Expand Up @@ -139,7 +140,10 @@ async def oauth_authorize_get(request: web.Request):
).fetchone()
if row is None:
# no active oauth cookie session
return web.HTTPTemporaryRedirect("/oauth/authenticate")
return web.HTTPTemporaryRedirect(
"/oauth/authenticate?"
+ urllib.parse.urlencode({"next": request.path_qs})
)

# if we reached here, either there was an existing session, or the user
# just created a new one and got redirected back again
Expand All @@ -164,6 +168,7 @@ async def oauth_authorize_post(request: web.Request):
now = int(time.time())
db = get_db(request)

# TODO: don't duplicate code between here and the GET handler
session_token = request.cookies.get("millipds-oauth-session")
row = db.con.execute(
"""
Expand All @@ -174,7 +179,11 @@ async def oauth_authorize_post(request: web.Request):
).fetchone()
if row is None:
# no active oauth cookie session
return web.HTTPTemporaryRedirect("/oauth/authenticate")
# this should be pretty rare - session expired between the initial GET and the form submission
return web.HTTPTemporaryRedirect(
"/oauth/authenticate?"
+ urllib.parse.urlencode({"next": request.path_qs})
)

# TODO: redirect back to app?
return web.Response(
Expand Down Expand Up @@ -227,8 +236,10 @@ async def oauth_authenticate_post(request: web.Request):
),
)
# we can't use a 301/302 redirect because we need to produce a GET
next = request.query.get("next", "")
# TODO: !!!important!!! assert next is a relative URL, or absolutify it somehow
DavidBuchanan314 marked this conversation as resolved.
Show resolved Hide resolved
res = web.Response(
text=html_templates.redirect("/oauth/authorize"),
text=html_templates.redirect(next),
content_type="text/html",
headers=WEBUI_HEADERS,
)
Expand Down
Loading