diff --git a/.env.example.aad b/.env.example.aad index 7034d92..ff22994 100644 --- a/.env.example.aad +++ b/.env.example.aad @@ -34,6 +34,15 @@ AZURE_APP_SCOPE=".default" AZURE_API_ENDPOINT="https://graph.microsoft.com/v1.0" ## Custom attribute for usernames AZURE_USERNAME_ATTRIBUTE=userPrincipalName +## If we don't have a custom username attribute, we'll +## need to make sure the username matches what's in +## GitHub. This will take the UPN and split the +## string on "@", making user@example.com just "user" +## in order to match GitHub. +## This should not be necessary if you add a new +## attribute for user mapping +## Default: false +#AZURE_USER_IS_UPN=true ######################### ## Additional settings ## diff --git a/README.md b/README.md index 86f9b96..e99c04b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # GitHub Team Sync This utility is intended to enable synchronization between GitHub and various LDAP and SAML providers. -This is particularly useful for large organizations with many teams that either use GitHub Enterprise Cloud, +This is particularly useful for large organizations with many teams that either use GitHub Enterprise Cloud, do not use LDAP for authentication, or use a SAML provider other than what is natively supported. It supports both GitHub.com, GitHub Enterprise Server (GHES) and GitHub , but it will need to live in a location that can access your LDAP servers. @@ -157,6 +157,7 @@ AZURE_CLIENT_SECRET="" AZURE_APP_SCOPE="default" AZURE_API_ENDPOINT="https://graph.microsoft.com/v1.0" AZURE_USERNAME_ATTRIBUTE=userPrincipalName +AZURE_USER_IS_UPN=true ``` ### Sample `.env` for Okta diff --git a/githubapp/azuread.py b/githubapp/azuread.py index 5c79b94..7f76cfe 100644 --- a/githubapp/azuread.py +++ b/githubapp/azuread.py @@ -1,7 +1,7 @@ import os import json import logging - +from distutils.util import strtobool import requests import msal @@ -21,8 +21,13 @@ def __init__(self): f"https://graph.microsoft.com/{x}" for x in os.environ["AZURE_APP_SCOPE"].split(" ") ] - self.AZURE_API_ENDPOINT = os.environ["AZURE_API_ENDPOINT"] - self.USERNAME_ATTRIBUTE = os.environ["AZURE_USERNAME_ATTRIBUTE"] + self.AZURE_API_ENDPOINT = os.environ.get( + "AZURE_API_ENDPOINT", "https://graph.microsoft.com/v1.0" + ) + self.USERNAME_ATTRIBUTE = os.environ.get( + "AZURE_USERNAME_ATTRIBUTE", "userPrincipalName" + ) + self.AZURE_USER_IS_UPN = strtobool(os.environ.get("AZURE_USER_IS_UPN", "False")) def get_access_token(self): """ @@ -77,10 +82,16 @@ def get_group_members(self, token=None, group_name=None): ).json()["value"] for member in members: user_info = self.get_user_info(token=token, user=member["id"]) - user = { - "username": user_info[self.USERNAME_ATTRIBUTE], - "email": user_info["mail"], - } + 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 diff --git a/githubapp/onelogin.py b/githubapp/onelogin.py index a50a7a4..5b84ade 100644 --- a/githubapp/onelogin.py +++ b/githubapp/onelogin.py @@ -7,11 +7,7 @@ def __init__(self): CLIENT_ID = os.environ["ONELOGIN_CLIENT_ID"] CLIENT_SECRET = os.environ["ONELOGIN_CLIENT_SECRET"] REGION = os.environ.get("ONELOGIN_REGION", "US").upper() - self.client = OneLoginClient( - CLIENT_ID, - CLIENT_SECRET, - REGION - ) + self.client = OneLoginClient(CLIENT_ID, CLIENT_SECRET, REGION) def get_group_members(self, group_name=None): """