예제 #1
0
파일: test_auth.py 프로젝트: sharwell/otter
    def setUp(self):
        """
        Shortcut by mocking all the helper functions that do IO.
        """
        self.authenticate_user = patch(self, 'otter.auth.authenticate_user')
        self.user_for_tenant = patch(self, 'otter.auth.user_for_tenant')
        self.impersonate_user = patch(self, 'otter.auth.impersonate_user')
        self.endpoints_for_token = patch(self,
                                         'otter.auth.endpoints_for_token')

        self.authenticate_user.return_value = succeed(
            {'access': {
                'token': {
                    'id': 'auth-token'
                }
            }})
        self.user_for_tenant.return_value = succeed('test_user')
        self.impersonate_user.return_value = succeed(
            {'access': {
                'token': {
                    'id': 'impersonation_token'
                }
            }})
        self.endpoints_for_token.return_value = succeed(
            {'endpoints': [{
                'name': 'anEndpoint',
                'type': 'anType'
            }]})

        self.url = 'http://identity/v2.0'
        self.admin_url = 'http://identity_admin/v2.0'
        self.user = '******'
        self.password = '******'
        self.ia = ImpersonatingAuthenticator(self.user, self.password,
                                             self.url, self.admin_url)
예제 #2
0
    def setUp(self):
        """
        Shortcut by mocking all the helper functions that do IO.
        """
        self.authenticate_user = patch(self, 'otter.auth.authenticate_user')
        self.user_for_tenant = patch(self, 'otter.auth.user_for_tenant')
        self.impersonate_user = patch(self, 'otter.auth.impersonate_user')
        self.endpoints_for_token = patch(self,
                                         'otter.auth.endpoints_for_token')

        self.authenticate_user.side_effect = lambda *a, **kw: succeed(
            {'access': {'token': {'id': 'auth-token'}}})
        self.user_for_tenant.side_effect = lambda *a, **kw: succeed('test_user')
        self.impersonate_user.side_effect = lambda *a, **kw: succeed(
            {'access': {'token': {'id': 'impersonation_token'}}})
        self.endpoints_for_token.side_effect = lambda *a, **kw: succeed(
            {'endpoints': [{'name': 'anEndpoint', 'type': 'anType'}]})

        self.url = 'http://identity/v2.0'
        self.admin_url = 'http://identity_admin/v2.0'
        self.user = '******'
        self.password = '******'
        self.ia = ImpersonatingAuthenticator(self.user, self.password,
                                             self.url, self.admin_url)
        self.log = mock.Mock()
예제 #3
0
def makeService(config):
    """
    Set up the otter-api service.
    """
    set_config_data(dict(config))

    if not config_value('mock'):
        seed_endpoints = [
            clientFromString(reactor, str(host))
            for host in config_value('cassandra.seed_hosts')
        ]

        cassandra_cluster = LoggingCQLClient(
            RoundRobinCassandraCluster(seed_endpoints,
                                       config_value('cassandra.keyspace')),
            log.bind(system='otter.silverberg'))

        set_store(CassScalingGroupCollection(cassandra_cluster))

    bobby_url = config_value('bobby_url')
    if bobby_url is not None:
        set_bobby(BobbyClient(bobby_url))

    cache_ttl = config_value('identity.cache_ttl')

    if cache_ttl is None:
        # FIXME: Pick an arbitrary cache ttl value based on absolutely no
        # science.
        cache_ttl = 300

    authenticator = CachingAuthenticator(
        reactor,
        ImpersonatingAuthenticator(config_value('identity.username'),
                                   config_value('identity.password'),
                                   config_value('identity.url'),
                                   config_value('identity.admin_url')),
        cache_ttl)

    supervisor = Supervisor(authenticator.authenticate_tenant, coiterate)

    set_supervisor(supervisor)

    s = MultiService()

    site = Site(root)
    site.displayTracebacks = False

    api_service = service(str(config_value('port')), site)
    api_service.setServiceParent(s)

    if config_value('scheduler') and not config_value('mock'):
        scheduler_service = SchedulerService(
            int(config_value('scheduler.batchsize')),
            int(config_value('scheduler.interval')), cassandra_cluster)
        scheduler_service.setServiceParent(s)

    return s
