121 lines
4.1 KiB
Python
121 lines
4.1 KiB
Python
from __future__ import annotations
|
|
|
|
from types import SimpleNamespace
|
|
|
|
from ariadne.services import oauth2_proxy as oauth_module
|
|
from ariadne.services.oauth2_proxy import OAuth2ProxyService, _oauth_client_payload, _valid_cookie_secret
|
|
|
|
|
|
def test_oauth_client_payload() -> None:
|
|
payload = _oauth_client_payload("wolf", "https://wolf.bstein.dev")
|
|
assert payload["clientId"] == "wolf"
|
|
assert payload["redirectUris"] == ["https://wolf.bstein.dev/oauth2/callback"]
|
|
|
|
|
|
def test_valid_cookie_secret() -> None:
|
|
assert _valid_cookie_secret("x" * 32) == "x" * 32
|
|
assert _valid_cookie_secret("short") == ""
|
|
assert _valid_cookie_secret(None) == ""
|
|
|
|
|
|
def test_ensure_wolf_creates_client_and_writes_vault(monkeypatch) -> None:
|
|
monkeypatch.setattr(
|
|
oauth_module,
|
|
"settings",
|
|
SimpleNamespace(wolf_oidc_client_id="wolf", wolf_oidc_base_url="https://wolf.bstein.dev", wolf_oidc_vault_path="game-stream/wolf-oidc"),
|
|
)
|
|
calls: list[str] = []
|
|
written = {}
|
|
|
|
class DummyKeycloak:
|
|
def __init__(self) -> None:
|
|
self.created = False
|
|
|
|
def ready(self):
|
|
return True
|
|
|
|
def find_client(self, client_id):
|
|
return {"id": "client-uuid", "clientId": client_id} if self.created else None
|
|
|
|
def create_client(self, _payload):
|
|
self.created = True
|
|
calls.append("create")
|
|
|
|
def update_client(self, _client_uuid, _payload):
|
|
calls.append("update")
|
|
|
|
def find_client_scope_id(self, _name):
|
|
return "scope-uuid"
|
|
|
|
def attach_optional_client_scope(self, _client_uuid, _scope_id):
|
|
calls.append("scope")
|
|
|
|
def get_client_secret(self, _client_uuid):
|
|
return "client-secret"
|
|
|
|
class DummyVault:
|
|
def read_kv_secret(self, _path):
|
|
return {"cookie_secret": "a" * 32}
|
|
|
|
def write_kv_secret(self, path, data):
|
|
written["path"] = path
|
|
written["data"] = data
|
|
|
|
monkeypatch.setattr(oauth_module, "keycloak_admin", DummyKeycloak())
|
|
monkeypatch.setattr(oauth_module, "vault", DummyVault())
|
|
|
|
assert OAuth2ProxyService().ensure_wolf()["status"] == "ok"
|
|
assert calls == ["create", "update", "scope"]
|
|
assert written["data"]["client_secret"] == "client-secret"
|
|
assert written["data"]["cookie_secret"] == "a" * 32
|
|
|
|
|
|
def test_ensure_wolf_reports_missing_keycloak(monkeypatch) -> None:
|
|
monkeypatch.setattr(
|
|
oauth_module,
|
|
"settings",
|
|
SimpleNamespace(wolf_oidc_client_id="wolf", wolf_oidc_base_url="https://wolf.bstein.dev", wolf_oidc_vault_path="game-stream/wolf-oidc"),
|
|
)
|
|
monkeypatch.setattr(oauth_module, "keycloak_admin", SimpleNamespace(ready=lambda: False))
|
|
assert OAuth2ProxyService().ensure_wolf()["status"] == "error"
|
|
|
|
|
|
def test_ensure_wolf_rejects_missing_client_after_create(monkeypatch) -> None:
|
|
monkeypatch.setattr(
|
|
oauth_module,
|
|
"settings",
|
|
SimpleNamespace(wolf_oidc_client_id="wolf", wolf_oidc_base_url="https://wolf.bstein.dev", wolf_oidc_vault_path="game-stream/wolf-oidc"),
|
|
)
|
|
monkeypatch.setattr(
|
|
oauth_module,
|
|
"keycloak_admin",
|
|
SimpleNamespace(ready=lambda: True, find_client=lambda _client_id: None, create_client=lambda _payload: None),
|
|
)
|
|
|
|
try:
|
|
OAuth2ProxyService().ensure_wolf()
|
|
except RuntimeError as exc:
|
|
assert "not found" in str(exc)
|
|
else:
|
|
raise AssertionError("missing client should fail")
|
|
|
|
|
|
def test_ensure_wolf_rejects_missing_client_uuid(monkeypatch) -> None:
|
|
monkeypatch.setattr(
|
|
oauth_module,
|
|
"settings",
|
|
SimpleNamespace(wolf_oidc_client_id="wolf", wolf_oidc_base_url="https://wolf.bstein.dev", wolf_oidc_vault_path="game-stream/wolf-oidc"),
|
|
)
|
|
monkeypatch.setattr(
|
|
oauth_module,
|
|
"keycloak_admin",
|
|
SimpleNamespace(ready=lambda: True, find_client=lambda _client_id: {"id": ""}, create_client=lambda _payload: None),
|
|
)
|
|
|
|
try:
|
|
OAuth2ProxyService().ensure_sunshine()
|
|
except RuntimeError as exc:
|
|
assert "id missing" in str(exc)
|
|
else:
|
|
raise AssertionError("missing client id should fail")
|