Example #1
0
    def mkdir(self, args):
        "Create a new container."
        session = self.get_session()
        cwd = session.get('cwd', '/')
 
        path = args[ARG_PATH]
        # Collections names should end with a '/'
        if not path.endswith("/"):
            path += '/'
        
        if not path.startswith("/"):
            # relative path
            path = "{}{}".format(cwd, path)

        col = Collection.find(path)
        if col:
            self.print_error(MSG_COLL_EXIST.format(path))
            return

        parent, name = split(path)
        if name.startswith("cdmi_"):
            self.print_error(MSG_COLL_WRONG_NAME.format(name))
            return
        
        p_coll = Collection.find(parent)
        if not p_coll:
            self.print_error(MSG_COLL_NOT_EXIST.format(path))
            return
         
        Collection.create(name=name, container=parent)
Example #2
0
def delete_collection(request, path):
    """Display the page to delete a collection"""
    coll = Collection.find(path)
    if not coll:
        raise Http404
 
    if not coll.user_can(request.user, "delete"):
        raise PermissionDenied
 
    if request.method == "POST":
        parent_coll = Collection.find(coll.path)
        if parent_coll:
            parent_path = parent_coll.container
        else:
            # Just in case
            parent_path = ""
        coll.delete(username=request.user.name)
        messages.add_message(
            request,
            messages.INFO,
            u"The collection '{}' has been deleted".format(coll.name),
        )
        return redirect("archive:view", path=parent_path)
 
    return render(request, "archive/delete.html", {"collection": coll})
Example #3
0
def test_find():
    coll1 = Collection.create("/", "a")

    assert Collection.find("/a") == None
    assert Collection.find("/a/") != None
    assert Collection.find("/a/", 1) == None

    coll1.delete()
Example #4
0
 def get_authorized_actions(self, user):
     """"
     Get available actions for a user according to the groups it belongs
     
     :param user: The user we want to check
     :type user: :class:`radon.model.User`
     
     :return: the set of actions the user can do
     :rtype: Set[str]
     """
     # Check permission on the parent container if there's no action
     # defined at this level
     acl = self.get_acl_dict()
     if not acl:
         from radon.model import Collection
         parent_container = Collection.find(self.container)
         return parent_container.get_authorized_actions(user)
     actions = set([])
     for gid in user.groups + ["AUTHENTICATED@"]:
         if gid in acl:
             ace = acl[gid]
             level = acemask_to_str(ace.acemask, True)
             if level == "read":
                 actions.add("read")
             elif level == "write":
                 actions.add("write")
                 actions.add("delete")
                 actions.add("edit")
             elif level == "read/write":
                 actions.add("read")
                 actions.add("write")
                 actions.add("delete")
                 actions.add("edit")
     return actions
Example #5
0
def test_get_child():
    # Create a new collection with a random name
    coll_name = uuid.uuid4().hex
    coll1 = Collection.create('/', coll_name)
    coll2 = Collection.create(coll1.path, uuid.uuid4().hex)
    coll3 = Collection.create(coll1.path, uuid.uuid4().hex)
    coll4 = Collection.create(coll1.path, uuid.uuid4().hex)
    resc1 = Resource.create(coll1.path,
                            uuid.uuid4().hex,
                            url="http://www.google.fr")
    resc2 = Resource.create(coll1.path,
                            uuid.uuid4().hex,
                            url="http://www.google.fr")

    coll_childs, resc_childs = coll1.get_child()

    assert set(coll_childs) == set([coll2.name, coll3.name, coll4.name])
    assert set(resc_childs) == set([resc1.get_name(), resc2.get_name()])
    assert coll1.get_child_resource_count() == 2

    coll_root = Collection.find("/")
    # Test for a resource where the url has been lost somehow
    resc3 = Resource.create(coll_root.path, uuid.uuid4().hex)
    resc3.update(object_url=None)
    resc3 = Resource.find(resc3.path)
    coll_childs, resc_childs = coll_root.get_child()
    assert set(coll_childs) == set(["1/", "2/", coll1.name])
    assert set(resc_childs) == set([resc3.get_name(), 'g'])

    coll1.delete()
