def dispatch_request(self, username, collection_name):
        log = logging.getLogger("GetCollectionAttributeView")
        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 = {1}, " \
                 "user_name = {1}, " \
                 "collection_name = {1}".format(user_request_id,
                                                username, 
                                                collection_name))

        result_dict = 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".format(user_request_id))
                flask.abort(httplib.UNAUTHORIZED)

            cursor = connection.cursor()
            if "action" in  flask.request.args:
                assert flask.request.args["action"] == "space_usage"
                try:
                    status, result_dict = \
                        _get_collection_space_usage(self.memcached_client,
                                                    cursor, 
                                                    customer_id,
                                                    collection_name, 
                                                    flask.request.args)
                except Exception:
                    log.exception("user_request_id = {0}, " \
                                  "{1} {2}".format(user_request_id, 
                                                   collection_name, 
                                                   flask.request.args))
                    cursor.close()
                    raise
            else:
                try:
                    status, result_dict = _get_collection_info(cursor, 
                                                               username,
                                                               customer_id,
                                                               collection_name)
                except Exception:
                    log.exception("user_request_id = {0}, " \
                                  "{1} {2}".format(user_request_id,
                                                   collection_name, 
                                                   flask.request.args))
                    cursor.close()
                    raise
            cursor.close()


        # Ticket #33 Make Nimbus.io API responses consistently JSON
        data = json.dumps(result_dict, sort_keys=True, indent=4) 

        response = flask.Response(data, 
                                  status=status,
                                  content_type="application/json")
        response.headers["content-length"] = str(len(data))
        return response
Example #2
0
    def dispatch_request(self, username):
        log = logging.getLogger("ListCollectionsView")
        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}".format(user_request_id,
                                          username))

        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".format(
                    user_request_id))
                flask.abort(httplib.UNAUTHORIZED)

            try:
                raw_collection_list = _list_collections(
                    connection, customer_id)
            except Exception:
                log.exception("user_request_id = {0}".format(user_request_id))
                raise

        # ticket #50 When listing collections for a user, show whether a
        # collection is a default collection.
        default_collection_name = compute_default_collection_name(username)

        collection_list = list()
        for raw_entry in raw_collection_list:
            name, versioning, raw_access_control, raw_creation_time = raw_entry
            if raw_access_control is None:
                access_control = None
            else:
                access_control = json.loads(raw_access_control)
            entry = {
                "name": name,
                "default_collection": name == default_collection_name,
                "versioning": versioning,
                "access_control": access_control,
                "creation-time": http_timestamp_str(raw_creation_time)
            }
            collection_list.append(entry)

        log.info("user_request_id = {0}, found {1} collections".format(
            user_request_id, len(collection_list)))

        # 2012-08-16 dougfort Ticket #29 - format json for debuging
        data = json.dumps(collection_list, sort_keys=True, indent=4)

        # 2012-08-16 dougfort Ticket #28 - set content_type
        response = flask.Response(data,
                                  status=httplib.OK,
                                  content_type="application/json")
        response.headers["content-length"] = str(len(data))
        return response
    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
Example #4
0
    def dispatch_request(self, username, collection_name):
        log = logging.getLogger("SetCollectionAttributeView")
        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,
                                                collection_name))

        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".format(user_request_id))
                flask.abort(httplib.UNAUTHORIZED)

            cursor = connection.cursor()
            attribute = None
            arg_value = None
            status = None
            result_dict = None
            for key in flask.request.args:
                if key not in _dispatch_table:
                    error_message = "unknown attribute '{0}'".format(
                        flask.request.args)
                    log.error("user_request_id = {0}, " \
                              "{1}".format(user_request_id,
                                           error_message))
                    result_dict = {
                        "success": False,
                        "error_message": error_message
                    }
                    status = httplib.METHOD_NOT_ALLOWED
                    break
                attribute = key
                arg_value = flask.request.args[attribute]
                break

            if attribute is not None:
                try:
                    status, result_dict = \
                        _dispatch_table[attribute](cursor,
                                                   user_request_id,
                                                   customer_id,
                                                   collection_name,
                                                   arg_value)
                except Exception:
                    log.exception("user_request_id = {0}, " \
                                  "{1} {2}".format(user_request_id,
                                                   collection_name,
                                                   attribute))
                    cursor.close()
                    connection.rollback()
                    raise

            cursor.close()
            connection.commit()

        # Ticket #33 Make Nimbus.io API responses consistently JSON
        data = json.dumps(result_dict, sort_keys=True, indent=4)

        response = flask.Response(data,
                                  status=status,
                                  content_type="application/json")
        response.headers["content-length"] = str(len(data))
        return response
