def fake_catalog(tenant, token): """Generate a fake Service Catalog """ catalog_gen = servicecatalog.ServiceCatalogGenerator(token, tenant) catalog = catalog_gen.generate_full_catalog()['access'] return access.AccessInfoV2(**catalog)
def get_auth_ref(self, session, **kwargs): headers = {'Accept': 'application/json'} url = self.auth_url.rstrip('/') + '/tokens' params = {'auth': self.get_auth_data(headers)} if self.tenant_id: params['auth']['tenantId'] = self.tenant_id elif self.tenant_name: params['auth']['tenantName'] = self.tenant_name if self.trust_id: params['auth']['trust_id'] = self.trust_id _logger.debug('Making authentication request to %s', url) resp = session.post(url, json=params, headers=headers, authenticated=False, log=False) try: resp_data = resp.json()['access'] except (KeyError, ValueError): raise exceptions.InvalidResponse(response=resp) return access.AccessInfoV2(**resp_data)
def _retrieve_data_from_cache(redis_client, url, tenant, token): """Retrieve the authentication data from cache :param redis_client: redis.Redis object connected to the redis cache :param url: URL used for authentication :param tenant: tenant id of the user :param token: auth_token for the user :returns: a keystoneclient.access.AccessInfo on success or None """ cached_data = None cache_key = None try: # Try to get the data from the cache cache_key_tuple = (tenant, token, url) cache_key = _tuple_to_cache_key(cache_key_tuple) cached_data = redis_client.get(cache_key) except Exception as ex: LOG.debug( ( 'Failed to retrieve data to cache for key {0}' 'Exception: {1}' ).format(cache_key, str(ex)) ) return None if cached_data is not None: # So 'data' can be used in the exception handler... data = None try: data = __unpacker(cached_data) return access.AccessInfoV2(data) except Exception as ex: # The cached object didn't match what we expected msg = ( 'Stored Data does not contain any credentials - ' 'Exception: {0}; Data: {1}' ).format(str(ex), data) LOG.error(msg) return None else: LOG.debug('No data in cache for key {0}'.format(cache_key)) # It wasn't cached return None
def get_auth_ref(self, session, **kwargs): headers = {} url = self.auth_url + '/tokens' params = {'auth': self.get_auth_data(headers)} if self.tenant_id: params['auth']['tenantId'] = self.tenant_id elif self.tenant_name: params['auth']['tenantName'] = self.tenant_name if self.trust_id: params['auth']['trust_id'] = self.trust_id resp = session.post(url, json=params, headers=headers, authenticated=False) return access.AccessInfoV2(**resp.json()['access'])
def get_raw_token_from_identity_service(self, auth_url, tenant_id, token): LOG.debug('URL: {0}'.format(auth_url)) LOG.debug('Token: {0}'.format(token)) LOG.debug('Tenant: {0}'.format(tenant_id)) if token == 'valid_token' and tenant_id == 'valid_projectid': catalog_gen = servicecatalog.ServiceCatalogGenerator( token, tenant_id) catalog = catalog_gen.generate_full_catalog()['access'] return access.AccessInfoV2(**catalog) else: if token == 'valid_token': raise exceptions.AuthorizationFailure( 'mocking - invalid project id') elif tenant_id == 'valid_projectid': raise exceptions.AuthorizationFailure( 'mocking - invalid token') else: raise exceptions.AuthorizationFailure( 'mocking - invalid or missing token or project id')
def test__retrieve_data_from_keystone_alt_auth(self): redis_client = fakeredis_connection() tenant_id = '172839405' token = 'AaBbCcDdEeFf' url = 'myurl' bttl = 5 with mock.patch('eom.auth.get_conf') as mock_auth_conf: with mock.patch('requests.get') as mock_requests: mock_auth_conf.return_value.alternate_validation = True cat = servicecatalog.ServiceCatalogGenerator(token, tenant_id) resp_json = cat.generate_without_catalog() mock_requests.return_value.json.return_value = resp_json mock_requests.return_value.status_code = 200 access_info = auth._retrieve_data_from_keystone( redis_client, url, tenant_id, token, bttl, self.default_max_cache_life) self.assertEqual( access_info, access.AccessInfoV2( cat.generate_without_catalog()['access']))
def _retrieve_data_from_keystone(redis_client, url, tenant, token, blacklist_ttl, max_cache_life): """Retrieve the authentication data from OpenStack Keystone :param redis_client: redis.Redis object connected to the redis cache :param url: Keystone Identity URL to authenticate against :param tenant: tenant id of user data to retrieve :param token: auth_token for the tenant_id :param blacklist_ttl: time in milliseconds for blacklisting failed tokens :param max_cache_life: time in seconds for the maximum time a cache entry should remain in the cache of valid data :returns: a keystoneclient.access.AccessInfo on success or None on error """ try: # Try to authenticate the user and get the user information using # only the data provided, no special administrative tokens required. # When using the alternative validation method, the service catalog # identity does not return a service catalog for valid tokens. if get_conf().alternate_validation is True: _url = url.rstrip('/') + '/tokens' validation_url = _url + '/{0}'.format(token) headers = { 'Accept': 'application/json', 'X-Auth-Token': token } resp = requests.get(validation_url, headers=headers) if resp.status_code >= 400: LOG.debug('Request returned failure status: {0}'.format( resp.status_code)) raise exceptions.from_response(resp, 'GET', _url) try: resp_data = resp.json()['access'] except (KeyError, ValueError): raise exceptions.InvalidResponse(response=resp) access_info = access.AccessInfoV2(**resp_data) else: keystone = keystonev2_client.Client(tenant_id=tenant, token=token, auth_url=url) access_info = keystone.get_raw_token_from_identity_service( auth_url=url, tenant_id=tenant, token=token) # cache the data so it is easier to access next time _send_data_to_cache(redis_client, url, access_info, max_cache_life) return access_info except (exceptions.AuthorizationFailure, exceptions.Unauthorized) as ex: # re-raise 413 here and later on respond with 503 if 'HTTP 413' in str(ex): raise exceptions.RequestEntityTooLarge( method='POST', url=url, http_status=413 ) # Provided data was invalid and authorization failed msg = 'Failed to authenticate against {0} - {1}'.format( url, str(ex) ) LOG.debug(msg) # Blacklist the token _blacklist_token(redis_client, token, blacklist_ttl) return None except exceptions.RequestEntityTooLarge: LOG.debug('Request entity too large error from authentication server.') raise except Exception as ex: # Provided data was invalid or something else went wrong msg = 'Failed to authenticate against {0} - {1}'.format( url, str(ex) ) LOG.debug(msg) return None