From d1879b456bb826edce0e8f60e48b60c836709242 Mon Sep 17 00:00:00 2001 From: Gabriel Rudloff Date: Fri, 19 Sep 2025 12:46:04 +0000 Subject: [PATCH] test: add tests for PKCE flow --- tests/test_pkce_flow.py | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 tests/test_pkce_flow.py diff --git a/tests/test_pkce_flow.py b/tests/test_pkce_flow.py new file mode 100644 index 0000000..3823f7f --- /dev/null +++ b/tests/test_pkce_flow.py @@ -0,0 +1,49 @@ +from unittest import mock + +from keycloak import KeycloakOpenID +from keycloak.pkce_utils import generate_code_challenge, generate_code_verifier + + +def test_pkce_auth_url_and_token(env): + """ + Test PKCE flow: auth_url includes code_challenge, token includes code_verifier. + """ + oid = KeycloakOpenID( + server_url=f"http://{env.keycloak_host}:{env.keycloak_port}", + realm_name="master", + client_id="admin-cli", + ) + code_verifier = generate_code_verifier() + code_challenge, code_challenge_method = generate_code_challenge(code_verifier) + + # Build PKCE auth URL + url = oid.auth_url( + redirect_uri="http://test.test/*", + code_challenge=code_challenge, + code_challenge_method=code_challenge_method, + ) + assert f"code_challenge={code_challenge}" in url + assert f"code_challenge_method={code_challenge_method}" in url + + # Simulate token exchange with PKCE + # This part would require a real code from Keycloak, so we mock the response + with mock.patch.object(oid, "token", return_value={ + "access_token": mock.ANY, + "refresh_token": mock.ANY, + "token_type": "Bearer", + }) as mocked_token: + token = oid.token( + grant_type="authorization_code", + code="dummy_code", + redirect_uri="http://test.test/*", + code_verifier=code_verifier, + ) + mocked_token.assert_called_with( + grant_type="authorization_code", + code="dummy_code", + redirect_uri="http://test.test/*", + code_verifier=code_verifier, + ) + assert "access_token" in token + assert "refresh_token" in token + assert token["token_type"] == "Bearer"