Skip to content

Update python-keycloak requirement from <4.0.0,>=3.9.1 to >=3.9.1,<6.0.0 #1109

Update python-keycloak requirement from <4.0.0,>=3.9.1 to >=3.9.1,<6.0.0

Update python-keycloak requirement from <4.0.0,>=3.9.1 to >=3.9.1,<6.0.0 #1109

GitHub Actions / Test Report ubuntu-latest:3.10 failed Dec 16, 2024 in 0s

89 tests run, 83 passed, 5 skipped, 1 failed.

Annotations

Check failure on line 182 in tests/auth/test_api.py

See this annotation in the file changed.

@github-actions github-actions / Test Report ubuntu-latest:3.10

test_api.test_impersonate_user

TypeError: JWT.__init__() got an unexpected keyword argument 'options'
Raw output
url = 'https://localhost:8443/hps'
keycloak_client = <keycloak.keycloak_admin.KeycloakAdmin object at 0x7f233a1dac80>

    def test_impersonate_user(url, keycloak_client):
        """
        Test token exchange for impersonation, see https://www.rfc-editor.org/rfc/rfc8693.html
    
        Requires activating the token-exchange feature in keycloak
        by passing --features=token-exchange to the start command.
        """
    
        username = f"test_user_{uuid.uuid4()}"
        new_user = User(
            username=username,
            password="test_auth_client",
            email=f"{username}@test.com",
            first_name="Test",
            last_name="User",
        )
        new_user = create_user(keycloak_client, new_user)
    
        realm_clients = keycloak_client.get_clients()
        rep_impersonation_client = next(
            (x for x in realm_clients if x["clientId"] == "rep-impersonation"), None
        )
        assert rep_impersonation_client is not None
    
        client = Client(
            url=url,
            client_id=rep_impersonation_client["clientId"],
            client_secret=rep_impersonation_client["secret"],
        )
    
        r = None
        try:
            r = authenticate(
                url=url,
                client_id=rep_impersonation_client["clientId"],
                client_secret=rep_impersonation_client["secret"],
                scope="opendid offline_access",
                grant_type="urn:ietf:params:oauth:grant-type:token-exchange",
                subject_token=client.access_token,
                requested_token_type="urn:ietf:params:oauth:token-type:refresh_token",
                requested_subject=new_user.id,
                verify=False,
            )
        except HPSError as e:
            if e.response.status_code == 501 and "Feature not enabled" in e.reason:
                pytest.skip(f"This test requires to enable the feature 'token-exchange' in keycloak.")
    
        assert r is not None
        assert "refresh_token" in r
    
        refresh_token_impersonated = r["refresh_token"]
    
        client_impersonated = Client(
            url,
            username=new_user.username,
            grant_type="refresh_token",
            refresh_token=refresh_token_impersonated,
            client_id=rep_impersonation_client["clientId"],
            client_secret=rep_impersonation_client["secret"],
        )
    
        assert client_impersonated.access_token is not None
        assert client_impersonated.refresh_token is not None
    
        keycloak_openid = KeycloakOpenID(
            server_url=client.auth_api_url,
            client_id="account",
            realm_name="rep",
            client_secret_key="**********",
            verify=False,
        )
        KEYCLOAK_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n"
        KEYCLOAK_PUBLIC_KEY += keycloak_openid.public_key()
        KEYCLOAK_PUBLIC_KEY += "\n-----END PUBLIC KEY-----"
    
        options = {"verify_signature": True, "verify_aud": True, "verify_exp": True}
>       token_info = keycloak_openid.decode_token(
            client_impersonated.access_token,
            key=KEYCLOAK_PUBLIC_KEY,
            options=options,
        )

