diff --git a/app.py b/app.py index c17ceae..205fd0c 100644 --- a/app.py +++ b/app.py @@ -9,12 +9,11 @@ from apscheduler.triggers.cron import CronTrigger from flask import Flask -from githubapp import GitHubApp, DirectoryClient, CRON_INTERVAL, TEST_MODE +from githubapp import GitHubApp, DirectoryClient, CRON_INTERVAL, TEST_MODE, ADD_MEMBER app = Flask(__name__) github_app = GitHubApp(app) directory = DirectoryClient() -addUserAsMember = os.environ.get("ADD_MEMBER", False) # Schedule a full sync scheduler = BackgroundScheduler(daemon=True) @@ -182,7 +181,7 @@ def execute_sync(org, team, slug, state): else: for user in state["action"]["add"]: # Validate that user is in org - if org.is_member(user) or addUserAsMember: + if org.is_member(user) or ADD_MEMBER: try: print(f"Adding {user} to {slug}") team.add_or_update_membership(user) diff --git a/githubapp/__init__.py b/githubapp/__init__.py index affc84b..eef1eca 100644 --- a/githubapp/__init__.py +++ b/githubapp/__init__.py @@ -37,3 +37,5 @@ rootlogger.warn('TEST_MODE should be set to "true" or "false"') rootlogger.warn(e) TEST_MODE = False +# Check if should add member to organization +ADD_MEMBER = strtobool(os.environ.get("ADD_MEMBER", "False")) diff --git a/githubapp/azuread.py b/githubapp/azuread.py index 4dc01df..4f00b70 100644 --- a/githubapp/azuread.py +++ b/githubapp/azuread.py @@ -79,27 +79,54 @@ def get_group_members(self, token=None, group_name=None): # print("Graph API call result: %s" % json.dumps(graph_data, indent=2)) try: group_info = json.loads(json.dumps(graph_data, indent=2))["value"][0] - members = requests.get( - f'{self.AZURE_API_ENDPOINT}/groups/{group_info["id"]}/members', - headers={"Authorization": f"Bearer {token}"}, - ).json()["value"] + members = self.get_group_members_pages( + token, f'{self.AZURE_API_ENDPOINT}/groups/{group_info["id"]}/members' + ) except IndexError as e: members = [] for member in members: - user_info = self.get_user_info(token=token, user=member["id"]) - if self.AZURE_USER_IS_UPN: - user = { - "username": user_info[self.USERNAME_ATTRIBUTE].split("@")[0], - "email": user_info["mail"], - } + if member["@odata.type"] == "#microsoft.graph.group": + print("Nested group: ", member["displayName"]) else: - user = { - "username": user_info[self.USERNAME_ATTRIBUTE], - "email": user_info["mail"], - } - member_list.append(user) + user_info = self.get_user_info(token=token, user=member["id"]) + if self.AZURE_USER_IS_UPN: + user = { + "username": user_info[self.USERNAME_ATTRIBUTE].split("@")[0], + "email": user_info["mail"], + } + else: + user = { + "username": user_info[self.USERNAME_ATTRIBUTE], + "email": user_info["mail"], + } + member_list.append(user) return member_list + def get_group_members_pages(self, token=None, url=None): + """ + Get group members + :param token: + :param url: + :return members: + :rtype members: dict + """ + members_data = requests.get(url, headers={"Authorization": f"Bearer {token}"}) + if members_data.ok != True: + print( + f"[GetMembers]: Error getting members data error code {members_data.status_code}" + ) + return [] + + members_data_content = members_data.json() + members = members_data_content["value"] + if "@odata.nextLink" in members_data_content: + members.extend( + self.get_group_members_pages( + token, members_data_content["@odata.nextLink"] + ) + ) + return members + def get_user_info(self, token=None, user=None): """ Get user info