class GetQRCodeTests(TestCase): def setUp(self): self.mb = MountebankProcess() def tearDown(self): self.mb.destroy_all_imposters() def setup_imposter(self, file_name): port = self.mb.create_imposter("test_auth_client/stubs/" + file_name) return self.mb.get_imposter_url(port) def test_happy_path(self): imposter_url = self.setup_imposter("test_qr_code.json") response = {"_embedded": {"activation": {"_links": {"qrcode": {"href": imposter_url}}}}} qr_code = _get_qr_code_from_response(response) self.assertIsNotNone(qr_code) def test_missing_qr_code_link(self): response = {"_embedded": {"activation": {"_links": {"qrcode": {}}}}} qr_code = _get_qr_code_from_response(response) self.assertIsNone(qr_code) def test_bad_link(self): response = {"_embedded": {"activation": {"_links": {"qrcode": {"href": "http://localhost:1/asdf"}}}}} qr_code = _get_qr_code_from_response(response) self.assertIsNone(qr_code)
class GetQRCodeTests(TestCase): def setUp(self): self.mb = MountebankProcess() def tearDown(self): self.mb.destroy_all_imposters() def setup_imposter(self, file_name): port = self.mb.create_imposter('test_auth_client/stubs/' + file_name) return self.mb.get_imposter_url(port) def test_happy_path(self): imposter_url = self.setup_imposter('test_qr_code.json') response = { '_embedded': { 'activation': { '_links': { 'qrcode': { 'href': imposter_url } } } } } qr_code = _get_qr_code_from_response(response) self.assertIsNotNone(qr_code) def test_missing_qr_code_link(self): response = {'_embedded': {'activation': {'_links': {'qrcode': {}}}}} qr_code = _get_qr_code_from_response(response) self.assertIsNone(qr_code) def test_bad_link(self): response = { '_embedded': { 'activation': { '_links': { 'qrcode': { 'href': 'http://localhost:1/asdf' } } } } } qr_code = _get_qr_code_from_response(response) self.assertIsNone(qr_code)
def main(): # start mountebank mb_proc = MountebankProcess() try: print('Starting mountebank...') mb_proc.start() print('Mountebank started.') sys.stdout.flush() except Exception as err: print(err) print("We'll try to run the tests anyway, but no promises.") # automatically discover tests suite = unittest.TestLoader().discover('.') # run tests unittest.TextTestRunner().run(suite) if mb_proc.is_running(): sys.stdout.flush() try: print('Stopping mountebank...') return_code = mb_proc.stop() except Exception as err: print(err) sys.exit(-1) if return_code != 0: print('Mountebank closed with a status of {}.'.format(return_code)) else: print('Mountebank stopped properly.')
def setUp(self): self.mb = MountebankProcess()
def setUp(self): self.mb = MountebankProcess() api_client = ApiClient() self.broker = UserBroker(api_client)
class TestUserBroker(unittest.TestCase): def setUp(self): self.mb = MountebankProcess() api_client = ApiClient() self.broker = UserBroker(api_client) def tearDown(self): self.mb.destroy_all_imposters() def test_create_new_user_with_invalid_data(self): with self.assertRaises(AssertionError): self.broker.create_user(user_one) def test_create_new_user_with_valid_data(self): self.setup_imposter('create_new_user.json') user = self.broker.create_user(user_two) self.assertIsNotNone(user) self.assertEqual(user['id'], '00002') self.assertEqual(user['login'], user_two.get('login')) self.assertEqual(user['mobile_phone'], user_two.get('mobile_phone')) def test_create_user_with_differing_login_email(self): self.setup_imposter('create_new_user.json') user = self.broker.create_user(user_seven) self.assertIsNotNone(user) self.assertEqual(user['id'], '00002') self.assertEqual(user_seven['login'], user['login']) self.assertEqual(user_seven['email'], user['email']) def test_update_existing_user_with_id(self): self.setup_imposter('update_existing_user.json') user = self.broker.update_user_phone_number(user_three['id'], user_three['mobile_phone']) self.assertIsNotNone(user) self.assertEqual(user['id'], user_three.get('id')) self.assertEqual(user['login'], user_three.get('login')) self.assertEqual(user['mobile_phone'], user_three.get('mobile_phone')) def test_update_existing_user_without_id_or_phone(self): with self.assertRaises(AssertionError): self.broker.update_user_phone_number(user_two['id'], user_two['mobile_phone']) with self.assertRaises(AssertionError): self.broker.update_user_phone_number(user_three['id'], None) def test_get_user_method(self): self.setup_imposter('update_existing_user.json') user = self.broker.get_user(user_four.get('login')) self.assertEqual(user['login'], user_four.get('login')) self.assertIn('factors', user) self.assertEqual(len(user['factors']), 1) self.assertEqual(user['factors'][0]['phone_number'], user_four['mobile_phone']) def test_get_user_fail(self): self.setup_imposter('update_existing_user.json') self.assertIsNone(self.broker.get_user(user_five.get('login'))) def test_get_user_factors_fail(self): self.setup_imposter('update_existing_user.json') self.assertIsNone(self.broker.get_user(user_six.get('login'))) def test_get_user_id_method(self): self.setup_imposter('update_existing_user.json') user_id = self.broker.get_user_id(user_four.get('login')) self.assertEqual(user_id, '00003') def setup_imposter(self, file_name): file_path = 'test_user_broker/stubs/' + file_name imposter = self.mb.create_imposter(file_path) self.broker._api_client = ApiClient( BASE_URL=self.mb.get_imposter_url(imposter), API_TOKEN='1')
def setUp(self): self.api_client = ApiClient() self.auth_client = OktaAuthClient(OktaFactors(self.api_client)) self.mb = MountebankProcess()
class TestResponses(unittest.TestCase): def setUp(self): self.mb = MountebankProcess() def tearDown(self): self.mb.destroy_all_imposters() def test_no_response(self): """Ensure that API client handles no response from the server gracefully""" api_client = ApiClient(BASE_URL='http://example.com', API_TOKEN='dummy') # fake out the requests.get method requests.get = MagicMock(return_value=None) response, status_code = api_client.get('/') self.assertIsNone(response) self.assertIsNone(status_code) # fake out the requests.post method requests.post = MagicMock(return_value=None) response, status_code = api_client.post('/') self.assertIsNone(response) self.assertIsNone(status_code) # reload requests so that the methods are back to normal reload(requests) def test_non_json_response(self): """Ensure that the API client handles non-JSON responses gracefully""" imposter = self.mb.create_imposter( 'test_api_client/stubs/test_client_response.json') api_client = ApiClient(BASE_URL=self.mb.get_imposter_url(imposter), API_TOKEN='dummy') response, _ = api_client.get('/non-json') self.assertEqual('<html><body><h1>Testing!</h1></body></html>', response) response, _ = api_client.post('/non-json') self.assertEqual('<html><body><h1>Testing!</h1></body></html>', response) def test_check_api_response_no_causes(self): api_client = ApiClient() err_msg = { "errorSummary": "This is a short error message", "errorCauses": [] } try: api_client.check_api_response(err_msg, 400) raise AssertionError( "check_api_response should have raised an exception and didn't." ) except ApiException as err: self.assertIn(err_msg['errorSummary'], str(err)) def test_check_api_response_with_causes(self): api_client = ApiClient() err_msg = { "errorSummary": "This is a short error message", "errorCauses": [{ "errorSummary": "This is a more detailed error message" }, { "errorSummary": "This is a second error" }] } try: api_client.check_api_response(err_msg, 400) raise AssertionError( "check_api_response should have raised an exception and didn't." ) except ApiException as err: self.assertIn(err_msg['errorCauses'][0]['errorSummary'], str(err)) def test_check_api_response_without_okta_error(self): """Ensure that an invalid response without an OKTA error gets handled properly""" api_client = ApiClient() try: api_client.check_api_response({}, 400) raise AssertionError( "check_api_response should have raised an exception and didn't." ) except ApiException as err: self.assertIn('Okta returned 400', str(err)) def test_check_status(self): imposter = self.mb.create_imposter( 'test_api_client/stubs/test_client_response.json') imposter_url = self.mb.get_imposter_url(imposter) api_client = ApiClient(BASE_URL=imposter_url) status = api_client.check_status() self.assertTrue(status['okta']['is_available']) self.assertEqual(1199, status['okta']['calls_remaining']) self.assertTrue(isinstance(status['okta']['time_of_reset'], datetime)) # this is the fail case status = api_client.check_status() self.assertFalse(status['okta']['is_available'])
class GoogleAuthenticatorTests(TestCase): def setUp(self): self.api_client = ApiClient() self.auth_client = OktaAuthClient(OktaFactors(self.api_client)) self.mb = MountebankProcess() def tearDown(self): self.mb.destroy_all_imposters() def setup_imposter(self, file_name): port = self.mb.create_imposter('test_auth_client/stubs/' + file_name) imposter_url = self.mb.get_imposter_url(port) self.api_client.settings.set('BASE_URL', imposter_url) return imposter_url def test_enrollment_requirements(self): with self.assertRaises(AssertionError): self.auth_client.enroll_user_for_google_authenticator(None) def test_activation_requirements(self): with self.assertRaises(AssertionError): self.auth_client.activate_google_authenticator_factor( None, '123456') with self.assertRaises(AssertionError): self.auth_client.activate_google_authenticator_factor('0001', None) def test_verification_requirements(self): with self.assertRaises(AssertionError): self.auth_client.verify_google_authenticator_factor(None, '123456') with self.assertRaises(AssertionError): self.auth_client.verify_google_authenticator_factor('0001', None) def test_is_enrolled_requirements(self): with self.assertRaises(AssertionError): self.auth_client.is_user_enrolled_for_google_authenticator(None) def test_delete_requirements(self): with self.assertRaises(AssertionError): self.auth_client.delete_google_authenticator_factor(None) def test_enrollment_success(self): self.setup_imposter('test_google_authenticator_enrollment.json') response, message, error_code, extras = self.auth_client.enroll_user_for_google_authenticator( USER_ONE['id']) self.assertTrue(response) self.assertIsNotNone(response['id']) self.assertEqual('token:software:totp', response['factorType']) self.assertEqual('GOOGLE', response['provider']) self.assertEqual(message, "Success") self.assertIsNone(error_code) self.assertIn('shared_secret', extras) self.assertIsNotNone(extras['shared_secret']) self.assertIn('qr_code', extras) self.assertIsNotNone(extras['qr_code']) def test_enrollment_failure(self): self.setup_imposter('test_google_authenticator_enrollment.json') response, message, error_code, extras = self.auth_client.enroll_user_for_google_authenticator( USER_TWO['id']) self.assertFalse(response) self.assertEqual('Factor already exists.', message) self.assertIsNotNone(error_code) def test_activation_success(self): self.setup_imposter('test_google_authenticator_activation.json') response, message, error_code = self.auth_client.activate_google_authenticator_factor( USER_ONE['id'], '12345') self.assertTrue(response) self.assertEqual("Success", message) self.assertIsNone(error_code) def test_activation_failure_one(self): self.setup_imposter('test_google_authenticator_activation.json') response, message, error_code = self.auth_client.activate_google_authenticator_factor( USER_TWO['id'], '1') self.assertFalse(response) self.assertEqual( "Your passcode doesn't match our records. Please try again.", message) self.assertEqual('E0000068', error_code) def test_activation_failure_two(self): self.setup_imposter('test_google_authenticator_activation.json') response, message, error_code = self.auth_client.activate_google_authenticator_factor( USER_THREE['id'], 'not-enrolled') self.assertFalse(response) self.assertEqual("Not enrolled in factor.", message) self.assertIsNotNone(error_code) def test_activation_failure_three(self): self.setup_imposter('test_google_authenticator_activation.json') response, message, error_code = self.auth_client.activate_google_authenticator_factor( USER_FOUR['id'], 'not-found') self.assertFalse(response) self.assertEqual("Not found: Resource not found: invalid_id (User)", message) self.assertIsNotNone(error_code) def test_verify_challenge_success(self): self.setup_imposter('test_google_authenticator_challenge.json') response, message, error_code = self.auth_client.verify_google_authenticator_factor( USER_ONE['id'], '12345') self.assertTrue(response) self.assertEqual(response.get('factorResult'), 'SUCCESS') self.assertEqual("Success", message) self.assertIsNone(error_code) def test_verify_challenge_failure_one(self): self.setup_imposter('test_google_authenticator_challenge.json') response, message, error_code = self.auth_client.verify_google_authenticator_factor( USER_ONE['id'], 'invalid-passcode') self.assertFalse(response) self.assertEqual( "Your passcode doesn't match our records. Please try again.", message) self.assertEqual('E0000068', error_code) def test_verify_challenge_two(self): self.setup_imposter('test_google_authenticator_challenge.json') response, message, error_code = self.auth_client.verify_google_authenticator_factor( USER_THREE['id'], '12345') self.assertFalse(response) self.assertEqual("Not enrolled in factor.", message) def test_verify_challenge_failure_three(self): self.setup_imposter('test_google_authenticator_challenge.json') response, message, error_code = self.auth_client.verify_google_authenticator_factor( USER_FOUR['id'], '12345') self.assertFalse(response) self.assertEqual("Not found: Resource not found: invalid_id (User)", message) def test_user_is_enrolled(self): self.setup_imposter('test_google_authenticator_challenge.json') is_enrolled = self.auth_client.is_user_enrolled_for_google_authenticator( USER_ONE['id']) self.assertTrue(is_enrolled) def test_user_is_not_enrolled_in_pending_activation(self): self.setup_imposter('test_google_authenticator_challenge.json') is_enrolled = self.auth_client.is_user_enrolled_for_google_authenticator( USER_TWO['id']) self.assertFalse(is_enrolled) def test_user_is_not_enrolled_different_factor(self): self.setup_imposter('test_google_authenticator_challenge.json') is_enrolled = self.auth_client.is_user_enrolled_for_google_authenticator( USER_THREE['id']) self.assertFalse(is_enrolled) def test_user_is_not_enrolled_invalid_id(self): self.setup_imposter('test_google_authenticator_challenge.json') is_enrolled = self.auth_client.is_user_enrolled_for_google_authenticator( "invalid_id") self.assertFalse(is_enrolled) def test_delete_factor(self): self.setup_imposter('test_google_authenticator_challenge.json') response, message, error_code = self.auth_client.delete_google_authenticator_factor( USER_ONE['id']) self.assertEqual(message, 'Success') self.assertIsNone(error_code)
def setUp(self): self.api_client = ApiClient(API_TOKEN='jrr-tolkien') self.auth_client = OktaAuthClient(OktaFactors(self.api_client)) self.mb = MountebankProcess()
class SMSAuthTests(unittest.TestCase): def setUp(self): self.api_client = ApiClient(API_TOKEN='jrr-tolkien') self.auth_client = OktaAuthClient(OktaFactors(self.api_client)) self.mb = MountebankProcess() def tearDown(self): self.mb.destroy_all_imposters() def setup_imposter(self, file_name): imposter = self.mb.create_imposter('test_auth_client/stubs/' + file_name) api_client = ApiClient(BASE_URL=self.mb.get_imposter_url(imposter)) return OktaAuthClient(OktaFactors(api_client)) def test_sms_enrollment_requirements(self): with self.assertRaises(AssertionError): self.auth_client.enroll_user_for_sms(user_no_id.get('id'), user_no_id.get('phone_number')) with self.assertRaises(AssertionError): self.auth_client.enroll_user_for_sms( user_no_phone_number.get('id'), user_no_phone_number.get('phone_number')) def test_sms_enrollment_success(self): auth_client = self.setup_imposter('test_sms_enrollment.json') response, message, error_code = auth_client.enroll_user_for_sms( user_one.get('id'), user_one.get('phone_number')) self.assertTrue(response) self.assertEqual(response.get('id'), user_one.get('id')) self.assertEqual(message, "Success") self.assertIsNone(error_code) def test_sms_enrollment_failure(self): auth_client = self.setup_imposter('test_sms_enrollment.json') response, message, error_code = auth_client.enroll_user_for_sms( user_two.get('id'), user_two.get('phone_number')) self.assertFalse(response) self.assertEqual(message, "Factor already exists.") self.assertIsNotNone(error_code) def test_sms_activation_requirements(self): with self.assertRaises(AssertionError): self.auth_client.activate_sms_factor(user_no_id.get('id'), '123') with self.assertRaises(AssertionError): self.auth_client.activate_sms_factor(user_one.get('id'), None) def test_sms_activation_success(self): auth_client = self.setup_imposter('test_sms_activation.json') response, message, error_code = auth_client.activate_sms_factor(user_one.get('id'), '12345') self.assertTrue(response) self.assertEqual(response.get('id'), user_one.get('id')) self.assertEqual(message, "Success") self.assertIsNone(error_code) def test_sms_activation_failure_one(self): auth_client = self.setup_imposter('test_sms_activation.json') response, message, error_code = auth_client.activate_sms_factor(user_two.get('id'), 'invalid-passcode') self.assertFalse(response) self.assertEqual(message, "Your passcode doesn't match our records. Please try again.") self.assertEqual('E0000068', error_code) def test_sms_activation_failure_two(self): auth_client = self.setup_imposter('test_sms_activation.json') response, message, error_code = auth_client.activate_sms_factor(user_three.get('id'), '12345') self.assertFalse(response) self.assertEqual(message, "Not enrolled in factor.") self.assertIsNotNone(error_code) def test_sms_activation_failure_three(self): auth_client = self.setup_imposter('test_sms_activation.json') response, message, error_code = auth_client.activate_sms_factor(user_invalid_id.get('id'), '12345') self.assertFalse(response) self.assertEqual(message, "Not found: Resource not found: invalid_id (User)") self.assertIsNotNone(error_code) def test_sms_challenge_requirements(self): with self.assertRaises(AssertionError): self.auth_client.send_sms_challenge(user_no_id.get('id')) def test_sms_challenge_success(self): auth_client = self.setup_imposter('test_send_sms_challenge.json') response, message, error_code = auth_client.send_sms_challenge(user_one.get('id')) self.assertTrue(response) self.assertEqual(response.get('factorResult'), 'CHALLENGE') self.assertEqual(message, "Success") self.assertIsNone(error_code) def test_sms_challenge_failure_one(self): auth_client = self.setup_imposter('test_send_sms_challenge.json') response, message, error_code = auth_client.send_sms_challenge(user_two.get('id')) self.assertFalse(response) self.assertEqual(message, "Your passcode doesn't match our records. Please try again.") self.assertEqual('E0000068', error_code) def test_sms_challenge_failure_two(self): auth_client = self.setup_imposter('test_send_sms_challenge.json') response, message, error_code = auth_client.send_sms_challenge(user_invalid_id.get('id')) self.assertFalse(response) self.assertEqual(message, "Not found: Resource not found: invalid_id (User)") def test_sms_challenge_failure_three(self): auth_client = self.setup_imposter('test_send_sms_challenge.json') response, message, error_code = auth_client.send_sms_challenge(user_three.get('id')) self.assertFalse(response) self.assertEqual('Not enrolled in factor.', message) self.assertIsNotNone(error_code) def test_verify_sms_challenge_requirements(self): with self.assertRaises(AssertionError): self.auth_client.verify_sms_challenge_passcode(user_no_id.get('id'), '12345') def test_verify_sms_challenge_success(self): auth_client = self.setup_imposter('test_verify_sms_challenge.json') response, message, error_code = auth_client.verify_sms_challenge_passcode(user_one.get('id'), '12345') self.assertTrue(response) self.assertEqual(response.get('factorResult'), 'SUCCESS') self.assertEqual(message, "Success") self.assertIsNone(error_code) def test_verify_sms_challenge_failure_one(self): auth_client = self.setup_imposter('test_verify_sms_challenge.json') response, message, error_code = auth_client.verify_sms_challenge_passcode( user_two.get('id'), "invalid-passcode") self.assertFalse(response) self.assertEqual(message, "Your passcode doesn't match our records. Please try again.") self.assertEqual('E0000068', error_code) def test_verify_sms_challenge_failure_two(self): auth_client = self.setup_imposter('test_verify_sms_challenge.json') response, message, error_code = auth_client.verify_sms_challenge_passcode(user_invalid_id.get('id'), '12345') self.assertFalse(response) self.assertEqual(message, "Not found: Resource not found: invalid_id (User)") def test_verify_sms_challenge_three(self): auth_client = self.setup_imposter('test_verify_sms_challenge.json') response, message, error_code = auth_client.verify_sms_challenge_passcode(user_three.get('id'), '12345') self.assertFalse(response) self.assertEqual("Not enrolled in factor.", message) def test_user_is_enrolled_in_sms(self): auth_client = self.setup_imposter('test_sms_is_enrolled.json') is_enrolled = auth_client.is_user_enrolled_for_sms(user_one.get('id')) self.assertTrue(is_enrolled) def test_user_is_not_enrolled_in_sms_pending_activation(self): auth_client = self.setup_imposter('test_sms_is_enrolled.json') is_enrolled = auth_client.is_user_enrolled_for_sms(user_two.get('id')) self.assertFalse(is_enrolled) def test_user_is_not_enrolled_in_sms_different_factor(self): auth_client = self.setup_imposter('test_sms_is_enrolled.json') is_enrolled = auth_client.is_user_enrolled_for_sms(user_three.get('id')) self.assertFalse(is_enrolled) def test_user_is_not_enrolled_in_sms_invalid_id(self): auth_client = self.setup_imposter('test_sms_is_enrolled.json') is_enrolled = auth_client.is_user_enrolled_for_sms("invalid_id") self.assertFalse(is_enrolled) def test_delete_sms_factor(self): auth_client = self.setup_imposter('test_sms_delete_factor.json') response, message, error_code = auth_client.delete_sms_factor(user_one['id']) self.assertEqual(message, 'Success') self.assertIsNone(error_code) def test_update_sms_phone_number(self): auth_client = self.setup_imposter('test_sms_delete_factor.json') new_phone_number = '+1 666-666-6666' response, message, error_code = auth_client.update_sms_phone_number(user_one['id'], new_phone_number) self.assertTrue(response) self.assertEqual(response.get('id'), user_one.get('id')) self.assertEqual(response['profile']['phoneNumber'], new_phone_number) self.assertEqual(message, "Success") self.assertIsNone(error_code) def test_update_sms_phone_number_failure(self): auth_client = self.setup_imposter('test_sms_delete_factor.json') response, message, error_code = auth_client.update_sms_phone_number(user_two['id'], '+1 666-666-6666') self.assertFalse(response) self.assertEqual('Tom wanted 100% test coverage.', message) self.assertIsNotNone(error_code) def test_update_sms_phone_number_delete_failure(self): auth_client = self.setup_imposter('test_sms_delete_factor.json') response, message, error_code = auth_client.update_sms_phone_number(user_three['id'], '+1 666-666-6666') self.assertFalse(response) self.assertEqual('Tom wanted 100% test coverage.', message) self.assertIsNotNone(error_code)
class TestUserBroker(unittest.TestCase): def setUp(self): self.mb = MountebankProcess() api_client = ApiClient() self.broker = UserBroker(api_client) def tearDown(self): self.mb.destroy_all_imposters() def test_create_new_user_with_invalid_data(self): with self.assertRaises(AssertionError): self.broker.create_user(user_one) def test_create_new_user_with_valid_data(self): self.setup_imposter('create_new_user.json') user = self.broker.create_user(user_two) self.assertIsNotNone(user) self.assertEqual(user['id'], '00002') self.assertEqual(user['login'], user_two.get('login')) self.assertEqual(user['mobile_phone'], user_two.get('mobile_phone')) def test_create_user_with_differing_login_email(self): self.setup_imposter('create_new_user.json') user = self.broker.create_user(user_seven) self.assertIsNotNone(user) self.assertEqual(user['id'], '00002') self.assertEqual(user_seven['login'], user['login']) self.assertEqual(user_seven['email'], user['email']) def test_update_existing_user_with_id(self): self.setup_imposter('update_existing_user.json') user = self.broker.update_user_phone_number(user_three['id'], user_three['mobile_phone']) self.assertIsNotNone(user) self.assertEqual(user['id'], user_three.get('id')) self.assertEqual(user['login'], user_three.get('login')) self.assertEqual(user['mobile_phone'], user_three.get('mobile_phone')) def test_update_existing_user_without_id_or_phone(self): with self.assertRaises(AssertionError): self.broker.update_user_phone_number(user_two['id'], user_two['mobile_phone']) with self.assertRaises(AssertionError): self.broker.update_user_phone_number(user_three['id'], None) def test_get_user_method(self): self.setup_imposter('update_existing_user.json') user = self.broker.get_user(user_four.get('login')) self.assertEqual(user['login'], user_four.get('login')) self.assertIn('factors', user) self.assertEqual(len(user['factors']), 1) self.assertEqual(user['factors'][0]['phone_number'], user_four['mobile_phone']) def test_get_user_fail(self): self.setup_imposter('update_existing_user.json') self.assertIsNone(self.broker.get_user(user_five.get('login'))) def test_get_user_factors_fail(self): self.setup_imposter('update_existing_user.json') self.assertIsNone(self.broker.get_user(user_six.get('login'))) def test_get_user_id_method(self): self.setup_imposter('update_existing_user.json') user_id = self.broker.get_user_id(user_four.get('login')) self.assertEqual(user_id, '00003') def setup_imposter(self, file_name): file_path = 'test_user_broker/stubs/' + file_name imposter = self.mb.create_imposter(file_path) self.broker._api_client = ApiClient(BASE_URL=self.mb.get_imposter_url(imposter), API_TOKEN='1')
class GoogleAuthenticatorTests(TestCase): def setUp(self): self.api_client = ApiClient() self.auth_client = OktaAuthClient(OktaFactors(self.api_client)) self.mb = MountebankProcess() def tearDown(self): self.mb.destroy_all_imposters() def setup_imposter(self, file_name): port = self.mb.create_imposter("test_auth_client/stubs/" + file_name) imposter_url = self.mb.get_imposter_url(port) self.api_client.settings.set("BASE_URL", imposter_url) return imposter_url def test_enrollment_requirements(self): with self.assertRaises(AssertionError): self.auth_client.enroll_user_for_google_authenticator(None) def test_activation_requirements(self): with self.assertRaises(AssertionError): self.auth_client.activate_google_authenticator_factor(None, "123456") with self.assertRaises(AssertionError): self.auth_client.activate_google_authenticator_factor("0001", None) def test_verification_requirements(self): with self.assertRaises(AssertionError): self.auth_client.verify_google_authenticator_factor(None, "123456") with self.assertRaises(AssertionError): self.auth_client.verify_google_authenticator_factor("0001", None) def test_is_enrolled_requirements(self): with self.assertRaises(AssertionError): self.auth_client.is_user_enrolled_for_google_authenticator(None) def test_delete_requirements(self): with self.assertRaises(AssertionError): self.auth_client.delete_google_authenticator_factor(None) def test_enrollment_success(self): self.setup_imposter("test_google_authenticator_enrollment.json") response, message, error_code, extras = self.auth_client.enroll_user_for_google_authenticator(USER_ONE["id"]) self.assertTrue(response) self.assertIsNotNone(response["id"]) self.assertEqual("token:software:totp", response["factorType"]) self.assertEqual("GOOGLE", response["provider"]) self.assertEqual(message, "Success") self.assertIsNone(error_code) self.assertIn("shared_secret", extras) self.assertIsNotNone(extras["shared_secret"]) self.assertIn("qr_code", extras) self.assertIsNotNone(extras["qr_code"]) def test_enrollment_failure(self): self.setup_imposter("test_google_authenticator_enrollment.json") response, message, error_code, extras = self.auth_client.enroll_user_for_google_authenticator(USER_TWO["id"]) self.assertFalse(response) self.assertEqual("Factor already exists.", message) self.assertIsNotNone(error_code) def test_activation_success(self): self.setup_imposter("test_google_authenticator_activation.json") response, message, error_code = self.auth_client.activate_google_authenticator_factor(USER_ONE["id"], "12345") self.assertTrue(response) self.assertEqual("Success", message) self.assertIsNone(error_code) def test_activation_failure_one(self): self.setup_imposter("test_google_authenticator_activation.json") response, message, error_code = self.auth_client.activate_google_authenticator_factor(USER_TWO["id"], "1") self.assertFalse(response) self.assertEqual("Your passcode doesn't match our records. Please try again.", message) self.assertEqual("E0000068", error_code) def test_activation_failure_two(self): self.setup_imposter("test_google_authenticator_activation.json") response, message, error_code = self.auth_client.activate_google_authenticator_factor( USER_THREE["id"], "not-enrolled" ) self.assertFalse(response) self.assertEqual("Not enrolled in factor.", message) self.assertIsNotNone(error_code) def test_activation_failure_three(self): self.setup_imposter("test_google_authenticator_activation.json") response, message, error_code = self.auth_client.activate_google_authenticator_factor( USER_FOUR["id"], "not-found" ) self.assertFalse(response) self.assertEqual("Not found: Resource not found: invalid_id (User)", message) self.assertIsNotNone(error_code) def test_verify_challenge_success(self): self.setup_imposter("test_google_authenticator_challenge.json") response, message, error_code = self.auth_client.verify_google_authenticator_factor(USER_ONE["id"], "12345") self.assertTrue(response) self.assertEqual(response.get("factorResult"), "SUCCESS") self.assertEqual("Success", message) self.assertIsNone(error_code) def test_verify_challenge_failure_one(self): self.setup_imposter("test_google_authenticator_challenge.json") response, message, error_code = self.auth_client.verify_google_authenticator_factor( USER_ONE["id"], "invalid-passcode" ) self.assertFalse(response) self.assertEqual("Your passcode doesn't match our records. Please try again.", message) self.assertEqual("E0000068", error_code) def test_verify_challenge_two(self): self.setup_imposter("test_google_authenticator_challenge.json") response, message, error_code = self.auth_client.verify_google_authenticator_factor(USER_THREE["id"], "12345") self.assertFalse(response) self.assertEqual("Not enrolled in factor.", message) def test_verify_challenge_failure_three(self): self.setup_imposter("test_google_authenticator_challenge.json") response, message, error_code = self.auth_client.verify_google_authenticator_factor(USER_FOUR["id"], "12345") self.assertFalse(response) self.assertEqual("Not found: Resource not found: invalid_id (User)", message) def test_user_is_enrolled(self): self.setup_imposter("test_google_authenticator_challenge.json") is_enrolled = self.auth_client.is_user_enrolled_for_google_authenticator(USER_ONE["id"]) self.assertTrue(is_enrolled) def test_user_is_not_enrolled_in_pending_activation(self): self.setup_imposter("test_google_authenticator_challenge.json") is_enrolled = self.auth_client.is_user_enrolled_for_google_authenticator(USER_TWO["id"]) self.assertFalse(is_enrolled) def test_user_is_not_enrolled_different_factor(self): self.setup_imposter("test_google_authenticator_challenge.json") is_enrolled = self.auth_client.is_user_enrolled_for_google_authenticator(USER_THREE["id"]) self.assertFalse(is_enrolled) def test_user_is_not_enrolled_invalid_id(self): self.setup_imposter("test_google_authenticator_challenge.json") is_enrolled = self.auth_client.is_user_enrolled_for_google_authenticator("invalid_id") self.assertFalse(is_enrolled) def test_delete_factor(self): self.setup_imposter("test_google_authenticator_challenge.json") response, message, error_code = self.auth_client.delete_google_authenticator_factor(USER_ONE["id"]) self.assertEqual(message, "Success") self.assertIsNone(error_code)
class TestResponses(unittest.TestCase): def setUp(self): self.mb = MountebankProcess() def tearDown(self): self.mb.destroy_all_imposters() def test_no_response(self): """Ensure that API client handles no response from the server gracefully""" api_client = ApiClient(BASE_URL='http://example.com', API_TOKEN='dummy') # fake out the requests.get method requests.get = MagicMock(return_value=None) response, status_code = api_client.get('/') self.assertIsNone(response) self.assertIsNone(status_code) # fake out the requests.post method requests.post = MagicMock(return_value=None) response, status_code = api_client.post('/') self.assertIsNone(response) self.assertIsNone(status_code) # reload requests so that the methods are back to normal reload(requests) def test_non_json_response(self): """Ensure that the API client handles non-JSON responses gracefully""" imposter = self.mb.create_imposter('test_api_client/stubs/test_client_response.json') api_client = ApiClient(BASE_URL=self.mb.get_imposter_url(imposter), API_TOKEN='dummy') response, _ = api_client.get('/non-json') self.assertEqual('<html><body><h1>Testing!</h1></body></html>', response) response, _ = api_client.post('/non-json') self.assertEqual('<html><body><h1>Testing!</h1></body></html>', response) def test_check_api_response_no_causes(self): api_client = ApiClient() err_msg = { "errorSummary": "This is a short error message", "errorCauses": [] } try: api_client.check_api_response(err_msg, 400) raise AssertionError("check_api_response should have raised an exception and didn't.") except ApiException as err: self.assertIn(err_msg['errorSummary'], str(err)) def test_check_api_response_with_causes(self): api_client = ApiClient() err_msg = { "errorSummary": "This is a short error message", "errorCauses": [ { "errorSummary": "This is a more detailed error message" }, { "errorSummary": "This is a second error" } ] } try: api_client.check_api_response(err_msg, 400) raise AssertionError("check_api_response should have raised an exception and didn't.") except ApiException as err: self.assertIn(err_msg['errorCauses'][0]['errorSummary'], str(err)) def test_check_api_response_without_okta_error(self): """Ensure that an invalid response without an OKTA error gets handled properly""" api_client = ApiClient() try: api_client.check_api_response({}, 400) raise AssertionError("check_api_response should have raised an exception and didn't.") except ApiException as err: self.assertIn('Okta returned 400', str(err)) def test_check_status(self): imposter = self.mb.create_imposter('test_api_client/stubs/test_client_response.json') imposter_url = self.mb.get_imposter_url(imposter) api_client = ApiClient(BASE_URL=imposter_url) status = api_client.check_status() self.assertTrue(status['okta']['is_available']) self.assertEqual(1199, status['okta']['calls_remaining']) self.assertTrue(isinstance(status['okta']['time_of_reset'], datetime)) # this is the fail case status = api_client.check_status() self.assertFalse(status['okta']['is_available'])