def test_safe_rstrip(self): value = '/test/' rstripped_value = '/test' not_rstripped = '/' self.assertEqual(utils.safe_rstrip(value, '/'), rstripped_value) self.assertEqual(utils.safe_rstrip(not_rstripped, '/'), not_rstripped)
def before(self, state): user_id = state.request.headers.get('X-User-Id') user_id = state.request.headers.get('X-User', user_id) tenant = state.request.headers.get('X-Tenant-Id') tenant = state.request.headers.get('X-Tenant', tenant) domain_id = state.request.headers.get('X-User-Domain-Id') domain_name = state.request.headers.get('X-User-Domain-Name') auth_token = state.request.headers.get('X-Auth-Token', None) creds = {'roles': state.request.headers.get('X-Roles', '').split(',')} catalog_header = state.request.headers.get('X-Service-Catalog') service_catalog = None if catalog_header: try: service_catalog = jsonutils.loads(catalog_header) except ValueError: raise webob.exc.HTTPInternalServerError( _('Invalid service catalog json.')) is_admin = policy.check('admin', state.request.headers, creds) utils.safe_rstrip(state.request.path, '/') is_public_api = state.request.environ.get('is_public_api', False) state.request.context = context.RequestContext( auth_token=auth_token, user=user_id, tenant=tenant, domain_id=domain_id, domain_name=domain_name, is_admin=is_admin, is_public_api=is_public_api, service_catalog=service_catalog)
def __call__(self, env, start_response): path = utils.safe_rstrip(env.get('PATH_INFO'), '/') if path in self.public_api_routes: return self.app(env, start_response) # pylint: disable=no-member return super(AuthTokenMiddleware, self).__call__(env, start_response) # pylint: disable=too-many-function-args
def test_safe_rstrip_not_raises_exceptions(self): # Supplying an integer should normally raise an exception because it # does not save the rstrip() method. value = 10 # In the case of raising an exception safe_rstrip() should return the # original value. self.assertEqual(utils.safe_rstrip(value), value)
def __call__(self, env, start_response): path = utils.safe_rstrip(env.get('PATH_INFO'), '/') # The information whether the API call is being performed against the # public API is required for some other components. Saving it to the # WSGI environment is reasonable thereby. env['is_public_api'] = any( [re.match(pattern, path) for pattern in self.public_api_routes]) if env['is_public_api']: LOG.debug("Found match request") return self._sysinv_app(env, start_response) response = super(AuthTokenMiddleware, self).__call__(env, start_response) # The response could have error code 401 (unauthorized) for two cases: # First case is that the token (user token) of the request is invalid. # Second case is that sysinv's own token is invalid for reason such as # its user ID or project ID or assignment changed, where keystone will # return 404 but keystonemiddleware converts it into 401 as well. There # is no obvious way to distinguish these two cases outside of # keystonemiddleware, so here we setup sysinv to re-authenticate against # keystone to get a new token for its own and retry the request as long # as the response is errored with 401. try: resp_m = json.loads(response[0]) except Exception as e: LOG.debug("Request response is not in json format: %s" % e) pass else: k_error = 'error' k_code = 'code' if (k_error in resp_m) and (k_code in resp_m[k_error]) and \ (resp_m[k_error][k_code] == 401) and \ 'HTTP_X_AUTH_TOKEN' in env: # Need to clear the cached value for this token since it # is marked as invalid in the cache in the previous process. user_token = env['HTTP_X_AUTH_TOKEN'] token_hashes = self._token_hashes(user_token) self._token_cache.set(token_hashes[0], None) # Sysinv re-authenticate against keystone to get a new token # for itself. self._auth = self._create_auth_plugin() self._session = self._create_session() self._identity_server = self._create_identity_server() # Retry and retry only once of the request from client. response = super(AuthTokenMiddleware, self).__call__(env, start_response) return response
def __call__(self, env, start_response): path = utils.safe_rstrip(env.get('PATH_INFO'), '/') # The information whether the API call is being performed against the # public API is required for some other components. Saving it to the # WSGI environment is reasonable thereby. env['is_public_api'] = any([re.match(pattern, path) for pattern in self.public_api_routes]) if env['is_public_api']: LOG.debug("Found match request") return self._sysinv_app(env, start_response) return super(AuthTokenMiddleware, self).__call__(env, start_response)
def before(self, state): user_id = state.request.headers.get('X-User-Id') user_id = state.request.headers.get('X-User', user_id) tenant = state.request.headers.get('X-Tenant-Id') tenant = state.request.headers.get('X-Tenant', tenant) domain_id = state.request.headers.get('X-User-Domain-Id') domain_name = state.request.headers.get('X-User-Domain-Name') auth_token = state.request.headers.get('X-Auth-Token', None) creds = {'roles': state.request.headers.get('X-Roles', '').split(',')} is_admin = policy.check('admin', state.request.headers, creds) path = utils.safe_rstrip(state.request.path, '/') is_public_api = path in self.public_api_routes state.request.context = context.RequestContext( auth_token=auth_token, user=user_id, tenant=tenant, domain_id=domain_id, domain_name=domain_name, is_admin=is_admin, is_public_api=is_public_api)