def _validate_user_token(self, user_token, retry=True): """Authenticate user using PKI :param user_token: user's token id :param retry: Ignored, as it is not longer relevant :return uncrypted body of the token if the token is valid :raise InvalidUserToken if token is rejected :no longer raises ServiceError since it no longer makes RPC """ token_id = None try: token_id = cms.cms_hash_token(user_token) cached = self._cache_get(token_id) if cached: return cached if cms.is_ans1_token(user_token): verified = self.verify_signed_token(user_token) data = jsonutils.loads(verified) else: data = self.verify_uuid_token(user_token, retry) expires = confirm_token_not_expired(data) self._cache_put(token_id, data, expires) return data except NetworkError: self.LOG.debug('Token validation failure.', exc_info=True) self.LOG.warn("Authorization failed for token %s", token_id) raise InvalidUserToken('Token authorization failed') except Exception: self.LOG.debug('Token validation failure.', exc_info=True) if token_id: self._cache_store_invalid(token_id) self.LOG.warn("Authorization failed for token %s", token_id) raise InvalidUserToken('Token authorization failed')
def test_fetch_revocation_list_with_expire(self): # first response to revocation list should return 401 Unauthorized # to pretend to be an expired token resp1 = FakeHTTPResponse(200, jsonutils.dumps({ 'access': { 'token': {'id': 'admin_token2'}, }, })) resp2 = FakeHTTPResponse(401, jsonutils.dumps('')) resp3 = FakeHTTPResponse(200, jsonutils.dumps({ 'access': { 'token': {'id': 'admin_token2'}, }, })) resp4 = FakeHTTPResponse(200, SIGNED_REVOCATION_LIST) # first get_admin_token() call FAKE_RESPONSE_STACK.append(resp1) # request revocation list, get "unauthorized" due to simulated expired # token FAKE_RESPONSE_STACK.append(resp2) # request a new admin_token FAKE_RESPONSE_STACK.append(resp3) # request revocation list, get the revocation list properly FAKE_RESPONSE_STACK.append(resp4) fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list()) self.assertEqual(fetched_list, client_fixtures.REVOCATION_LIST)
def assertRequestBodyIs(self, body=None, json=None): last_request_body = self.requests.last_request.body if json: val = jsonutils.loads(last_request_body) self.assertEqual(json, val) elif body: self.assertEqual(body, last_request_body)
def from_response(response, body=None): """Return an instance of a ClientException or subclass based on a requests response. Usage:: resp = requests.request(...) if resp.status_code != 200: raise exception_from_response(resp, resp.text) """ cls = _code_map.get(response.status_code, ClientException) if body is None: try: body = jsonutils.loads(response.text) except Exception: body = response.text if body: if hasattr(body, 'keys'): error = body[body.keys()[0]] message = error.get('message', None) details = error.get('details', None) else: # If we didn't get back a properly formed error message we # probably couldn't communicate with Keystone at all. message = "Unable to communicate with identity service: %s." % body details = None return cls(code=response.status_code, message=message, details=details) else: return cls(code=response.status_code)
def setUpModule(self): signing_path = CMSDIR with open(os.path.join(signing_path, 'auth_token_scoped.pem')) as f: self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(signing_path, 'auth_token_unscoped.pem')) as f: self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) with open(os.path.join(signing_path, 'auth_token_revoked.pem')) as f: self.REVOKED_TOKEN = cms.cms_to_token(f.read()) self.REVOKED_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_TOKEN) with open(os.path.join(signing_path, 'revocation_list.json')) as f: self.REVOCATION_LIST = jsonutils.loads(f.read()) with open(os.path.join(signing_path, 'revocation_list.pem')) as f: self.VALID_SIGNED_REVOCATION_LIST = jsonutils.dumps( {'signed': f.read()}) self.SIGNED_TOKEN_SCOPED_KEY =\ cms.cms_hash_token(self.SIGNED_TOKEN_SCOPED) self.SIGNED_TOKEN_UNSCOPED_KEY =\ cms.cms_hash_token(self.SIGNED_TOKEN_UNSCOPED) self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_KEY] = { 'access': { 'token': { 'id': self.SIGNED_TOKEN_SCOPED_KEY, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'tenantId': 'tenant_id1', 'tenantName': 'tenant_name1', 'roles': [ { 'name': 'role1' }, { 'name': 'role2' }, ], }, }, } self.TOKEN_RESPONSES[SIGNED_TOKEN_UNSCOPED_KEY] = { 'access': { 'token': { 'id': SIGNED_TOKEN_UNSCOPED_KEY, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ { 'name': 'role1' }, { 'name': 'role2' }, ], }, }, },
def _cache_get(self, token_id, ignore_expires=False): """Return token information from cache. If token is invalid raise InvalidUserToken return token only if fresh (not expired). """ if self._cache and token_id: if self._memcache_security_strategy is None: key = CACHE_KEY_TEMPLATE % token_id serialized = self._cache.get(key) else: keys = memcache_crypt.derive_keys( token_id, self._memcache_secret_key, self._memcache_security_strategy) cache_key = CACHE_KEY_TEMPLATE % ( memcache_crypt.get_cache_key(keys)) raw_cached = self._cache.get(cache_key) try: # unprotect_data will return None if raw_cached is None serialized = memcache_crypt.unprotect_data(keys, raw_cached) except Exception: msg = 'Failed to decrypt/verify cache data' self.LOG.exception(msg) # this should have the same effect as data not # found in cache serialized = None if serialized is None: return None # Note that 'invalid' and (data, expires) are the only # valid types of serialized cache entries, so there is not # a collision with jsonutils.loads(serialized) == None. cached = jsonutils.loads(serialized) if cached == 'invalid': self.LOG.debug('Cached Token %s is marked unauthorized', token_id) raise InvalidUserToken('Token authorization failed') data, expires = cached try: expires = timeutils.parse_isotime(expires) except ValueError: # Gracefully handle upgrade of expiration times from *nix # timestamps to ISO 8601 formatted dates by ignoring old cached # values. return expires = timeutils.normalize_time(expires) utcnow = timeutils.utcnow() if ignore_expires or utcnow < expires: self.LOG.debug('Returning cached token %s', token_id) return data else: self.LOG.debug('Cached Token %s seems expired', token_id)
def _cache_get(self, token_id, ignore_expires=False): """Return token information from cache. If token is invalid raise InvalidUserToken return token only if fresh (not expired). """ if self._cache and token_id: if self._memcache_security_strategy is None: key = CACHE_KEY_TEMPLATE % token_id serialized = self._cache.get(key) else: keys = memcache_crypt.derive_keys( token_id, self._memcache_secret_key, self._memcache_security_strategy) cache_key = CACHE_KEY_TEMPLATE % ( memcache_crypt.get_cache_key(keys)) raw_cached = self._cache.get(cache_key) try: # unprotect_data will return None if raw_cached is None serialized = memcache_crypt.unprotect_data( keys, raw_cached) except Exception: msg = 'Failed to decrypt/verify cache data' self.LOG.exception(msg) # this should have the same effect as data not # found in cache serialized = None if serialized is None: return None # Note that 'invalid' and (data, expires) are the only # valid types of serialized cache entries, so there is not # a collision with jsonutils.loads(serialized) == None. cached = jsonutils.loads(serialized) if cached == 'invalid': self.LOG.debug('Cached Token %s is marked unauthorized', token_id) raise InvalidUserToken('Token authorization failed') data, expires = cached try: expires = timeutils.parse_isotime(expires) except ValueError: # Gracefully handle upgrade of expiration times from *nix # timestamps to ISO 8601 formatted dates by ignoring old cached # values. return expires = timeutils.normalize_time(expires) utcnow = timeutils.utcnow() if ignore_expires or utcnow < expires: self.LOG.debug('Returning cached token %s', token_id) return data else: self.LOG.debug('Cached Token %s seems expired', token_id)
def setUpModule(self): signing_path = CMSDIR with open(os.path.join(signing_path, "auth_token_scoped.pem")) as f: self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(signing_path, "auth_token_unscoped.pem")) as f: self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) with open(os.path.join(signing_path, "auth_v3_token_scoped.pem")) as f: self.SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(signing_path, "auth_token_revoked.pem")) as f: self.REVOKED_TOKEN = cms.cms_to_token(f.read()) self.REVOKED_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_TOKEN) with open(os.path.join(signing_path, "auth_v3_token_revoked.pem")) as f: self.REVOKED_v3_TOKEN = cms.cms_to_token(f.read()) self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_v3_TOKEN) with open(os.path.join(signing_path, "revocation_list.json")) as f: self.REVOCATION_LIST = jsonutils.loads(f.read()) with open(os.path.join(signing_path, "revocation_list.pem")) as f: self.VALID_SIGNED_REVOCATION_LIST = jsonutils.dumps({"signed": f.read()}) self.SIGNED_TOKEN_SCOPED_KEY = cms.cms_hash_token(self.SIGNED_TOKEN_SCOPED) self.SIGNED_TOKEN_UNSCOPED_KEY = cms.cms_hash_token(self.SIGNED_TOKEN_UNSCOPED) self.SIGNED_v3_TOKEN_SCOPED_KEY = cms.cms_hash_token(self.SIGNED_v3_TOKEN_SCOPED) self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_KEY] = { "access": { "token": {"id": self.SIGNED_TOKEN_SCOPED_KEY}, "user": { "id": "user_id1", "name": "user_name1", "tenantId": "tenant_id1", "tenantName": "tenant_name1", "roles": [{"name": "role1"}, {"name": "role2"}], }, } } self.TOKEN_RESPONSES[SIGNED_TOKEN_UNSCOPED_KEY] = ( { "access": { "token": {"id": SIGNED_TOKEN_UNSCOPED_KEY}, "user": {"id": "user_id1", "name": "user_name1", "roles": [{"name": "role1"}, {"name": "role2"}]}, } }, ) self.TOKEN_RESPONSES[self.SIGNED_v3_TOKEN_SCOPED_KEY] = { "token": { "expires": "2999-01-01T00:00:10Z", "user": {"id": "user_id1", "name": "user_name1", "domain": {"id": "domain_id1", "name": "domain_name1"}}, "project": { "id": "tenant_id1", "name": "tenant_name1", "domain": {"id": "domain_id1", "name": "domain_name1"}, }, "roles": [{"name": "role1"}, {"name": "role2"}], "catalog": {}, } }
def token_revocation_list(self, value): """Save a revocation list to memory and to disk. :param value: A json-encoded revocation list """ self._token_revocation_list = jsonutils.loads(value) self.token_revocation_list_fetched_time = timeutils.utcnow() with open(self.revoked_file_name, 'w') as f: f.write(value)
def assertRequestBodyIs(self, body=None, json=None): last_request_body = httpretty.last_request().body if six.PY3: last_request_body = last_request_body.decode('utf-8') if json: val = jsonutils.loads(last_request_body) self.assertEqual(json, val) elif body: self.assertEqual(body, last_request_body)
def token_revocation_list(self): timeout = self.token_revocation_list_fetched_time + self.token_revocation_list_cache_timeout list_is_current = timeutils.utcnow() < timeout if list_is_current: # Load the list from disk if required if not self._token_revocation_list: with open(self.revoked_file_name, "r") as f: self._token_revocation_list = jsonutils.loads(f.read()) else: self.token_revocation_list = self.fetch_revocation_list() return self._token_revocation_list
def _decode_body(resp): if resp.text: try: body_resp = jsonutils.loads(resp.text) except (ValueError, TypeError): body_resp = None _logger.debug("Could not decode JSON from body: %s", resp.text) else: _logger.debug("No body was returned.") body_resp = None return body_resp
def _decode_body(resp): if resp.text: try: body_resp = jsonutils.loads(resp.text) except (ValueError, TypeError): body_resp = None _logger.debug("Could not decode JSON from body: %s" % resp.text) else: _logger.debug("No body was returned.") body_resp = None return body_resp
def token_revocation_list(self): timeout = (self.token_revocation_list_fetched_time + self.token_revocation_list_cache_timeout) list_is_current = timeutils.utcnow() < timeout if list_is_current: # Load the list from disk if required if not self._token_revocation_list: with open(self.revoked_file_name, 'r') as f: self._token_revocation_list = jsonutils.loads(f.read()) else: self.token_revocation_list = self.fetch_revocation_list() return self._token_revocation_list
def setUpModule(self): signing_path = CMSDIR with open(os.path.join(signing_path, 'auth_token_scoped.pem')) as f: self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(signing_path, 'auth_token_unscoped.pem')) as f: self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) with open(os.path.join(signing_path, 'auth_token_revoked.pem')) as f: self.REVOKED_TOKEN = cms.cms_to_token(f.read()) self.REVOKED_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_TOKEN) with open(os.path.join(signing_path, 'revocation_list.json')) as f: self.REVOCATION_LIST = jsonutils.loads(f.read()) with open(os.path.join(signing_path, 'revocation_list.pem')) as f: self.VALID_SIGNED_REVOCATION_LIST = jsonutils.dumps( {'signed': f.read()}) self.SIGNED_TOKEN_SCOPED_KEY =\ cms.cms_hash_token(self.SIGNED_TOKEN_SCOPED) self.SIGNED_TOKEN_UNSCOPED_KEY =\ cms.cms_hash_token(self.SIGNED_TOKEN_UNSCOPED) self.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED_KEY] = { 'access': { 'token': { 'id': self.SIGNED_TOKEN_SCOPED_KEY, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'tenantId': 'tenant_id1', 'tenantName': 'tenant_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, } self.TOKEN_RESPONSES[SIGNED_TOKEN_UNSCOPED_KEY] = { 'access': { 'token': { 'id': SIGNED_TOKEN_UNSCOPED_KEY, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, },
def _cache_get(self, token_id, ignore_expires=False): """Return token information from cache. If token is invalid raise InvalidUserToken return token only if fresh (not expired). """ if self._cache and token_id: if self._memcache_security_strategy is None: key = CACHE_KEY_TEMPLATE % token_id serialized = self._cache.get(key) else: keys = memcache_crypt.derive_keys( token_id, self._memcache_secret_key, self._memcache_security_strategy) cache_key = CACHE_KEY_TEMPLATE % ( memcache_crypt.get_cache_key(keys)) raw_cached = self._cache.get(cache_key) try: # unprotect_data will return None if raw_cached is None serialized = memcache_crypt.unprotect_data(keys, raw_cached) except Exception: msg = 'Failed to decrypt/verify cache data' self.LOG.exception(msg) # this should have the same effect as data not # found in cache serialized = None if serialized is None: return None # Note that 'invalid' and (data, expires) are the only # valid types of serialized cache entries, so there is not # a collision with jsonutils.loads(serialized) == None. cached = jsonutils.loads(serialized) if cached == 'invalid': self.LOG.debug('Cached Token %s is marked unauthorized', token_id) raise InvalidUserToken('Token authorization failed') data, expires = cached if ignore_expires or time.time() < float(expires): self.LOG.debug('Returning cached token %s', token_id) return data else: self.LOG.debug('Cached Token %s seems expired', token_id)
def get_token_for_user_and_project(test_domain, test_project, test_user): user_client = ( client.Client(auth_url='http://localhost:5000/v3', management_url='http://localhost:35357/v3', user_id=test_user.id, user_domain_id=test_domain.id, password=test_user.name, project_id=test_project.id, project_domain_id=test_domain.id)) token = user_client.auth_ref['auth_token'] user_token = jsonutils.loads( cms.verify_token( token, '/etc/keystone/ssl/certs/signing_cert.pem', '/etc/keystone/ssl/certs/ca.pem')) return user_token
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 keystone """ conn = self._get_http_connection() kwargs = { 'headers': { 'Content-type': 'application/json', 'Accept': 'application/json', }, } if additional_headers: kwargs['headers'].update(additional_headers) if body: kwargs['body'] = jsonutils.dumps(body) full_path = self.auth_admin_prefix + path try: conn.request(method, full_path, **kwargs) response = conn.getresponse() body = response.read() except Exception as e: self.LOG.error('HTTP connection exception: %s' % e) raise ServiceError('Unable to communicate with keystone') finally: conn.close() try: data = jsonutils.loads(body) except ValueError: self.LOG.debug('Keystone did not return json-encoded body') data = {} return response, data
def request(self, url, method, body=None, **kwargs): """Send an http request with the specified characteristics. Wrapper around requests.request to handle tasks such as setting headers, JSON encoding/decoding, and error handling. """ # Copy the kwargs so we can reuse the original in case of redirects request_kwargs = copy.copy(kwargs) request_kwargs.setdefault('headers', kwargs.get('headers', {})) if body: request_kwargs['headers']['Content-Type'] = 'application/json' request_kwargs['data'] = self.serialize(body) if self.cert: request_kwargs.setdefault('cert', self.cert) if self.timeout is not None: request_kwargs.setdefault('timeout', self.timeout) resp = request(url, method, original_ip=self.original_ip, verify=self.verify_cert, debug=self.debug_log, **request_kwargs) if resp.text: try: body_resp = jsonutils.loads(resp.text) except (ValueError, TypeError): body_resp = None _logger.debug("Could not decode JSON from body: %s" % resp.text) else: _logger.debug("No body was returned.") body_resp = None if resp.status_code in (301, 302, 305): # Redirected. Reissue the request to the new location. return self.request(resp.headers['location'], method, body, **request_kwargs) return resp, body_resp
def test_auth_url_token_authentication(self): fake_token = 'fake_token' fake_url = '/fake-url' fake_resp = {'result': True} self.stub_auth(json=self.TEST_RESPONSE_DICT) self.stub_url('GET', [fake_url], json=fake_resp, base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT) cl = client.Client(auth_url=self.TEST_URL, token=fake_token) body = jsonutils.loads(self.requests.last_request.body) self.assertEqual(body['auth']['identity']['token']['id'], fake_token) resp, body = cl.get(fake_url) self.assertEqual(fake_resp, body) token = self.requests.last_request.headers.get('X-Auth-Token') self.assertEqual(self.TEST_TOKEN, token)
def request(self, *args, **kwargs): headers = kwargs.setdefault('headers', {}) headers.setdefault('Accept', 'application/json') try: kwargs['json'] = kwargs.pop('body') except KeyError: pass resp = super(LegacyJsonAdapter, self).request(*args, **kwargs) body = None if resp.text: try: body = jsonutils.loads(resp.text) except ValueError: pass return resp, body
def test_fetch_revocation_list_with_expire(self): self.set_middleware() # Get a token, then try to retrieve revocation list and get a 401. # Get a new token, try to retrieve revocation list and return 200. httpretty.register_uri(httpretty.POST, "%s/v2.0/tokens" % BASE_URI, body=FAKE_ADMIN_TOKEN) responses = [ httpretty.Response(body="", status=401), httpretty.Response(body=client_fixtures.SIGNED_REVOCATION_LIST), ] httpretty.register_uri(httpretty.GET, "%s/v2.0/tokens/revoked" % BASE_URI, responses=responses) fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list()) self.assertEqual(fetched_list, client_fixtures.REVOCATION_LIST) # Check that 4 requests have been made self.assertEqual(len(httpretty.httpretty.latest_requests), 4)
def test_auth_url_token_authentication(self): fake_token = "fake_token" fake_url = "/fake-url" fake_resp = {"result": True} self.stub_auth(json=self.TEST_RESPONSE_DICT) self.stub_url("GET", [fake_url], json=fake_resp, base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT) cl = client.Client(auth_url=self.TEST_URL, token=fake_token) body = httpretty.last_request().body if six.PY3: body = body.decode("utf-8") body = jsonutils.loads(body) self.assertEqual(body["auth"]["token"]["id"], fake_token) resp, body = cl.get(fake_url) self.assertEqual(fake_resp, body) self.assertEqual(httpretty.last_request().headers.get("X-Auth-Token"), self.TEST_TOKEN)
def test_auth_url_token_authentication(self): fake_token = 'fake_token' fake_url = '/fake-url' fake_resp = {'result': True} self.stub_auth(json=self.TEST_RESPONSE_DICT) self.stub_url('GET', [fake_url], json=fake_resp, base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT) cl = client.Client(auth_url=self.TEST_URL, token=fake_token) json_body = jsonutils.loads(self.requests.last_request.body) self.assertEqual(json_body['auth']['token']['id'], fake_token) resp, body = cl.get(fake_url) self.assertEqual(fake_resp, body) token = self.requests.last_request.headers.get('X-Auth-Token') self.assertEqual(self.TEST_TOKEN, token)
def request(self, url, method, body=None, **kwargs): """Send an http request with the specified characteristics. Wrapper around requests.request to handle tasks such as setting headers, JSON encoding/decoding, and error handling. """ # Copy the kwargs so we can reuse the original in case of redirects _logger.debug("url in request is %s", url) request_kwargs = copy.copy(kwargs) request_kwargs.setdefault('headers', kwargs.get('headers', {})) if body: request_kwargs['headers']['Content-Type'] = 'application/json' request_kwargs['data'] = self.serialize(body) if self.cert: request_kwargs.setdefault('cert', self.cert) if self.timeout is not None: request_kwargs.setdefault('timeout', self.timeout) _logger.debug("url11111 is : %s", url) resp = request(url, method, original_ip=self.original_ip, verify=self.verify_cert, debug=self.debug_log, **request_kwargs) if resp.text: try: body_resp = jsonutils.loads(resp.text) except (ValueError, TypeError): body_resp = None _logger.debug("Could not decode JSON from body: %s" % resp.text) else: _logger.debug("No body was returned.") body_resp = None if resp.status_code in (301, 302, 305): # Redirected. Reissue the request to the new location. return self.request(resp.headers['location'], method, body, **request_kwargs) return resp, body_resp
def _cache_get(self, policy, token): """Return policy information from cache. """ if self._cache and policy: if self._memcache_security_strategy is None: key = CACHE_KEY_TEMPLATE try: timestamp, serialized = self._cache.get(key) except: timestamp = None serialized = None else: keys = memcache_crypt.derive_keys( token, self._memcache_secret_key, self._memcache_security_strategy) try: cache_key = CACHE_KEY_TEMPLATE % ( memcache_crypt.get_cache_key(keys)) raw_cached = self._cache.get(cache_key) serialized = memcache_crypt.unprotect_data(keys, raw_cached) except Exception: msg = 'Failed to decrypt/verify cache data' self.logger.exception(msg) serialized = None #if serialized is None: # return None if serialized and timestamp == policy[0]['timestamp']: cached = jsonutils.loads(serialized) self.logger.debug('Policy is synced') return cached else: #self.LOG.debug('Cached Policy %s seems expired', policy) new_policy = self._fetch_policy(token, policy[0]) self._cache_store(new_policy) return new_policy['blob']
def test_auth_url_token_authentication(self): fake_token = 'fake_token' fake_url = '/fake-url' fake_resp = {'result': True} self.stub_auth(json=self.TEST_RESPONSE_DICT) self.stub_url('GET', [fake_url], json=fake_resp, base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT) cl = client.Client(auth_url=self.TEST_URL, token=fake_token) body = httpretty.last_request().body if six.PY3: body = body.decode('utf-8') body = jsonutils.loads(body) self.assertEqual(body['auth']['token']['id'], fake_token) resp, body = cl.get(fake_url) self.assertEqual(fake_resp, body) self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'), self.TEST_TOKEN)
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 keystone """ kwargs = { 'headers': { 'Content-type': 'application/json', 'Accept': 'application/json', }, } if additional_headers: kwargs['headers'].update(additional_headers) if body: kwargs['data'] = jsonutils.dumps(body) path = self.auth_admin_prefix + path self.LOG.debug('Calling _http_request') response = self._http_request(method, path, **kwargs) try: data = jsonutils.loads(response.text) except ValueError: self.LOG.debug('Keystone did not return json-encoded body') data = {} return response, data
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 keystone """ kwargs = { 'headers': { 'Content-type': 'application/json', 'Accept': 'application/json', }, } if additional_headers: kwargs['headers'].update(additional_headers) if body: kwargs['data'] = jsonutils.dumps(body) path = self.auth_admin_prefix + path response = self._http_request(method, path, **kwargs) try: data = jsonutils.loads(response.text) except ValueError: self.LOG.debug('Keystone did not return json-encoded body') data = {} return response, data
# in the signing subdirectory. In order to keep the values consistent between # the tests and the signed documents, we read them in for use in the tests. with open(os.path.join(CMSDIR, "auth_token_scoped.pem")) as f: SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, "auth_token_unscoped.pem")) as f: SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, "auth_v3_token_scoped.pem")) as f: SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, "auth_token_revoked.pem")) as f: REVOKED_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, "auth_token_scoped_expired.pem")) as f: SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, "auth_v3_token_revoked.pem")) as f: REVOKED_v3_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, "revocation_list.json")) as f: REVOCATION_LIST = jsonutils.loads(f.read()) with open(os.path.join(CMSDIR, "revocation_list.pem")) as f: SIGNED_REVOCATION_LIST = jsonutils.dumps({"signed": f.read()}) with open(os.path.join(CERTDIR, "signing_cert.pem")) as f: SIGNING_CERT = f.read() with open(os.path.join(CERTDIR, "cacert.pem")) as f: SIGNING_CA = f.read() UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d" UUID_TOKEN_NO_SERVICE_CATALOG = "8286720fbe4941e69fa8241723bb02df" UUID_TOKEN_UNSCOPED = "731f903721c14827be7b2dc912af7776" VALID_DIABLO_TOKEN = "b0cf19b55dbb4f20a6ee18e6c6cf1726" v3_UUID_TOKEN_DEFAULT = "5603457654b346fdbb93437bfe76f2f1" v3_UUID_TOKEN_UNSCOPED = "d34835fdaec447e695a0a024d84f8d79" v3_UUID_TOKEN_DOMAIN_SCOPED = "e8a7b63aaa4449f38f0c5c05c3581792"
def load_json(cls, data, default_rule=None): """Init a brain using json instead of a rules dictionary.""" rules_dict = jsonutils.loads(data) return cls(rules=rules_dict, default_rule=default_rule)
# in the signing subdirectory. In order to keep the values consistent between # the tests and the signed documents, we read them in for use in the tests. with open(os.path.join(CMSDIR, 'auth_token_scoped.pem')) as f: SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_unscoped.pem')) as f: SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pem')) as f: SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f: REVOKED_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f: SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pem')) as f: REVOKED_v3_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'revocation_list.json')) as f: REVOCATION_LIST = jsonutils.loads(f.read()) with open(os.path.join(CMSDIR, 'revocation_list.pem')) as f: SIGNED_REVOCATION_LIST = jsonutils.dumps({'signed': f.read()}) with open(os.path.join(CERTDIR, 'signing_cert.pem')) as f: SIGNING_CERT = f.read() with open(os.path.join(CERTDIR, 'cacert.pem')) as f: SIGNING_CA = f.read() UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d" UUID_TOKEN_NO_SERVICE_CATALOG = '8286720fbe4941e69fa8241723bb02df' UUID_TOKEN_UNSCOPED = '731f903721c14827be7b2dc912af7776' VALID_DIABLO_TOKEN = 'b0cf19b55dbb4f20a6ee18e6c6cf1726' v3_UUID_TOKEN_DEFAULT = '5603457654b346fdbb93437bfe76f2f1' v3_UUID_TOKEN_UNSCOPED = 'd34835fdaec447e695a0a024d84f8d79' v3_UUID_TOKEN_DOMAIN_SCOPED = 'e8a7b63aaa4449f38f0c5c05c3581792'
def assertRequestBodyIs(self, body=None, json=None): if json: val = jsonutils.loads(httpretty.last_request().body) self.assertEqual(json, val) elif body: self.assertEqual(body, httpretty.last_request().body)
if body: kwargs['body'] = jsonutils.dumps(body) full_path = self.auth_admin_prefix + path try: conn.request(method, full_path, **kwargs) response = conn.getresponse() body = response.read() except Exception, e: self.logger.error('HTTP connection exception: %s' % e) raise ServiceError('Unable to communicate with keystone') finally: conn.close() try: data = jsonutils.loads(body) except ValueError: self.logger.debug('Keystone did not return json-encoded body') data = {} return response, data def _request_admin_token(self): """Retrieve new token as admin user from keystone. :return token id upon success :raises ServerError when unable to communicate with keystone """ params = { 'auth': {
def test_fetch_revocation_list(self): # auth_token uses v2 to fetch this, so don't allow the v3 # tests to override the fake http connection self.set_fake_http(FakeHTTPConnection) fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list()) self.assertEqual(fetched_list, REVOCATION_LIST)
def test_fetch_revocation_list(self): fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list()) self.assertEqual(fetched_list, REVOCATION_LIST)
def test_fetch_revocation_list(self): # auth_token uses v2 to fetch this, so don't allow the v3 # tests to override the fake http connection self.set_fake_http(FakeHTTPConnection) fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list()) self.assertEqual(fetched_list, client_fixtures.REVOCATION_LIST)
def test_fetch_revocation_list(self): # auth_token uses v2 to fetch this, so don't allow the v3 # tests to override the fake http connection fetched_list = jsonutils.loads(self.middleware.fetch_revocation_list()) self.assertEqual(fetched_list, client_fixtures.REVOCATION_LIST)
def setUp(self): super(Examples, self).setUp() # The data for several tests are signed using openssl and are stored in # files in the signing subdirectory. In order to keep the values # consistent between the tests and the signed documents, we read them # in for use in the tests. with open(os.path.join(CMSDIR, 'auth_token_scoped.pem')) as f: self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_unscoped.pem')) as f: self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pem')) as f: self.SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f: self.REVOKED_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f: self.SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pem')) as f: self.REVOKED_v3_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'revocation_list.json')) as f: self.REVOCATION_LIST = jsonutils.loads(f.read()) with open(os.path.join(CMSDIR, 'revocation_list.pem')) as f: self.SIGNED_REVOCATION_LIST = jsonutils.dumps({'signed': f.read()}) self.SIGNING_CERT_FILE = os.path.join(CERTDIR, 'signing_cert.pem') with open(self.SIGNING_CERT_FILE) as f: self.SIGNING_CERT = f.read() self.KERBEROS_BIND = 'USER@REALM' self.SIGNING_KEY_FILE = os.path.join(KEYDIR, 'signing_key.pem') with open(self.SIGNING_KEY_FILE) as f: self.SIGNING_KEY = f.read() self.SIGNING_CA_FILE = os.path.join(CERTDIR, 'cacert.pem') with open(self.SIGNING_CA_FILE) as f: self.SIGNING_CA = f.read() self.UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d" self.UUID_TOKEN_NO_SERVICE_CATALOG = '8286720fbe4941e69fa8241723bb02df' self.UUID_TOKEN_UNSCOPED = '731f903721c14827be7b2dc912af7776' self.UUID_TOKEN_BIND = '3fc54048ad64405c98225ce0897af7c5' self.UUID_TOKEN_UNKNOWN_BIND = '8885fdf4d42e4fb9879e6379fa1eaf48' self.VALID_DIABLO_TOKEN = 'b0cf19b55dbb4f20a6ee18e6c6cf1726' self.v3_UUID_TOKEN_DEFAULT = '5603457654b346fdbb93437bfe76f2f1' self.v3_UUID_TOKEN_UNSCOPED = 'd34835fdaec447e695a0a024d84f8d79' self.v3_UUID_TOKEN_DOMAIN_SCOPED = 'e8a7b63aaa4449f38f0c5c05c3581792' self.v3_UUID_TOKEN_BIND = '2f61f73e1c854cbb9534c487f9bd63c2' self.v3_UUID_TOKEN_UNKNOWN_BIND = '7ed9781b62cd4880b8d8c6788ab1d1e2' revoked_token = self.REVOKED_TOKEN if isinstance(revoked_token, six.text_type): revoked_token = revoked_token.encode('utf-8') self.REVOKED_TOKEN_HASH = utils.hash_signed_token(revoked_token) self.REVOKED_TOKEN_LIST = ( {'revoked': [{'id': self.REVOKED_TOKEN_HASH, 'expires': timeutils.utcnow()}]}) self.REVOKED_TOKEN_LIST_JSON = jsonutils.dumps(self.REVOKED_TOKEN_LIST) revoked_v3_token = self.REVOKED_v3_TOKEN if isinstance(revoked_v3_token, six.text_type): revoked_v3_token = revoked_v3_token.encode('utf-8') self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token(revoked_v3_token) self.REVOKED_v3_TOKEN_LIST = ( {'revoked': [{'id': self.REVOKED_v3_TOKEN_HASH, 'expires': timeutils.utcnow()}]}) self.REVOKED_v3_TOKEN_LIST_JSON = jsonutils.dumps( self.REVOKED_v3_TOKEN_LIST) self.SIGNED_TOKEN_SCOPED_KEY = cms.cms_hash_token( self.SIGNED_TOKEN_SCOPED) self.SIGNED_TOKEN_UNSCOPED_KEY = cms.cms_hash_token( self.SIGNED_TOKEN_UNSCOPED) self.SIGNED_v3_TOKEN_SCOPED_KEY = cms.cms_hash_token( self.SIGNED_v3_TOKEN_SCOPED) self.INVALID_SIGNED_TOKEN = ( "MIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" "0000000000000000000000000000000000000000000000000000000000000000" "1111111111111111111111111111111111111111111111111111111111111111" "2222222222222222222222222222222222222222222222222222222222222222" "3333333333333333333333333333333333333333333333333333333333333333" "4444444444444444444444444444444444444444444444444444444444444444" "5555555555555555555555555555555555555555555555555555555555555555" "6666666666666666666666666666666666666666666666666666666666666666" "7777777777777777777777777777777777777777777777777777777777777777" "8888888888888888888888888888888888888888888888888888888888888888" "9999999999999999999999999999999999999999999999999999999999999999" "0000000000000000000000000000000000000000000000000000000000000000") # JSON responses keyed by token ID self.TOKEN_RESPONSES = { self.UUID_TOKEN_DEFAULT: { 'access': { 'token': { 'id': self.UUID_TOKEN_DEFAULT, 'expires': '2020-01-01T00:00:10.000123Z', 'tenant': { 'id': 'tenant_id1', 'name': 'tenant_name1', }, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, 'serviceCatalog': {} }, }, self.VALID_DIABLO_TOKEN: { 'access': { 'token': { 'id': self.VALID_DIABLO_TOKEN, 'expires': '2020-01-01T00:00:10.000123Z', 'tenantId': 'tenant_id1', }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, }, self.UUID_TOKEN_UNSCOPED: { 'access': { 'token': { 'id': self.UUID_TOKEN_UNSCOPED, 'expires': '2020-01-01T00:00:10.000123Z', }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, }, self.UUID_TOKEN_NO_SERVICE_CATALOG: { 'access': { 'token': { 'id': 'valid-token', 'expires': '2020-01-01T00:00:10.000123Z', 'tenant': { 'id': 'tenant_id1', 'name': 'tenant_name1', }, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], } }, }, self.UUID_TOKEN_BIND: { 'access': { 'token': { 'bind': {'kerberos': self.KERBEROS_BIND}, 'id': self.UUID_TOKEN_BIND, 'expires': '2020-01-01T00:00:10.000123Z', 'tenant': { 'id': 'tenant_id1', 'name': 'tenant_name1', }, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, 'serviceCatalog': {} }, }, self.UUID_TOKEN_UNKNOWN_BIND: { 'access': { 'token': { 'bind': {'FOO': 'BAR'}, 'id': self.UUID_TOKEN_UNKNOWN_BIND, 'expires': '2020-01-01T00:00:10.000123Z', 'tenant': { 'id': 'tenant_id1', 'name': 'tenant_name1', }, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, 'serviceCatalog': {} }, }, self.v3_UUID_TOKEN_DEFAULT: { 'token': { 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'project': { 'id': 'tenant_id1', 'name': 'tenant_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'roles': [ {'name': 'role1', 'id': 'Role1'}, {'name': 'role2', 'id': 'Role2'}, ], 'catalog': {} } }, self.v3_UUID_TOKEN_UNSCOPED: { 'token': { 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } } } }, self.v3_UUID_TOKEN_DOMAIN_SCOPED: { 'token': { 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'domain': { 'id': 'domain_id1', 'name': 'domain_name1', }, 'roles': [ {'name': 'role1', 'id': 'Role1'}, {'name': 'role2', 'id': 'Role2'}, ], 'catalog': {} } }, self.SIGNED_TOKEN_SCOPED_KEY: { 'access': { 'token': { 'id': self.SIGNED_TOKEN_SCOPED_KEY, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'tenantId': 'tenant_id1', 'tenantName': 'tenant_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, }, self.SIGNED_TOKEN_UNSCOPED_KEY: { 'access': { 'token': { 'id': self.SIGNED_TOKEN_UNSCOPED_KEY, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, }, self.SIGNED_v3_TOKEN_SCOPED_KEY: { 'token': { 'expires': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'project': { 'id': 'tenant_id1', 'name': 'tenant_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'roles': [ {'name': 'role1'}, {'name': 'role2'} ], 'catalog': {} } }, self.v3_UUID_TOKEN_BIND: { 'token': { 'bind': {'kerberos': self.KERBEROS_BIND}, 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'project': { 'id': 'tenant_id1', 'name': 'tenant_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'roles': [ {'name': 'role1', 'id': 'Role1'}, {'name': 'role2', 'id': 'Role2'}, ], 'catalog': {} } }, self.v3_UUID_TOKEN_UNKNOWN_BIND: { 'token': { 'bind': {'FOO': 'BAR'}, 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'project': { 'id': 'tenant_id1', 'name': 'tenant_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'roles': [ {'name': 'role1', 'id': 'Role1'}, {'name': 'role2', 'id': 'Role2'}, ], 'catalog': {} } }, } self.JSON_TOKEN_RESPONSES = dict([(k, jsonutils.dumps(v)) for k, v in six.iteritems(self.TOKEN_RESPONSES)])
def setUp(self): super(Examples, self).setUp() # The data for several tests are signed using openssl and are stored in # files in the signing subdirectory. In order to keep the values # consistent between the tests and the signed documents, we read them # in for use in the tests. with open(os.path.join(CMSDIR, 'auth_token_scoped.pem')) as f: self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_unscoped.pem')) as f: self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pem')) as f: self.SIGNED_v3_TOKEN_SCOPED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f: self.REVOKED_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f: self.SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pem')) as f: self.REVOKED_v3_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'revocation_list.json')) as f: self.REVOCATION_LIST = jsonutils.loads(f.read()) with open(os.path.join(CMSDIR, 'revocation_list.pem')) as f: self.SIGNED_REVOCATION_LIST = jsonutils.dumps({'signed': f.read()}) self.SIGNING_CERT_FILE = os.path.join(CERTDIR, 'signing_cert.pem') with open(self.SIGNING_CERT_FILE) as f: self.SIGNING_CERT = f.read() self.KERBEROS_BIND = 'USER@REALM' self.SIGNING_KEY_FILE = os.path.join(KEYDIR, 'signing_key.pem') with open(self.SIGNING_KEY_FILE) as f: self.SIGNING_KEY = f.read() self.SIGNING_CA_FILE = os.path.join(CERTDIR, 'cacert.pem') with open(self.SIGNING_CA_FILE) as f: self.SIGNING_CA = f.read() self.UUID_TOKEN_DEFAULT = "ec6c0710ec2f471498484c1b53ab4f9d" self.UUID_TOKEN_NO_SERVICE_CATALOG = '8286720fbe4941e69fa8241723bb02df' self.UUID_TOKEN_UNSCOPED = '731f903721c14827be7b2dc912af7776' self.UUID_TOKEN_BIND = '3fc54048ad64405c98225ce0897af7c5' self.UUID_TOKEN_UNKNOWN_BIND = '8885fdf4d42e4fb9879e6379fa1eaf48' self.VALID_DIABLO_TOKEN = 'b0cf19b55dbb4f20a6ee18e6c6cf1726' self.v3_UUID_TOKEN_DEFAULT = '5603457654b346fdbb93437bfe76f2f1' self.v3_UUID_TOKEN_UNSCOPED = 'd34835fdaec447e695a0a024d84f8d79' self.v3_UUID_TOKEN_DOMAIN_SCOPED = 'e8a7b63aaa4449f38f0c5c05c3581792' self.v3_UUID_TOKEN_BIND = '2f61f73e1c854cbb9534c487f9bd63c2' self.v3_UUID_TOKEN_UNKNOWN_BIND = '7ed9781b62cd4880b8d8c6788ab1d1e2' self.REVOKED_TOKEN_HASH = utils.hash_signed_token(self.REVOKED_TOKEN) self.REVOKED_TOKEN_LIST = ( {'revoked': [{'id': self.REVOKED_TOKEN_HASH, 'expires': timeutils.utcnow()}]}) self.REVOKED_TOKEN_LIST_JSON = jsonutils.dumps(self.REVOKED_TOKEN_LIST) self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token( self.REVOKED_v3_TOKEN) self.REVOKED_v3_TOKEN_LIST = ( {'revoked': [{'id': self.REVOKED_v3_TOKEN_HASH, 'expires': timeutils.utcnow()}]}) self.REVOKED_v3_TOKEN_LIST_JSON = jsonutils.dumps( self.REVOKED_v3_TOKEN_LIST) self.SIGNED_TOKEN_SCOPED_KEY = cms.cms_hash_token( self.SIGNED_TOKEN_SCOPED) self.SIGNED_TOKEN_UNSCOPED_KEY = cms.cms_hash_token( self.SIGNED_TOKEN_UNSCOPED) self.SIGNED_v3_TOKEN_SCOPED_KEY = cms.cms_hash_token( self.SIGNED_v3_TOKEN_SCOPED) self.INVALID_SIGNED_TOKEN = ( "MIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" "0000000000000000000000000000000000000000000000000000000000000000" "1111111111111111111111111111111111111111111111111111111111111111" "2222222222222222222222222222222222222222222222222222222222222222" "3333333333333333333333333333333333333333333333333333333333333333" "4444444444444444444444444444444444444444444444444444444444444444" "5555555555555555555555555555555555555555555555555555555555555555" "6666666666666666666666666666666666666666666666666666666666666666" "7777777777777777777777777777777777777777777777777777777777777777" "8888888888888888888888888888888888888888888888888888888888888888" "9999999999999999999999999999999999999999999999999999999999999999" "0000000000000000000000000000000000000000000000000000000000000000") # JSON responses keyed by token ID self.TOKEN_RESPONSES = { self.UUID_TOKEN_DEFAULT: { 'access': { 'token': { 'id': self.UUID_TOKEN_DEFAULT, 'expires': '2020-01-01T00:00:10.000123Z', 'tenant': { 'id': 'tenant_id1', 'name': 'tenant_name1', }, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, 'serviceCatalog': {} }, }, self.VALID_DIABLO_TOKEN: { 'access': { 'token': { 'id': self.VALID_DIABLO_TOKEN, 'expires': '2020-01-01T00:00:10.000123Z', 'tenantId': 'tenant_id1', }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, }, self.UUID_TOKEN_UNSCOPED: { 'access': { 'token': { 'id': self.UUID_TOKEN_UNSCOPED, 'expires': '2020-01-01T00:00:10.000123Z', }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, }, self.UUID_TOKEN_NO_SERVICE_CATALOG: { 'access': { 'token': { 'id': 'valid-token', 'expires': '2020-01-01T00:00:10.000123Z', 'tenant': { 'id': 'tenant_id1', 'name': 'tenant_name1', }, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], } }, }, self.UUID_TOKEN_BIND: { 'access': { 'token': { 'bind': {'kerberos': self.KERBEROS_BIND}, 'id': self.UUID_TOKEN_BIND, 'expires': '2020-01-01T00:00:10.000123Z', 'tenant': { 'id': 'tenant_id1', 'name': 'tenant_name1', }, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, 'serviceCatalog': {} }, }, self.UUID_TOKEN_UNKNOWN_BIND: { 'access': { 'token': { 'bind': {'FOO': 'BAR'}, 'id': self.UUID_TOKEN_UNKNOWN_BIND, 'expires': '2020-01-01T00:00:10.000123Z', 'tenant': { 'id': 'tenant_id1', 'name': 'tenant_name1', }, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, 'serviceCatalog': {} }, }, self.v3_UUID_TOKEN_DEFAULT: { 'token': { 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'project': { 'id': 'tenant_id1', 'name': 'tenant_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'roles': [ {'name': 'role1', 'id': 'Role1'}, {'name': 'role2', 'id': 'Role2'}, ], 'catalog': {} } }, self.v3_UUID_TOKEN_UNSCOPED: { 'token': { 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } } } }, self.v3_UUID_TOKEN_DOMAIN_SCOPED: { 'token': { 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'domain': { 'id': 'domain_id1', 'name': 'domain_name1', }, 'roles': [ {'name': 'role1', 'id': 'Role1'}, {'name': 'role2', 'id': 'Role2'}, ], 'catalog': {} } }, self.SIGNED_TOKEN_SCOPED_KEY: { 'access': { 'token': { 'id': self.SIGNED_TOKEN_SCOPED_KEY, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'tenantId': 'tenant_id1', 'tenantName': 'tenant_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, }, self.SIGNED_TOKEN_UNSCOPED_KEY: { 'access': { 'token': { 'id': self.SIGNED_TOKEN_UNSCOPED_KEY, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ {'name': 'role1'}, {'name': 'role2'}, ], }, }, }, self.SIGNED_v3_TOKEN_SCOPED_KEY: { 'token': { 'expires': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'project': { 'id': 'tenant_id1', 'name': 'tenant_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'roles': [ {'name': 'role1'}, {'name': 'role2'} ], 'catalog': {} } }, self.v3_UUID_TOKEN_BIND: { 'token': { 'bind': {'kerberos': self.KERBEROS_BIND}, 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'project': { 'id': 'tenant_id1', 'name': 'tenant_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'roles': [ {'name': 'role1', 'id': 'Role1'}, {'name': 'role2', 'id': 'Role2'}, ], 'catalog': {} } }, self.v3_UUID_TOKEN_UNKNOWN_BIND: { 'token': { 'bind': {'FOO': 'BAR'}, 'expires_at': '2020-01-01T00:00:10.000123Z', 'user': { 'id': 'user_id1', 'name': 'user_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'project': { 'id': 'tenant_id1', 'name': 'tenant_name1', 'domain': { 'id': 'domain_id1', 'name': 'domain_name1' } }, 'roles': [ {'name': 'role1', 'id': 'Role1'}, {'name': 'role2', 'id': 'Role2'}, ], 'catalog': {} } }, } self.JSON_TOKEN_RESPONSES = dict([(k, jsonutils.dumps(v)) for k, v in six.iteritems(self.TOKEN_RESPONSES)])