Send Repixelizer Discord access policy

This commit is contained in:
Meta Vens 2026-04-29 13:22:00 +01:00
commit cae9cbf9ad
2 changed files with 27 additions and 0 deletions

View file

@ -197,6 +197,8 @@ class AccessRuntimeConfig:
auth_attempt_ttl_seconds: int = 600
http_timeout_seconds: float = 10.0
jwks_cache_seconds: int = 300
discord_access_guild_id: str | None = None
discord_access_role_ids: tuple[str, ...] = ()
@property
def enabled(self) -> bool:
@ -460,6 +462,8 @@ class AccessController:
heimdall_jwks_url = None
app_public_base_url = None
start_endpoint = None
discord_access_guild_id = None
discord_access_role_ids: tuple[str, ...] = ()
login_url = _env_text("GC_ACCESS_LOGIN_URL")
logout_url = _env_text("GC_ACCESS_LOGOUT_URL")
verifier: HeimdallVerifier | None = None
@ -498,6 +502,8 @@ class AccessController:
login_url = login_url or "/"
logout_url = logout_url or _AUTH_LOGOUT_PATH
start_endpoint = _AUTH_START_PATH
discord_access_guild_id = _env_text("REPIXELIZER_ACCESS_DISCORD_GUILD_ID")
discord_access_role_ids = tuple(_parse_csv(_env_text("REPIXELIZER_ACCESS_DISCORD_ALLOWED_ROLE_IDS")))
verifier = HeimdallVerifier(
issuer=heimdall_issuer,
app_slug=app_slug,
@ -526,6 +532,8 @@ class AccessController:
auth_attempt_ttl_seconds=attempt_ttl_seconds,
http_timeout_seconds=timeout_seconds,
jwks_cache_seconds=jwks_cache_seconds,
discord_access_guild_id=discord_access_guild_id,
discord_access_role_ids=discord_access_role_ids,
)
return cls(runtime, verifier=verifier)
@ -610,6 +618,16 @@ class AccessController:
"callbackUrl": callback_url,
},
}
if (
provider_slug == "discord"
and self.runtime.discord_access_guild_id
and self.runtime.discord_access_role_ids
):
request_payload["entitlementPolicy"] = {
"kind": "discord_role_access",
"guildId": self.runtime.discord_access_guild_id,
"allowedRoleIds": list(self.runtime.discord_access_role_ids),
}
start_url = urljoin(f"{heimdall_base_url}/", _AUTH_START_ENDPOINT_TEMPLATE.format(provider=provider_slug).lstrip("/"))
try:
response_payload = _post_json(

View file

@ -426,6 +426,8 @@ def test_gui_hosted_root_renders_heimdall_login_buttons(monkeypatch, tmp_path: P
monkeypatch.setenv("GC_ACCESS_HEIMDALL_BASE_URL", "https://heimdall.gamecult.org")
monkeypatch.setenv("GC_ACCESS_APP_PUBLIC_BASE_URL", "https://repixelizer.gamecult.org")
monkeypatch.setenv("GC_ACCESS_ALLOWED_PROVIDERS", "discord,patreon")
monkeypatch.setenv("REPIXELIZER_ACCESS_DISCORD_GUILD_ID", "gamecult-guild")
monkeypatch.setenv("REPIXELIZER_ACCESS_DISCORD_ALLOWED_ROLE_IDS", "role-repixelizer,role-patreon")
app = create_app()
status, _headers, body = asyncio.run(_get_response(app, "/"))
@ -752,6 +754,8 @@ def test_gui_heimdall_callback_flow_adopts_local_cookie_session(monkeypatch, tmp
monkeypatch.setenv("GC_ACCESS_HEIMDALL_BASE_URL", "https://heimdall.gamecult.org")
monkeypatch.setenv("GC_ACCESS_APP_PUBLIC_BASE_URL", "https://repixelizer.gamecult.org")
monkeypatch.setenv("GC_ACCESS_ALLOWED_PROVIDERS", "discord,patreon")
monkeypatch.setenv("REPIXELIZER_ACCESS_DISCORD_GUILD_ID", "gamecult-guild")
monkeypatch.setenv("REPIXELIZER_ACCESS_DISCORD_ALLOWED_ROLE_IDS", "role-repixelizer,role-patreon")
monkeypatch.setattr("repixelizer.access._post_json", fake_post_json)
monkeypatch.setattr("repixelizer.access._fetch_json", fake_fetch_json)
@ -774,6 +778,11 @@ def test_gui_heimdall_callback_flow_adopts_local_cookie_session(monkeypatch, tmp
assert start_calls
assert start_calls[0][0] == "https://heimdall.gamecult.org/v1/oauth/discord/start"
assert start_calls[0][1]["handoff"]["callbackUrl"] == "https://repixelizer.gamecult.org/api/auth/heimdall/callback"
assert start_calls[0][1]["entitlementPolicy"] == {
"kind": "discord_role_access",
"guildId": "gamecult-guild",
"allowedRoleIds": ["role-repixelizer", "role-patreon"],
}
pending_status, _pending_headers, pending_body = asyncio.run(_get_response(app, f"/api/auth/attempts/{attempt_id}"))
pending_payload = _response_json(type("Response", (), {"body": pending_body})())