Example #5
0
    def dispatch_request(self, username, collection_name):
        log = logging.getLogger("DeleteCollectionView")
        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,
                                                collection_name))

        assert flask.request.method == "DELETE" or \
            (flask.request.method == "POST" \
             and flask.request.args["action"] == "delete"), \
                (user_request_id, flask.request.method, flask.request.args, )

        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}, " \
                         "unauthroized".format(user_request_id))
                flask.abort(httplib.UNAUTHORIZED)

            # you can't delete your default collection
            default_collection_name = compute_default_collection_name(username)
            if collection_name == default_collection_name:
                log.warn("user_request_id = {0}, " \
                         "attempt to delete default collection {1}".format(
                         user_request_id, default_collection_name))
                flask.abort(httplib.METHOD_NOT_ALLOWED)

            # TODO: can't delete a collection that contains keys

            cursor = connection.cursor()
            try:
                deleted = _delete_collection(cursor, user_request_id,
                                             customer_id, collection_name)
            except Exception:
                log.exception("user_request_id = {0}".format(user_request_id))
                cursor.close()
                connection.rollback()
                raise

            cursor.close()

            # Ticket #39 collection manager allows authenticated users to set
            # versioning property on collections they don't own
            if not deleted:
                log.error("user_request_id = {0}, " \
                          "forbidden".format(user_request_id))
                connection.rollback()
                flask.abort(httplib.FORBIDDEN)

            connection.commit()

        log.info("user_request_id = {0}, "\
                 "collection {1} deleted".format(user_request_id,
                                                 collection_name))

        # Ticket #33 Make Nimbus.io API responses consistently JSON
        collection_dict = {"success": True}
        data = json.dumps(collection_dict, sort_keys=True, indent=4)

        response = flask.Response(data,
                                  status=httplib.OK,
                                  content_type="application/json")
        response.headers["content-length"] = str(len(data))
        return response
    def dispatch_request(self, username):
        log = logging.getLogger("ListCollectionsView")
        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}".format(user_request_id, 
                                          username))

        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".format(
                         user_request_id))
                flask.abort(httplib.UNAUTHORIZED)

            try:
                raw_collection_list = _list_collections(connection, customer_id)
            except Exception:
                log.exception("user_request_id = {0}".format(user_request_id))
                raise

        # ticket #50 When listing collections for a user, show whether a
        # collection is a default collection.
        default_collection_name = compute_default_collection_name(username)

        collection_list = list()
        for raw_entry in raw_collection_list:
            name, versioning, raw_access_control, raw_creation_time = raw_entry
            if raw_access_control is None:
                access_control = None
            else:
                access_control = json.loads(raw_access_control)
            entry = {"name" : name, 
                     "default_collection" : name == default_collection_name,
                     "versioning" : versioning, 
                     "access_control" : access_control,
                     "creation-time" : http_timestamp_str(raw_creation_time)}
            collection_list.append(entry)

        log.info("user_request_id = {0}, found {1} collections".format(
                 user_request_id, len(collection_list)))

        # 2012-08-16 dougfort Ticket #29 - format json for debuging
        data = json.dumps(collection_list, sort_keys=True, indent=4) 

        # 2012-08-16 dougfort Ticket #28 - set content_type
        response = flask.Response(data, 
                                  status=httplib.OK,
                                  content_type="application/json")
        response.headers["content-length"] = str(len(data))
        return response
