67 lines
2.0 KiB
Python
67 lines
2.0 KiB
Python
|
|
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"]
|