Skip to content

Commit 8b138c7

Browse files
committed
globus, maint: persist globus groups in auth state, and misc refactor
1 parent 8acf905 commit 8b138c7

File tree

2 files changed

+24
-35
lines changed

2 files changed

+24
-35
lines changed

oauthenticator/globus.py

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,6 @@ def _revoke_tokens_on_logout_default(self):
165165
their UUIDs. Setting this will add the Globus Groups scope."""
166166
).tag(config=True)
167167

168-
@staticmethod
169-
def check_user_in_groups(member_groups, allowed_groups):
170-
return bool(set(member_groups) & set(allowed_groups))
171-
172168
async def pre_spawn_start(self, user, spawner):
173169
"""Add tokens to the spawner whenever the spawner starts a notebook.
174170
This will allow users to create a transfer client:
@@ -230,11 +226,8 @@ def build_auth_state_dict(self, token_info, user_info):
230226
self.user_auth_state_key: user_info,
231227
}
232228

233-
# FIXME: Should we persist info about user groups in auth model
234-
# to be consistent with what's happening in bitbucket.py
235-
# where the `auth_model` is updated with `user_teams`.
236-
async def get_users_groups_ids(self, tokens):
237-
user_group_ids = set()
229+
async def _fetch_users_groups(self, tokens):
230+
user_groups = set()
238231
# Get Groups access token, may not be in dict headed to auth state
239232
for token_dict in tokens:
240233
if token_dict['resource_server'] == 'groups.api.globus.org':
@@ -247,9 +240,9 @@ async def get_users_groups_ids(self, tokens):
247240
)
248241
# Build set of Group IDs
249242
for group in groups_resp:
250-
user_group_ids.add(group['id'])
243+
user_groups.add(group['id'])
251244

252-
return user_group_ids
245+
return user_groups
253246

254247
async def check_allowed(self, username, auth_model):
255248
"""
@@ -274,7 +267,7 @@ async def check_allowed(self, username, auth_model):
274267
user_info = auth_model["auth_state"][self.user_auth_state_key]
275268
domain = user_info.get(self.username_claim).split('@', 1)[-1]
276269
if domain != self.identity_provider:
277-
self.log.error(
270+
self.log.warning(
278271
f"Trying to login from an identity provider that was not allowed {domain}",
279272
)
280273
raise HTTPError(
@@ -289,14 +282,8 @@ async def check_allowed(self, username, auth_model):
289282
if username in self.allowed_users:
290283
return True
291284
if self.allowed_globus_groups:
292-
tokens = self.get_globus_tokens(
293-
auth_model["auth_state"]["token_response"]
294-
)
295-
user_group_ids = await self.get_users_groups_ids(tokens)
296-
297-
if self.check_user_in_groups(
298-
user_group_ids, self.allowed_globus_groups
299-
):
285+
user_groups = auth_model["auth_state"]["globus_groups"]
286+
if any(user_groups & self.allowed_globus_groups):
300287
return True
301288
self.log.warning(f"{username} not in an allowed Globus Group")
302289

@@ -315,18 +302,20 @@ async def update_auth_model(self, auth_model):
315302
`admin_globus_groups`. Note that leaving it at None makes users able to
316303
retain an admin status while setting it to False makes it be revoked.
317304
"""
318-
if auth_model["admin"] is True:
305+
user_groups = set()
306+
if self.allowed_globus_groups or self.admin_globus_groups:
307+
tokens = self.get_globus_tokens(auth_model["auth_state"]["token_response"])
308+
user_groups = await self._fetch_users_groups(tokens)
309+
auth_model["auth_state"]["globus_groups"] = user_groups
310+
311+
if auth_model["admin"]:
312+
# auth_model["admin"] being True means the user was in admin_users
319313
return auth_model
320314