Example #6
0
    def change_dir(self, args):
        "Move into a different container."
        session = self.get_session()
        cwd = session.get('cwd', '/')

        if args[ARG_PATH]:
            path = args[ARG_PATH]
        else:
            path = "/"

        if not path.startswith("/"):
            # relative path
            path = "{}{}".format(cwd, path)

        if not path.endswith("/"):
            path = path + '/'

        col = Collection.find(path)
        if not col:
            self.print_error(MSG_COLL_NOT_EXIST.format(path))
            return
        
        session['cwd'] = path
        # Save the client for persistent use
        self.save_session(session)
        return 0
Example #7
0
 def read_data_object(self, path):
     """Read a resource"""
     resource = Resource.find(path)
     if not resource:
         collection = Collection.find(path)
         if collection:
             self.logger.info(
                 u"Fail to read a resource at '{}', test if it's a collection"
                 .format(path))
             return self.read_container(path)
         else:
             self.logger.info(
                 u"Fail to read a resource at '{}'".format(path))
             return Response(status=HTTP_404_NOT_FOUND)
     if not resource.user_can(self.user, "read"):
         self.logger.warning(
             u"User {} tried to read resource at '{}'".format(
                 self.user, path))
         return Response(status=HTTP_403_FORBIDDEN)
     cdmi_resource = CDMIResource(resource, self.api_root)
     if self.http_mode:
         if cdmi_resource.is_reference():
             return self.read_data_object_reference(cdmi_resource)
         else:
             return self.read_data_object_http(cdmi_resource)
     else:
         return self.read_data_object_cdmi(cdmi_resource)
Example #8
0
def delete_resource(request, path):
    """Display the page to delete a resource"""
    resource = Resource.find(path)
    if not resource:
        raise Http404
 
    if not resource.user_can(request.user, "delete"):
        raise PermissionDenied
 
    container = Collection.find(resource.container)
    if request.method == "POST":
        resource.delete(username=request.user.name)
        messages.add_message(
            request,
            messages.INFO,
            "The resource '{}' has been deleted".format(resource.name),
        )
        return redirect("archive:view", path=container.path)
 
    # Requires delete on resource
    ctx = {
        "resource": resource,
        "container": container,
    }
 
    return render(request, "archive/resource/delete.html", ctx)
Example #9
0
def home(request):
    """Default view for Activities"""
    notifications = Notification.recent(10)
    activities = []
    for notif in notifications:
        tmpl = template.Template(notif["tmpl"])

        obj_uuid = notif["object_uuid"]
        obj = None
        if notif["object_type"] == OBJ_RESOURCE:
            obj = Resource.find(obj_uuid)
            if obj:
                object_dict = obj.to_dict()
            else:
                object_dict = {"name": obj_uuid}
        elif notif["object_type"] == OBJ_COLLECTION:
            obj = Collection.find(obj_uuid)
            if obj:
                object_dict = obj.to_dict()
            else:
                object_dict = {"name": obj_uuid}
        elif notif["object_type"] == OBJ_USER:
            obj = User.find(obj_uuid)
            if obj:
                object_dict = obj.to_dict()
            else:
                # User has been deleted it can't be find by uuid
                # look in payload of the message to get the name
                if notif["operation"] in [OP_CREATE, OP_UPDATE]:
                    name = notif["payload"]["post"]["name"]
                else:  # OP_DELETE
                    name = notif["payload"]["pre"]["name"]
                object_dict = {"name": name}
        elif notif["object_type"] == OBJ_GROUP:
            obj = Group.find(obj_uuid)
            if obj:
                object_dict = obj.to_dict()
            else:
                # User has been deleted it can't be find by uuid
                # look in payload of the message to get the name
                if notif["operation"] in [OP_CREATE, OP_UPDATE]:
                    name = notif["payload"]["post"]["name"]
                else:  # OP_DELETE
                    name = notif["payload"]["pre"]["name"]
                object_dict = {"uuid": obj_uuid, "name": name}
        user_dict = {}
        if notif["username"]:
            user = User.find(notif["username"])
            if user:
                user_dict = user.to_dict()
            else:
                user_dict = { 'name': notif["username"], 
                              'email': notif["username"]+ '@radon.org' }
        variables = {"user": user_dict, "when": notif["when"], "object": object_dict}

        ctx = template.Context(variables)
        activities.append({"html": tmpl.render(ctx)})

    return render(request, "activity/index.html", {"activities": activities})
