2021-03-22 23:15:32 +03:00
|
|
|
import asyncio
|
|
|
|
import os
|
|
|
|
import logging
|
2023-04-01 06:09:22 +03:00
|
|
|
import re
|
2021-03-22 23:15:32 +03:00
|
|
|
from okta.client import Client as OktaClient
|
|
|
|
|
|
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class Okta:
|
|
|
|
def __init__(self):
|
2021-03-23 03:52:16 +03:00
|
|
|
self.USERNAME_ATTRIBUTE = os.environ.get("OKTA_USERNAME_ATTRIBUTE", "login")
|
2022-04-20 21:48:52 +03:00
|
|
|
auth_method = os.environ.get("OKTA_AUTH_METHOD", "token")
|
|
|
|
config = {"orgUrl": os.environ["OKTA_ORG_URL"]}
|
|
|
|
if auth_method == "oauth":
|
|
|
|
config["authorizationMode"] = "PrivateKey"
|
|
|
|
config["clientId"] = os.environ["OKTA_CLIENT_ID"]
|
2022-05-26 15:38:09 +03:00
|
|
|
config["scopes"] = os.environ["OKTA_SCOPES"].split(" ")
|
2022-04-20 21:48:52 +03:00
|
|
|
config["privateKey"] = os.environ["OKTA_PRIVATE_KEY"]
|
|
|
|
else:
|
|
|
|
config["token"] = os.environ["OKTA_ACCESS_TOKEN"]
|
2021-03-22 23:15:32 +03:00
|
|
|
self.client = OktaClient(config)
|
|
|
|
|
|
|
|
def get_group_members(self, group_name=None):
|
|
|
|
"""
|
|
|
|
Get a list of users that are part of a given group in Okta
|
|
|
|
:param group_name: Group name to look up
|
|
|
|
:type group_name: str
|
|
|
|
:return member_list: A list of dictionaries containing usernames and emails
|
|
|
|
:rtype member_list: list
|
|
|
|
"""
|
|
|
|
member_list = []
|
|
|
|
|
|
|
|
async def get_group_id(client=None):
|
|
|
|
"""
|
|
|
|
Get the group ID
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
group = await client.list_groups(query_params={"q": group_name})
|
|
|
|
return group[0][0].id
|
|
|
|
|
|
|
|
async def get_members(client=None, groupId=None):
|
|
|
|
"""
|
|
|
|
Get the users that belong to this group
|
|
|
|
:param groupId:
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
members = await client.list_group_users(groupId=groupId)
|
|
|
|
return members[0]
|
|
|
|
|
|
|
|
def get_or_create_eventloop():
|
|
|
|
"""
|
|
|
|
Create an async loop if we're in a child thread
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
return asyncio.get_event_loop()
|
|
|
|
except RuntimeError as ex:
|
|
|
|
if "There is no current event loop in thread" in str(ex):
|
|
|
|
loop = asyncio.new_event_loop()
|
|
|
|
asyncio.set_event_loop(loop)
|
|
|
|
return asyncio.get_event_loop()
|
|
|
|
|
|
|
|
loop = get_or_create_eventloop()
|
|
|
|
gid = loop.run_until_complete(get_group_id(client=self.client))
|
|
|
|
users = loop.run_until_complete(get_members(client=self.client, groupId=gid))
|
|
|
|
for user in users:
|
|
|
|
try:
|
2023-04-01 06:09:22 +03:00
|
|
|
username = getattr(user.profile, self.USERNAME_ATTRIBUTE)
|
|
|
|
username = username.split("@")[0]
|
|
|
|
username = re.sub('[^0-9a-zA-Z-]+', '-', username)
|
2021-03-22 23:15:32 +03:00
|
|
|
member_list.append(
|
|
|
|
{
|
2023-04-01 06:09:22 +03:00
|
|
|
"username": username,
|
2021-03-22 23:15:32 +03:00
|
|
|
"email": user.profile.email,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
except AttributeError as e:
|
2022-05-03 11:09:40 +03:00
|
|
|
if user.links:
|
2022-05-26 15:38:09 +03:00
|
|
|
user_info = user.links["self"]["href"]
|
2022-05-03 11:09:40 +03:00
|
|
|
else:
|
|
|
|
user_info = user
|
|
|
|
print(f"User {user_info}: {e}")
|
2021-03-22 23:15:32 +03:00
|
|
|
return member_list
|