예제 #4
0
파일: test_auth.py 프로젝트: thudoan/otter
class ImpersonatingAuthenticatorTests(TestCase):
    """
    Tests for the end-to-end impersonation workflow.
    """
    def setUp(self):
        """
        Shortcut by mocking all the helper functions that do IO.
        """
        self.authenticate_user = patch(self, 'otter.auth.authenticate_user')
        self.user_for_tenant = patch(self, 'otter.auth.user_for_tenant')
        self.impersonate_user = patch(self, 'otter.auth.impersonate_user')
        self.endpoints_for_token = patch(self,
                                         'otter.auth.endpoints_for_token')

        self.authenticate_user.return_value = succeed(
            {'access': {'token': {'id': 'auth-token'}}})
        self.user_for_tenant.return_value = succeed('test_user')
        self.impersonate_user.return_value = succeed(
            {'access': {'token': {'id': 'impersonation_token'}}})
        self.endpoints_for_token.return_value = succeed(
            {'endpoints': [{'name': 'anEndpoint', 'type': 'anType'}]})

        self.url = 'http://identity/v2.0'
        self.admin_url = 'http://identity_admin/v2.0'
        self.user = '******'
        self.password = '******'
        self.ia = ImpersonatingAuthenticator(self.user, self.password,
                                             self.url, self.admin_url)

    def test_authenticate_tenant_auth_as_service_user(self):
        """
        authenticate_tenant authenticates as the service user.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))

        self.authenticate_user.assert_called_once_with(self.url, self.user,
                                                       self.password)

    def test_authenticate_tenant_gets_user_for_specified_tenant(self):
        """
        authenticate_tenant gets user for the specified tenant from the admin
        endpoint.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))

        self.user_for_tenant.assert_called_once_with(self.admin_url, self.user,
                                                     self.password, 111111)

    def test_authenticate_tenant_impersonates_first_user(self):
        """
        authenticate_tenant impersonates the first user from the list of
        users for the tenant using the admin endpoint.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))

        self.impersonate_user.assert_called_once_with(self.admin_url,
                                                      'auth-token',
                                                      'test_user')

    def test_authenticate_tenant_gets_endpoints_for_the_impersonation_token(self):
        """
        authenticate_tenant fetches all the endpoints for the impersonation
        token.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))

        self.endpoints_for_token.assert_called_once_with(
            self.admin_url, 'auth-token', 'impersonation_token')

    def test_authenticate_tenant_returns_impersonation_token_and_endpoint_list(self):
        """
        authenticate_tenant returns the impersonation token and the endpoint
        list.
        """
        result = self.successResultOf(self.ia.authenticate_tenant(1111111))

        self.assertEqual(result[0], 'impersonation_token')
        self.assertEqual(result[1],
                         [{'name': 'anEndpoint',
                           'type': 'anType',
                           'endpoints': [
                               {'name': 'anEndpoint', 'type': 'anType'}]}])

    def test_authenticate_tenant_propagates_auth_errors(self):
        """
        authenticate_tenant propagates errors from authenticate_user.
        """
        self.authenticate_user.return_value = fail(APIError(500, '500'))

        failure = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertTrue(failure.check(APIError))

    def test_authenticate_tenant_propagates_user_list_errors(self):
        """
        authenticate_tenant propagates errors from user_for_tenant
        """
        self.user_for_tenant.return_value = fail(APIError(500, '500'))

        failure = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertTrue(failure.check(APIError))

    def test_authenticate_tenant_propagates_impersonation_errors(self):
        """
        authenticate_tenant propagates errors from impersonate_user
        """
        self.impersonate_user.return_value = fail(APIError(500, '500'))

        failure = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertTrue(failure.check(APIError))

    def test_authenticate_tenant_propagates_endpoint_list_errors(self):
        """
        authenticate_tenant propagates errors from endpoints_for_token
        """
        self.endpoints_for_token.return_value = fail(APIError(500, '500'))

        failure = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertTrue(failure.check(APIError))
