Ejemplo n.º 1
0
def delete_access_perms(node, access_list):
    """
    same input as for set_access_perms
    """

    access_diff_d = Diff(operation=Diff.DELETE)
    # by the user
    for access_item in node.access_set.all():
        if access_item.user:
            name = access_item.user.username
            model_type = 'user'
        elif access_item.group:
            name = access_item.group.name
            model_type = 'group'

        # if node's access list contains items
        # which are in access_list - delete respective
        # node's access
        filtered = [
            x for x in access_list
            if x['model'] == model_type and x['name'] == name
        ]

        if len(filtered) > 0:
            # further propagation is done via pre_delete
            # signals for Access models
            access_diff_d.add(access_item)
            access_item.delete()

    return [access_diff_d]
Ejemplo n.º 2
0
def node_post_save(sender, node, created, *kwargs):
    if created:
        # New node instance was created.
        # Create associated Access Model:
        # node creater has full access.
        create_access(
            node=node,
            model_type=Access.MODEL_USER,
            name=node.user.username,
            access_type=Access.ALLOW,
            access_inherited=False,
            permissions=Access.OWNER_PERMS_MAP  # full access
        )

    # Consider this two persons use case:
    # User uploader uploads scans for user margaret.
    # Initially document is in uploader's Inbox folder.
    # Afterwards, uploader moves new document X into common shared_folder.
    # shared_folder has full access permissions for
    # boths uploader and margaret.
    # When margaret sees document X, she copies it into
    # her private folder X_margaret_fld. X_margaret_fld is
    # owned only by margaret.
    # Now document X's path is margaret//X_margaret_fld/X.pdf
    # If X.pdf access permissions stay same, then uploader will
    # still have access to X.pdf (via search) which means,
    # that margaret will need to change manually X.pdf's
    # access permissions. To avoid manual change of access
    # permissions from margaret side - papermerge feature
    # is that X.pdf inherits access permissions from new
    # parent (X_margaret_fld). Thus, just by copying it,
    # X.pdf becomes margaret private doc - and uploader
    # lose its access to it.
    if node.parent:  # current node has a parent?
        # Following statement covers case when node
        # is moved from one parent to another parent.

        # When node moved from one parent to another
        # it get all its access replaced by access list of the
        # parent
        access_diff = Diff(operation=Diff.REPLACE,
                           instances_set=node.parent.access_set.all())
        node.propagate_changes(diffs_set=[access_diff], apply_to_self=True)
    else:
        # In case node has no parent, all its access permission
        # remain the same.
        pass
Ejemplo n.º 3
0
    def test_changes_resursive_inheritance(self):
        """
        1. uploader creates:
            F1 -> L1a -> L2a -> L3a
            F1 -> L1b -> L2b

        2. Uploader gives read access to margaret on F1

        3. Margaret will have read access on L1a, L1b, L2a, L2b,
            L3a as well (because of recursive inheritance)
        """
        F1 = Folder.objects.create(title="F1", user=self.uploader_user)
        L1a = Folder.objects.create(title="L1a",
                                    user=self.uploader_user,
                                    parent=F1)
        L2a = Folder.objects.create(title="L2a",
                                    user=self.uploader_user,
                                    parent=L1a)
        L3a = Folder.objects.create(title="L3a",
                                    user=self.uploader_user,
                                    parent=L2a)
        L1b = Folder.objects.create(title="L1b",
                                    user=self.uploader_user,
                                    parent=F1)
        L2b = Folder.objects.create(title="L2b",
                                    user=self.uploader_user,
                                    parent=L1b)
        # give margaret read access on topmost folder
        new_access = create_access(
            node=F1,
            model_type=Access.MODEL_USER,
            name=self.margaret_user,
            access_type=Access.ALLOW,
            access_inherited=False,
            permissions={READ: True}  # allow read access to margaret
        )
        # function which does the trick
        access_diff = Diff(operation=Diff.ADD, instances_set=[new_access])
        F1.propagate_changes(diffs_set=[access_diff], apply_to_self=True)

        # and assert
        for folder in [F1, L1a, L1b, L2a, L3a, L2b]:
            self.assertTrue(self.margaret_user.has_perm(READ, folder),
                            f"margaret: Failed for folder {folder.title}")
            # uploader still has full access ?
            self.assertTrue(self.uploader_user.has_perms(FULL_ACCESS, folder),
                            f"uploader: Failed for folder {folder.title}")
Ejemplo n.º 4
0
def set_access_perms(node, access_list):
    """
    node is an instance of core.models.BaseTreeNode
    access is an array/list of hashes of following
    format:

    access = [
        {
            'model': 'user',
            'access_type': 'allow',
            'name': 'margaret',
            'permissions': {
                'read': true,
                'write': true,
                'delete': true,
                'change_perm': true,
                'take_ownership': true
            }
        },
        {
            'model': 'group',
            'access_type': 'allow',
            'name': 'employee',
            'permissions': {
                'read': true,
                'write': true,
                'delete': true,
                'change_perm': true,
                'take_ownership': true
            }
        }, ...
    ]
    """
    # first, add new access entries to the node
    # or update existing onces.
    access_diff_u = Diff(operation=Diff.UPDATE)
    access_diff_a = Diff(operation=Diff.ADD)

    for access_hash in access_list:
        access = get_access_for(
            node=node,
            model_type=access_hash['model'],
            name=access_hash['name']
        )
        if access:
            if access.perm_diff(access_hash['permissions']):
                access.set_perms(access_hash['permissions'])
                access_diff_u.add(access)
        else:
            access = create_access(
                node=node,
                model_type=access_hash['model'],
                name=access_hash['name'],
                access_type=access_hash['access_type'],
                access_inherited=False,
                permissions=access_hash['permissions']
            )
            access_diff_a.add(access)

    ret = []
    if len(access_diff_a) > 0:
        ret.append(access_diff_a)

    if len(access_diff_u) > 0:
        ret.append(access_diff_u)

    return ret