Skip to content

Commit

Permalink
gh: Allow setting JupyterHub groups from GitHub teams
Browse files Browse the repository at this point in the history
Looking at #735,
I realize it will not actually allow us to use GitHub teams or orgs as
JupyterHub groups, since that's an extra API call. This PR keeps it
simple, and adds config to pick this up from teams list directly.
  • Loading branch information
yuvipanda committed Apr 5, 2024
1 parent 1f0cbc0 commit e9a7f2a
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions oauthenticator/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,26 @@ def _userdata_url_default(self):
https://docs.github.com/en/rest/reference/teams#list-teams-for-the-authenticated-user.
Requires `read:org` to be set in `scope`.
Note that authentication state is only be available to a
`post_auth_hook` before being discarded unless configured to be
persisted via `enable_auth_state`. For more information, see
https://jupyterhub.readthedocs.io/en/stable/reference/authenticators.html#authentication-state.
""",
)

populate_groups_from_teams = Bool(
False,
config=True,
help="""
Populates JupyterHub groups from list of GitHub teams the user is a part of.
Requires `read:org` to be set in `scope`.
Requires `manage_groups` to be set to True.
"""
)

# _deprecated_oauth_aliases is used by deprecation logic in OAuthenticator
_deprecated_oauth_aliases = {
"github_client_id": ("client_id", "0.1.0"),
Expand Down Expand Up @@ -224,6 +236,9 @@ async def update_auth_model(self, auth_model):
user_info["email"] = val["email"]
break


# https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user
teams_url = f"{self.github_api}/user/teams?per_page=100"
if self.populate_teams_in_auth_state:
if "read:org" not in self.scope:
# This means the "read:org" scope was not set, and we can't
Expand All @@ -232,13 +247,22 @@ async def update_auth_model(self, auth_model):
"read:org scope is required for populate_teams_in_auth_state functionality to work"
)
else:
# https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams-for-the-authenticated-user
url = f"{self.github_api}/user/teams?per_page=100"
user_teams = await self._paginated_fetch(url, access_token, token_type)
user_teams = await self._paginated_fetch(teams_url, access_token, token_type)
auth_model["auth_state"]["teams"] = user_teams

if self.manage_groups and self.populate_groups_from_teams:
if "read:org" not in self.scope:
# This means the "read:org" scope was not set, and we can't fetch teams
self.log.error(
"read:org scope is required for populate_groups_from_teams functionality to work"
)
else:
user_teams = await self._paginated_fetch(teams_url, access_token, token_type)
auth_model["groups"] = user_teams

return auth_model


async def _paginated_fetch(self, api_url, access_token, token_type):
"""
Fetch all items via a paginated GitHub API call
Expand Down

0 comments on commit e9a7f2a

Please sign in to comment.