Example #10
0
 def get_parentID(self):
     """Conditional Object ID of the parent container object
     We don't support objects only accessible by ID so this is mandatory"""
     parent_path = self.collection.container
     if self.collection.is_root:
         parent_path = "/"
     parent = Collection.find(parent_path)
     return parent.uuid
Example #11
0
    def put_data_object(self, path):
        """Put a data object to a specific collection"""
        # Check if a collection with the name exists
        collection = Collection.find(path)
        if collection:
            # Try to put a data_object when a collection of the same name
            # already exists
            self.logger.info(
                "Impossible to create a new resource, the collection '{}' already exists, try to update it"
                .format(path))
            return self.put_container(path)

        parent, name = split(path)
        # Check if the resource already exists
        resource = Resource.find(path)
        # Check permissions
        if resource:
            # Update Resource
            if not resource.user_can(self.user, "edit"):
                self.logger.warning(
                    "User {} tried to modify resource at '{}'".format(
                        self.user, path))
                return Response(status=HTTP_403_FORBIDDEN)
        else:
            # Create Resource
            parent_collection = Collection.find(parent)
            if not parent_collection:
                self.logger.info(
                    "Fail to create a resource at '{}', collection doesn't exist"
                    .format(path))
                return Response(status=HTTP_404_NOT_FOUND)
            # Check if user can create a new resource in the collection
            if not parent_collection.user_can(self.user, "write"):
                self.logger.warning(
                    "User {} tried to create new resource at '{}'".format(
                        self.user, path))
                return Response(status=HTTP_403_FORBIDDEN)
        # All permissions are checked, we can proceed to create/update
        if self.http_mode:
            return self.put_data_object_http(parent, name, resource)
        else:
            return self.put_data_object_cdmi(parent, name, resource)
Example #12
0
def is_collection(path):
    """Check if the collection exists
    
    :param path: The path of the collection in Radon
    :type path: str
     
     :return: a boolean
     :rtype: bool
     """
    from radon.model import Collection
    return Collection.find(path) is not None
Example #13
0
 def ls(self, args):
     """List a container."""
     session = self.get_session()
     cwd = session.get('cwd', '/')
     if args[ARG_PATH]:
         path = args[ARG_PATH]
         if not path.startswith("/"):
             # relative path
             path = "{}{}".format(cwd, path)
     else:
         # Get the current working dir from the session file
         path = cwd
     # --v option specify the version we want to display
     if args["--v"]:
         version = int(args["--v"])
         col = Collection.find(path, version)
     else:
         col = Collection.find(path)
     if not col:
         self.print_error(MSG_COLL_NOT_EXIST.format(path))
         return
     # Display name of the collection
     if path == "/":
         print("Root:")
     else:
         print("{}:".format(col.path))
     # Display Acl
     if args["-a"]:
         acl = col.get_acl_dict()
         if acl:
             for gid in acl:
                 print("  ACL - {}: {}".format(
                     gid, acl[gid]))
         else:
             print("  ACL: No ACE defined")
     # Display child
     c_colls, c_objs = col.get_child()
     for child in sorted(c_colls, key=methodcaller("lower")):
         print(self.terminal.blue(child))
     for child in sorted(c_objs, key=methodcaller("lower")):
         print(child)
