This repository has been archived on 2026-02-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
shared/infrastructure/urls.py
giles 46f44f6171 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>
2026-02-23 09:55:27 +00:00

94 lines
2.6 KiB
Python

from __future__ import annotations
import os
from urllib.parse import quote
from shared.config import config
def _get_app_url(app_name: str) -> str:
env_key = f"APP_URL_{app_name.upper()}"
env_val = os.getenv(env_key)
if env_val:
return env_val.rstrip("/")
return config()["app_urls"][app_name].rstrip("/")
def app_url(app_name: str, path: str = "/") -> str:
base = _get_app_url(app_name)
if not path.startswith("/"):
path = "/" + path
return base + path
def blog_url(path: str = "/") -> str:
return app_url("blog", path)
def market_url(path: str = "/") -> str:
return app_url("market", path)
def cart_url(path: str = "/") -> str:
return app_url("cart", path)
def events_url(path: str = "/") -> str:
return app_url("events", path)
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
return cart_url(f"/{page_slug}{path}")
def market_product_url(product_slug: str, suffix: str = "", market_place=None) -> str:
"""Build a market product URL with the correct page/market prefix.
Resolves the prefix from:
- market app context: g.post_slug + g.market_slug
- cart app context: g.page_slug + market_place.slug
"""
from quart import g
page_slug = getattr(g, "post_slug", None) or getattr(g, "page_slug", None)
ms = getattr(g, "market_slug", None) or (
getattr(market_place, "slug", None) if market_place else None
)
prefix = f"/{page_slug}/{ms}" if page_slug and ms else ""
tail = f"/{suffix}" if suffix else "/"
return market_url(f"{prefix}/product/{product_slug}{tail}")
def login_url(next_url: str = "") -> 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:
return f"{base}?next={quote(next_url, safe='')}"
return base