def test_basic_authentication(self): tuples = [ ('1.0', OpenStackMockHttp), ('1.1', OpenStackMockHttp), ('2.0', OpenStack_2_0_MockHttp), ('2.0_apikey', OpenStack_2_0_MockHttp), ('2.0_password', OpenStack_2_0_MockHttp) ] user_id = OPENSTACK_PARAMS[0] key = OPENSTACK_PARAMS[1] for (auth_version, mock_http_class) in tuples: connection = \ self._get_mock_connection(mock_http_class=mock_http_class) auth_url = connection.auth_url cls = get_class_for_auth_version(auth_version=auth_version) osa = cls(auth_url=auth_url, user_id=user_id, key=key, parent_conn=connection) self.assertEqual(osa.urls, {}) self.assertEqual(osa.auth_token, None) self.assertEqual(osa.auth_user_info, None) osa = osa.authenticate() self.assertTrue(len(osa.urls) >= 1) self.assertTrue(osa.auth_token is not None) if auth_version in ['1.1', '2.0', '2.0_apikey', '2.0_password']: self.assertTrue(osa.auth_token_expires is not None) if auth_version in ['2.0', '2.0_apikey', '2.0_password']: self.assertTrue(osa.auth_user_info is not None)
def test_basic_authentication(self): tuples = [('1.0', OpenStackMockHttp), ('1.1', OpenStackMockHttp), ('2.0', OpenStack_2_0_MockHttp), ('2.0_apikey', OpenStack_2_0_MockHttp), ('2.0_password', OpenStack_2_0_MockHttp)] user_id = OPENSTACK_PARAMS[0] key = OPENSTACK_PARAMS[1] for (auth_version, mock_http_class) in tuples: connection = \ self._get_mock_connection(mock_http_class=mock_http_class) auth_url = connection.auth_url cls = get_class_for_auth_version(auth_version=auth_version) osa = cls(auth_url=auth_url, user_id=user_id, key=key, parent_conn=connection) self.assertEqual(osa.urls, {}) self.assertEqual(osa.auth_token, None) self.assertEqual(osa.auth_user_info, None) osa = osa.authenticate() self.assertTrue(len(osa.urls) >= 1) self.assertTrue(osa.auth_token is not None) if auth_version in ['1.1', '2.0', '2.0_apikey', '2.0_password']: self.assertTrue(osa.auth_token_expires is not None) if auth_version in ['2.0', '2.0_apikey', '2.0_password']: self.assertTrue(osa.auth_user_info is not None)
def get_auth_class(self): """ Retrieve identity / authentication class instance. :rtype: :class:`OpenStackIdentityConnection` """ if not self._osa: auth_url = self._get_auth_url() cls = get_class_for_auth_version(auth_version=self._auth_version) self._osa = cls( auth_url=auth_url, user_id=self.user_id, key=self.key, tenant_name=self._ex_tenant_name, tenant_domain_id=self._ex_tenant_domain_id, domain_name=self._ex_domain_name, token_scope=self._ex_token_scope, timeout=self.timeout, proxy_url=self.proxy_url, parent_conn=self, auth_cache=self._ex_auth_cache, ) return self._osa
def test_auth_url_is_correctly_assembled(self): tuples = [ ('1.0', OpenStackMockHttp, {}), ('1.1', OpenStackMockHttp, {}), ('2.0', OpenStack_2_0_MockHttp, {}), ('2.0_apikey', OpenStack_2_0_MockHttp, {}), ('2.0_password', OpenStack_2_0_MockHttp, {}), ('3.x_password', OpenStackIdentity_3_0_MockHttp, {'tenant_name': 'tenant-name'}), ('3.x_appcred', OpenStackIdentity_3_0_MockHttp, {}), ('3.x_oidc_access_token', OpenStackIdentity_3_0_MockHttp, {'tenant_name': 'tenant-name'}) ] APPEND = 0 NOTAPPEND = 1 auth_urls = [ ('https://auth.api.example.com', APPEND, ''), ('https://auth.api.example.com/', NOTAPPEND, '/'), ('https://auth.api.example.com/foo/bar', NOTAPPEND, '/foo/bar'), ('https://auth.api.example.com/foo/bar/', NOTAPPEND, '/foo/bar/') ] actions = { '1.0': '/v1.0', '1.1': '/v1.1/auth', '2.0': '/v2.0/tokens', '2.0_apikey': '/v2.0/tokens', '2.0_password': '******', '3.x_password': '******', '3.x_appcred': '/v3/auth/tokens', '3.x_oidc_access_token': '/v3/OS-FEDERATION/identity_providers/user_name/protocols/tenant-name/auth', } user_id = OPENSTACK_PARAMS[0] key = OPENSTACK_PARAMS[1] for (auth_version, mock_http_class, kwargs) in tuples: for (url, should_append_default_path, expected_path) in auth_urls: connection = \ self._get_mock_connection(mock_http_class=mock_http_class, auth_url=url) auth_url = connection.auth_url cls = get_class_for_auth_version(auth_version=auth_version) osa = cls(auth_url=auth_url, user_id=user_id, key=key, parent_conn=connection, **kwargs) try: osa = osa.authenticate() except Exception: pass if (should_append_default_path == APPEND): expected_path = actions[auth_version] self.assertEqual(osa.action, expected_path)
def test_basic_authentication(self): tuples = [('1.0', OpenStackMockHttp, {}), ('1.1', OpenStackMockHttp, {}), ('2.0', OpenStack_2_0_MockHttp, {}), ('2.0_apikey', OpenStack_2_0_MockHttp, {}), ('2.0_password', OpenStack_2_0_MockHttp, {}), ('3.x_password', OpenStackIdentity_3_0_MockHttp, { 'user_id': 'test_user_id', 'key': 'test_key', 'token_scope': 'project', 'tenant_name': 'test_tenant', 'tenant_domain_id': 'test_tenant_domain_id', 'domain_name': 'test_domain' }), ('3.x_oidc_access_token', OpenStackIdentity_3_0_MockHttp, { 'user_id': 'test_user_id', 'key': 'test_key', 'token_scope': 'domain', 'tenant_name': 'test_tenant', 'tenant_domain_id': 'test_tenant_domain_id', 'domain_name': 'test_domain' })] user_id = OPENSTACK_PARAMS[0] key = OPENSTACK_PARAMS[1] for (auth_version, mock_http_class, kwargs) in tuples: connection = \ self._get_mock_connection(mock_http_class=mock_http_class) auth_url = connection.auth_url if not kwargs: kwargs['user_id'] = user_id kwargs['key'] = key cls = get_class_for_auth_version(auth_version=auth_version) osa = cls(auth_url=auth_url, parent_conn=connection, **kwargs) self.assertEqual(osa.urls, {}) self.assertIsNone(osa.auth_token) self.assertIsNone(osa.auth_user_info) osa = osa.authenticate() self.assertTrue(len(osa.urls) >= 1) self.assertTrue(osa.auth_token is not None) if auth_version in [ '1.1', '2.0', '2.0_apikey', '2.0_password', '3.x_password', '3.x_oidc_access_token' ]: self.assertTrue(osa.auth_token_expires is not None) if auth_version in [ '2.0', '2.0_apikey', '2.0_password', '3.x_password', '3.x_oidc_access_token' ]: self.assertTrue(osa.auth_user_info is not None)
def test_auth_url_is_correctly_assembled(self): tuples = [ ('1.0', OpenStackMockHttp), ('1.1', OpenStackMockHttp), ('2.0', OpenStack_2_0_MockHttp), ('2.0_apikey', OpenStack_2_0_MockHttp), ('2.0_password', OpenStack_2_0_MockHttp) ] APPEND = 0 NOTAPPEND = 1 auth_urls = [ ('https://auth.api.example.com', APPEND, ''), ('https://auth.api.example.com/', NOTAPPEND, '/'), ('https://auth.api.example.com/foo/bar', NOTAPPEND, '/foo/bar'), ('https://auth.api.example.com/foo/bar/', NOTAPPEND, '/foo/bar/') ] actions = { '1.0': '/v1.0', '1.1': '/v1.1/auth', '2.0': '/v2.0/tokens', '2.0_apikey': '/v2.0/tokens', '2.0_password': '******' } user_id = OPENSTACK_PARAMS[0] key = OPENSTACK_PARAMS[1] for (auth_version, mock_http_class) in tuples: for (url, should_append_default_path, expected_path) in auth_urls: connection = \ self._get_mock_connection(mock_http_class=mock_http_class, auth_url=url) auth_url = connection.auth_url cls = get_class_for_auth_version(auth_version=auth_version) osa = cls(auth_url=auth_url, user_id=user_id, key=key, parent_conn=connection) try: osa = osa.authenticate() except: pass if (should_append_default_path == APPEND): expected_path = actions[auth_version] self.assertEqual(osa.action, expected_path)
def get_auth_class(self): """ Retrieve identity / authentication class instance. :rtype: :class:`OpenStackIdentityConnection` """ if not self._osa: auth_url = self._get_auth_url() cls = get_class_for_auth_version(auth_version=self._auth_version) self._osa = cls(auth_url=auth_url, user_id=self.user_id, key=self.key, tenant_name=self._ex_tenant_name, timeout=self.timeout, parent_conn=self) return self._osa
def test_auth_url_is_correctly_assembled(self): tuples = [ ("1.0", OpenStackMockHttp, {}), ("1.1", OpenStackMockHttp, {}), ("2.0", OpenStack_2_0_MockHttp, {}), ("2.0_apikey", OpenStack_2_0_MockHttp, {}), ("2.0_password", OpenStack_2_0_MockHttp, {}), ( "3.x_password", OpenStackIdentity_3_0_MockHttp, {"tenant_name": "tenant-name"}, ), ("3.x_appcred", OpenStackIdentity_3_0_MockHttp, {}), ( "3.x_oidc_access_token", OpenStackIdentity_3_0_MockHttp, {"tenant_name": "tenant-name"}, ), ] APPEND = 0 NOTAPPEND = 1 auth_urls = [ ("https://auth.api.example.com", APPEND, ""), ("https://auth.api.example.com/", NOTAPPEND, "/"), ("https://auth.api.example.com/foo/bar", NOTAPPEND, "/foo/bar"), ("https://auth.api.example.com/foo/bar/", NOTAPPEND, "/foo/bar/"), ] actions = { "1.0": "/v1.0", "1.1": "/v1.1/auth", "2.0": "/v2.0/tokens", "2.0_apikey": "/v2.0/tokens", "2.0_password": "******", "3.x_password": "******", "3.x_appcred": "/v3/auth/tokens", "3.x_oidc_access_token": "/v3/OS-FEDERATION/identity_providers/user_name/protocols/tenant-name/auth", } user_id = OPENSTACK_PARAMS[0] key = OPENSTACK_PARAMS[1] for (auth_version, mock_http_class, kwargs) in tuples: for (url, should_append_default_path, expected_path) in auth_urls: connection = self._get_mock_connection( mock_http_class=mock_http_class, auth_url=url ) auth_url = connection.auth_url cls = get_class_for_auth_version(auth_version=auth_version) osa = cls( auth_url=auth_url, user_id=user_id, key=key, parent_conn=connection, **kwargs, ) try: osa = osa.authenticate() except Exception: pass if should_append_default_path == APPEND: expected_path = actions[auth_version] self.assertEqual(osa.action, expected_path)
def test_authentication_cache(self): tuples = [ # 1.0 does not provide token expiration, so it always # re-authenticates and never uses the cache. # ('1.0', OpenStackMockHttp, {}), ("1.1", OpenStackMockHttp, {}), ("2.0", OpenStack_2_0_MockHttp, {}), ("2.0_apikey", OpenStack_2_0_MockHttp, {}), ("2.0_password", OpenStack_2_0_MockHttp, {}), ( "3.x_password", OpenStackIdentity_3_0_MockHttp, { "user_id": "test_user_id", "key": "test_key", "token_scope": "project", "tenant_name": "test_tenant", "tenant_domain_id": "test_tenant_domain_id", "domain_name": "test_domain", }, ), ( "3.x_oidc_access_token", OpenStackIdentity_3_0_MockHttp, { "user_id": "test_user_id", "key": "test_key", "token_scope": "domain", "tenant_name": "test_tenant", "tenant_domain_id": "test_tenant_domain_id", "domain_name": "test_domain", }, ), ] user_id = OPENSTACK_PARAMS[0] key = OPENSTACK_PARAMS[1] for (auth_version, mock_http_class, kwargs) in tuples: mock_http_class.type = None connection = self._get_mock_connection(mock_http_class=mock_http_class) auth_url = connection.auth_url if not kwargs: kwargs["user_id"] = user_id kwargs["key"] = key auth_cache = OpenStackMockAuthCache() self.assertEqual(len(auth_cache), 0) kwargs["auth_cache"] = auth_cache cls = get_class_for_auth_version(auth_version=auth_version) osa = cls(auth_url=auth_url, parent_conn=connection, **kwargs) osa = osa.authenticate() # Token is cached self.assertEqual(len(auth_cache), 1) # New client, token from cache is re-used osa = cls(auth_url=auth_url, parent_conn=connection, **kwargs) osa.request = Mock(wraps=osa.request) osa = osa.authenticate() # No auth API call if auth_version in ("1.1", "2.0", "2.0_apikey", "2.0_password"): self.assertEqual(osa.request.call_count, 0) elif auth_version in ("3.x_password", "3.x_oidc_access_token"): # v3 only caches token and expiration; service catalog URLs # and the rest of the auth context are fetched from Keystone osa.request.assert_called_once_with( action="/v3/auth/tokens", params=None, data=None, headers={ "X-Subject-Token": "00000000000000000000000000000000", "X-Auth-Token": "00000000000000000000000000000000", }, method="GET", raw=False, ) # Cache size unchanged self.assertEqual(len(auth_cache), 1) # Authenticates if cached token expired cache_key = list(auth_cache.store.keys())[0] auth_context = auth_cache.get(cache_key) auth_context.expiration = YESTERDAY auth_cache.put(cache_key, auth_context) osa = cls(auth_url=auth_url, parent_conn=connection, **kwargs) osa.request = Mock(wraps=osa.request) osa._get_unscoped_token_from_oidc_token = Mock(return_value="000") OpenStackIdentity_3_0_MockHttp.type = "GET_UNAUTHORIZED_POST_OK" osa = osa.authenticate() if auth_version in ("1.1", "2.0", "2.0_apikey", "2.0_password"): self.assertEqual(osa.request.call_count, 1) self.assertTrue(osa.request.call_args[1]["method"], "POST") elif auth_version in ("3.x_password", "3.x_oidc_access_token"): self.assertTrue(osa.request.call_args[0][0], "/v3/auth/tokens") self.assertTrue(osa.request.call_args[1]["method"], "POST") # Token evicted from cache if 401 received on another call if hasattr(osa, "list_projects"): mock_http_class.type = None auth_cache.reset() osa = cls(auth_url=auth_url, parent_conn=connection, **kwargs) osa.request = Mock(wraps=osa.request) osa = osa.authenticate() self.assertEqual(len(auth_cache), 1) mock_http_class.type = "UNAUTHORIZED" try: osa.list_projects() except: # These methods don't handle 401s pass self.assertEqual(len(auth_cache), 0)
def test_basic_authentication(self): tuples = [ ("1.0", OpenStackMockHttp, {}), ("1.1", OpenStackMockHttp, {}), ("2.0", OpenStack_2_0_MockHttp, {}), ("2.0_apikey", OpenStack_2_0_MockHttp, {}), ("2.0_password", OpenStack_2_0_MockHttp, {}), ( "3.x_password", OpenStackIdentity_3_0_MockHttp, { "user_id": "test_user_id", "key": "test_key", "token_scope": "project", "tenant_name": "test_tenant", "tenant_domain_id": "test_tenant_domain_id", "domain_name": "test_domain", }, ), ( "3.x_appcred", OpenStackIdentity_3_0_MockHttp, {"user_id": "appcred_id", "key": "appcred_secret"}, ), ( "3.x_oidc_access_token", OpenStackIdentity_3_0_MockHttp, { "user_id": "test_user_id", "key": "test_key", "token_scope": "domain", "tenant_name": "test_tenant", "tenant_domain_id": "test_tenant_domain_id", "domain_name": "test_domain", }, ), ] user_id = OPENSTACK_PARAMS[0] key = OPENSTACK_PARAMS[1] for (auth_version, mock_http_class, kwargs) in tuples: connection = self._get_mock_connection(mock_http_class=mock_http_class) auth_url = connection.auth_url if not kwargs: kwargs["user_id"] = user_id kwargs["key"] = key cls = get_class_for_auth_version(auth_version=auth_version) osa = cls(auth_url=auth_url, parent_conn=connection, **kwargs) self.assertEqual(osa.urls, {}) self.assertIsNone(osa.auth_token) self.assertIsNone(osa.auth_user_info) osa = osa.authenticate() self.assertTrue(len(osa.urls) >= 1) self.assertTrue(osa.auth_token is not None) if auth_version in [ "1.1", "2.0", "2.0_apikey", "2.0_password", "3.x_password", "3.x_appcred", "3.x_oidc_access_token", ]: self.assertTrue(osa.auth_token_expires is not None) if auth_version in [ "2.0", "2.0_apikey", "2.0_password", "3.x_password", "3.x_appcred", "3.x_oidc_access_token", ]: self.assertTrue(osa.auth_user_info is not None)