kaya-oidc 0.0.6 can run several providers in one app (OIDCProviders), each with its own login route and namespaced session state. Adopt it: providers are configured in indexed, contiguous OIDC_<n>_* blocks (0-based) with OIDC_<n>_PROVIDER naming the provider in its login URL and session keys. The old unindexed OIDC_ISSUER/OIDC_CLIENT_ID/... names are no longer read; startup fails with a rename hint when they are set. With no OIDC variables at all, the single dev mock provider named "default" is used, as before. The platform now authenticates through OIDCProviders: auth.current_user returns the session's user (sessions stay single-identity, so at most one provider is logged in) and require_auth/route handlers use it, while the websocket path keeps scanning for any provider's user. New routes expose the configuration to the SPA and keep old links working: GET /api/auth/providers lists the login URLs, GET /auth/login redirects to the first provider and GET /auth/logout to whichever provider the session is logged in with. The lobby renders one login button per provider from that endpoint. Update the env examples, compose and k8s manifests to the indexed scheme, document the multiple-provider setup and the migration, and cover it with config, auth and route tests.
52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
"""The :class:`PlatformMixin`: mounts the whole platform on a kaya app.
|
|
|
|
``Platform`` bundles the collaborators every platform endpoint needs —
|
|
the game registry, the live-game store, the deadline scheduler and the
|
|
OIDC providers used for authentication — so route and websocket modules
|
|
never reach for module-global state. :class:`PlatformMixin` is a plain
|
|
:class:`~kaya.core.KayaMixin`: applying it registers the lobby, stats
|
|
and health HTTP routes plus the live-play websocket endpoint, and the
|
|
app stays a :class:`~kaya.core.KayaApp` (both ASGI and RSGI keep
|
|
working).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from kaya.core import KayaApp, KayaMixin
|
|
from kaya.oidc import OIDCProviders
|
|
|
|
from .deadlines import DeadlineScheduler
|
|
from .registry import GameRegistry
|
|
from .store import GameStore
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Platform:
|
|
"""The collaborators shared by all platform endpoints."""
|
|
|
|
registry: GameRegistry
|
|
game_store: GameStore
|
|
scheduler: DeadlineScheduler
|
|
oidc: OIDCProviders
|
|
|
|
|
|
class PlatformMixin(KayaMixin):
|
|
"""Register the game-independent routes and the websocket endpoint."""
|
|
|
|
def __init__(self, platform: Platform) -> None:
|
|
self.platform = platform
|
|
|
|
def apply(self, app: KayaApp) -> None:
|
|
# Imported here so module import order stays acyclic: the route
|
|
# modules reference Platform only for typing.
|
|
from . import ws
|
|
from .routes import auth, games, health, me, stats
|
|
|
|
health.register(app, self.platform)
|
|
auth.register(app, self.platform)
|
|
me.register(app, self.platform)
|
|
games.register(app, self.platform)
|
|
stats.register(app, self.platform)
|
|
ws.register(app, self.platform)
|