Пример #1
0
def write(avatar, name, container_path, fullpath, mimetype, metadata, content,
          valueencoding, on_behalf=None, desired_backend=None):
    """ Write or update content of a blob. """
    from vcdm.server.cdmi.generic import get_parent
    parent_container = get_parent(fullpath)

    uid, vals = vcdm.env['ds'].find_by_path(fullpath, object_type='blob',
                                            fields=['parent_container','backend_name'])
    # assert that we have a consistency in case of an existig blob
    if uid is not None and parent_container != vals['parent_container']:
        log.err("ERROR: Inconsistent information! path: %s, parent_container in db: %s" %
                                                    (fullpath,
                                                     vals['parent_container']))
        return (INTERNAL_SERVER_ERROR, uid)

    # assert we can write to the defined path
    # TODO: expensive check for consistency, make optional
    if config.getboolean('general', 'check_for_existing_parents'):
        if not check_path(container_path):
            log.err("Writing to a container is not allowed. Container path: %s" %
                    '/'.join(container_path))
            return (FORBIDDEN, uid)

    # authorize call
    if uid is None:
        # the new file
        # take parent permissions
        _, cvals = vcdm.env['ds'].find_by_path(parent_container,
                                           object_type='container',
                                           fields=['metadata'])
    else:
        # updating the file
        # take file permissions
        _, cvals = vcdm.env['ds'].find_by_path(fullpath,
                                           object_type='blob',
                                           fields=['metadata'])
    
    acl = cvals['metadata'].get('cdmi_acl', {})
    
    if not authorize(avatar, parent_container, "write_blob", acl):
        return (UNAUTHORIZED, uid)

    # ok, time for action
    # pick a blob back-end
    # if file going to be updated take backend_name from metadata 
    # otherwise use backend is specified in the request 
    # if it is not available in the system - resolve to default one.
    if uid is not None:
        desired_backend=vals['backend_name']
    blob_backend = vcdm.env['blobs'].get(desired_backend, vcdm.env['blob'])

    # add default acls
    if avatar is None:
        avatar = 'Anonymous'
    blob_acl = metadata.get('cdmi_acl')
    if blob_acl is None:
        metadata['cdmi_acl'] = acl  # append parent ACLs for a new folder
    metadata['cdmi_acl'].update({avatar: 'rwd'})  # and creator's ACLs just in case

    # if uid is None, create a new entry, update otherwise
    if uid is None:
        uid = uuid4().hex
        actual_uri = blob_backend.create(uid, content)
        vcdm.env['ds'].write({
                        'object': 'blob',
                        'owner': avatar,
                        'fullpath': fullpath,
                        'mimetype': mimetype,
                        'metadata': metadata,
                        'valuetransferencoding': valueencoding,
                        'filename': name,
                        'actual_uri': actual_uri,
                        'parent_container': parent_container,
                        'ctime': str(time.time()),
                        'mtime': str(time.time()),
                        'atime': str(time.time()),
                        'size': int(content[1]),  # length
                        'backend_type': blob_backend.backend_type,
                        'backend_name': blob_backend.backend_name},
                        uid)
        # update the parent container as well
        from vcdm.container import _append_child
        _append_child(parent_container, uid, name)
        log.msg(type='accounting', avatar=avatar if not on_behalf else on_behalf,
                    amount=int(content[1]), acc_type='blob_creation')
        return (CREATED, uid)
    else:
        actual_uri = blob_backend.update(uid, content)
        uid = vcdm.env['ds'].write({
                        'metadata': metadata,
                        'mimetype': mimetype,
                        'mtime': str(time.time()),
                        'actual_uri': actual_uri,
                        'atime': str(time.time()),
                        'size': int(content[1]),  # length
                        'backend_type': blob_backend.backend_type,
                        'backend_name': blob_backend.backend_name},
                        uid)
        log.msg(type='accounting', avatar=avatar if not on_behalf else on_behalf,
                amount=int(content[1]), acc_type='blob_update')

        return (NO_CONTENT, uid)
