def _set_collection_access_control(cursor, user_request_id, customer_id, collection_name, _value): """ set the access_control attribute of the collection """ log = logging.getLogger("_set_collection_access_control") # Ticket # 43 Implement access_control properties for collections access_control = None if "Content-Type" in flask.request.headers and \ flask.request.headers['Content-Type'] == 'application/json': access_control, error_list = \ cleanse_access_control(flask.request.data) if error_list is not None: log.error("user_request_id = {0}, {1}".format( user_request_id, error_list)) result_dict = { "success": False, "error_list": error_list, } return httplib.BAD_REQUEST, result_dict cursor.execute( """update nimbusio_central.collection set access_control = %s where customer_id = %s and name = %s""", [ access_control, customer_id, collection_name, ]) # Ticket #49 collection manager allows authenticated users to set # versioning property on collections they don't own if cursor.rowcount == 0: log.error("user_request_id = {0}, " \ "unknown collection {1} {2}".format(user_request_id, customer_id, collection_name)) collection_dict = {"success": False} return httplib.FORBIDDEN, collection_dict log.info("user_request_id = {0}, " \ "access_control set to {1}".format(user_request_id, access_control)) collection_dict = {"success": True} return httplib.OK, collection_dict
def test_cleanse_access_control(self): """ test producing a safe access_control dict from possibly malicious data """ for index, test_case in enumerate(_cleanse_test_cases): if test_case.raw_data is None: test_data = None else: test_data = json.dumps(test_case.raw_data) try: access_control, error_messages = \ cleanse_access_control(test_data) except Exception, instance: self.assertTrue(False, str(test_case)) if access_control is None: access_control_dict = None else: access_control_dict = json.loads(access_control) self.assertEqual(access_control_dict, test_case.expected_dict, "Test #{0} expected {1} received {2}".format( index+1, test_case.expected_dict, access_control_dict)) if test_case.error_re is None: self.assertTrue(error_messages is None, "Test #{0} unexpected error {1}".format( index+1, error_messages)) else: self.assertTrue(error_messages is not None, "Test #{0} expect errors {0} got None".format( index+1, test_case.error_re)) match_count = 0 for error_re in test_case.error_re: for error_message in error_messages: match_object = error_re.match(error_message) if match_object is not None: match_count += 1 self.assertEqual(match_count, len(test_case.error_re), "Test #{0} matched {1} expected {2} {3} {4}".format( index+1, match_count, len(test_case.error_re), [r.pattern for r in test_case.error_re], str(error_messages)))
def test_cleanse_access_control(self): """ test producing a safe access_control dict from possibly malicious data """ for index, test_case in enumerate(_cleanse_test_cases): if test_case.raw_data is None: test_data = None else: test_data = json.dumps(test_case.raw_data) try: access_control, error_messages = \ cleanse_access_control(test_data) except Exception, instance: self.assertTrue(False, str(test_case)) if access_control is None: access_control_dict = None else: access_control_dict = json.loads(access_control) self.assertEqual( access_control_dict, test_case.expected_dict, "Test #{0} expected {1} received {2}".format( index + 1, test_case.expected_dict, access_control_dict)) if test_case.error_re is None: self.assertTrue( error_messages is None, "Test #{0} unexpected error {1}".format( index + 1, error_messages)) else: self.assertTrue( error_messages is not None, "Test #{0} expect errors {0} got None".format( index + 1, test_case.error_re)) match_count = 0 for error_re in test_case.error_re: for error_message in error_messages: match_object = error_re.match(error_message) if match_object is not None: match_count += 1 self.assertEqual( match_count, len(test_case.error_re), "Test #{0} matched {1} expected {2} {3} {4}".format( index + 1, match_count, len(test_case.error_re), [r.pattern for r in test_case.error_re], str(error_messages)))
def _set_collection_access_control(cursor, user_request_id, customer_id, collection_name, _value): """ set the access_control attribute of the collection """ log = logging.getLogger("_set_collection_access_control") # Ticket # 43 Implement access_control properties for collections access_control = None if "Content-Type" in flask.request.headers and \ flask.request.headers['Content-Type'] == 'application/json': access_control, error_list = \ cleanse_access_control(flask.request.data) if error_list is not None: log.error("user_request_id = {0}, {1}".format(user_request_id, error_list)) result_dict = {"success" : False, "error_list" : error_list, } return httplib.BAD_REQUEST, result_dict cursor.execute("""update nimbusio_central.collection set access_control = %s where customer_id = %s and name = %s""", [access_control, customer_id, collection_name, ]) # Ticket #49 collection manager allows authenticated users to set # versioning property on collections they don't own if cursor.rowcount == 0: log.error("user_request_id = {0}, " \ "unknown collection {1} {2}".format(user_request_id, customer_id, collection_name)) collection_dict = {"success" : False} return httplib.FORBIDDEN, collection_dict log.info("user_request_id = {0}, " \ "access_control set to {1}".format(user_request_id, access_control)) collection_dict = {"success" : True} return httplib.OK, collection_dict
def dispatch_request(self, username): log = logging.getLogger("CreateCollectionView") try: user_request_id = \ flask.request.headers['x-nimbus-io-user-request-id'] except KeyError: user_request_id = str(uuid.uuid4()) log.warn("user_request_id = {0}, " \ "no x-nimbus-io-user-request-id " \ "header".format(user_request_id)) log.info("user_request_id = {0}, user_name = {1}, " \ "collection_name = {2}".format(user_request_id, username, flask.request.args["name"])) assert flask.request.args["action"] == "create", flask.request.args collection_name = flask.request.args["name"] if not valid_collection_name(collection_name): # Ticket #48 Creating collection incorrectly handles # creating colliding collections log.error("user_request_id = {0}, " \ "invalid collection name '{1}'".format(user_request_id, collection_name)) collection_dict = { "name" : collection_name, "error-messages" : ["Invalid Name"]} data = json.dumps(collection_dict, sort_keys=True, indent=4) response = flask.Response(data, status=httplib.CONFLICT, content_type="application/json") response.headers["content-length"] = str(len(data)) return response versioning = False # Ticket # 43 Implement access_control properties for collections if "Content-Type" in flask.request.headers and \ flask.request.headers['Content-Type'] == 'application/json': access_control, error_list = \ cleanse_access_control(flask.request.data) if error_list is not None: log.error("user_request_id = {0}, " \ "invalid access control '{1}'".format(user_request_id, error_list)) result_dict = {"success" : False, "error_list" : error_list, } data = json.dumps(result_dict, sort_keys=True, indent=4) response = flask.Response(data, status=httplib.BAD_REQUEST, content_type="application/json") response.headers["content-length"] = str(len(data)) return response else: access_control = None with GetConnection(self.connection_pool) as connection: customer_key_lookup = \ CustomerKeyConnectionLookup(self.memcached_client, connection) customer_id = authenticate(customer_key_lookup, username, flask.request) if customer_id is None: log.info("user_request_id = {0}, unauthorized") flask.abort(httplib.UNAUTHORIZED) cursor = connection.cursor() cursor.execute("begin") try: creation_time = _create_collection(cursor, customer_id, collection_name, versioning, access_control) except DuplicateCollection: cursor.close() connection.rollback() # Ticket #48 Creating collection incorrectly handles # creating colliding collections log.error("user_request_id = {0}, " \ "duplicate collection name '{1}'".format( user_request_id, collection_name)) collection_dict = { "name" : collection_name, "error-messages" : ["Invalid Name"]} data = json.dumps(collection_dict, sort_keys=True, indent=4) response = flask.Response(data, status=httplib.CONFLICT, content_type="application/json") response.headers["content-length"] = str(len(data)) return response except Exception: log.exception("user_request_id = {0}".format(user_request_id)) cursor.close() connection.rollback() raise else: cursor.close() connection.commit() log.info("user_request_id = {0}, created {1}".format(user_request_id, collection_name)) # this is the same format returned by list_collection collection_dict = { "name" : collection_name, "versioning" : versioning, "creation-time" : http_timestamp_str(creation_time)} # 2012-08-16 dougfort Ticket #29 - format json for debuging data = json.dumps(collection_dict, sort_keys=True, indent=4) # 2012-04-15 dougfort Ticket #12 - return 201 'created' # 2012-08-16 dougfort Ticket #28 - set content_type response = flask.Response(data, status=httplib.CREATED, content_type="application/json") response.headers["content-length"] = str(len(data)) return response