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)
Example #3
0
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()
Example #5
0
 def setUp(self):
     self.mb = MountebankProcess()
     api_client = ApiClient()
     self.broker = UserBroker(api_client)
Example #6
0
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'])
 def setUp(self):
     self.mb = MountebankProcess()
 def setUp(self):
     self.api_client = ApiClient()
     self.auth_client = OktaAuthClient(OktaFactors(self.api_client))
     self.mb = MountebankProcess()
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)
Example #12
0
 def setUp(self):
     self.api_client = ApiClient(API_TOKEN='jrr-tolkien')
     self.auth_client = OktaAuthClient(OktaFactors(self.api_client))
     self.mb = MountebankProcess()
Example #13
0
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)
Example #14
0
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)
Example #16
0
 def setUp(self):
     self.mb = MountebankProcess()
     api_client = ApiClient()
     self.broker = UserBroker(api_client)
Example #17
0
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'])