Example #7
0
    def dispatch_request(self, username, collection_name):
        log = logging.getLogger("GetCollectionAttributeView")
        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 = {1}, " \
                 "user_name = {1}, " \
                 "collection_name = {1}".format(user_request_id,
                                                username,
                                                collection_name))

        result_dict = 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".format(user_request_id))
                flask.abort(httplib.UNAUTHORIZED)

            cursor = connection.cursor()
            if "action" in flask.request.args:
                assert flask.request.args["action"] == "space_usage"
                try:
                    status, result_dict = \
                        _get_collection_space_usage(self.memcached_client,
                                                    cursor,
                                                    customer_id,
                                                    collection_name,
                                                    flask.request.args)
                except Exception:
                    log.exception("user_request_id = {0}, " \
                                  "{1} {2}".format(user_request_id,
                                                   collection_name,
                                                   flask.request.args))
                    cursor.close()
                    raise
            else:
                try:
                    status, result_dict = _get_collection_info(
                        cursor, username, customer_id, collection_name)
                except Exception:
                    log.exception("user_request_id = {0}, " \
                                  "{1} {2}".format(user_request_id,
                                                   collection_name,
                                                   flask.request.args))
                    cursor.close()
                    raise
            cursor.close()

        # Ticket #33 Make Nimbus.io API responses consistently JSON
        data = json.dumps(result_dict, sort_keys=True, indent=4)

        response = flask.Response(data,
                                  status=status,
                                  content_type="application/json")
        response.headers["content-length"] = str(len(data))
        return response
    def dispatch_request(self, username, collection_name):
        log = logging.getLogger("SetCollectionAttributeView")
        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, 
                                                collection_name))

        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".format(user_request_id))
                flask.abort(httplib.UNAUTHORIZED)

            cursor = connection.cursor()
            attribute = None
            arg_value = None
            status = None
            result_dict = None
            for key in flask.request.args:
                if key not in _dispatch_table:
                    error_message = "unknown attribute '{0}'".format(
                        flask.request.args)
                    log.error("user_request_id = {0}, " \
                              "{1}".format(user_request_id, 
                                           error_message))
                    result_dict = {"success" : False,
                                   "error_message" : error_message}
                    status = httplib.METHOD_NOT_ALLOWED
                    break
                attribute = key
                arg_value = flask.request.args[attribute]
                break

            if attribute is not None:
                try:
                    status, result_dict = \
                        _dispatch_table[attribute](cursor,
                                                   user_request_id, 
                                                   customer_id,
                                                   collection_name, 
                                                   arg_value)
                except Exception:
                    log.exception("user_request_id = {0}, " \
                                  "{1} {2}".format(user_request_id, 
                                                   collection_name, 
                                                   attribute))
                    cursor.close()
                    connection.rollback()
                    raise

            cursor.close()
            connection.commit()

        # Ticket #33 Make Nimbus.io API responses consistently JSON
        data = json.dumps(result_dict, sort_keys=True, indent=4) 

        response = flask.Response(data, 
                                  status=status,
                                  content_type="application/json")
        response.headers["content-length"] = str(len(data))
        return response
    def dispatch_request(self, username, collection_name):
        log = logging.getLogger("DeleteCollectionView")
        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, 
                                                collection_name))

        assert flask.request.method == "DELETE" or \
            (flask.request.method == "POST" \
             and flask.request.args["action"] == "delete"), \
                (user_request_id, flask.request.method, flask.request.args, )

        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}, " \
                         "unauthroized".format(user_request_id))
                flask.abort(httplib.UNAUTHORIZED)

            # you can't delete your default collection
            default_collection_name = compute_default_collection_name(username)
            if collection_name == default_collection_name:
                log.warn("user_request_id = {0}, " \
                         "attempt to delete default collection {1}".format(
                         user_request_id, default_collection_name))
                flask.abort(httplib.METHOD_NOT_ALLOWED)

            # TODO: can't delete a collection that contains keys

            cursor = connection.cursor()
            try:
                deleted = _delete_collection(cursor, 
                                             user_request_id,
                                             customer_id, 
                                             collection_name)
            except Exception:
                log.exception("user_request_id = {0}".format(user_request_id))
                cursor.close()
                connection.rollback()
                raise

            cursor.close()

            # Ticket #39 collection manager allows authenticated users to set 
            # versioning property on collections they don't own
            if not deleted:
                log.error("user_request_id = {0}, " \
                          "forbidden".format(user_request_id))
                connection.rollback()
                flask.abort(httplib.FORBIDDEN)

            connection.commit()

        log.info("user_request_id = {0}, "\
                 "collection {1} deleted".format(user_request_id,
                                                 collection_name))

        # Ticket #33 Make Nimbus.io API responses consistently JSON
        collection_dict = {"success" : True}
        data = json.dumps(collection_dict, sort_keys=True, indent=4) 

        response = flask.Response(data, 
                                  status=httplib.OK,
                                  content_type="application/json")
        response.headers["content-length"] = str(len(data))
        return response