fastapi-keycloak icon indicating copy to clipboard operation
fastapi-keycloak copied to clipboard

realmRoles Field required

Open ricciarellif opened this issue 2 years ago • 4 comments

Using the examples provided, I'm unable to get the user's info through the route

http://localhost:8081/user/2b1b34f0-5efb-4cf8-b620-b619fd9b98bc (it's a valid user-id)

due to a pydantic error:

pydantic_core._pydantic_core.ValidationError: 1 validation error for KeycloakUser realmRoles Field required [type=missing, input_value={'id': '2b1b34f0-5efb-4cf8-b620-b619fd9b98bc'...}, input_type=dict] For further information visit https://errors.pydantic.dev/2.1/v/missing

This is due to the absence, in the incoming json (Python dict), of the key "realmRoles" which is NOT always returned by the KeyCloak platform.

In your model.py module, class KeycloakUser(BaseModel), the realmRoles field is specified as "Optional" (realmRoles: Optional[List[str]]) but this attribute seems to be ignored by pydantic...

Any suggestion? Thanks in advance

My requirements.txt: fastapi==0.100.1 fastapi_keycloak==1.0.10 pydantic==2.2.1 uvicorn==0.23.1

My KeyCloack platform: docker image of jsboss/keycloak:latest (Server version: 16.1.1) with postgresql 13.0

ricciarellif avatar Jul 28 '23 13:07 ricciarellif

Hi, you can apply a workaround as a patch of KeycloakUser.__init__ like the following:

    oryg__init__ = KeycloakUser.__init__

    def mocked__init__(*args, **kwargs):
        kwargs['realmRoles'] = kwargs.get('realmRoles', [])
        kwargs['attributes'] = kwargs.get('attributes', {})
        oryg__init__(*args, **kwargs)

    KeycloakUser.__init__ = mocked__init__

softfactory1 avatar Aug 09 '23 10:08 softfactory1

In which file we have to apply this?

praveenexaf avatar Sep 21 '23 16:09 praveenexaf

You can define it in any file like the following function

def patcher():
    from fastapi_keycloak import KeycloakUser

    oryg__init__ = KeycloakUser.__init__

    def new__init__(*args, **kwargs):
        kwargs['realmRoles'] = kwargs.get('realmRoles', [])
        kwargs['attributes'] = kwargs.get('attributes', {})
        oryg__init__(*args, **kwargs)

    KeycloakUser.__init__ = new__init__

And call patcher before any fast API code is executed in some main.py or whatever the main module you defined.

softfactory1 avatar Sep 22 '23 05:09 softfactory1

I believe that this is related to #97. But it has been a while, so maybe I misremember the error I got at that point.

alexbarcelo avatar Dec 20 '23 15:12 alexbarcelo