Example #14
0
def edit_collection(request, path):
    """Display the form to edit an existing collection"""
    coll = Collection.find(path)
    if not coll:
        raise Http404
 
    if not coll.user_can(request.user, "edit"):
        raise PermissionDenied
 
    if request.method == "POST":
        form = CollectionForm(request.POST)
        if form.is_valid():
            metadata = {}
            for k, v in json.loads(form.cleaned_data["metadata"]):
                if k in metadata:
                    if isinstance(metadata[k], list):
                        metadata[k].append(v)
                    else:
                        metadata[k] = [metadata[k], v]
                else:
                    metadata[k] = v
 
            try:
                data = form.cleaned_data
                coll.update(metadata=metadata, username=request.user.name)
                coll.create_acl_list(data["read_access"], data["write_access"])
                return redirect("archive:view", path=coll.path)
            except CollectionConflictError:
                messages.add_message(
                    request,
                    messages.ERROR,
                    "That name is in use in the current collection",
                )
    else:
        md = coll.get_cdmi_user_meta()
        metadata = json.dumps(md)
        if not md:
            metadata = '{"":""}'
        read_access, write_access = coll.get_acl_list()
        initial_data = {
            "name": coll.name,
            "metadata": metadata,
            "read_access": read_access,
            "write_access": write_access,
        }
        form = CollectionForm(initial=initial_data)
 
    groups = Group.objects.all()
    return render(
        request,
        "archive/edit.html",
        {"form": form, "collection": coll, "groups": groups},
    )
Example #15
0
def test_delete_all():
    coll1_name = uuid.uuid4().hex
    coll1 = Collection.create("/", coll1_name)
    coll2 = Collection.create(coll1.path, uuid.uuid4().hex)
    coll5 = Collection.create(coll2.path, uuid.uuid4().hex)
    resc1 = Resource.create(coll1.path,
                            uuid.uuid4().hex,
                            url="http://www.google.fr")
    Collection.delete_all("/{}/".format(coll1_name))

    assert Collection.find(coll1_name) == None

    assert Collection.delete_all("/unknown/") == None
Example #16
0
def test_delete():
    coll1_name = uuid.uuid4().hex
    coll1 = Collection.create("/", coll1_name)
    coll2 = Collection.create(coll1.path, uuid.uuid4().hex)
    coll3 = Collection.create(coll1.path, uuid.uuid4().hex)
    coll4 = Collection.create(coll2.path, uuid.uuid4().hex)
    coll5 = Collection.create(coll4.path, uuid.uuid4().hex)
    resc1 = Resource.create(coll1.path,
                            uuid.uuid4().hex,
                            url="http://www.google.fr")
    coll1.delete()

    assert Collection.find(coll1_name) == None
Example #17
0
def view_resource(request, path):
    """Display the page for a resource in the archive"""
    resource = Resource.find(path)
    if not resource:
        raise Http404()
 
    if not resource.user_can(request.user, "read"):
        raise PermissionDenied
 
    container = Collection.find(resource.container)
    if not container:
        # TODO: the container has to be there. If not it may be a network
        # issue with Cassandra so we try again before raising an error to the
        # user
        container = Collection.find(resource.container)
        if not container:
            return HttpResponse(
                status=408,
                content="Unable to find parent container '{}'".format(
                    resource.container
                ),
            )
 
    paths = []
    full = "/"
    for pth in container.path.split("/"):
        if not pth:
            continue
        full = u"{}{}/".format(full, pth)
        paths.append((pth, full))
 
    ctx = {
        "resource": resource.full_dict(request.user),
        "container": container,
        "container_path": container.path,
        "collection_paths": paths,
    }
    return render(request, "archive/resource/view.html", ctx)