tests/auth/test_api.py:182: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.tox/py310-coverage/lib/python3.10/site-packages/keycloak/keycloak_openid.py:645: in decode_token
    return self._verify_token(token, key, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

token = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJqeXZyeXhzeWViQUtiX01TYnRpcTBtWWpDbU41bjZmcmQ0bW16S1lRRnBVIn0.eyJleHAiOjE3MzQzNjg3MzksImlhdCI6MTczNDM2ODYxOSwianRpIjoiYTJlNjRkY2QtMDI5YS00YmM1LWJiZmEtYmUwZmE4Mzc1MDI4IiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0My9ocHMvYXV0aC9yZWFsbXMvcmVwIiwiYXVkIjpbInJlYWxtLW1hbmFnZW1lbnQiLCJhY2NvdW50Il0sInN1YiI6IjgxMjZiMWYyLTYyOTgtNDZkNi04Mzc5LWE3YThhYmU5MDExOCIsInR5cCI6IkJlYXJlciIsImF6cCI6InJlcC1pbXBlcnNvbmF0aW9uIiwic2Vzc2lvbl9zdGF0ZSI6IjdmNTUyMTM0LWE1YmUtNDdhNC1iZWUxLWI2YzcwOGQ1ODViNCIsInJlc291cmNlX2FjY2VzcyI6eyJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJxdWVyeS1ncm91cHMiLCJxdWVyeS11c2VycyJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIG1pY3JvcHJvZmlsZS1qd3QiLCJzaWQiOiI3ZjU1MjEzNC1hNWJlLTQ3YTQtYmVlMS1iNmM3MDhkNTg1YjQiLCJ1cG4iOiJ0ZXN0X3VzZXJfNTkxNDg0YTMtNmFmOC00NDI2LWE1YzktZjI1ZGYzNjZiNzg2IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXJlcC0xIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJuYW1lIjoiVGVzdCBVc2VyIiwiZ3JvdXBzIjpbImRlZmF1bHQtcm9sZXMtcmVwLTEiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6InRlc3RfdXNlcl81OTE0ODRhMy02YWY4LTQ0MjYtYTVjOS1mMjVkZjM2NmI3ODYiLCJnaXZlbl9uYW1lIjoiVGVzdCIsImZhbWlseV9uYW1lIjoiVXNlciIsImVtYWlsIjoidGVzdF91c2VyXzU5MTQ4NGEzLTZhZjgtNDQyNi1hNWM5LWYyNWRmMzY2Yjc4NkB0ZXN0LmNvbSIsInVzZXJuYW1lIjoidGVzdF91c2VyXzU5MTQ4NGEzLTZhZjgtNDQyNi1hNWM5LWYyNWRmMzY2Yjc4NiJ9.NAlw2bLlyJdt3RlsH_0tywUhQFvMsCSJSluUFkWK_f7ZN_Hgp7XRHW6FVRBXfHwEe5IZsKDskFzjISYF5PUoLO3f7Cd1unC2lYzyvNaA7NU94fnfSkxFzsZ0oAvX31NGkwvvNHoyTP-taoTaMRCmU12H9XcEllgLOH7jGNjAKUNAHF0kU-SW5BwnWrioE-AC5Q7My2GXxlawuETLkpzTUf4FHZVDE32gdsGHL7cB1NNiVj1_AFicm-6nzh3VmTfxE1nVazLQHc56wtstWXH2X0m7LcDfl7FpQMhbuwXLAE5O65LXvTZOWdWJJa6GOLoqKq72aPkSjXvOeXFpqiRWOA'
key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw5jVK2ZyxuqnDYRgtkSwixm2PK4s1fiqrtVA3K3RHuCBaZxVaUrGyYnVB7viGY/VI0tf6D7HejZ+II13RLQOODx1QKUHdnT8240wXzOYyeEWt223AO8bxsf3aT+syZDAqmb1m2ESQbDhoqxZDyX4Soie9J7pnHwWfGHxyQ+dLQiIDY+27fpojZ4Yj8iZpV4t0p2Wi41KF6F+667HZqZxvIHd90lFcQwc8rz5DcfPMV17j+xbmWmtjUViPPDQ2a4LJnNH/HRv0spTSDt4dealRt/bu5tbjzSGpuo0gTh2LS0hluC79jihX7Omer5ESbJVetVNHFfRlSZfJ6fdEOR8oQIDAQAB\n-----END PUBLIC KEY-----'
kwargs = {'options': {'verify_aud': True, 'verify_exp': True, 'verify_signature': True}}
leeway = 60

    @staticmethod
    def _verify_token(token, key: Union[jwk.JWK, jwk.JWKSet, None], **kwargs):
        """Decode and optionally validate a token.
    
        :param token: The token to verify
        :type token: str
        :param key: Which key should be used for validation.
            If not provided, the validation is not performed and the token is implicitly valid.
        :type key: Union[jwk.JWK, jwk.JWKSet, None]
        :param kwargs: Additional keyword arguments for jwcrypto's JWT object
        :type kwargs: dict
        :returns: Decoded token
        """
        # keep the function free of IO
        # this way it can be used by `decode_token` and `a_decode_token`
    
        if key is not None:
            leeway = kwargs.pop("leeway", 60)
>           full_jwt = jwt.JWT(jwt=token, **kwargs)
E           TypeError: JWT.__init__() got an unexpected keyword argument 'options'

.tox/py310-coverage/lib/python3.10/site-packages/keycloak/keycloak_openid.py:602: TypeError