Пример #2
0
def write(
    avatar,
    name,
    container_path,
    fullpath,
    mimetype,
    metadata,
    content,
    valueencoding,
    on_behalf=None,
    desired_backend=None,
):
    """ Write or update content of a blob. """
    from vcdm.server.cdmi.generic import get_parent

    parent_container = get_parent(fullpath)

    uid, vals = vcdm.env["ds"].find_by_path(fullpath, object_type="blob", fields=["parent_container"])
    # assert that we have a consistency in case of an existig blob
    if uid is not None and parent_container != vals["parent_container"]:
        log.err(
            "ERROR: Inconsistent information! path: %s, parent_container in db: %s"
            % (fullpath, vals["parent_container"])
        )
        return (INTERNAL_SERVER_ERROR, uid)

    # assert we can write to the defined path
    # TODO: expensive check for consistency, make optional
    if config.getboolean("general", "check_for_existing_parents"):
        if not check_path(container_path):
            log.err("Writing to a container is not allowed. Container path: %s" % "/".join(container_path))
            return (FORBIDDEN, uid)

    # authorize call, take parent permissions
    _, cvals = vcdm.env["ds"].find_by_path(parent_container, object_type="container", fields=["metadata"])
    acl = cvals["metadata"].get("cdmi_acl", {})
    if not authorize(avatar, parent_container, "write_blob", acl):
        return (UNAUTHORIZED, uid)

    # ok, time for action
    # pick a blob back-end - if request_backend is specified in the metadata and
    # available in the system - use it. Else - resolve to default one.
    blob_backend = vcdm.env["blobs"].get(desired_backend, vcdm.env["blob"])

    # add default acls
    if avatar is None:
        avatar = "Anonymous"
    blob_acl = metadata.get("cdmi_acl")
    if blob_acl is None:
        metadata["cdmi_acl"] = acl  # append parent ACLs for a new folder
    metadata["cdmi_acl"].update({avatar: "rwd"})  # and creator's ACLs just in case

    # if uid is None, create a new entry, update otherwise
    if uid is None:
        uid = uuid4().hex
        actual_uri = blob_backend.create(uid, content)
        vcdm.env["ds"].write(
            {
                "object": "blob",
                "owner": avatar,
                "fullpath": fullpath,
                "mimetype": mimetype,
                "metadata": metadata,
                "valuetransferencoding": valueencoding,
                "filename": name,
                "actual_uri": actual_uri,
                "parent_container": parent_container,
                "ctime": str(time.time()),
                "mtime": str(time.time()),
                "atime": str(time.time()),
                "size": int(content[1]),  # length
                "backend_type": blob_backend.backend_type,
                "backend_name": blob_backend.backend_name,
            },
            uid,
        )
        # update the parent container as well
        from vcdm.container import _append_child

        _append_child(parent_container, uid, name)
        log.msg(
            type="accounting",
            avatar=avatar if not on_behalf else on_behalf,
            amount=int(content[1]),
            acc_type="blob_creation",
        )
        return (CREATED, uid)
    else:
        actual_uri = blob_backend.update(uid, content)
        uid = vcdm.env["ds"].write(
            {
                "metadata": metadata,
                "mimetype": mimetype,
                "mtime": str(time.time()),
                "actual_uri": actual_uri,
                "atime": str(time.time()),
                "size": int(content[1]),  # length
                "backend_type": blob_backend.backend_type,
                "backend_name": blob_backend.backend_name,
            },
            uid,
        )
        log.msg(
            type="accounting",
            avatar=avatar if not on_behalf else on_behalf,
            amount=int(content[1]),
            acc_type="blob_update",
        )

        return (NO_CONTENT, uid)
