def request(self, method, path, **kwargs): """Fakes out several http responses. If a POST request is made, we assume the calling code is trying to get a new admin token. If a GET request is made to validate a token, return success if the token is 'token1'. If a different token is provided, return a 404, indicating an unknown (therefore unauthorized) token. """ FakeHTTPConnection.last_requested_url = path if method == 'POST': status = 200 body = jsonutils.dumps({ 'access': { 'token': { 'id': 'admin_token2' }, }, }) else: token_id = path.rsplit('/', 1)[1] if token_id in TOKEN_RESPONSES.keys(): status = 200 body = jsonutils.dumps(TOKEN_RESPONSES[token_id]) elif token_id == "revoked": status = 200 body = SIGNED_REVOCATION_LIST else: status = 404 body = str() self.resp = FakeHTTPResponse(status, body)
def request(self, method, path, **kwargs): """Fakes out several http responses. If a POST request is made, we assume the calling code is trying to get a new admin token. If a GET request is made to validate a token, return success if the token is 'token1'. If a different token is provided, return a 404, indicating an unknown (therefore unauthorized) token. """ FakeHTTPConnection.last_requested_url = path if method == 'POST': status = 200 body = jsonutils.dumps({ 'access': { 'token': {'id': 'admin_token2'}, }, }) else: token_id = path.rsplit('/', 1)[1] if token_id in TOKEN_RESPONSES.keys(): status = 200 body = jsonutils.dumps(TOKEN_RESPONSES[token_id]) elif token_id == "revoked": status = 200 body = SIGNED_REVOCATION_LIST else: status = 404 body = str() self.resp = FakeHTTPResponse(status, body)
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, REVOCATION_LIST)
def request(self, method, path, **kwargs): """Fakes out several http responses. If a POST request is made, we assume the calling code is trying to get a new admin token. If a GET request is made to validate a token, return success if the token is 'token1'. If a different token is provided, return a 404, indicating an unknown (therefore unauthorized) token. """ if method == "POST": status = 200 body = jsonutils.dumps({"access": {"token": {"id": "admin_token2"}}}) else: token_id = path.rsplit("/", 1)[1] if token_id in TOKEN_RESPONSES.keys(): status = 200 body = jsonutils.dumps(TOKEN_RESPONSES[token_id]) else: status = 404 body = str() self.resp = FakeHTTPResponse(status, body)
def convert_ec2_to_v3_credential(ec2credential): blob = {'access': ec2credential.access, 'secret': ec2credential.secret} return {'id': hash_access_key(ec2credential.access), 'user_id': ec2credential.user_id, 'project_id': ec2credential.tenant_id, 'blob': jsonutils.dumps(blob), 'type': 'ec2', 'extra': jsonutils.dumps({})}
def __call__(self, target, creds, enforcer): """Check http: rules by calling to a remote server. This example implementation simply verifies that the response is exactly 'True'. """ url = ("http:" + self.match) % target data = {"target": jsonutils.dumps(target), "credentials": jsonutils.dumps(creds)} post_data = urlparse.urlencode(data) f = urlrequest.urlopen(url, post_data) return f.read() == "True"
def __call__(self, target, creds, enforcer): """Check http: rules by calling to a remote server. This example implementation simply verifies that the response is exactly 'True'. """ url = ('http:' + self.match) % target data = {'target': jsonutils.dumps(target), 'credentials': jsonutils.dumps(creds)} post_data = urlparse.urlencode(data) f = urlrequest.urlopen(url, post_data) return f.read() == "True"
def __call__(self, target, creds): """ Check http: rules by calling to a remote server. This example implementation simply verifies that the response is exactly 'True'. """ url = ('http:' + self.match) % target data = {'target': jsonutils.dumps(target), 'credentials': jsonutils.dumps(creds)} post_data = urllib.urlencode(data) f = urllib2.urlopen(url, post_data) return f.read() == "True"
def _check_http(self, match, target_dict, cred_dict): """Check http: rules by calling to a remote server. This example implementation simply verifies that the response is exactly 'True'. A custom brain using response codes could easily be implemented. """ url = match % target_dict data = {'target': jsonutils.dumps(target_dict), 'credentials': jsonutils.dumps(cred_dict)} post_data = urllib.urlencode(data) f = urllib2.urlopen(url, post_data) return f.read() == "True"
def _pack_json_msg(self, msg): """Qpid cannot serialize dicts containing strings longer than 65535 characters. This function dumps the message content to a JSON string, which Qpid is able to handle. :param msg: May be either a Qpid Message object or a bare dict. :returns: A Qpid Message with its content field JSON encoded. """ try: msg.content = jsonutils.dumps(msg.content) except AttributeError: # Need to have a Qpid message so we can set the content_type. msg = qpid_messaging.Message(jsonutils.dumps(msg)) msg.content_type = JSON_CONTENT_TYPE return msg
def render_response(body=None, status=None, headers=None): """Forms a WSGI response.""" if headers is None: headers = [] else: headers = list(headers) headers.append(('Vary', 'X-Auth-Token')) if body is None: body = '' status = status or (204, 'No Content') else: content_types = [v for h, v in headers if h == 'Content-Type'] if content_types: content_type = content_types[0] else: content_type = None if content_type is None or content_type == 'application/json': body = jsonutils.dumps(body, cls=utils.SmarterEncoder) if content_type is None: headers.append(('Content-Type', 'application/json')) status = status or (200, 'OK') return webob.Response(body=body, status='%s %s' % status, headerlist=headers)
def get_ticket(self, source, target, crypto, key): # prepare metadata md = {'requestor': source, 'target': target, 'timestamp': time.time(), 'nonce': struct.unpack('Q', os.urandom(8))[0]} metadata = base64.b64encode(jsonutils.dumps(md)) # sign metadata signature = crypto.sign(key, metadata) # HTTP request reply = self._get_ticket({'metadata': metadata, 'signature': signature}) # verify reply signature = crypto.sign(key, (reply['metadata'] + reply['ticket'])) if signature != reply['signature']: raise InvalidEncryptedTicket(md['source'], md['destination']) md = jsonutils.loads(base64.b64decode(reply['metadata'])) if ((md['source'] != source or md['destination'] != target or md['expiration'] < time.time())): raise InvalidEncryptedTicket(md['source'], md['destination']) # return ticket data tkt = jsonutils.loads(crypto.decrypt(key, reply['ticket'])) return tkt, md['expiration']
def create_credential(self, context, user_id, tenant_id): """Create a secret/access pair for use with ec2 style auth. Generates a new set of credentials that map the user/tenant pair. :param context: standard context :param user_id: id of user :param tenant_id: id of tenant :returns: credential: dict of ec2 credential """ self.identity_api.get_user(user_id) self.assignment_api.get_project(tenant_id) trust_id = self._get_trust_id_for_request(context) blob = {"access": uuid.uuid4().hex, "secret": uuid.uuid4().hex, "trust_id": trust_id} credential_id = utils.hash_access_key(blob["access"]) cred_ref = { "user_id": user_id, "project_id": tenant_id, "blob": jsonutils.dumps(blob), "id": credential_id, "type": "ec2", } self.credential_api.create_credential(credential_id, cred_ref) return {"credential": self._convert_v3_to_ec2_credential(cred_ref)}
def encode(self, version, target, json_msg): """This is the main encoding function. It takes a target and a message and returns a tuple consisting of a JSON serialized metadata object, a JSON serialized (and optionally encrypted) message, and a signature. :param version: the current envelope version :param target: The name of the target service (usually with hostname) :param json_msg: a serialized json message object """ ticket = self._get_ticket(target) metadata = jsonutils.dumps({'source': self._name, 'destination': target, 'timestamp': time.time(), 'nonce': _get_nonce(), 'esek': ticket.esek, 'encryption': self._encrypt}) message = json_msg if self._encrypt: message = self._crypto.encrypt(ticket.ekey, message) signature = self._crypto.sign(ticket.skey, version + metadata + message) return (metadata, message, signature)
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, e: LOG.error('HTTP connection exception: %s' % e) raise ServiceError('Unable to communicate with keystone')
def _assign_unique_id(self, ref, trust_id=None): # Generates and assigns a unique identifier to # a credential reference. if ref.get('type', '').lower() == 'ec2': try: blob = jsonutils.loads(ref.get('blob')) except (ValueError, TypeError): raise exception.ValidationError( message=_('Invalid blob in credential')) if not blob or not isinstance(blob, dict): raise exception.ValidationError(attribute='blob', target='credential') if blob.get('access') is None: raise exception.ValidationError(attribute='access', target='blob') ret_ref = ref.copy() ret_ref['id'] = hashlib.sha256(blob['access']).hexdigest() # Update the blob with the trust_id, so credentials created # with a trust scoped token will result in trust scoped # tokens when authentication via ec2tokens happens if trust_id is not None: blob['trust_id'] = trust_id ret_ref['blob'] = jsonutils.dumps(blob) return ret_ref else: return super(CredentialV3, self)._assign_unique_id(ref)
def _add_to_revocation_list(self, data): data_json = jsonutils.dumps(data) if not self.client.append(self.revocation_key, ",%s" % data_json): if not self.client.add(self.revocation_key, data_json): if not self.client.append(self.revocation_key, ",%s" % data_json): msg = _("Unable to add token to revocation list.") raise exception.UnexpectedError(msg)
def __init__(self, session, node_name, node_opts=None): """Init the Publisher class with the exchange_name, routing_key, and other options """ self.sender = None self.session = session addr_opts = { "create": "always", "node": { "type": "topic", "x-declare": { "durable": False, # auto-delete isn't implemented for exchanges in qpid, # but put in here anyway "auto-delete": True, }, }, } if node_opts: addr_opts["node"]["x-declare"].update(node_opts) self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts)) self.reconnect(session)
def render_response(body=None, status=None, headers=None, method=None): """Forms a WSGI response.""" headers = headers or [] headers.append(('Vary', 'X-Auth-Token')) if body is None: body = '' status = status or (204, 'No Content') else: body = jsonutils.dumps(body, cls=utils.SmarterEncoder) headers.append(('Content-Type', 'application/json')) status = status or (200, 'OK') resp = webob.Response(body=body, status='%s %s' % status, headerlist=headers) if method == 'HEAD': # NOTE(morganfainberg): HEAD requests should return the same status # as a GET request and same headers (including content-type and # content-length). The webob.Response object automatically changes # content-length (and other headers) if the body is set to b''. Capture # all headers and reset them on the response object after clearing the # body. The body can only be set to a binary-type (not TextType or # NoneType), so b'' is used here and should be compatible with # both py2x and py3x. stored_headers = resp.headers.copy() resp.body = b'' for header, value in six.iteritems(stored_headers): resp.headers[header] = value return resp
def setUp(self, expected_env=None): expected_env = expected_env or {} conf = { 'admin_token': 'admin_token1', 'auth_host': 'keystone.example.com', 'auth_port': 1234, 'auth_admin_prefix': '/testadmin', 'signing_dir': 'signing', } self.middleware = auth_token.AuthProtocol(FakeApp(expected_env), conf) self.middleware.http_client_class = FakeHTTPConnection self.middleware._iso8601 = iso8601 self.response_status = None self.response_headers = None self.middleware.revoked_file_name = tempfile.mkstemp()[1] self.middleware.token_revocation_list_cache_timeout =\ datetime.timedelta(days=1) self.middleware.token_revocation_list = jsonutils.dumps({ "revoked": [], "extra": "success" }) globals()['SIGNED_REVOCATION_LIST'] =\ globals()['VALID_SIGNED_REVOCATION_LIST'] super(BaseAuthTokenMiddlewareTest, self).setUp()
def format(self, record): message = { 'message': record.getMessage(), 'asctime': self.formatTime(record, self.datefmt), 'name': record.name, 'msg': record.msg, 'args': record.args, 'levelname': record.levelname, 'levelno': record.levelno, 'pathname': record.pathname, 'filename': record.filename, 'module': record.module, 'lineno': record.lineno, 'funcname': record.funcName, 'created': record.created, 'msecs': record.msecs, 'relative_created': record.relativeCreated, 'thread': record.thread, 'thread_name': record.threadName, 'process_name': record.processName, 'process': record.process, 'traceback': None } if hasattr(record, 'extra'): message['extra'] = record.extra if record.exc_info: message['traceback'] = self.formatException(record.exc_info) return jsonutils.dumps(message)
def __init__(self, conf, session, node_name, node_opts=None): """Init the Publisher class with the exchange_name, routing_key, and other options """ self.sender = None self.session = session if conf.qpid_topology_version == 1: addr_opts = { "create": "always", "node": { "type": "topic", "x-declare": { "durable": False, # auto-delete isn't implemented for exchanges in qpid, # but put in here anyway "auto-delete": True, }, }, } if node_opts: addr_opts["node"]["x-declare"].update(node_opts) self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts)) elif conf.qpid_topology_version == 2: self.address = node_name else: raise_invalid_topology_version() self.reconnect(session)
def _migrate_enabled_to_extra(migrate_engine, endpoint_table): """Get enabled value from 'enabled' column and put it in 'extra' JSON. Only put the enabled value to the 'extra' JSON if it's False, since the default is True. """ eps = list(endpoint_table.select().execute()) for ep in eps: if ep.enabled: # Nothing to do since the endpoint is enabled. continue extra_dict = jsonutils.loads(ep.extra) extra_dict['enabled'] = False new_values = { 'extra': jsonutils.dumps(extra_dict), } f = endpoint_table.c.id == ep.id update = endpoint_table.update().where(f).values(new_values) migrate_engine.execute(update)
def _migrate_enabled_from_extra(migrate_engine, endpoint_table): """Remove `enabled` from `extra`, put it in the `enabled` column.""" eps = list(endpoint_table.select().execute()) for ep in eps: extra_dict = jsonutils.loads(ep.extra) if 'enabled' not in extra_dict: # `enabled` and `extra` are already as expected. continue enabled = extra_dict.pop('enabled') if enabled is None: enabled = True else: enabled = strutils.bool_from_string(enabled, default=True) new_values = { 'enabled': enabled, 'extra': jsonutils.dumps(extra_dict), } f = endpoint_table.c.id == ep.id update = endpoint_table.update().where(f).values(new_values) migrate_engine.execute(update)
def good_request(cls, method, path, **kwargs): cls.status = 201 ret = {'access': {'token': {'id': 'TOKEN_ID', 'tenant': {'id': 'TENANT_ID'}}}} body = jsonutils.dumps(ret) cls.resp = FakeHTTPResponse(cls.status, body)
def create_credential(self, context, user_id, tenant_id): """Create a secret/access pair for use with ec2 style auth. Generates a new set of credentials that map the user/tenant pair. :param context: standard context :param user_id: id of user :param tenant_id: id of tenant :returns: credential: dict of ec2 credential """ self.identity_api.get_user(user_id) self.assignment_api.get_project(tenant_id) trust_id = self._get_trust_id_for_request(context) blob = {'access': uuid.uuid4().hex, 'secret': uuid.uuid4().hex, 'trust_id': trust_id} credential_id = utils.hash_access_key(blob['access']) cred_ref = {'user_id': user_id, 'project_id': tenant_id, 'blob': jsonutils.dumps(blob), 'id': credential_id, 'type': 'ec2'} self.credential_api.create_credential(credential_id, cred_ref) return {'credential': self._convert_v3_to_ec2_credential(cred_ref)}
def setUp(self, expected_env=None): expected_env = expected_env or {} conf = { 'admin_token': 'admin_token1', 'auth_host': 'keystone.example.com', 'auth_port': 1234, 'auth_admin_prefix': '/testadmin', 'signing_dir': CERTDIR, } self.middleware = auth_token.AuthProtocol(FakeApp(expected_env), conf) self.middleware.http_client_class = FakeHTTPConnection self.middleware._iso8601 = iso8601 self.response_status = None self.response_headers = None self.middleware.revoked_file_name = tempfile.mkstemp()[1] cache_timeout = datetime.timedelta(days=1) self.middleware.token_revocation_list_cache_timeout = cache_timeout self.middleware.token_revocation_list = jsonutils.dumps( {"revoked": [], "extra": "success"}) signed_list = 'SIGNED_REVOCATION_LIST' valid_signed_list = 'VALID_SIGNED_REVOCATION_LIST' globals()[signed_list] = globals()[valid_signed_list] super(BaseAuthTokenMiddlewareTest, self).setUp()
def create_credential(self, context, user_id, tenant_id): """Create a secret/access pair for use with ec2 style auth. Generates a new set of credentials that map the user/tenant pair. :param context: standard context :param user_id: id of user :param tenant_id: id of tenant :returns: credential: dict of ec2 credential """ if not self._is_admin(context): self._assert_identity(context, user_id) self._assert_valid_user_id(user_id) self._assert_valid_project_id(tenant_id) trust_id = self._get_trust_id_for_request(context) blob = {'access': uuid.uuid4().hex, 'secret': uuid.uuid4().hex, 'trust_id': trust_id} credential_id = utils.hash_access_key(blob['access']) cred_ref = {'user_id': user_id, 'project_id': tenant_id, 'blob': jsonutils.dumps(blob), 'id': credential_id, 'type': 'ec2'} self.credential_api.create_credential(credential_id, cred_ref) return {'credential': self._convert_v3_to_ec2_credential(cred_ref)}
def serialize_msg(raw_msg): # NOTE(russellb) See the docstring for _RPC_ENVELOPE_VERSION for more # information about this format. msg = {_VERSION_KEY: _RPC_ENVELOPE_VERSION, _MESSAGE_KEY: jsonutils.dumps(raw_msg)} return msg
def format(self, record): message = {'message': record.getMessage(), 'asctime': self.formatTime(record, self.datefmt), 'name': record.name, 'msg': record.msg, 'args': record.args, 'levelname': record.levelname, 'levelno': record.levelno, 'pathname': record.pathname, 'filename': record.filename, 'module': record.module, 'lineno': record.lineno, 'funcname': record.funcName, 'created': record.created, 'msecs': record.msecs, 'relative_created': record.relativeCreated, 'thread': record.thread, 'thread_name': record.threadName, 'process_name': record.processName, 'process': record.process, 'traceback': None} if hasattr(record, 'extra'): message['extra'] = record.extra if record.exc_info: message['traceback'] = self.formatException(record.exc_info) return jsonutils.dumps(message)
def request(self, method, path, **kwargs): ret = {"error": {"message": "EC2 access key not found.", "code": 401, "title": "Unauthorized"}} body = jsonutils.dumps(ret) self.status = 403 self.resp = FakeHTTPResponse(self.status, body)
def _add_to_revocation_list(self, data): data_json = jsonutils.dumps(data) if not self.client.append(self.revocation_key, ',%s' % data_json): if not self.client.add(self.revocation_key, data_json): if not self.client.append(self.revocation_key, ',%s' % data_json): msg = _('Unable to add token to revocation list.') raise exception.UnexpectedError(msg)
def request(self, method, path, **kwargs): if self.status == 503: raise Exception ret = {'access': {'token': {'id': 'TOKEN_ID', 'tenant': {'id': 'TENANT_ID'}}}} body = jsonutils.dumps(ret) status = self.status self.resp = FakeHTTPResponse(status, body)
def create_token(self, token_id, data): data_copy = copy.deepcopy(data) user_id = data_copy.get('user', None) if 'expires' not in data_copy: data_copy['expires'] = self._get_default_expire_time() json_data = jsonutils.dumps(data_copy) self._set_keys(user_id, token_id, json_data, self.ttl_seconds) return data_copy
def __call__(self, req): # Read request signature and access id. try: signature = req.params['Signature'] access = req.params['AWSAccessKeyId'] except KeyError: raise webob.exc.HTTPBadRequest() # Make a copy of args for authentication and signature verification. auth_params = dict(req.params) # Not part of authentication args auth_params.pop('Signature') # Authenticate the request. creds = { 'ec2Credentials': { 'access': access, 'signature': signature, 'host': req.host, 'verb': req.method, 'path': req.path, 'params': auth_params, } } creds_json = jsonutils.dumps(creds) headers = {'Content-Type': 'application/json'} verify = True if CONF.keystone_ec2_insecure: verify = False elif CONF.keystone_ec2_cafile: verify = CONF.keystone_ec2_cafile cert = None if CONF.keystone_ec2_certfile and CONF.keystone_ec2_keyfile: cert = (CONF.keystone_ec2_certfile, CONF.keystone_ec2_keyfile) elif CONF.keystone_ec2_certfile: cert = CONF.keystone_ec2_certfile response = requests.post(CONF.keystone_ec2_url, data=creds_json, headers=headers, verify=verify, cert=cert) # NOTE(vish): We could save a call to keystone by # having keystone return token, tenant, # user, and roles from this call. result = response.json() try: token_id = result['access']['token']['id'] except (AttributeError, KeyError): raise webob.exc.HTTPBadRequest() # Authenticated! req.headers['X-Auth-Token'] = token_id return self.application
def _get_token_id(self, token_data): try: token_id = cms.pkiz_sign(jsonutils.dumps(token_data), CONF.signing.certfile, CONF.signing.keyfile) return token_id except environment.subprocess.CalledProcessError: LOG.exception(ERROR_MESSAGE) raise exception.UnexpectedError(ERROR_MESSAGE)
def __init__(self, conf, session, callback, node_name, node_opts, link_name, link_opts): """Declare a queue on an amqp session. 'session' is the amqp session to use 'callback' is the callback to call when messages are received 'node_name' is the first part of the Qpid address string, before ';' 'node_opts' will be applied to the "x-declare" section of "node" in the address string. 'link_name' goes into the "name" field of the "link" in the address string 'link_opts' will be applied to the "x-declare" section of "link" in the address string. """ self.callback = callback self.receiver = None self.session = None if conf.qpid_topology_version == 1: addr_opts = { "create": "always", "node": { "type": "topic", "x-declare": { "durable": True, "auto-delete": True, }, }, "link": { "durable": True, "x-declare": { "durable": False, "auto-delete": True, "exclusive": False, }, }, } addr_opts["node"]["x-declare"].update(node_opts) elif conf.qpid_topology_version == 2: addr_opts = { "link": { "x-declare": { "auto-delete": True, "exclusive": False, }, }, } else: raise_invalid_topology_version() addr_opts["link"]["x-declare"].update(link_opts) if link_name: addr_opts["link"]["name"] = link_name self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts)) self.connect(session)
def serialize_msg(raw_msg): # NOTE(russellb) See the docstring for _RPC_ENVELOPE_VERSION for more # information about this format. msg = { _VERSION_KEY: _RPC_ENVELOPE_VERSION, _MESSAGE_KEY: jsonutils.dumps(raw_msg) } return msg
def create_mapping(self, mapping_id, mapping): session = db_session.get_session() ref = {} ref['id'] = mapping_id ref['rules'] = jsonutils.dumps(mapping.get('rules')) with session.begin(): mapping_ref = MappingModel.from_dict(ref) session.add(mapping_ref) return mapping_ref.to_dict()
def test_cas_failure(self): self.token_api.driver.client.reject_cas = True token_id = uuid.uuid4().hex user_id = unicode(uuid.uuid4().hex) user_key = self.token_api.driver._prefix_user_id(user_id) token_data = jsonutils.dumps(token_id) self.assertRaises(exception.UnexpectedError, self.token_api.driver._update_user_list_with_cas, user_key, token_data)
def test_is_signed_token_revoked_returns_false(self): #explicitly setting an empty revocation list here to document intent self.middleware.token_revocation_list = jsonutils.dumps({ "revoked": [], "extra": "success" }) result = self.middleware.is_signed_token_revoked(REVOKED_TOKEN) self.assertFalse(result)
def setUpModule(self): signing_path = os.path.join(os.path.dirname(__file__), 'signing') 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.TOKEN_RESPONSES[self.SIGNED_TOKEN_SCOPED] = { 'access': { 'token': { 'id': self.SIGNED_TOKEN_SCOPED, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'tenantId': 'tenant_id1', 'tenantName': 'tenant_name1', 'roles': [ { 'name': 'role1' }, { 'name': 'role2' }, ], }, }, } self.TOKEN_RESPONSES[self.SIGNED_TOKEN_UNSCOPED] = { 'access': { 'token': { 'id': self.SIGNED_TOKEN_UNSCOPED, }, 'user': { 'id': 'user_id1', 'name': 'user_name1', 'roles': [ { 'name': 'role1' }, { 'name': 'role2' }, ], }, }, },
def _blob_to_json(ref): # credentials stored via ec2tokens before the fix for #1259584 # need json serializing, as that's the documented API format blob = ref.get('blob') if isinstance(blob, dict): new_ref = ref.copy() new_ref['blob'] = jsonutils.dumps(blob) return new_ref else: return ref
def get_revocation_list_json(self, token_ids=None): if token_ids is None: token_ids = [REVOKED_TOKEN_HASH] revocation_list = { 'revoked': [{ 'id': x, 'expires': timeutils.utcnow() } for x in token_ids] } return jsonutils.dumps(revocation_list)
def get_default_domain(): # Return the reference used for the default domain structure during # sql migrations. return { 'id': CONF.identity.default_domain_id, 'name': 'Default', 'enabled': True, 'extra': jsonutils.dumps({'description': 'Owns users and tenants ' '(i.e. projects) available ' 'on Identity API v2.'})}
def _serialize(data): """Serialization wrapper. We prefer using JSON, but it cannot encode all types. Error if a developer passes us bad data. """ try: return jsonutils.dumps(data, ensure_ascii=True) except TypeError: with excutils.save_and_reraise_exception(): LOG.error(_("JSON serialization failed."))
def __call__(self, req): # Read request signature and access id. try: signature = req.params['Signature'] access = req.params['AWSAccessKeyId'] except KeyError: raise webob.exc.HTTPBadRequest() # Make a copy of args for authentication and signature verification. auth_params = dict(req.params) # Not part of authentication args auth_params.pop('Signature') # Authenticate the request. creds = { 'ec2Credentials': { 'access': access, 'signature': signature, 'host': req.host, 'verb': req.method, 'path': req.path, 'params': auth_params, } } creds_json = jsonutils.dumps(creds) headers = {'Content-Type': 'application/json'} # Disable 'has no x member' pylint error # for httplib and urlparse # pylint: disable-msg=E1101 o = urllib.parse.urlparse(CONF.keystone_ec2_url) if o.scheme == 'http': conn = httplib.HTTPConnection(o.netloc) else: conn = httplib.HTTPSConnection(o.netloc) conn.request('POST', o.path, body=creds_json, headers=headers) response = conn.getresponse().read() conn.close() # NOTE(vish): We could save a call to keystone by # having keystone return token, tenant, # user, and roles from this call. result = jsonutils.loads(response) try: token_id = result['access']['token']['id'] except (AttributeError, KeyError): raise webob.exc.HTTPBadRequest() # Authenticated! req.headers['X-Auth-Token'] = token_id return self.application
def process_request(self, request): """Transform the request from XML to JSON.""" incoming_xml = 'application/xml' in str(request.content_type) if incoming_xml and request.body: request.content_type = 'application/json' try: request.body = jsonutils.dumps( serializer.from_xml(request.body)) except Exception: LOG.exception('Serializer failed') e = exception.ValidationError(attribute='valid XML', target='request body') return wsgi.render_exception(e, request=request)