def _get_aws_account_info(okta_org_url, okta_api_key, username): """ Call the Okta User API and process the results to return just the information we need for gimme_aws_creds""" # We need access to the entire JSON response from the Okta APIs, so we need to # use the low-level ApiClient instead of UsersClient and AppInstanceClient users_client = ApiClient(okta_org_url, okta_api_key, pathname='/api/v1/users') # Get User information try: result = users_client.get_path('/{0}'.format(username)) user = result.json() except OktaError as e: if e.error_code == 'E0000007': print("Error: " + username + " was not found!", file=sys.stderr) exit(1) else: print("Error: " + e.error_summary, file=sys.stderr) exit(1) try: # Get first page of results result = users_client.get_path('/{0}/appLinks'.format(user['id'])) final_result = result.json() # Loop through other pages while 'next' in result.links: result = users_client.get(result.links['next']['url']) final_result = final_result + result.json() print("done\n", file=sys.stderr) except OktaError as e: if e.error_code == 'E0000007': print("Error: No applications found for " + username, file=sys.stderr) exit(1) else: print("Error: " + e.error_summary, file=sys.stderr) exit(1) # Loop through the list of apps and filter it down to just the info we need app_list = [] for app in final_result: # All AWS connections have the same app name if (app['appName'] == 'amazon_aws'): newAppEntry = {} newAppEntry['id'] = app['id'] newAppEntry['name'] = app['label'] newAppEntry['links'] = {} newAppEntry['links']['appLink'] = app['linkUrl'] newAppEntry['links']['appLogo'] = app['logoUrl'] app_list.append(newAppEntry) # Throw an error if we didn't get any accounts back if not app_list: print("No AWS accounts found.", file=sys.stderr) exit() return app_list
def create_api_client(okta_org, path_name, api_key): """ Create Okta ApiClient :param okta_org: Okta organization name :param path_name: API Path :param api_key: Okta api key :return: Instance of ApiClient """ api_client = ApiClient( base_url=f"https://{okta_org}.okta.com/", pathname=path_name, api_token=api_key, ) return api_client
def __init__(self, connection_config, reauth_time, auth_attrib) -> None: ''' Args: connection_config (Dict): Parameters required to connect to the Okta API reauth_time (int): The min time in seconds to cache auth requests auth_attrib (str): The attribute of the user record that will be used to authenticate them. ''' super().__init__(reauth_time, auth_attrib) connection_config['pathname'] = '/api/v1/users' self.usersclient = UsersClient(**connection_config) self.factorsclient = FactorsClient(**connection_config) self.apiclient = ApiClient(**connection_config) # Maintain a per user lookup for poll URL self.poll_url = {}
def load_okta_users(): ret = [] apiClient = ApiClient(pathname='/api/v1/users', base_url=os.getenv('OKTA_CLIENT_ORGURL'), api_token=os.getenv('OKTA_CLIENT_TOKEN')) params = { 'search': "profile.department eq \"Engineering\" and (status eq \"ACTIVE\")" } response = ApiClient.get_path(apiClient, '/', params=params) users = Utils.deserialize(response.text, User) for u in users: response = ApiClient.get_path(apiClient, '/{}/groups'.format(u.id)) userGroups = Utils.deserialize(response.text, UserGroup) groups = [] for ug in userGroups: groups.append(ug.profile.name) oktaUser = OktaUser(u.profile.login, u.profile.firstName, u.profile.lastName, groups) ret.append(oktaUser) return ret
def aws_account_info(event, context): # We need access to the entire JSON response from the Okta APIs, so we need to # use the low-level ApiClient instead of UsersClient and AppInstanceClient usersClient = ApiClient(os.environ['OKTA_ORG_URL'], os.environ['OKTA_API_KEY'], pathname='/api/v1/users') appClient = ApiClient(os.environ['OKTA_ORG_URL'], os.environ['OKTA_API_KEY'], pathname='/api/v1/apps') # Get User information username = event['requestContext']['authorizer']['principalId'] try: result = usersClient.get_path('/{0}'.format(username)) user = result.json() except OktaError as e: if e.error_code == 'E0000007': statusCode = 404 else: statusCode = 500 return { 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': True }, "statusCode": statusCode, "body": e.error_summary } # Get a list of apps for this user and include extended info about the user params = { 'limit': 200, 'filter': 'user.id+eq+%22' + user['id'] + '%22&expand=user%2F' + user['id'] } try: # Get first page of results result = usersClient.get_path('/{0}/appLinks'.format(user['id'])) final_result = result.json() # Loop through other pages while 'next' in result.links: result = appClient.get(result.links['next']['url']) final_result = final_result + result.json() except OktaError as e: if e.error_code == 'E0000007': statusCode = 404 else: statusCode = 500 return { 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': True }, "statusCode": statusCode, "body": e.error_summary } # Loop through the list of apps and filter it down to just the info we need appList = [] for app in final_result: # All AWS connections have the same app name if (app['appName'] == 'amazon_aws'): newAppEntry = {} newAppEntry['id'] = app['id'] newAppEntry['name'] = app['label'] newAppEntry['links'] = {} newAppEntry['links']['appLink'] = app['linkUrl'] newAppEntry['links']['appLogo'] = app['logoUrl'] appList.append(newAppEntry) response = { 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': True }, "statusCode": 200, "body": json.dumps(appList) } return response
def _get_aws_account_info(okta_org_url, okta_api_key, username): """ Call the Okta User and App APIs and process the results to return just the information we need for gimme_aws_creds""" # We need access to the entire JSON response from the Okta APIs, so we need to # use the low-level ApiClient instead of UsersClient and AppInstanceClient users_client = ApiClient(okta_org_url, okta_api_key, pathname='/api/v1/users') app_client = ApiClient(okta_org_url, okta_api_key, pathname='/api/v1/apps') # Get User information try: result = users_client.get_path('/{0}'.format(username)) user = result.json() except OktaError as e: if e.error_code == 'E0000007': print("Error: " + username + " was not found!") exit(1) else: print("Error: " + e.error_summary) exit(1) # Get a list of apps for this user and include extended info about the user params = { 'limit': 50, 'filter': 'user.id+eq+%22' + user['id'] + '%22&expand=user%2F' + user['id'] } try: # Get first page of results result = app_client.get_path('/', params=params) final_result = result.json() # Loop through other pages while 'next' in result.links: print('.', end='', flush=True) result = app_client.get(result.links['next']['url']) final_result = final_result + result.json() print("done\n") except OktaError as e: if e.error_code == 'E0000007': print("Error: No applications found for " + username) exit(1) else: print("Error: " + e.error_summary) exit(1) # Loop through the list of apps and filter it down to just the info we need app_list = [] for app in final_result: # All AWS connections have the same app name if app['name'] == 'amazon_aws': new_app_entry = { 'id': app['id'], 'name': app['label'], 'identityProviderArn': app['settings']['app']['identityProviderArn'], 'roles': [] } # Build a list of the roles this user has access to for role in app['_embedded']['user']['profile']['samlRoles']: role_info = { 'name': role, 'arn': re.sub(':saml-provider.*', ':role/' + role, app['settings']['app']['identityProviderArn']) } # We can figure out the role ARN based on the ARN for the IdP new_app_entry['roles'].append(role_info) new_app_entry['links'] = {} new_app_entry['links']['appLink'] = app['_links']['appLinks'][ 0]['href'] new_app_entry['links']['appLogo'] = app['_links']['logo'][0][ 'href'] app_list.append(new_app_entry) # Throw an error if we didn't get any accounts back if not app_list: print("No AWS accounts found.") exit() return app_list