async def test_client_session(mocker): org_url = "https://test.okta.com" token = "TOKEN" # no session config = {'orgUrl': org_url, 'token': token} client = OktaClient(config) assert client._request_executor._http_client._session is None # with session config = {'orgUrl': org_url, 'token': token} async with OktaClient(config) as client: assert isinstance(client._request_executor._http_client._session, aiohttp.ClientSession)
def test_constructor_user_config_url_has_admin(url): config = {'orgUrl': url, 'token': 'TOKEN'} with pytest.raises(ValueError) as exception_info: OktaClient(user_config=config) assert all( string in str(exception_info.value) for string in [ERROR_MESSAGE_ORG_URL_ADMIN, f"Current value: {url}"])
def main(): """Main application loop""" # Get Applications from API print("Querying Okta API and Retrieving Results...\n") try: client = OktaClient() loop = asyncio.get_event_loop() apps = loop.run_until_complete(get_apps(client)) except ValueError as err: print(err) exit() # Sort Applications saml2, oidc, auto_login, ad_resources, unknown = sort_apps(apps) print( f"SAML: {len(saml2)}, OIDC: {len(oidc)}, AUTO_LOGIN: {len(auto_login)}, AD: {len(ad_resources)}, Unknown: {len(unknown)}" ) # Get Location for File Output location = input("Location for Terraform Files: ") # Create TF for SAML Apps for app in saml2: saml_app(app, location)
def test_constructor_custom_http_client_impl(): class CustomHTTPClient(HTTPClient): pass config = {'httpClient': CustomHTTPClient} client = OktaClient(config) assert isinstance(client._request_executor._http_client, CustomHTTPClient)
def test_constructor_client_logging(): logger = logging.getLogger('okta-sdk-python') assert logger.disabled config = {'logging': {"enabled": True, "logLevel": logging.DEBUG}} client = OktaClient(config) assert not logger.disabled assert logger.level == logging.DEBUG
def test_constructor_user_config_url_has_yourOktaDomain(): config = { 'orgUrl': 'https://{yourOktaDomain}.okta.com', 'token': 'TOKEN' } with pytest.raises(ValueError) as exception_info: OktaClient(user_config=config) assert ERROR_MESSAGE_ORG_URL_YOUROKTADOMAIN in str(exception_info.value)
def test_client_raise_exception(): org_url = "https://test.okta.com" token = "TOKEN" config = {'orgUrl': org_url, 'token': token, 'raiseException': True} client = OktaClient(config) with pytest.raises(HTTPException): asyncio.run(client.list_users())
def test_client_ssl_context(monkeypatch, mocker): org_url = "https://test.okta.com" token = "TOKEN" mock_ssl_context = mocker.MagicMock() config = {'orgUrl': org_url, 'token': token, 'sslContext': mock_ssl_context} client = OktaClient(config) # mock http requests, verify if custom header is present in request class MockHTTPRequest(): def __call__(self, **params): self.request_info = params self.headers = params['headers'] self.url = params['url'] self.content_type = 'application/json' self.links = '' self.text = MockHTTPRequest.mock_response_text self.status = 200 return self async def __aenter__(self): return self async def __aexit__(self, exc_type, exc, tb): pass @staticmethod async def mock_response_text(): return '[{"text": "mock response text"}]' mock_http_request = MockHTTPRequest() monkeypatch.setattr(aiohttp.ClientSession, 'request', mock_http_request) asyncio.run(client.list_users()) assert mock_http_request.request_info['ssl_context'] == mock_ssl_context
def test_constructor_precedence_highest_rank_env_vars(fs): # Setup Local config fs.pause() local_sample = os.path.join(os.path.dirname( __file__), "files", "SSWS-sample-local.yaml") with open(local_sample) as file: local_config = yaml.load(file, Loader=yaml.SafeLoader) local_org_url = local_config["okta"]["client"]["orgUrl"] local_token = local_config["okta"]["client"]["token"] fs.resume() fs.create_file(_LOCAL_YAML_PATH, contents=yaml.dump(local_config)) # Setup env. vars env_org_url = "https://test.env.okta.com" env_token = "envTOKEN" os.environ["OKTA_CLIENT_ORGURL"] = env_org_url os.environ["OKTA_CLIENT_TOKEN"] = env_token client = OktaClient() loaded_config = client.get_config() os.environ.pop("OKTA_CLIENT_ORGURL") os.environ.pop("OKTA_CLIENT_TOKEN") assert local_org_url != loaded_config['client']['orgUrl'] assert local_token != loaded_config['client']['token'] assert local_org_url != env_org_url assert local_token != env_token assert env_org_url == loaded_config['client']['orgUrl'] assert env_token == loaded_config['client']['token']
def test_constructor_precedence_highest_rank_local_yaml(fs): # Setup Global config fs.pause() global_sample = os.path.join(os.path.dirname( __file__), "files", "SSWS-sample-global.yaml") with open(global_sample) as file: global_config = yaml.load(file, Loader=yaml.SafeLoader) global_org_url = global_config["okta"]["client"]["orgUrl"] global_token = global_config["okta"]["client"]["token"] fs.resume() fs.create_file(_GLOBAL_YAML_PATH, contents=yaml.dump(global_config)) # Setup Local config fs.pause() local_sample = os.path.join(os.path.dirname( __file__), "files", "SSWS-sample-local.yaml") with open(local_sample) as file: local_config = yaml.load(file, Loader=yaml.SafeLoader) local_org_url = local_config["okta"]["client"]["orgUrl"] local_token = local_config["okta"]["client"]["token"] fs.resume() fs.create_file(_LOCAL_YAML_PATH, contents=yaml.dump(local_config)) # Create client and validate values client = OktaClient() loaded_config = client.get_config() assert local_org_url == loaded_config['client']['orgUrl'] assert local_token == loaded_config['client']['token'] assert local_org_url != global_org_url assert local_token != global_token assert global_org_url != loaded_config['client']['orgUrl'] assert global_token != loaded_config['client']['token']
def test_constructor_user_config_url_has_apiToken(fs): config = { 'orgUrl': 'https://test.okta.com', 'token': '{apiToken}' } with pytest.raises(ValueError) as exception_info: OktaClient(user_config=config) assert ERROR_MESSAGE_API_TOKEN_DEFAULT in str(exception_info.value)
def test_constructor_env_vars_PK(): authorizationMode = "PrivateKey" org_url = "https://test.okta.com" client_id = "clientID" scopes = "scope1,scope2,scope3" private_key = "private key" os.environ["OKTA_CLIENT_AUTHORIZATIONMODE"] = authorizationMode os.environ["OKTA_CLIENT_ORGURL"] = org_url os.environ["OKTA_CLIENT_CLIENTID"] = client_id os.environ["OKTA_CLIENT_SCOPES"] = scopes os.environ["OKTA_CLIENT_PRIVATEKEY"] = private_key client = OktaClient() loaded_config = client.get_config() os.environ.pop("OKTA_CLIENT_ORGURL") os.environ.pop("OKTA_CLIENT_AUTHORIZATIONMODE") os.environ.pop("OKTA_CLIENT_CLIENTID") os.environ.pop("OKTA_CLIENT_SCOPES") os.environ.pop("OKTA_CLIENT_PRIVATEKEY") assert authorizationMode == loaded_config['client']['authorizationMode'] assert org_url == loaded_config['client']['orgUrl'] assert client_id == loaded_config['client']['clientId'] assert scopes.split(',') == loaded_config['client']['scopes'] assert private_key == loaded_config['client']['privateKey']
def __init__(self): self.USERNAME_ATTRIBUTE = os.environ.get("OKTA_USERNAME_ATTRIBUTE", "login") config = { "orgUrl": os.environ["OKTA_ORG_URL"], "token": os.environ["OKTA_ACCESS_TOKEN"], } self.client = OktaClient(config)
def _create_okta_client(self): config = { "orgUrl": f"https://{self.config.okta_domain}", "token": f"{self.config.okta_api_token}", "raiseException": True, } return OktaClient(config)
async def test_update_feature_for_application(monkeypatch, mocker): org_url = "https://test.okta.com" token = "TOKEN" config = {'orgUrl': org_url, 'token': token} client = OktaClient(config) # mock http requests, verify if custom header is present in request class MockHTTPRequest(): def __call__(self, **params): self.request_info = params self.headers = params['headers'] self.url = params['url'] self.content_type = 'application/json' self.links = '' self.text = MockHTTPRequest.mock_response_text self.status = 200 return self async def __aenter__(self): return self async def __aexit__(self, exc_type, exc, tb): pass @staticmethod async def mock_response_text(): return '[{"text": "mock response text"}]' mock_http_request = MockHTTPRequest() monkeypatch.setattr(aiohttp.ClientSession, 'request', mock_http_request) capabilities_object_dict = { "create": { "lifecycleCreate": { "status": "ENABLED" } }, "update": { "lifecycleDeactivate": { "status": "ENABLED" }, "profile": { "status": "ENABLED" }, "password": { "status": "ENABLED", "seed": "RANDOM", "change": "CHANGE" } } } capabilities_object = models.CapabilitiesObject(capabilities_object_dict) feature, _, err = await client.update_feature_for_application( 'test_app_id', 'test_name', capabilities_object) assert mock_http_request.request_info['url'].endswith( '/apps/test_app_id/features/test_name') data = mock_http_request.request_info['data'] assert json.loads(data) == capabilities_object_dict
def test_constructor_user_config_url_dot_com_twice(): url = 'https://test.okta.com.com' config = {'orgUrl': url, 'token': 'TOKEN'} with pytest.raises(ValueError) as exception_info: OktaClient(user_config=config) assert all( string in str(exception_info.value) for string in [ERROR_MESSAGE_ORG_URL_TYPO, f"Current value: {url}"])
def test_constructor_user_config_SSWS(): org_url = "https://test.okta.com" token = "TOKEN" config = {'orgUrl': org_url, 'token': token} client = OktaClient(user_config=config) loaded_config = client.get_config() assert org_url == loaded_config['client']['orgUrl'] assert token == loaded_config['client']['token']
def test_constructor_user_config_url_punctuation(): # test for urls with '://' multiple times url = 'https://://test.okta.com' config = {'orgUrl': url, 'token': 'TOKEN'} with pytest.raises(ValueError) as exception_info: OktaClient(user_config=config) assert all( string in str(exception_info.value) for string in [ERROR_MESSAGE_ORG_URL_TYPO, f"Current value: {url}"])
def test_constructor_valid_no_proxy(): org_url = "https://test.okta.com" token = "TOKEN" config = {'orgUrl': org_url, 'token': token} # Ensure no error is raised and proxy is None client = OktaClient(user_config=config) assert client.get_request_executor()._http_client._proxy is None
def test_constructor_user_config_auth_mode_invalid(): authorizationMode = "blah" config = {'orgUrl': "https://test.okta.com", 'token': "TOKEN", 'authorizationMode': authorizationMode} with pytest.raises(ValueError) as exception_info: OktaClient(user_config=config) assert all(string in str(exception_info.value) for string in [ ERROR_MESSAGE_AUTH_MODE_INVALID, f"with {authorizationMode}"])
def test_constructor_custom_http_client_impl(): class CustomHTTPClient(HTTPClient): pass org_url = "https://test.okta.com" token = "TOKEN" config = {'orgUrl': org_url, 'token': token, 'httpClient': CustomHTTPClient} client = OktaClient(config) assert isinstance(client._request_executor._http_client, CustomHTTPClient)
def test_constructor_client_logging(): logger = logging.getLogger('okta-sdk-python') assert logger.disabled org_url = "https://test.okta.com" token = "TOKEN" config = {'orgUrl': org_url, 'token': token, 'logging': {"enabled": True, "logLevel": logging.DEBUG}} client = OktaClient(config) assert not logger.disabled assert logger.level == logging.DEBUG
async def main(): client = OktaClient(config) users, resp, err = await client.list_users() while True: for user in users: print(user.profile.login, '|', user.created, '|', user.last_login) # Add more properties here. if resp.has_next(): users, err = await resp.next() else: break
def test_constructor_user_config_Bearer(): authorizationMode = "Bearer" org_url = "https://test.okta.com" token = "TOKEN" config = {'orgUrl': org_url, 'token': token, 'authorizationMode': authorizationMode} client = OktaClient(user_config=config) loaded_config = client.get_config() assert org_url == loaded_config['client']['orgUrl'] assert token == loaded_config['client']['token'] assert authorizationMode == loaded_config['client']['authorizationMode']
def test_client_log_debug(monkeypatch, caplog): org_url = "https://test.okta.com" token = "TOKEN" config = { 'orgUrl': org_url, 'token': token, 'logging': { 'enabled': True, 'logLevel': logging.DEBUG } } client = OktaClient(config) class MockHTTPRequest(): def __call__(self, **params): self.request_info = params self.headers = params['headers'] self.url = params['url'] self.content_type = 'application/json' self.links = '' self.text = MockHTTPRequest.mock_response_text self.status = 200 return self async def __aenter__(self): return self async def __aexit__(self, exc_type, exc, tb): pass @staticmethod async def mock_response_text(): return '[{"embedded": null,' \ '"links": {"self": {"href": "https://test.okta.com/v1/users/test_id"}},' \ '"activated": "2021-01-01T00:00:00.000Z",' \ '"created": "2021-01-01T00:00:00.000Z",' \ '"credentials": null,' \ '"id": "test_id",' \ '"last_login": null,' \ '"profile": {"name": "test_name"},' \ '"status": null,' \ '"status_changed": null,' \ '"transitioning_to_status": null,' \ '"type": null}]' mock_http_request = MockHTTPRequest() monkeypatch.setattr(aiohttp, 'request', mock_http_request) with caplog.at_level(logging.DEBUG): res, resp_body, error = asyncio.run(client.list_users()) assert 'okta-sdk-python' in caplog.text assert 'DEBUG' in caplog.text assert "'method': 'GET'" in caplog.text assert "'url': 'https://test.okta.com/api/v1/users'" in caplog.text
async def skipFunc(oktaDomain): configOkta = {'orgUrl': oktaDomain, 'token': apiKey.get()} okta_client = OktaClient(configOkta) apps, resp, err = await okta_client.list_applications() for app in apps: appsList = (app.label, app.id) for app.label in appsList: if app.label == appNameAWS.get(): strApp = str(app) appJson = ast.literal_eval(strApp) metadataURL = (appJson['links']['metadata']['href']) appID = (appJson['id']) createStackCF(metadataURL, appID)
def __init__(self): self.USERNAME_ATTRIBUTE = os.environ.get("OKTA_USERNAME_ATTRIBUTE", "login") 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"] config["scopes"] = os.environ["OKTA_SCOPES"].split(" ") config["privateKey"] = os.environ["OKTA_PRIVATE_KEY"] else: config["token"] = os.environ["OKTA_ACCESS_TOKEN"] self.client = OktaClient(config)
def test_constructor_user_config_PK_empty(fs): org_url = "https://test.okta.com" authorizationMode = "PrivateKey" config = { 'orgUrl': org_url, 'authorizationMode': authorizationMode, } with pytest.raises(ValueError) as exception_info: OktaClient(user_config=config) assert all(string in str(exception_info.value) for string in [ ERROR_MESSAGE_CLIENT_ID_MISSING, ERROR_MESSAGE_SCOPES_PK_MISSING ])
async def test_set_provisioning_connection(monkeypatch, mocker): org_url = "https://test.okta.com" token = "TOKEN" config = {'orgUrl': org_url, 'token': token} client = OktaClient(config) # mock http requests, verify if custom header is present in request class MockHTTPRequest(): def __call__(self, **params): self.request_info = params self.headers = params['headers'] self.url = params['url'] self.content_type = 'application/json' self.links = '' self.text = MockHTTPRequest.mock_response_text self.status = 200 return self async def __aenter__(self): return self async def __aexit__(self, exc_type, exc, tb): pass @staticmethod async def mock_response_text(): return '[{"text": "mock response text"}]' mock_http_request = MockHTTPRequest() monkeypatch.setattr(aiohttp.ClientSession, 'request', mock_http_request) profile = models.ProvisioningConnectionProfile({ 'authScheme': models.ProvisioningConnectionAuthScheme('TOKEN'), 'token': 'TEST' }) provisioning_conn_req = models.ProvisioningConnectionRequest( {'profile': profile}) _ = await client.set_default_provisioning_connection_for_application( 'test_app_id', provisioning_conn_req, query_params={'activate': True}) assert mock_http_request.request_info['url'].endswith( '/apps/test_app_id/connections/default/?activate=True') data = mock_http_request.request_info['data'] assert json.loads(data) == { "profile": { "authScheme": "TOKEN", "token": "TEST" } }
def test_constructor_env_vars_SSWS(): org_url = "https://test.okta.com" token = "TOKEN" os.environ["OKTA_CLIENT_ORGURL"] = org_url os.environ["OKTA_CLIENT_TOKEN"] = token client = OktaClient() loaded_config = client.get_config() os.environ.pop("OKTA_CLIENT_ORGURL") os.environ.pop("OKTA_CLIENT_TOKEN") assert org_url == loaded_config['client']['orgUrl'] assert token == loaded_config['client']['token']