Example #18
0
def view_collection(request, path='/'):
    """Display the page which shows the subcollections/resources of a collection"""
    if not path:
        path = "/"
    collection = Collection.find(path)

    if not collection:
        raise Http404()
 
    if not collection.user_can(request.user, "read") and not collection.is_root:
        # If the user can't read, then return 404 rather than 403 so that
        # we don't leak information.
        raise Http404()

    paths = []
    full = "/"
    for p in collection.path.split("/"):
        if not p:
            continue
        full = u"{}{}/".format(full, p)
        paths.append((p, full))
 
    children_c, children_r = collection.get_child(False)
    children_c.sort(key=lambda x: x.lower())
    children_r.sort(key=lambda x: x.lower())
        
    ctx = {
        "collection": collection.to_dict(request.user),
        "children_c": [
            Collection.find(merge(path, c)).to_dict(request.user) for c in children_c
        ],
        "children_r": [
            Resource.find(merge(path, c)).simple_dict(request.user) for c in children_r
        ],
        "collection_paths": paths,
        "empty": len(children_c) + len(children_r) == 0,
    }
    return render(request, "archive/index.html", ctx)
Example #19
0
def test_create_acl_fail(mocker):
    list_read = ['grp1']
    list_write = ['grp1']
    user2 = User.find("user2")

    # Create a new collection with a random name
    coll_name = uuid.uuid4().hex + "/"
    coll = Collection.create('/', coll_name)

    mocker.patch('radon.model.collection.acemask_to_str',
                 return_value="wrong_oper")
    coll.create_acl_list(list_read, list_write)
    coll = Collection.find('/{}'.format(coll_name))
    # Test get_acl_list wrong operation name
    acl_list = coll.get_acl_list()
    assert acl_list == ([], [])

    coll.delete()

    # Check authorized actions for root
    coll = Collection.find("/")
    mocker.patch.object(Collection, 'get_acl_dict', return_value=None)
    assert coll.get_authorized_actions(user2) == set([])
Example #20
0
 def delete_container(self, path):
     """Delete a container"""
     collection = Collection.find(path)
     if not collection:
         self.logger.info(u"Fail to delete collection at '{}'".format(path))
         return Response(status=HTTP_404_NOT_FOUND)
     if not collection.user_can(self.user, "delete"):
         self.logger.warning(
             u"User {} tried to delete container '{}'".format(
                 self.user, path))
         return Response(status=HTTP_403_FORBIDDEN)
     Collection.delete_all(collection.path)
     self.logger.info(
         u"The container '{}' was successfully deleted".format(path))
     return Response(status=HTTP_204_NO_CONTENT)
Example #21
0
def test_metadata():
    # Create a new collection with a random name
    coll_name = uuid.uuid4().hex
    coll1 = Collection.create('/', coll_name)
    metadata = {"test": "val", "test_json": '["t", "e", "s", "t"]'}
    coll1.update(metadata=metadata)

    coll1 = Collection.find("/{}/".format(coll_name))
    assert coll1.get_list_user_meta() == [('test', 'val'),
                                          ('test_json', '["t", "e", "s", "t"]')
                                          ]
    assert coll1.get_user_meta_key("test_json") == '["t", "e", "s", "t"]'

    sys_meta = coll1.get_cdmi_sys_meta()
    assert "radon_create_ts" in sys_meta
    assert "radon_modify_ts" in sys_meta
Example #22
0
 def rm(self, args):
     """Remove a data object or a collection.
     """
     path = args["<path>"]
      # Get the full path of the object to delete
     path = self.get_full_path(path)
     
     resc = Resource.find(path)
     if resc:
         resc.delete()
         return
     
     coll = Collection.find(path)
     if coll:
         coll.delete()
         return
         
     self.print_error(MSG_NO_OBJECT.format(path))
