OAuth SSO infrastructure + account app support
- OAuthCode model + migration for authorization code flow
- OAuth client blueprint (auto-registered for non-federation apps)
- Per-app first-party session cookies (fixes Safari ITP)
- /oauth/authorize endpoint support in URL helpers
- account_url() helper + Jinja global
- Templates: federation_url('/auth/...') → account_url('/...')
- Widget registry: account page links use account_url
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,10 @@ def federation_url(path: str = "/") -> str:
|
||||
return app_url("federation", path)
|
||||
|
||||
|
||||
def account_url(path: str = "/") -> str:
|
||||
return app_url("account", path)
|
||||
|
||||
|
||||
def page_cart_url(page_slug: str, path: str = "/") -> str:
|
||||
if not path.startswith("/"):
|
||||
path = "/" + path
|
||||
@@ -66,17 +70,24 @@ def market_product_url(product_slug: str, suffix: str = "", market_place=None) -
|
||||
|
||||
|
||||
def login_url(next_url: str = "") -> str:
|
||||
# Auth lives in federation. Set AUTH_APP to override.
|
||||
from quart import session as qsession
|
||||
auth_app = os.getenv("AUTH_APP", "federation")
|
||||
base = app_url(auth_app, "/auth/login/")
|
||||
params: list[str] = []
|
||||
from quart import current_app
|
||||
|
||||
# Federation handles login directly (magic link flow)
|
||||
if current_app.name == "federation":
|
||||
base = "/auth/login/"
|
||||
params: list[str] = []
|
||||
if next_url:
|
||||
params.append(f"next={quote(next_url, safe='')}")
|
||||
from quart import session as qsession
|
||||
cart_sid = qsession.get("cart_sid")
|
||||
if cart_sid:
|
||||
params.append(f"cart_sid={quote(cart_sid, safe='')}")
|
||||
if params:
|
||||
return f"{base}?{'&'.join(params)}"
|
||||
return base
|
||||
|
||||
# Client apps: local /auth/login triggers OAuth redirect to federation
|
||||
base = "/auth/login/"
|
||||
if next_url:
|
||||
params.append(f"next={quote(next_url, safe='')}")
|
||||
# Pass anonymous cart session so the auth app can adopt it on login
|
||||
cart_sid = qsession.get("cart_sid")
|
||||
if cart_sid:
|
||||
params.append(f"cart_sid={quote(cart_sid, safe='')}")
|
||||
if params:
|
||||
return f"{base}?{'&'.join(params)}"
|
||||
return f"{base}?next={quote(next_url, safe='')}"
|
||||
return base
|
||||
|
||||
Reference in New Issue
Block a user