321315
if self.admin_globus_groups:
322-
tokens = self.get_globus_tokens(auth_model["auth_state"]["token_response"])
323-
# If any of these configurations are set, user must be in the allowed or admin Globus Group
324-
user_group_ids = await self.get_users_groups_ids(tokens)
325-
# Admin users are being managed via Globus Groups
326-
# Default to False
327-
auth_model["admin"] = False
328-
if self.check_user_in_groups(user_group_ids, self.admin_globus_groups):
329-
auth_model["admin"] = True
316+
# admin status should in this case be True or False, not None
317+
auth_model["admin"] = any(user_groups & self.admin_globus_groups)
318+
330319
return auth_model
331320

332321
def user_info_to_username(self, user_info):

oauthenticator/tests/test_globus.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ async def test_logout_revokes_tokens(globus_client, monkeypatch, mock_globus_use
395395

396396
async def test_group_scope_added(globus_client):
397397
authenticator = GlobusOAuthenticator()
398-
authenticator.allowed_globus_groups = set({'21c6bc5d-fc12-4f60-b999-76766cd596c2'})
398+
authenticator.allowed_globus_groups = {'21c6bc5d-fc12-4f60-b999-76766cd596c2'}
399399
assert authenticator.scope == [
400400
'openid',
401401
'profile',
@@ -406,23 +406,23 @@ async def test_group_scope_added(globus_client):
406406

407407
async def test_user_in_allowed_group(globus_client):
408408
authenticator = GlobusOAuthenticator()
409-
authenticator.allowed_globus_groups = set({'21c6bc5d-fc12-4f60-b999-76766cd596c2'})
409+
authenticator.allowed_globus_groups = {'21c6bc5d-fc12-4f60-b999-76766cd596c2'}
410410
handler = globus_client.handler_for_user(user_model('[email protected]'))
411411
auth_model = await authenticator.get_authenticated_user(handler, None)
412412
assert auth_model['name'] == 'wash'
413413

414414

415415
async def test_user_not_allowed(globus_client):
416416
authenticator = GlobusOAuthenticator()
417-
authenticator.allowed_globus_groups = set({'3f1f85c4-f084-4173-9efb-7c7e0b44291a'})
417+
authenticator.allowed_globus_groups = {'3f1f85c4-f084-4173-9efb-7c7e0b44291a'}
418418
handler = globus_client.handler_for_user(user_model('[email protected]'))
419419
auth_model = await authenticator.get_authenticated_user(handler, None)
420420
assert auth_model == None
421421

422422

423423
async def test_user_is_admin(globus_client):
424424
authenticator = GlobusOAuthenticator()
425-
authenticator.admin_globus_groups = set({'21c6bc5d-fc12-4f60-b999-76766cd596c2'})
425+
authenticator.admin_globus_groups = {'21c6bc5d-fc12-4f60-b999-76766cd596c2'}
426426
handler = globus_client.handler_for_user(user_model('[email protected]'))
427427
auth_model = await authenticator.get_authenticated_user(handler, None)
428428
assert auth_model['name'] == 'wash'
@@ -431,8 +431,8 @@ async def test_user_is_admin(globus_client):
431431

432432
async def test_user_allowed_not_admin(globus_client):
433433
authenticator = GlobusOAuthenticator()
434-
authenticator.allowed_globus_groups = set({'21c6bc5d-fc12-4f60-b999-76766cd596c2'})
435-
authenticator.admin_globus_groups = set({'3f1f85c4-f084-4173-9efb-7c7e0b44291a'})
434+
authenticator.allowed_globus_groups = {'21c6bc5d-fc12-4f60-b999-76766cd596c2'}
435+
authenticator.admin_globus_groups = {'3f1f85c4-f084-4173-9efb-7c7e0b44291a'}
436436
handler = globus_client.handler_for_user(user_model('[email protected]'))
437437
auth_model = await authenticator.get_authenticated_user(handler, None)
438438
assert auth_model['name'] == 'wash'

0 commit comments

Comments
 (0)