marcospereirampj / python-keycloak

MIT License
704 stars 297 forks source link

Groups are broken in 23.0 #509

Closed ryshoooo closed 6 months ago

ryshoooo commented 9 months ago

The get_groups function is a bit broken in Keycloak 23. It seems to be linked to their breaking changes in the GET groups admin API endpoint, which does not return subgroups anymore.

There is a specific option to include the full hierarchy, but that does not seem to have any effect. We'll be tracking the progress in https://github.com/keycloak/keycloak/issues/25053 at least to identify whether this is an intended behavior and we need to update our library to accommodate for the new way of getting children groups, or maybe it is a bug on Keycloak's side and the populateHiearchy attribute should work.

zhengdechang commented 8 months ago

Is this version 3.7.0 fixed?

althaf004 commented 8 months ago

@ryshoooo when can we expect a fix on this?

transducer commented 8 months ago

As mentioned here it's intended behaviour (a performance tradeoff). Subgroups have be explicitly fetched using GET /groups/{parent-id}/children.

DZiso commented 8 months ago

as the method mentioned by @transducer is not yet available in the lib and there are some nice cve's in <23.0.4, for everyone looking for a quick workaround, the get_groups endpoint delivers a pretty similar result when searching for %.

In the api docs: GET /admin/realms/{realm}/groups

In this lib:

session.get_groups({"search": "%"})

keep in mind.. performance is likely not optimal/similar to the old endpoint

robson90 commented 7 months ago

@DZiso thanks for the workaround.

I have another one implemented myself. I dont know if it is more performant.

 def get_complete_tree_structure(self, parent_id):
        if (parent_id == ''):
            groups = self.keycloak_admin.get_groups()
            for group in groups:
                if group['subGroupCount'] != 0:
                    group['subGroups'] = self.get_complete_tree_structure(group['id'])
            return groups
        else:
            groups = self.get_children(parent_id)
            for group in groups:
                if group['subGroupCount'] != 0:
                    group['subGroups'] = self.get_complete_tree_structure(group['id'])
            return groups

    def get_children(self, parent_id):
        endpoint = "http://localhost:8080/admin/realms/pfi-local-web/groups/" + parent_id + "/children"
        headers = {"Authorization": "Bearer " + self.keycloak_admin.token['access_token']}

        return requests.get(endpoint, headers=headers).json()
NikolaiES commented 7 months ago

I took a crack at implementing a fix that follows the recommendation of this comment in the original keycloak issue. #516

It is not a direct replacement for how things worked before, but it would make it easier to work the way keycloak authors seem to intend and I see no reason it could not coexist with some other solution as well which tried to replicate the old functionality.

marcospereirampj commented 6 months ago

Fixed: #525!