Example #23
0
    def read_container(self, path):
        """Get information on a container"""
        collection = Collection.find(path)
        if not collection:
            self.logger.info(u"Fail to read a collection at '{}'".format(path))
            return Response(status=HTTP_404_NOT_FOUND)
        if not collection.user_can(self.user, "read"):
            self.logger.warning(
                u"User {} tried to read container at '{}'".format(
                    self.user, path))
            return Response(status=HTTP_403_FORBIDDEN)

        cdmi_container = CDMIContainer(collection, self.api_root)
        if self.http_mode:
            # HTTP Request, unsupported
            self.logger.warning(
                u"Read container '{}' using HTTP is undefined".format(path))
            return Response(status=HTTP_406_NOT_ACCEPTABLE)
        else:
            # Read using CDMI
            return self.read_container_cdmi(cdmi_container)
Example #24
0
    def delete_data_object(self, path):
        """Delete a resource"""
        resource = Resource.find(path)
        if not resource:
            collection = Collection.find(path)
            if collection:
                self.logger.info(
                    u"Fail to delete resource at '{}', test if it's a collection"
                    .format(path))
                return self.delete_container(path)
            else:
                self.logger.info(
                    u"Fail to delete resource at '{}'".format(path))
                return Response(status=HTTP_404_NOT_FOUND)
        if not resource.user_can(self.user, "delete"):
            self.logger.warning(
                u"User {} tried to delete resource '{}'".format(
                    self.user, path))
            return Response(status=HTTP_403_FORBIDDEN)

        resource.delete()
        self.logger.info(
            u"The resource '{}' was successfully deleted".format(path))
        return Response(status=HTTP_204_NO_CONTENT)
Example #25
0
def new_resource(request, parent):
    """Manage the forms to create a new resource"""
    parent_collection = Collection.find(parent)
    # Inherits perms from container by default.
    if not parent_collection:
        raise Http404()
 
    # User must be able to write to this collection
    if not parent_collection.user_can(request.user, "write"):
        raise PermissionDenied
 
    read_access, write_access = parent_collection.get_acl_list()
    initial = {
        "metadata": {},
        "read_access": read_access,
        "write_access": write_access,
    }
 
    if request.method == "POST":
        form = ResourceNewForm(request.POST, files=request.FILES, initial=initial)
        if form.is_valid():
            data = form.cleaned_data
            try:
                name = data["name"]
                metadata = {}

                for k, v in json.loads(data["metadata"]):
                    if k in metadata:
                        if isinstance(metadata[k], list):
                            metadata[k].append(v)
                        else:
                            metadata[k] = [metadata[k], v]
                    else:
                        metadata[k] = v

                resource = Resource.create(
                    container=parent_collection.path,
                    name=name,
                    metadata=metadata,
                    mimetype=data["file"].content_type,
                    creator=request.user.name,
                    size=data["file"].size,
                )
                res = resource.put(data["file"])
                resource.create_acl_list(data["read_access"], data["write_access"])
                messages.add_message(
                    request,
                    messages.INFO,
                    u"New resource '{}' created".format(resource.get_name()),
                )
            except ResourceConflictError:
                messages.add_message(
                    request,
                    messages.ERROR,
                    "That name is in use within the current collection",
                )
 
            return redirect("archive:view", path=parent_collection.path)
    else:
        form = ResourceNewForm(initial=initial)
 
    ctx = {"form": form, "container": parent_collection, "groups": Group.objects.all()}
    return render(request, "archive/resource/new.html", ctx)