예제 #5
0
class ImpersonatingAuthenticatorTests(SynchronousTestCase):
    """
    Tests for the end-to-end impersonation workflow.
    """
    def setUp(self):
        """
        Shortcut by mocking all the helper functions that do IO.
        """
        self.authenticate_user = patch(self, 'otter.auth.authenticate_user')
        self.user_for_tenant = patch(self, 'otter.auth.user_for_tenant')
        self.impersonate_user = patch(self, 'otter.auth.impersonate_user')
        self.endpoints_for_token = patch(self,
                                         'otter.auth.endpoints_for_token')

        self.authenticate_user.side_effect = lambda *a, **kw: succeed(
            {'access': {'token': {'id': 'auth-token'}}})
        self.user_for_tenant.side_effect = lambda *a, **kw: succeed('test_user')
        self.impersonate_user.side_effect = lambda *a, **kw: succeed(
            {'access': {'token': {'id': 'impersonation_token'}}})
        self.endpoints_for_token.side_effect = lambda *a, **kw: succeed(
            {'endpoints': [{'name': 'anEndpoint', 'type': 'anType'}]})

        self.url = 'http://identity/v2.0'
        self.admin_url = 'http://identity_admin/v2.0'
        self.user = '******'
        self.password = '******'
        self.ia = ImpersonatingAuthenticator(self.user, self.password,
                                             self.url, self.admin_url)
        self.log = mock.Mock()

    def test_verifyObject(self):
        """
        ImpersonatingAuthenticator provides the IAuthenticator interface.
        """
        verifyObject(IAuthenticator, self.ia)

    def test_auth_me_auth_as_service_user(self):
        """
        _auth_me authenticates as the service user.
        """
        self.successResultOf(self.ia._auth_me(None))
        self.authenticate_user.assert_called_once_with(self.url, self.user,
                                                       self.password,
                                                       log=None)
        self.assertEqual(self.ia._token, 'auth-token')
        self.assertFalse(self.log.msg.called)

        self.authenticate_user.reset_mock()

        self.successResultOf(self.ia._auth_me(self.log))
        self.authenticate_user.assert_called_once_with(self.url, self.user,
                                                       self.password,
                                                       log=self.log)
        self.log.msg.assert_called_once_with('Getting new identity admin token')
        self.assertEqual(self.ia._token, 'auth-token')

    def test_auth_me_waits(self):
        """
        _auth_me is called only once if it is called again while its previous call
        has not returned
        """
        aud = Deferred()
        self.authenticate_user.side_effect = lambda *a, **k: aud

        log = mock_log()

        self.ia._auth_me(log=log)
        self.ia._auth_me(log=log)
        self.assertEqual(len(self.authenticate_user.mock_calls), 1)
        log.msg.assert_called_once_with('Getting new identity admin token')

        aud.callback({'access': {'token': {'id': 'auth-token'}}})
        self.assertEqual(len(self.authenticate_user.mock_calls), 1)
        self.assertEqual(self.ia._token, 'auth-token')

    def test_authenticate_tenant_gets_user_for_specified_tenant(self):
        """
        authenticate_tenant gets user for the specified tenant from the admin
        endpoint.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))
        self.user_for_tenant.assert_called_once_with(self.admin_url, self.user,
                                                     self.password, 111111,
                                                     log=None)

        self.user_for_tenant.reset_mock()

        self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log))

        self.user_for_tenant.assert_called_once_with(self.admin_url, self.user,
                                                     self.password, 111111,
                                                     log=self.log)

    def test_authenticate_tenant_impersonates_first_user(self):
        """
        authenticate_tenant impersonates the first user from the list of
        users for the tenant using the admin endpoint.
        """
        self.ia._token = 'auth-token'
        self.successResultOf(self.ia.authenticate_tenant(111111))
        self.impersonate_user.assert_called_once_with(self.admin_url,
                                                      'auth-token',
                                                      'test_user', log=None)

        self.impersonate_user.reset_mock()

        self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log))
        self.impersonate_user.assert_called_once_with(self.admin_url,
                                                      'auth-token',
                                                      'test_user', log=self.log)

    def test_authenticate_tenant_retries_impersonates_first_user(self):
        """
        authenticate_tenant impersonates again with new auth if initial impersonation
        fails with 401
        """
        self.impersonate_user.side_effect = [
            fail(UpstreamError(Failure(APIError(401, '')), 'identity', 'o')),
            succeed({'access': {'token': {'id': 'impersonation_token'}}})]
        self.successResultOf(self.ia.authenticate_tenant(111111, self.log))
        self.impersonate_user.assert_has_calls(
            [mock.call(self.admin_url, None, 'test_user', log=self.log),
             mock.call(self.admin_url, 'auth-token', 'test_user', log=self.log)])
        self.authenticate_user.assert_called_once_with(self.url, self.user,
                                                       self.password,
                                                       log=self.log)
        self.log.msg.assert_called_once_with('Getting new identity admin token')

    def test_authenticate_tenant_gets_endpoints_for_the_impersonation_token(self):
        """
        authenticate_tenant fetches all the endpoints for the impersonation with
        cached token.
        """
        self.ia._token = 'auth-token'
        self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log))
        self.endpoints_for_token.assert_called_once_with(
            self.admin_url, 'auth-token', 'impersonation_token', log=self.log)

    def test_authenticate_tenant_retries_getting_endpoints_for_the_impersonation_token(self):
        """
        authenticate_tenant fetches all the endpoints for the impersonation and
        retries with new authentication token if it gets 401
        """
        self.endpoints_for_token.side_effect = [
            fail(UpstreamError(Failure(APIError(401, '')), 'identity', 'o')),
            succeed({'endpoints': [{'name': 'anEndpoint', 'type': 'anType'}]})]
        self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log))
        self.endpoints_for_token.assert_has_calls(
            [mock.call(self.admin_url, None, 'impersonation_token', log=self.log),
             mock.call(self.admin_url, 'auth-token', 'impersonation_token', log=self.log)])
        self.authenticate_user.assert_called_once_with(self.url, self.user,
                                                       self.password,
                                                       log=self.log)
        self.log.msg.assert_called_once_with('Getting new identity admin token')

    def test_authenticate_tenant_returns_impersonation_token_and_endpoint_list(self):
        """
        authenticate_tenant returns the impersonation token and the endpoint
        list.
        """
        result = self.successResultOf(self.ia.authenticate_tenant(1111111))

        self.assertEqual(result[0], 'impersonation_token')
        self.assertEqual(result[1],
                         [{'name': 'anEndpoint',
                           'type': 'anType',
                           'endpoints': [
                               {'name': 'anEndpoint', 'type': 'anType'}]}])

    def test_authenticate_tenant_propagates_auth_errors(self):
        """
        authenticate_tenant propagates errors from authenticate_user.
        """
        self.impersonate_user.side_effect = lambda *a, **k: fail(
            UpstreamError(Failure(APIError(401, '4')), 'identity', 'o'))
        self.authenticate_user.side_effect = lambda *a, **kw: fail(
            UpstreamError(Failure(APIError(500, '500')), 'identity', 'o'))

        f = self.failureResultOf(self.ia.authenticate_tenant(111111), UpstreamError)
        self.assertEqual(f.value.reason.value.code, 500)

    def test_authenticate_tenant_propagates_user_list_errors(self):
        """
        authenticate_tenant propagates errors from user_for_tenant
        """
        self.user_for_tenant.side_effect = lambda *a, **kw: fail(
            UpstreamError(Failure(APIError(500, '500')), 'identity', 'o'))

        f = self.failureResultOf(self.ia.authenticate_tenant(111111), UpstreamError)
        self.assertEqual(f.value.reason.value.code, 500)

    def test_authenticate_tenant_propagates_impersonation_errors(self):
        """
        authenticate_tenant propagates errors from impersonate_user
        """
        self.impersonate_user.side_effect = lambda *a, **kw: fail(
            UpstreamError(Failure(APIError(500, '500')), 'identity', 'o'))

        f = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertEqual(f.value.reason.value.code, 500)

    def test_authenticate_tenant_propagates_endpoint_list_errors(self):
        """
        authenticate_tenant propagates errors from endpoints_for_token
        """
        self.endpoints_for_token.side_effect = lambda *a, **kw: fail(
            UpstreamError(Failure(APIError(500, '500')), 'identity', 'o'))

        f = self.failureResultOf(self.ia.authenticate_tenant(111111), UpstreamError)
        self.assertEqual(f.value.reason.value.code, 500)
예제 #6
0
파일: test_auth.py 프로젝트: sharwell/otter
class ImpersonatingAuthenticatorTests(TestCase):
    """
    Tests for the end-to-end impersonation workflow.
    """
    def setUp(self):
        """
        Shortcut by mocking all the helper functions that do IO.
        """
        self.authenticate_user = patch(self, 'otter.auth.authenticate_user')
        self.user_for_tenant = patch(self, 'otter.auth.user_for_tenant')
        self.impersonate_user = patch(self, 'otter.auth.impersonate_user')
        self.endpoints_for_token = patch(self,
                                         'otter.auth.endpoints_for_token')

        self.authenticate_user.return_value = succeed(
            {'access': {
                'token': {
                    'id': 'auth-token'
                }
            }})
        self.user_for_tenant.return_value = succeed('test_user')
        self.impersonate_user.return_value = succeed(
            {'access': {
                'token': {
                    'id': 'impersonation_token'
                }
            }})
        self.endpoints_for_token.return_value = succeed(
            {'endpoints': [{
                'name': 'anEndpoint',
                'type': 'anType'
            }]})

        self.url = 'http://identity/v2.0'
        self.admin_url = 'http://identity_admin/v2.0'
        self.user = '******'
        self.password = '******'
        self.ia = ImpersonatingAuthenticator(self.user, self.password,
                                             self.url, self.admin_url)

    def test_verifyObject(self):
        """
        ImpersonatingAuthenticator provides the IAuthenticator interface.
        """
        verifyObject(IAuthenticator, self.ia)

    def test_authenticate_tenant_auth_as_service_user(self):
        """
        authenticate_tenant authenticates as the service user.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))

        self.authenticate_user.assert_called_once_with(self.url, self.user,
                                                       self.password)

    def test_authenticate_tenant_gets_user_for_specified_tenant(self):
        """
        authenticate_tenant gets user for the specified tenant from the admin
        endpoint.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))

        self.user_for_tenant.assert_called_once_with(self.admin_url, self.user,
                                                     self.password, 111111)

    def test_authenticate_tenant_impersonates_first_user(self):
        """
        authenticate_tenant impersonates the first user from the list of
        users for the tenant using the admin endpoint.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))

        self.impersonate_user.assert_called_once_with(self.admin_url,
                                                      'auth-token',
                                                      'test_user')

    def test_authenticate_tenant_gets_endpoints_for_the_impersonation_token(
            self):
        """
        authenticate_tenant fetches all the endpoints for the impersonation
        token.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))

        self.endpoints_for_token.assert_called_once_with(
            self.admin_url, 'auth-token', 'impersonation_token')

    def test_authenticate_tenant_returns_impersonation_token_and_endpoint_list(
            self):
        """
        authenticate_tenant returns the impersonation token and the endpoint
        list.
        """
        result = self.successResultOf(self.ia.authenticate_tenant(1111111))

        self.assertEqual(result[0], 'impersonation_token')
        self.assertEqual(
            result[1], [{
                'name': 'anEndpoint',
                'type': 'anType',
                'endpoints': [{
                    'name': 'anEndpoint',
                    'type': 'anType'
                }]
            }])

    def test_authenticate_tenant_propagates_auth_errors(self):
        """
        authenticate_tenant propagates errors from authenticate_user.
        """
        self.authenticate_user.return_value = fail(APIError(500, '500'))

        failure = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertTrue(failure.check(APIError))

    def test_authenticate_tenant_propagates_user_list_errors(self):
        """
        authenticate_tenant propagates errors from user_for_tenant
        """
        self.user_for_tenant.return_value = fail(APIError(500, '500'))

        failure = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertTrue(failure.check(APIError))

    def test_authenticate_tenant_propagates_impersonation_errors(self):
        """
        authenticate_tenant propagates errors from impersonate_user
        """
        self.impersonate_user.return_value = fail(APIError(500, '500'))

        failure = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertTrue(failure.check(APIError))

    def test_authenticate_tenant_propagates_endpoint_list_errors(self):
        """
        authenticate_tenant propagates errors from endpoints_for_token
        """
        self.endpoints_for_token.return_value = fail(APIError(500, '500'))

        failure = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertTrue(failure.check(APIError))
예제 #7
0
class ImpersonatingAuthenticatorTests(SynchronousTestCase):
    """
    Tests for the end-to-end impersonation workflow.
    """
    def setUp(self):
        """
        Shortcut by mocking all the helper functions that do IO.
        """
        self.authenticate_user = patch(self, 'otter.auth.authenticate_user')
        self.user_for_tenant = patch(self, 'otter.auth.user_for_tenant')
        self.impersonate_user = patch(self, 'otter.auth.impersonate_user')
        self.endpoints_for_token = patch(self,
                                         'otter.auth.endpoints_for_token')

        self.authenticate_user.side_effect = lambda *a, **kw: succeed(
            {'access': {
                'token': {
                    'id': 'auth-token'
                }
            }})
        self.user_for_tenant.side_effect = lambda *a, **kw: succeed('test_user'
                                                                    )
        self.impersonate_user.side_effect = lambda *a, **kw: succeed(
            {'access': {
                'token': {
                    'id': 'impersonation_token'
                }
            }})
        self.endpoints_for_token.side_effect = lambda *a, **kw: succeed(
            {'endpoints': [{
                'name': 'anEndpoint',
                'type': 'anType'
            }]})

        self.url = 'http://identity/v2.0'
        self.admin_url = 'http://identity_admin/v2.0'
        self.user = '******'
        self.password = '******'
        self.ia = ImpersonatingAuthenticator(self.user, self.password,
                                             self.url, self.admin_url)
        self.log = mock.Mock()

    def test_verifyObject(self):
        """
        ImpersonatingAuthenticator provides the IAuthenticator interface.
        """
        verifyObject(IAuthenticator, self.ia)

    def test_auth_me_auth_as_service_user(self):
        """
        _auth_me authenticates as the service user.
        """
        self.successResultOf(self.ia._auth_me(None))
        self.authenticate_user.assert_called_once_with(self.url,
                                                       self.user,
                                                       self.password,
                                                       log=None)
        self.assertEqual(self.ia._token, 'auth-token')
        self.assertFalse(self.log.msg.called)

        self.authenticate_user.reset_mock()

        self.successResultOf(self.ia._auth_me(self.log))
        self.authenticate_user.assert_called_once_with(self.url,
                                                       self.user,
                                                       self.password,
                                                       log=self.log)
        self.log.msg.assert_called_once_with(
            'Getting new identity admin token')
        self.assertEqual(self.ia._token, 'auth-token')

    def test_auth_me_waits(self):
        """
        _auth_me is called only once if it is called again while its previous call
        has not returned
        """
        aud = Deferred()
        self.authenticate_user.side_effect = lambda *a, **k: aud

        log = mock_log()

        self.ia._auth_me(log=log)
        self.ia._auth_me(log=log)
        self.assertEqual(len(self.authenticate_user.mock_calls), 1)
        log.msg.assert_called_once_with('Getting new identity admin token')

        aud.callback({'access': {'token': {'id': 'auth-token'}}})
        self.assertEqual(len(self.authenticate_user.mock_calls), 1)
        self.assertEqual(self.ia._token, 'auth-token')

    def test_authenticate_tenant_gets_user_for_specified_tenant(self):
        """
        authenticate_tenant gets user for the specified tenant from the admin
        endpoint.
        """
        self.successResultOf(self.ia.authenticate_tenant(111111))
        self.user_for_tenant.assert_called_once_with(self.admin_url,
                                                     self.user,
                                                     self.password,
                                                     111111,
                                                     log=None)

        self.user_for_tenant.reset_mock()

        self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log))

        self.user_for_tenant.assert_called_once_with(self.admin_url,
                                                     self.user,
                                                     self.password,
                                                     111111,
                                                     log=self.log)

    def test_authenticate_tenant_impersonates_first_user(self):
        """
        authenticate_tenant impersonates the first user from the list of
        users for the tenant using the admin endpoint.
        """
        self.ia._token = 'auth-token'
        self.successResultOf(self.ia.authenticate_tenant(111111))
        self.impersonate_user.assert_called_once_with(self.admin_url,
                                                      'auth-token',
                                                      'test_user',
                                                      log=None)

        self.impersonate_user.reset_mock()

        self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log))
        self.impersonate_user.assert_called_once_with(self.admin_url,
                                                      'auth-token',
                                                      'test_user',
                                                      log=self.log)

    def test_authenticate_tenant_retries_impersonates_first_user(self):
        """
        authenticate_tenant impersonates again with new auth if initial impersonation
        fails with 401
        """
        self.impersonate_user.side_effect = [
            fail(UpstreamError(Failure(APIError(401, '')), 'identity', 'o')),
            succeed({'access': {
                'token': {
                    'id': 'impersonation_token'
                }
            }})
        ]
        self.successResultOf(self.ia.authenticate_tenant(111111, self.log))
        self.impersonate_user.assert_has_calls([
            mock.call(self.admin_url, None, 'test_user', log=self.log),
            mock.call(self.admin_url, 'auth-token', 'test_user', log=self.log)
        ])
        self.authenticate_user.assert_called_once_with(self.url,
                                                       self.user,
                                                       self.password,
                                                       log=self.log)
        self.log.msg.assert_called_once_with(
            'Getting new identity admin token')

    def test_authenticate_tenant_gets_endpoints_for_the_impersonation_token(
            self):
        """
        authenticate_tenant fetches all the endpoints for the impersonation with
        cached token.
        """
        self.ia._token = 'auth-token'
        self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log))
        self.endpoints_for_token.assert_called_once_with(self.admin_url,
                                                         'auth-token',
                                                         'impersonation_token',
                                                         log=self.log)

    def test_authenticate_tenant_retries_getting_endpoints_for_the_impersonation_token(
            self):
        """
        authenticate_tenant fetches all the endpoints for the impersonation and
        retries with new authentication token if it gets 401
        """
        self.endpoints_for_token.side_effect = [
            fail(UpstreamError(Failure(APIError(401, '')), 'identity', 'o')),
            succeed({'endpoints': [{
                'name': 'anEndpoint',
                'type': 'anType'
            }]})
        ]
        self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log))
        self.endpoints_for_token.assert_has_calls([
            mock.call(self.admin_url,
                      None,
                      'impersonation_token',
                      log=self.log),
            mock.call(self.admin_url,
                      'auth-token',
                      'impersonation_token',
                      log=self.log)
        ])
        self.authenticate_user.assert_called_once_with(self.url,
                                                       self.user,
                                                       self.password,
                                                       log=self.log)
        self.log.msg.assert_called_once_with(
            'Getting new identity admin token')

    def test_authenticate_tenant_returns_impersonation_token_and_endpoint_list(
            self):
        """
        authenticate_tenant returns the impersonation token and the endpoint
        list.
        """
        result = self.successResultOf(self.ia.authenticate_tenant(1111111))

        self.assertEqual(result[0], 'impersonation_token')
        self.assertEqual(
            result[1], [{
                'name': 'anEndpoint',
                'type': 'anType',
                'endpoints': [{
                    'name': 'anEndpoint',
                    'type': 'anType'
                }]
            }])

    def test_authenticate_tenant_propagates_auth_errors(self):
        """
        authenticate_tenant propagates errors from authenticate_user.
        """
        self.impersonate_user.side_effect = lambda *a, **k: fail(
            UpstreamError(Failure(APIError(401, '4')), 'identity', 'o'))
        self.authenticate_user.side_effect = lambda *a, **kw: fail(
            UpstreamError(Failure(APIError(500, '500')), 'identity', 'o'))

        f = self.failureResultOf(self.ia.authenticate_tenant(111111),
                                 UpstreamError)
        self.assertEqual(f.value.reason.value.code, 500)

    def test_authenticate_tenant_propagates_user_list_errors(self):
        """
        authenticate_tenant propagates errors from user_for_tenant
        """
        self.user_for_tenant.side_effect = lambda *a, **kw: fail(
            UpstreamError(Failure(APIError(500, '500')), 'identity', 'o'))

        f = self.failureResultOf(self.ia.authenticate_tenant(111111),
                                 UpstreamError)
        self.assertEqual(f.value.reason.value.code, 500)

    def test_authenticate_tenant_propagates_impersonation_errors(self):
        """
        authenticate_tenant propagates errors from impersonate_user
        """
        self.impersonate_user.side_effect = lambda *a, **kw: fail(
            UpstreamError(Failure(APIError(500, '500')), 'identity', 'o'))

        f = self.failureResultOf(self.ia.authenticate_tenant(111111))
        self.assertEqual(f.value.reason.value.code, 500)

    def test_authenticate_tenant_propagates_endpoint_list_errors(self):
        """
        authenticate_tenant propagates errors from endpoints_for_token
        """
        self.endpoints_for_token.side_effect = lambda *a, **kw: fail(
            UpstreamError(Failure(APIError(500, '500')), 'identity', 'o'))

        f = self.failureResultOf(self.ia.authenticate_tenant(111111),
                                 UpstreamError)
        self.assertEqual(f.value.reason.value.code, 500)