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 get_paged_users(self, limit=None, filter_string=None, after=None, url=None): """Get a paged list of Users :param limit: maximum number of users to return :type limit: int or None :param filter_string: string to filter users :type filter_string: str or None :param after: user id that filtering will resume after :type after: str :param url: url that returns a list of User :type url: str :rtype: PagedResults of User """ if url: response = ApiClient.get(self, url) else: params = { 'limit': limit, 'after': after, 'filter': filter_string } response = ApiClient.get_path(self, '/', params=params) return PagedResults(response, User)
def get_paged_app_instances(self, limit=None, filter_string=None, after=None, url=None): """Get a paged list of AppInstances :param limit: maximum number of apps to return :type limit: int or None :param filter_string: string to filter apps :type filter_string: str or None :param after: app id that filtering will resume after :type after: str :param url: url that returns a list of AppInstance :type url: str :rtype: PagedResults of AppInstance """ if url: response = ApiClient.get(self, url) else: params = { 'limit': limit, 'after': after, 'filter': filter_string } response = ApiClient.get_path(self, '/', params=params) return PagedResults(response, AppInstance)
def get_paged_groups(self, limit=None, filter_string=None, after=None, url=None): """Get a paged list of UserGroups :param limit: maximum number of groups to return :type limit: int or None :param filter_string: Filter expression for groups :type filter_string: str or None :param after: group id that filtering will resume after :type after: str :param url: url that returns a list of UserGroup :type url: str :rtype: PagedResults of UserGroup """ if url: response = ApiClient.get(self, url) else: params = {'limit': limit, 'filter': filter_string, 'after': after} response = ApiClient.get_path(self, '/', params=params) return PagedResults(response, UserGroup)
def _get_okta_applications(api_client: ApiClient) -> List[Dict]: """ Get application data from Okta server :param app_client: api client :return: application data """ app_list: List[Dict] = [] next_url = None while True: try: # https://developer.okta.com/docs/reference/api/apps/#list-applications if next_url: paged_response = api_client.get(next_url) else: params = { 'limit': 500, } paged_response = api_client.get_path('/', params) except OktaError as okta_error: logger.debug(f"Got error while listing applications {okta_error}") break app_list.extend(json.loads(paged_response.text)) if not is_last_page(paged_response): next_url = paged_response.links.get("next").get("url") else: break return app_list
def _get_okta_groups(api_client: ApiClient) -> List[str]: """ Get groups from Okta server :param api_client: Okta api client :return: Array of group information """ group_list: List[str] = [] next_url = None # SDK Bug # get_paged_groups returns User object instead of UserGroup while True: # https://developer.okta.com/docs/reference/api/groups/#list-groups if next_url: paged_response = api_client.get(next_url) else: params = { 'limit': 10000, } paged_response = api_client.get_path('/', params) paged_results = PagedResults(paged_response, UserGroup) group_list.extend(paged_results.result) if not is_last_page(paged_response): next_url = paged_response.links.get("next").get("url") else: break return group_list
def _get_okta_group_members(api_client: ApiClient, group_id: str) -> List[str]: """ Get group members from Okta server :param api_client: Okta api client :param group_id: group to fetch members from :return: Array or group membership information """ member_list: List[str] = [] next_url = None while True: try: # https://developer.okta.com/docs/reference/api/groups/#list-group-members if next_url: paged_response = api_client.get(next_url) else: params = { 'limit': 1000, } paged_response = api_client.get_path(f'/{group_id}/users', params) except OktaError as okta_error: logger.debug( f"Got error while going through list group member {okta_error}" ) break member_list.append(paged_response.text) if not is_last_page(paged_response): next_url = paged_response.links.get("next").get("url") else: break return member_list
def get_okta_group_members(api_client: ApiClient, group_id: str) -> List[Dict]: """ Get group members from Okta server :param api_client: Okta api client :param group_id: group to fetch members from :return: Array or group membership information """ member_list: List[Dict] = [] next_url = None while True: try: # https://developer.okta.com/docs/reference/api/groups/#list-group-members if next_url: paged_response = api_client.get(next_url) else: params = { 'limit': 1000, } paged_response = api_client.get_path(f'/{group_id}/users', params) except OktaError: logger.error( f"OktaError while listing members of group {group_id}") raise member_list.extend(json.loads(paged_response.text)) if not is_last_page(paged_response): next_url = paged_response.links.get("next").get("url") else: break return member_list
def get_paged_users(self, limit=None, filter_string=None, search=None, after=None, url=None): """Get a paged list of Users :param limit: maximum number of users to return :type limit: int or None :param filter_string: string to filter users :type filter_string: str or None :param after: user id that filtering will resume after :type after: str :param url: url that returns a list of User :type url: str :rtype: PagedResults of User """ if url: response = ApiClient.get(self, url) else: params = { 'limit': limit, 'after': after, 'filter': filter_string, 'search': search } response = ApiClient.get_path(self, '/', params=params) return PagedResults(response, User)
def get_paged_log_events(self, since=None, until=None, q=None, filter=None, limit=None, url=None): """Get a paged list of log events :param since: filters the lower time bound of the log events published property :type since: datetime or None :param until: filters the upper time bound of the log events published property :type until: datetime or None :param filter: filter expression that filters the results :type filter: str or None :param q: filters the log events results by one or more exact keywords :type q: str or None :rtype: list of dictionaries representing log events :param limit: The number of results returned in the response :type limit: int or None :param url: url that returns a list of log events :type url: str :rtype: PagedResults of log events in JSON format """ if url: response = ApiClient.get(self, url) else: params = { 'since': since, 'until': until, 'q': q, 'filter': filter, 'limit': limit, } response = ApiClient.get_path(self, '/', params=params) return PagedResults(response)
def get_users(self, limit=None, q=None, filter_string=None, search_string=None): """Get a list of Users :param limit: maximum number of users to return :type limit: int or None :param q: string to search users' first names, last names, and emails :type q: str or None :param filter_string: string to filter users :type filter_string: str or None :param search_string: string to search users :type search_string: str or None :rtype: list of User """ params = { 'limit': limit, 'q': q, 'filter': filter_string, 'search': search_string, } response = ApiClient.get_path(self, '/', params=params) return Utils.deserialize(response.text, self.user_model)
def get_paged_events(self, limit=None, start_date=None, after=None, filter_string=None, url=None): """Get a paged list of Events :param limit: maximum number of events to return :type limit: int or None :param filter_string: string to filter events :type filter_string: str or None :param after: event id that filtering will resume after :type after: str or None :param url: url that returns a list of Event :type url: str or None :rtype: PagedResults of Event """ if url: response = ApiClient.get(self, url) else: params = { 'limit': limit, 'startDate': start_date, 'after': after, 'filter': filter_string } response = ApiClient.get_path(self, '/', params=params) return PagedResults(response, Event)
def validate_session(self, id): """Validate a session :param id: the target session id :rtype: Session """ response = ApiClient.get_path(self, '/{0}'.format(id)) return Utils.deserialize(response.text, Session)
def get_factors_catalog(self, user_id): """Get available factors for a user :param user_id: target user id :type user_id: str :rtype: list of FactorCatalogEntry """ response = ApiClient.get_path(self, '/{0}/factors/catalog'.format(user_id)) return Utils.deserialize(response.text, FactorCatalogEntry)
def get_user_admin_roles(self, uid): """Get roles for a single user :param uid: the user id :type uid: str :rtype: Array of Role """ response = ApiClient.get_path(self, '/{0}/roles'.format(uid)) return Utils.deserialize(response.text, Role)
def get_user_groups(self, uid): """Get the groups a single user is a member of :param uid: the user id or login :type uid: str :rtype: list of UserGroup """ response = ApiClient.get_path(self, '/{0}/groups'.format(uid)) return Utils.deserialize(response.text, UserGroup)
def get_app_instance(self, id): """Get a single app :param id: the app id :type id: str :rtype: AppInstance """ response = ApiClient.get_path(self, '/{0}'.format(id)) return Utils.deserialize(response.text, AppInstance)
def get_user_apps(self, uid): """Get the apps a single user has access to :param uid: the user id or login :type uid: str :rtype: dict """ response = ApiClient.get_path(self, '/{0}/appLinks'.format(uid)) return json.loads(response.text)
def get_user_admin_roles(self, uid): """Get all roles assigned to a user. :param uid: the user id :type uid: str :rtype: list of Role """ response = ApiClient.get_path(self, '/{0}/roles'.format(uid)) return Utils.deserialize(response.text, Role)
def get_group_users(self, gid): """Get the users of a group :param gid: the group id :type gid: str :rtype: User """ response = ApiClient.get_path(self, '/{0}/users'.format(gid)) return Utils.deserialize(response.text, User)
def get_user_applinks(self, uid): """Get applinks of a single user :param uid: the user id or login :type uid: str :rtype: AppLinks """ response = ApiClient.get_path(self, '/{0}/appLinks'.format(uid)) return Utils.deserialize(response.text, AppLinks)
def get_user(self, uid): """Get a single user :param uid: the user id or login :type uid: str :rtype: User """ response = ApiClient.get_path(self, '/{0}'.format(uid)) return Utils.deserialize(response.text, User)
def get_lifecycle_factors(self, user_id): """Get enrolled factors for a user :param user_id: target user id :type user_id: str :rtype: list of Factor """ response = ApiClient.get_path(self, '/{0}/factors'.format(user_id)) return Utils.deserialize(response.text, Factor)
def get_app_assignments_for_user(self, user): if hasattr(user, 'id'): uid = user.id else: uid = user path = "/?filter=user.id+eq+\"{uid}\"&expand=user/{uid}".format( uid=uid) response = ApiClient.get_path(self, path, params={}) return json.loads(response.text)
def get_group(self, gid): """Get a single group :param gid: the group id :type gid: str :rtype: UserGroup """ response = ApiClient.get_path(self, '/{0}'.format(gid)) return Utils.deserialize(response.text, UserGroup)
def introspect(self, token, token_type_hint, client_id, client_secret, client_assertion, client_assertion_type): headers = {} request = {} params = {} url_path = '/oauth2/v1/introspect' response = ApiClient.get_path(self, url_path, headers, request, params=params) pass
def get_available_questions(self, user_id): """Get available factor questions :param user_id: target user id :type user_id: str :rtype: list of Question """ response = ApiClient.get_path(self, '/{0}/factors/questions'.format(user_id)) return Utils.deserialize(response.text, Question)
def get_user_groups(self, uid): """Get groups of a single user :param uid: the user id or login :type uid: str :rtype: Groups """ response = ApiClient.get_path(self, '/{0}/groups'.format(uid)) return Utils.deserialize(response.text, UserGroup)
def get_assigned_users_to_app(self, aid): """Get assigned users to an application :param aid: the target app id :type aid: str :rtype: Array of AppUser """ response = ApiClient.get_path(self, '/{0}/users'.format(aid)) return Utils.deserialize(response.text, AppUser)
def userinfo(self, access_token): headers = { 'Content-Type': 'Authorization: Bearer {0}'.format(access_token) } #request = {} #params = {} url_path = '/oauth2/v1/userinfo' response = ApiClient.get_path(self, url_path, headers, request, params=params) return Utils.deserialize(response.text, AuthResult)
def oidc_discovery(self): #headers = {} #request = {} #params = {} url_path = '/.well-known/openid-configuration' response = ApiClient.get_path(self, url_path, request=None, params=None) self.discovery = Utils.deserialize(response.text, AuthResult) return Utils.deserialize(response.text, AuthResult)
def get_factor(self, user_id, user_factor_id): """Get information about an enrolled factor :param user_id: target user id :type user_id: str :param user_factor_id: target factor id :type user_factor_id: str :rtype: Factor """ response = ApiClient.get_path(self, '/{0}/factors/{1}'.format(user_id, user_factor_id)) return Utils.deserialize(response.text, Factor)
def get_org_factors(self, filter_string=None): """Get a list of OrgAuthFactors :param filter_string: string to filter factors :type filter_string: str or None :rtype: list of OrgAuthFactor """ params = { 'filter': filter_string } response = ApiClient.get_path(self, '/factors', params=params) return Utils.deserialize(response.text, OrgAuthFactor)
def get_factor_device(self, user_id, user_factor_id, device_id): """Get a factor device for a user :param user_id: target user id :type user_id: str :param user_factor_id: target factor id :type user_factor_id: str :param device_id: target factor device id :type device_id: str :rtype: FactorDevice """ response = ApiClient.get_path(self, '/{0}/factors/{1}/device/{2}'.format(user_id, user_factor_id, device_id)) return Utils.deserialize(response.text, FactorDevice)
def get_app_instances(self, limit=None, filter_string=None): """Get a list of AppInstances :param limit: maximum number of apps to return :type limit: int or None :param filter_string: string to filter users :type filter_string: str or None :rtype: list of AppInstance """ params = { 'limit': limit, 'filter': filter_string } response = ApiClient.get_path(self, '/', params=params) return Utils.deserialize(response.text, AppInstance)
def get_groups(self, limit=None, query=None): """Get a list of UserGroups :param limit: maximum number of groups to return :type limit: int or None :param query: string to search group names :type query: str or None :rtype: list of UserGroup """ params = { 'limit': limit, 'q': query } response = ApiClient.get_path(self, '/', params=params) return Utils.deserialize(response.text, UserGroup)
def get_events(self, limit=None, start_date=None, filter_string=None): """Get a list of Events :param limit: maximum number of events to return :type limit: int or None :param filter_string: string to filter events :type filter_string: str or None :rtype: list of Event """ params = { 'limit': limit, 'startDate': start_date, 'filter': filter_string } response = ApiClient.get_path(self, '/', params=params) return Utils.deserialize(response.text, Event)
def get_users(self, limit=None, query=None, filter_string=None): """Get a list of Users :param limit: maximum number of users to return :type limit: int or None :param query: string to search users' first names, last names, and emails :type query: str or None :param filter_string: string to filter users :type filter_string: str or None :rtype: list of User """ params = { 'limit': limit, 'q': query, 'filter': filter_string } response = ApiClient.get_path(self, '/', params=params) return Utils.deserialize(response.text, User)
def get_paged_groups(self, limit=None, after=None, url=None): """Get a paged list of UserGroups :param limit: maximum number of groups to return :type limit: int or None :param after: group id that filtering will resume after :type after: str :param url: url that returns a list of UserGroup :type url: str :rtype: PagedResults of UserGroup """ if url: response = ApiClient.get(self, url) else: params = { 'limit': limit, 'after': after } response = ApiClient.get_path(self, '/', params=params) return PagedResults(response, User)
def get_app_paged_users(self, gid=None, limit=None, after=None, url=None): """Get a paged list of AppUsers of an app :param gid: the app id :type gid: str :param limit: maximum number of AppUser to return :type limit: int or None :param after: app id that filtering will resume after :type after: str :param url: url that returns a list of AppUser :type url: str :rtype: AppUser """ if url: response = ApiClient.get(self, url) else: params = { 'limit': limit, 'after': after } response = ApiClient.get_path(self, '/{0}/users'.format(gid), params=params) return PagedResults(response, AppUser)