Пример #3
0
def write(avatar,
          name,
          container_path,
          fullpath,
          mimetype,
          metadata,
          content,
          valueencoding,
          on_behalf=None,
          desired_backend=None):
    """ Write or update content of a blob. """
    from vcdm.server.cdmi.generic import get_parent
    parent_container = get_parent(fullpath)

    uid, vals = vcdm.env['ds'].find_by_path(
        fullpath,
        object_type='blob',
        fields=['parent_container', 'backend_name'])
    # assert that we have a consistency in case of an existig blob
    if uid is not None and parent_container != vals['parent_container']:
        log.err(
            "ERROR: Inconsistent information! path: %s, parent_container in db: %s"
            % (fullpath, vals['parent_container']))
        return (INTERNAL_SERVER_ERROR, uid)

    # assert we can write to the defined path
    # TODO: expensive check for consistency, make optional
    if config.getboolean('general', 'check_for_existing_parents'):
        if not check_path(container_path):
            log.err(
                "Writing to a container is not allowed. Container path: %s" %
                '/'.join(container_path))
            return (FORBIDDEN, uid)

    # authorize call
    if uid is None:
        # the new file
        # take parent permissions
        _, cvals = vcdm.env['ds'].find_by_path(parent_container,
                                               object_type='container',
                                               fields=['metadata'])
    else:
        # updating the file
        # take file permissions
        _, cvals = vcdm.env['ds'].find_by_path(fullpath,
                                               object_type='blob',
                                               fields=['metadata'])

    acl = cvals['metadata'].get('cdmi_acl', {})

    if not authorize(avatar, parent_container, "write_blob", acl):
        return (UNAUTHORIZED, uid)

    # ok, time for action
    # pick a blob back-end
    # if file going to be updated take backend_name from metadata
    # otherwise use backend is specified in the request
    # if it is not available in the system - resolve to default one.
    if uid is not None:
        desired_backend = vals['backend_name']
    blob_backend = vcdm.env['blobs'].get(desired_backend, vcdm.env['blob'])

    # add default acls
    if avatar is None:
        avatar = 'Anonymous'
    blob_acl = metadata.get('cdmi_acl')
    if blob_acl is None:
        metadata['cdmi_acl'] = acl  # append parent ACLs for a new folder
    metadata['cdmi_acl'].update({avatar:
                                 'rwd'})  # and creator's ACLs just in case

    # if uid is None, create a new entry, update otherwise
    if uid is None:
        uid = uuid4().hex
        actual_uri = blob_backend.create(uid, content)
        vcdm.env['ds'].write(
            {
                'object': 'blob',
                'owner': avatar,
                'fullpath': fullpath,
                'mimetype': mimetype,
                'metadata': metadata,
                'valuetransferencoding': valueencoding,
                'filename': name,
                'actual_uri': actual_uri,
                'parent_container': parent_container,
                'ctime': str(time.time()),
                'mtime': str(time.time()),
                'atime': str(time.time()),
                'size': int(content[1]),  # length
                'backend_type': blob_backend.backend_type,
                'backend_name': blob_backend.backend_name
            },
            uid)
        # update the parent container as well
        from vcdm.container import _append_child
        _append_child(parent_container, uid, name)
        log.msg(type='accounting',
                avatar=avatar if not on_behalf else on_behalf,
                amount=int(content[1]),
                acc_type='blob_creation')
        return (CREATED, uid)
    else:
        actual_uri = blob_backend.update(uid, content)
        uid = vcdm.env['ds'].write(
            {
                'metadata': metadata,
                'mimetype': mimetype,
                'mtime': str(time.time()),
                'actual_uri': actual_uri,
                'atime': str(time.time()),
                'size': int(content[1]),  # length
                'backend_type': blob_backend.backend_type,
                'backend_name': blob_backend.backend_name
            },
            uid)
        log.msg(type='accounting',
                avatar=avatar if not on_behalf else on_behalf,
                amount=int(content[1]),
                acc_type='blob_update')

        return (NO_CONTENT, uid)
