Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Managing group information properly when tokens don't include groups claim key? #750

Closed
kellyrowland opened this issue Aug 22, 2024 · 2 comments · Fixed by #751
Closed

Comments

@kellyrowland
Copy link

We are upgrading a custom authenticator based on GenericOAuthenticator from 15.x to 16.x (or more likely, the currently in-development 17.0). We need to adapt our usage of manage_groups and allowed_groups. At this time our tokens do not include a groups claim key, so we've been getting groups information from a separate API call made from an overridden authenticate(). (Indeed, we see the warnings in the comments about that being the wrong way to do it, and we are working towards getting away from doing that.) While we see that a callable can be used to set the groups information in get_user_groups, it isn't async, nor is get_user_groups, etc. We're exploring options to get the groups info we needed added upstream, but in the meantime we're wondering if you can recommend a way for us to customize groups management? Or is it feasible to make the call to get_user_groups non-blocking?

@minrk
Copy link
Member

minrk commented Aug 23, 2024

get_user_groups is only called in async contexts, so allowing it to be async should be no problem. Since getting groups from the user model has been refactored a bit to promote it to the base OAuthenticator class (#735), I think we can take this opportunity to make sure "get groups with an additional request" is a case that's well covered.

Probably the way to work around it today is to override token_to_user in your GenericOAuthenticator subclass to make an additional request to populate the local user model with groups:

async def token_to_user(token_info):
    user_info = await super().token_to_user(token_info)
    user_info["groups_key"] = await my_get_groups_for(user_info[, token_info])

If get_user_groups itself is async, it may be called multiple times, which is a bit unnecessary, though probably not harmful.

@kellyrowland
Copy link
Author

Thanks, that was a super helpful suggestion. The function ended up looking like:

    async def token_to_user(self, token_info):
        user = await super().token_to_user(token_info)
        user["groups"] = await self._get_groups(user['preferred_username'])
        return user

and looks good on my end with OAuthenticator 16.3.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants