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)
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)
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)
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)
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)