4040
4141
4242class MASUserUtils ():
43+ '''
44+ A collection of utilities for interacting with the MAS Core V3 User APIs and related APIs.
45+ Each instance of this class is tied to a specific MAS instance and workspace ID.
46+ '''
4347
4448 MAXADMIN = "MAXADMIN"
4549
@@ -373,10 +377,40 @@ def get_user(self, user_id):
373377
374378 raise Exception (f"{ response .status_code } { response .text } " )
375379
380+ def get_user_workspaces (self , user_id ):
381+ '''
382+ Assumes user exists, raises if not.
383+ '''
384+ self .logger .info (f"Getting workspaces for user { user_id } " )
385+ url = f"{ self .mas_api_url } /v3/users/{ user_id } /workspaces"
386+ headers = {
387+ "Accept" : "application/json" ,
388+ "x-access-token" : self .superuser_auth_token
389+ }
390+ response = requests .get (
391+ url ,
392+ headers = headers ,
393+ verify = self .mas_api_url_ca_chain_file_path
394+ )
395+
396+ if response .status_code == 404 :
397+ raise Exception (f"User { user_id } does not exist" )
398+
399+ if response .status_code == 200 :
400+ return response .json ()
401+
402+ raise Exception (f"{ response .status_code } { response .text } " )
403+
376404 def add_user_to_workspace (self , user_id , is_workspace_admin = False ):
377405 '''
378- TODO: idempotency
406+ No-op if user is already a member of the workspace. No attempt will be made to update their existing is_workspace_admin flag if it differs.
379407 '''
408+ workspaces = self .get_user_workspaces (user_id )
409+ for workspace in workspaces :
410+ if "id" in workspace and workspace ["id" ] == self .mas_workspace_id :
411+ self .logger .info (f"User { user_id } is already a member of workspace { self .mas_workspace_id } " )
412+ return None
413+
380414 self .logger .info (f"Adding user { user_id } to { self .mas_workspace_id } (is_workspace_admin: { is_workspace_admin } )" )
381415 url = f"{ self .mas_api_url } /workspaces/{ self .mas_workspace_id } /users/{ user_id } "
382416 querystring = {}
@@ -396,7 +430,11 @@ def add_user_to_workspace(self, user_id, is_workspace_admin=False):
396430 params = querystring ,
397431 verify = self .mas_api_url_ca_chain_file_path
398432 )
399- return response .json ()
433+
434+ if response .status_code == 200 :
435+ return None
436+
437+ raise Exception (f"{ response .status_code } { response .text } " )
400438
401439 def set_user_application_permission (self , user_id , application_id , role ):
402440 '''
0 commit comments