Пример #4
0
def create_or_update(avatar, name, container_path, fullpath, metadata=None, on_behalf=None):
    """Create or update a container."""
    log.msg("Container create/update: %s" % fullpath)

    parent_container = get_parent(fullpath)
    uid, vals = vcdm.env["ds"].find_by_path(
        fullpath, object_type="container", fields=["children", "parent_container", "owner"]
    )
    vals["uid"] = uid
    # XXX: duplication of checks with blob (vcdm). Refactor.
    if uid is not None and parent_container != vals["parent_container"]:
        log.err("Inconsistency! path: %s, parent_container in db: %s" % (fullpath, vals["parent_container"]))
        return (FORBIDDEN, vals)

    # assert we can write to the defined path
    if not check_path(container_path):
        log.err("Writing to a container is not allowed. Container path: %s" % "/".join(container_path))
        return (FORBIDDEN, vals)

    # authorize call, take parent permissions
    _, cvals = vcdm.env["ds"].find_by_path(parent_container, object_type="container", fields=["metadata"])
    acl = cvals["metadata"].get("cdmi_acl", {})
    if not authorize(avatar, parent_container, "write_container", acl):
        return (UNAUTHORIZED, vals)

    # add default acls
    if avatar is None:
        avatar = "Anonymous"
    container_acl = metadata.get("cdmi_acl")
    if container_acl is None:
        metadata["cdmi_acl"] = acl  # append parent ACLs for a new folder
    metadata["cdmi_acl"].update({avatar: "rwd"})  # and creator's ACLs

    # if uid is None, it shall create a new entry, update otherwise
    if uid is None:
        uid = vcdm.env["ds"].write(
            {
                "object": "container",
                "metadata": metadata,
                "owner": avatar,
                "fullpath": fullpath,
                "name": name,
                "parent_container": parent_container,
                "children": {},
                "ctime": str(time.time()),
                "mtime": str(time.time()),
            },
            uid,
        )
        vals["uid"] = uid
        # update the parent container as well, unless it's a top-level container
        if fullpath != "/":
            _append_child(parent_container, uid, name + "/")
        log.msg(type="accounting", avatar=avatar if not on_behalf else on_behalf, amount=1, acc_type="container_create")
        return (CREATED, vals)
    else:
        # update container
        # forbid rewrites of containers by other users
        if vals.get("owner") is not None and vals.get("owner") != avatar:
            return (UNAUTHORIZED, vals)
        uid = vcdm.env["ds"].write({"metadata": metadata, "mtime": str(time.time())}, uid)
        log.msg(type="accounting", avatar=avatar if not on_behalf else on_behalf, amount=1, acc_type="container_update")
        return (NO_CONTENT, vals)
Пример #5
0
def create_or_update(avatar,
                     name,
                     container_path,
                     fullpath,
                     metadata=None,
                     on_behalf=None):
    """Create or update a container."""
    log.msg("Container create/update: %s" % fullpath)

    parent_container = get_parent(fullpath)
    uid, vals = vcdm.env['ds'].find_by_path(
        fullpath,
        object_type='container',
        fields=['children', 'parent_container', 'owner'])
    vals['uid'] = uid
    # XXX: duplication of checks with blob (vcdm). Refactor.
    if uid is not None and parent_container != vals['parent_container']:
        log.err("Inconsistency! path: %s, parent_container in db: %s" %
                (fullpath, vals['parent_container']))
        return (FORBIDDEN, vals)

    # assert we can write to the defined path
    if not check_path(container_path):
        log.err("Writing to a container is not allowed. Container path: %s" %
                '/'.join(container_path))
        return (FORBIDDEN, vals)

    # authorize call, take parent permissions
    _, cvals = vcdm.env['ds'].find_by_path(parent_container,
                                           object_type='container',
                                           fields=['metadata'])
    acl = cvals['metadata'].get('cdmi_acl', {})
    if not authorize(avatar, parent_container, "write_container", acl):
        return (UNAUTHORIZED, vals)

    # add default acls
    if avatar is None:
        avatar = 'Anonymous'
    container_acl = metadata.get('cdmi_acl')
    if container_acl is None:
        metadata['cdmi_acl'] = acl  # append parent ACLs for a new folder
    metadata['cdmi_acl'].update({avatar: 'rwd'})  # and creator's ACLs

    # if uid is None, it shall create a new entry, update otherwise
    if uid is None:
        uid = vcdm.env['ds'].write(
            {
                'object': 'container',
                'metadata': metadata,
                'owner': avatar,
                'fullpath': fullpath,
                'name': name,
                'parent_container': parent_container,
                'children': {},
                'ctime': str(time.time()),
                'mtime': str(time.time())
            }, uid)
        vals['uid'] = uid
        # update the parent container as well, unless it's a top-level container
        if fullpath != '/':
            _append_child(parent_container, uid, name + "/")
        log.msg(type='accounting',
                avatar=avatar if not on_behalf else on_behalf,
                amount=1,
                acc_type='container_create')
        return (CREATED, vals)
    else:
        # update container
        # forbid rewrites of containers by other users
        if vals.get('owner') is not None and vals.get('owner') != avatar:
            return (UNAUTHORIZED, vals)
        uid = vcdm.env['ds'].write(
            {
                'metadata': metadata,
                'mtime': str(time.time())
            }, uid)
        log.msg(type='accounting',
                avatar=avatar if not on_behalf else on_behalf,
                amount=1,
                acc_type='container_update')
        return (NO_CONTENT, vals)