Example #1
0
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)))
Example #3
0
 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