def _json_request(self, method, path, body=None, additional_headers=None): """HTTP request helper used to make json requests. :param method: http method :param path: relative request url :param body: dict to encode to json as request body. Optional. :param additional_headers: dict of additional headers to send with http request. Optional. :return (http response object, response body parsed as json) :raise ServerError when unable to communicate with monitor """ kwargs = { 'headers': { 'Content-type': 'application/json', 'Accept': 'application/json', }, } if additional_headers: kwargs['headers'].update(additional_headers) if body: kwargs['body'] = jsonutils.dumps(body) path = self.auth_admin_prefix + path response, body = self._http_request(method, path, **kwargs) try: data = jsonutils.loads(body) except ValueError: self.LOG.debug('Keystone did not return json-encoded body') data = {} return response, data
def _build_user_headers(self, token_info): """Convert token object into headers. Build headers that represent authenticated user - see main doc info at start of file for details of headers to be defined. :param token_info: token object returned by monitor on authentication :raise InvalidUserToken when unable to parse token object """ def get_tenant_info(): """Returns a (tenant_id, tenant_name) tuple from context.""" def essex(): """Essex puts the tenant ID and name on the token.""" return (token['tenant']['id'], token['tenant']['name']) def pre_diablo(): """Pre-diablo, Keystone only provided tenantId.""" return (token['tenantId'], token['tenantId']) def default_tenant(): """Pre-grizzly, assume the user's default tenant.""" return (user['tenantId'], user['tenantName']) for method in [essex, pre_diablo, default_tenant]: try: return method() except KeyError: pass raise InvalidUserToken('Unable to determine tenancy.') # For clarity. set all those attributes that are optional in # either a v2 or v3 token to None first domain_id = None domain_name = None project_id = None project_name = None user_domain_id = None user_domain_name = None project_domain_id = None project_domain_name = None if self._token_is_v2(token_info): user = token_info['access']['user'] token = token_info['access']['token'] roles = ','.join([role['name'] for role in user.get('roles', [])]) catalog_root = token_info['access'] catalog_key = 'serviceCatalog' project_id, project_name = get_tenant_info() else: #v3 token token = token_info['token'] user = token['user'] user_domain_id = user['domain']['id'] user_domain_name = user['domain']['name'] roles = (','.join([role['name'] for role in token.get('roles', [])])) catalog_root = token catalog_key = 'catalog' # For v3, the server will put in the default project if there is # one, so no need for us to add it here (like we do for a v2 token) if 'domain' in token: domain_id = token['domain']['id'] domain_name = token['domain']['name'] elif 'project' in token: project_id = token['project']['id'] project_name = token['project']['name'] project_domain_id = token['project']['domain']['id'] project_domain_name = token['project']['domain']['name'] user_id = user['id'] user_name = user['name'] rval = { 'X-Identity-Status': 'Confirmed', 'X-Domain-Id': domain_id, 'X-Domain-Name': domain_name, 'X-Project-Id': project_id, 'X-Project-Name': project_name, 'X-Project-Domain-Id': project_domain_id, 'X-Project-Domain-Name': project_domain_name, 'X-User-Id': user_id, 'X-User-Name': user_name, 'X-User-Domain-Id': user_domain_id, 'X-User-Domain-Name': user_domain_name, 'X-Roles': roles, # Deprecated 'X-User': user_name, 'X-Tenant-Id': project_id, 'X-Tenant-Name': project_name, 'X-Tenant': project_name, 'X-Role': roles, } try: catalog = catalog_root[catalog_key] rval['X-Service-Catalog'] = jsonutils.dumps(catalog) except KeyError: pass return rval
def _build_user_headers(self, token_info): """Convert token object into headers. Build headers that represent authenticated user - see main doc info at start of file for details of headers to be defined. :param token_info: token object returned by monitor on authentication :raise InvalidUserToken when unable to parse token object """ def get_tenant_info(): """Returns a (tenant_id, tenant_name) tuple from context.""" def essex(): """Essex puts the tenant ID and name on the token.""" return (token['tenant']['id'], token['tenant']['name']) def pre_diablo(): """Pre-diablo, Keystone only provided tenantId.""" return (token['tenantId'], token['tenantId']) def default_tenant(): """Pre-grizzly, assume the user's default tenant.""" return (user['tenantId'], user['tenantName']) for method in [essex, pre_diablo, default_tenant]: try: return method() except KeyError: pass raise InvalidUserToken('Unable to determine tenancy.') # For clarity. set all those attributes that are optional in # either a v2 or v3 token to None first domain_id = None domain_name = None project_id = None project_name = None user_domain_id = None user_domain_name = None project_domain_id = None project_domain_name = None if self._token_is_v2(token_info): user = token_info['access']['user'] token = token_info['access']['token'] roles = ','.join([role['name'] for role in user.get('roles', [])]) catalog_root = token_info['access'] catalog_key = 'serviceCatalog' project_id, project_name = get_tenant_info() else: #v3 token token = token_info['token'] user = token['user'] user_domain_id = user['domain']['id'] user_domain_name = user['domain']['name'] roles = (','.join( [role['name'] for role in token.get('roles', [])])) catalog_root = token catalog_key = 'catalog' # For v3, the server will put in the default project if there is # one, so no need for us to add it here (like we do for a v2 token) if 'domain' in token: domain_id = token['domain']['id'] domain_name = token['domain']['name'] elif 'project' in token: project_id = token['project']['id'] project_name = token['project']['name'] project_domain_id = token['project']['domain']['id'] project_domain_name = token['project']['domain']['name'] user_id = user['id'] user_name = user['name'] rval = { 'X-Identity-Status': 'Confirmed', 'X-Domain-Id': domain_id, 'X-Domain-Name': domain_name, 'X-Project-Id': project_id, 'X-Project-Name': project_name, 'X-Project-Domain-Id': project_domain_id, 'X-Project-Domain-Name': project_domain_name, 'X-User-Id': user_id, 'X-User-Name': user_name, 'X-User-Domain-Id': user_domain_id, 'X-User-Domain-Name': user_domain_name, 'X-Roles': roles, # Deprecated 'X-User': user_name, 'X-Tenant-Id': project_id, 'X-Tenant-Name': project_name, 'X-Tenant': project_name, 'X-Role': roles, } try: catalog = catalog_root[catalog_key] rval['X-Service-Catalog'] = jsonutils.dumps(catalog) except KeyError: pass return rval