from __future__ import annotations import jwt import pytest from ariadne.auth.keycloak import Authenticator, KeycloakOIDC def _make_token(kid: str = "test") -> str: return jwt.encode( {"sub": "user"}, "secret", algorithm="HS256", headers={"kid": kid}, ) def test_keycloak_verify_accepts_matching_audience(monkeypatch) -> None: token = _make_token() kc = KeycloakOIDC("https://jwks", "https://issuer", "portal") monkeypatch.setattr(kc, "_get_jwks", lambda force=False: {"keys": [{"kid": "test"}]}) monkeypatch.setattr(jwt.algorithms.RSAAlgorithm, "from_jwk", lambda key: "dummy") monkeypatch.setattr( jwt, "decode", lambda *args, **kwargs: {"azp": "portal", "preferred_username": "alice", "groups": ["/admin"]}, ) claims = kc.verify(token) assert claims["preferred_username"] == "alice" def test_keycloak_verify_rejects_wrong_audience(monkeypatch) -> None: token = _make_token() kc = KeycloakOIDC("https://jwks", "https://issuer", "portal") monkeypatch.setattr(kc, "_get_jwks", lambda force=False: {"keys": [{"kid": "test"}]}) monkeypatch.setattr(jwt.algorithms.RSAAlgorithm, "from_jwk", lambda key: "dummy") monkeypatch.setattr( jwt, "decode", lambda *args, **kwargs: {"azp": "other", "aud": ["other"]}, ) with pytest.raises(ValueError): kc.verify(token) def test_keycloak_verify_missing_kid(monkeypatch) -> None: kc = KeycloakOIDC("https://jwks", "https://issuer", "portal") monkeypatch.setattr(jwt, "get_unverified_header", lambda token: {}) with pytest.raises(ValueError): kc.verify("header.payload.sig") def test_authenticator_normalizes_groups(monkeypatch) -> None: token = _make_token() auth = Authenticator() monkeypatch.setattr(auth._oidc, "verify", lambda token: {"preferred_username": "bob", "groups": ["/admin", "dev"]}) ctx = auth.authenticate(token) assert ctx.username == "bob" assert ctx.groups == ["admin", "dev"]