Skip to content

Update python-keycloak requirement from <4.0.0,>=3.9.1 to >=3.9.1,<5.0.0 #1097

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

Update python-keycloak requirement from <4.0.0,>=3.9.1 to >=3.9.1,<5.0.0 #1097

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

89 tests run, 82 passed, 6 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 0x7fc56b028e80>

    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 = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJkT3VqVmljeGQ4MWZJdUFXVkVJdnFkTTNnYWNsNXQ1V3pjWkhsMnY4MVNvIn0.eyJleHAiOjE3MzMxNjAxNjcsImlhdCI6MTczMzE2MDA0NywianRpIjoiZTQ1NzRhYWEtZDU0OS00MDRlLWExYzctYWFkYjJlMDg0MTAxIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0My9ocHMvYXV0aC9yZWFsbXMvcmVwIiwiYXVkIjpbInJlYWxtLW1hbmFnZW1lbnQiLCJhY2NvdW50Il0sInN1YiI6ImE0NTY3YjJlLTRhNzctNDQ1Ni05Y2I0LTVkNTU2N2ZhMmRiZCIsInR5cCI6IkJlYXJlciIsImF6cCI6InJlcC1pbXBlcnNvbmF0aW9uIiwic2Vzc2lvbl9zdGF0ZSI6IjIwZjNjZGQ0LTM1NGQtNGRhYi1iYmU3LTkyNGQwZDUxNDdiOSIsInJlc291cmNlX2FjY2VzcyI6eyJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJxdWVyeS1ncm91cHMiLCJxdWVyeS11c2VycyJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIG1pY3JvcHJvZmlsZS1qd3QiLCJzaWQiOiIyMGYzY2RkNC0zNTRkLTRkYWItYmJlNy05MjRkMGQ1MTQ3YjkiLCJ1cG4iOiJ0ZXN0X3VzZXJfYTQ4YzBlYTItMTFlMi00NWUyLWJhMDctZTYyMmEyMGExNTllIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXJlcC0xIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJuYW1lIjoiVGVzdCBVc2VyIiwiZ3JvdXBzIjpbImRlZmF1bHQtcm9sZXMtcmVwLTEiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6InRlc3RfdXNlcl9hNDhjMGVhMi0xMWUyLTQ1ZTItYmEwNy1lNjIyYTIwYTE1OWUiLCJnaXZlbl9uYW1lIjoiVGVzdCIsImZhbWlseV9uYW1lIjoiVXNlciIsImVtYWlsIjoidGVzdF91c2VyX2E0OGMwZWEyLTExZTItNDVlMi1iYTA3LWU2MjJhMjBhMTU5ZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoidGVzdF91c2VyX2E0OGMwZWEyLTExZTItNDVlMi1iYTA3LWU2MjJhMjBhMTU5ZSJ9.B0a90AWuE8E6d_hENdrs0Vp4pAE1WLD8jLPTbbH5N6zzFljdW34DzZAgLbHOH5d4-5dtuWup7B-YekUayY5B2WIyiz5zQQSBBt5b7LKvNUb52jepTNtzccZgCCvMkDf0atewfZpB7S8GykGG9jqzqZXrEBnvSQvI0QDwxwMRJQAQ6YwYMb1cbfWi25JfZ5iQGmsE_MPxd_xoXJiMovLIdotT7EjTM2H-JYpwK4LuQ04CeI-BmBpSCJmQ_kB94BFMSD4JMl-oLuUPqxAPz2wFxJ76HDqrKHcwqThepPUQ_oTRuP4trL6lW1CPvqEXB0Hdvd7frYHNa3CTiXoMNc32nQ'
key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvIxy6qdtMCYlQwSni3jmbzt3QRsZqZAuR5X/p3AAhkSMvfLHxLzXsEV91McvtNzEhOK1qeQr08pWvuvcwOzc+FpHr5u/1jT6ACZe1/RSD/xpie0aA6VTEfcOwXvIQMnx7OWh1JSZ1Aw6tAjdbrYtEyigYbJBETqkzzxgxFROUAr/oMzBbxlqXoK2j0r+SRdBSzwWXva64VKi9NvGbN9XlpxpZhsYzk3J1KVcwquhX8Upf2cZTFvEVCF9B3pOAkZPoSuT1N6PsUoQ5roY6HvcpLPJj22TFOGogduZNgbPUFkn/gEreT/pDQaooV2A3tlJG0QeO1ZroraBUxUPCjfRNwIDAQAB\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