Example #26
0
def new_collection(request, parent):
    """Display the form to create a new collection"""
    parent_collection = Collection.find(parent)
 
    if not parent_collection.user_can(request.user, "write"):
        raise PermissionDenied
 
    read_access, write_access = parent_collection.get_acl_list()
    initial = {
        "metadata": {},
        "read_access": read_access,
        "write_access": write_access,
    }
    form = CollectionNewForm(request.POST or None, initial=initial)
    if request.method == "POST":
        if form.is_valid():
            data = form.cleaned_data
            try:
                name = data["name"]
                parent = parent_collection.path
                metadata = {}
 
                for k, v in json.loads(data["metadata"]):
                    if k in metadata:
                        if isinstance(metadata[k], list):
                            metadata[k].append(v)
                        else:
                            metadata[k] = [metadata[k], v]
                    else:
                        metadata[k] = v
 
                collection = Collection.create(
                    name=name,
                    container=parent,
                    metadata=metadata,
                    creator=request.user.name,
                )
                collection.create_acl_list(data["read_access"], data["write_access"])
                messages.add_message(
                    request,
                    messages.INFO,
                    u"New collection '{}' created".format(collection.name),
                )
                return redirect("archive:view", path=collection.path)
            except CollectionConflictError:
                messages.add_message(
                    request,
                    messages.ERROR,
                    "That name is in use in the current collection",
                )
            except ResourceConflictError:
                messages.add_message(
                    request,
                    messages.ERROR,
                    "That name is in use in the current collection",
                )
 
    groups = Group.objects.all()
    return render(
        request,
        "archive/new.html",
        {"form": form, "parent": parent_collection, "groups": groups},
    )
Example #27
0
def edit_resource(request, path):
    """Display the form to edit an existing resource"""
    # Requires edit on resource
    resource = Resource.find(path)
    if not resource:
        raise Http404()
 
    container = Collection.find(resource.container)
    if not container:
        raise Http404()
 
    if not resource.user_can(request.user, "edit"):
        raise PermissionDenied
 
    if request.method == "POST":
        form = ResourceForm(request.POST)
        if form.is_valid():
            metadata = {}
            for k, v in json.loads(form.cleaned_data["metadata"]):
                if k in metadata:
                    if isinstance(metadata[k], list):
                        metadata[k].append(v)
                    else:
                        metadata[k] = [metadata[k], v]
                else:
                    metadata[k] = v
            try:
                data = form.cleaned_data
                resource.update(metadata=metadata, username=request.user.name)
                resource.create_acl_list(data["read_access"], data["write_access"])
 
                return redirect("archive:resource_view", path=resource.path)
            except ResourceConflictError:
                messages.add_message(
                    request,
                    messages.ERROR,
                    "That name is in use within the current collection",
                )
    else:
        md = resource.get_cdmi_user_meta()
        metadata = json.dumps(md)
        if not md:
            metadata = '{"":""}'
 
        read_access, write_access = resource.get_acl_list()
        initial_data = {
            "name": resource.name,
            "metadata": metadata,
            "read_access": read_access,
            "write_access": write_access,
        }
        form = ResourceForm(initial=initial_data)
 
    ctx = {
        "form": form,
        "resource": resource,
        "container": container,
        "groups": Group.objects.all(),
    }
 
    return render(request, "archive/resource/edit.html", ctx)
Example #28
0
 def get_parentID(self):
     """Conditional Object ID of the parent container object
     We don't support objects only accessible by ID so this is mandatory"""
     parent = Collection.find(self.resource.container)
     return parent.uuid
Example #29
0
def test_create_acl():
    list_read = ['grp1']
    list_write = ['grp1']
    user1 = User.find("user1")
    user2 = User.find("user2")

    # Create a new collection with a random name
    coll_name = uuid.uuid4().hex + "/"
    coll = Collection.create('/', coll_name)

    # Test Read/Write ACL
    coll.create_acl_list(list_read, list_write)
    coll = Collection.find('/{}'.format(coll_name))
    acl = coll.get_acl_dict()
    assert acl['grp1'].acemask == 95
    acl_list = coll.get_acl_list()
    assert acl_list == (list_read, list_write)
    assert coll.get_authorized_actions(user2) == {
        'edit', 'write', 'delete', 'read'
    }
    cdmi_acl = coll.get_acl_metadata()
    assert 'cdmi_acl' in cdmi_acl

    # Test Read ACL
    coll.create_acl_list(list_read, [])
    coll = Collection.find('/{}'.format(coll_name))
    acl = coll.get_acl_dict()
    assert acl['grp1'].acemask == 9
    acl_list = coll.get_acl_list()
    assert acl_list == (list_read, [])
    assert coll.get_authorized_actions(user2) == {'read'}

    # Test Write ACL
    coll.create_acl_list([], list_write)
    coll = Collection.find('/{}'.format(coll_name))
    acl = coll.get_acl_dict()
    assert acl['grp1'].acemask == 86
    acl_list = coll.get_acl_list()
    assert acl_list == ([], list_write)
    assert coll.get_authorized_actions(user2) == {'edit', 'write', 'delete'}

    #     # Test the ACL metadata returned as a dictionary
    #     acl = coll.get_acl_metadata()
    #     assert acl['cdmi_acl'][0]['acetype'] == "ALLOW"
    #     assert acl['cdmi_acl'][0]['identifier'] == "grp1"
    #     assert acl['cdmi_acl'][0]['aceflags'] == 'CONTAINER_INHERIT, OBJECT_INHERIT'
    #     assert acl['cdmi_acl'][0]['acemask'] == 'DELETE_SUBCONTAINER, WRITE_METADATA, ADD_SUBCONTAINER, ADD_OBJECT'

    coll.delete()

    # Check authorized actions for root
    coll = Collection.find("/")
    assert coll.get_authorized_actions(user1) == {
        'edit', 'write', 'delete', 'read'
    }

    # Check the inheritance of the ACL
    # (from a collection to its parents, root in this test)
    coll = Collection.create('/', coll_name)
    assert coll.get_authorized_actions(user2) == {'read'}
    coll.delete()
Example #30
0
    def create(cls,
               container,
               name,
               url=None,
               metadata=None,
               creator=None,
               mimetype=None,
               size=None):
        """
        Create a new resource
        
        :param container: The name of the parent collection
        :type container: str
        :param name: The name of the resource
        :type name: str
        :param url: The url of the resource
        :type url: str, optional
        :param metadata: A Key/Value pair dictionary for user metadata
        :type metadata: dict, optional
        :param creator: The name of the user who created the resource
        :type creator: str, optional
        :param mimetype: The mimetype of the resource
        :type mimetype: str, optional
        :param size: The name of the user who created the resource
        :type size: str, optional
        
        :return: The new Resource object
        :rtype: :class:`radon.model.Resource`
        """
        from radon.model import Collection
        from radon.model import Notification
        if not container.endswith('/'):
            container += '/'

        # Make sure parent/name are not in use.
        path = merge(container, name)
        existing = cls.find(path)
        if existing:
            raise ResourceConflictError(path)

        # Check if parent collection exists
        parent = Collection.find(container)
        if parent is None:
            raise NoSuchCollectionError(container)

        now_date = now()
        if not metadata:
            user_meta = {}
        else:
            user_meta = {}
            for k in metadata:
                user_meta[k] = encode_meta(metadata[k])

        sys_meta = {
            radon.cfg.meta_create_ts: encode_meta(now_date),
            radon.cfg.meta_modify_ts: encode_meta(now_date)
        }

        if mimetype:
            sys_meta[radon.cfg.meta_mimetype] = mimetype
        if size:
            sys_meta[radon.cfg.meta_size] = str(size)

        if not url:
            url = "{}{}".format(radon.cfg.protocol_cassandra,
                                default_cdmi_id())

        resc_node = TreeNode.create(container=container,
                                    name=name,
                                    user_meta=user_meta,
                                    sys_meta=sys_meta,
                                    object_url=url)

        if not creator:
            creator = radon.cfg.sys_lib_user

        if url.startswith(radon.cfg.protocol_cassandra):
            new = RadonResource(resc_node)
        else:
            new = UrlLibResource(resc_node)

        state = new.mqtt_get_state()
        payload = new.mqtt_payload({}, state)
        Notification.create_resource(creator, path, payload)
        #         # Index the resource
        #         new.index()
        return new