示例#1
0
async def move(context, request):
    try:
        data = await request.json()
    except Exception:
        data = {}
    destination = data.get('destination')
    if destination is None:
        destination_ob = context.__parent__
    else:
        try:
            destination_ob = await navigate_to(request.container, destination)
        except KeyError:
            destination_ob = None

    if destination_ob is None:
        raise PreconditionFailed(context, 'Could not find destination object')
    old_id = context.id
    if 'new_id' in data:
        new_id = data['new_id']
        context.id = context.__name__ = new_id
    else:
        new_id = context.id

    security = IInteraction(request)
    if not security.check_permission('guillotina.AddContent', destination_ob):
        raise PreconditionFailed(
            context, 'You do not have permission to add content to the '
                     'destination object')

    if await destination_ob.async_contains(new_id):
        raise PreconditionFailed(
            context, f'Destination already has object with the id {new_id}')

    original_parent = context.__parent__

    txn = get_transaction(request)
    cache_keys = txn._cache.get_cache_keys(context, 'deleted')

    data['id'] = new_id
    await notify(
        BeforeObjectMovedEvent(context, original_parent, old_id, destination_ob,
                               new_id, payload=data))

    context.__parent__ = destination_ob
    context._p_register()

    await notify(
        ObjectMovedEvent(context, original_parent, old_id, destination_ob,
                         new_id, payload=data))

    cache_keys += txn._cache.get_cache_keys(context, 'added')
    await txn._cache.delete_all(cache_keys)

    absolute_url = query_multi_adapter((context, request), IAbsoluteURL)
    return {
        '@url': absolute_url()
    }
示例#2
0
async def apply_sharing(context, data):
    lroles = role.local_roles()
    changed = False
    for perminhe in data.get('perminhe') or []:
        setting = perminhe.get('setting')
        if setting not in PermissionMap['perminhe']:
            raise PreconditionFailed(context,
                                     'Invalid Type {}'.format(setting))
        manager = IInheritPermissionManager(context)
        operation = PermissionMap['perminhe'][setting]
        func = getattr(manager, operation)
        changed = True
        func(perminhe['permission'])

    for prinrole in data.get('prinrole') or []:
        setting = prinrole.get('setting')
        if setting not in PermissionMap['prinrole']:
            raise PreconditionFailed(context,
                                     'Invalid Type {}'.format(setting))
        manager = IPrincipalRoleManager(context)
        operation = PermissionMap['prinrole'][setting]
        func = getattr(manager, operation)
        if prinrole['role'] in lroles:
            changed = True
            func(prinrole['role'], prinrole['principal'])
        else:
            raise PreconditionFailed(context, 'No valid local role')

    for prinperm in data.get('prinperm') or []:
        setting = prinperm['setting']
        if setting not in PermissionMap['prinperm']:
            raise PreconditionFailed(context, 'Invalid Type')
        manager = IPrincipalPermissionManager(context)
        operation = PermissionMap['prinperm'][setting]
        func = getattr(manager, operation)
        changed = True
        func(prinperm['permission'], prinperm['principal'])

    for roleperm in data.get('roleperm') or []:
        setting = roleperm['setting']
        if setting not in PermissionMap['roleperm']:
            raise PreconditionFailed(context, 'Invalid Type')
        manager = IRolePermissionManager(context)
        operation = PermissionMap['roleperm'][setting]
        func = getattr(manager, operation)
        changed = True
        func(roleperm['permission'], roleperm['role'])

    if changed:
        context._p_register()  # make sure data is saved
        await notify(ObjectPermissionsModifiedEvent(context, data))
示例#3
0
    async def __call__(self, changed=False):
        """Change permissions"""
        context = self.context
        request = self.request
        lroles = local_roles()
        data = await request.json()
        if 'prinrole' not in data and \
                'roleperm' not in data and \
                'prinperm' not in data:
            raise PreconditionFailed(
                self.context, 'prinrole or roleperm or prinperm missing')

        for prinrole in data.get('prinrole') or []:
            setting = prinrole.get('setting')
            if setting not in PermissionMap['prinrole']:
                raise PreconditionFailed(self.context,
                                         'Invalid Type {}'.format(setting))
            manager = IPrincipalRoleManager(context)
            operation = PermissionMap['prinrole'][setting]
            func = getattr(manager, operation)
            if prinrole['role'] in lroles:
                changed = True
                func(prinrole['role'], prinrole['principal'])
            else:
                raise PreconditionFailed(self.context, 'No valid local role')

        for prinperm in data.get('prinperm') or []:
            setting = prinperm['setting']
            if setting not in PermissionMap['prinperm']:
                raise PreconditionFailed(self.context, 'Invalid Type')
            manager = IPrincipalPermissionManager(context)
            operation = PermissionMap['prinperm'][setting]
            func = getattr(manager, operation)
            changed = True
            func(prinperm['permission'], prinperm['principal'])

        for roleperm in data.get('roleperm') or []:
            setting = roleperm['setting']
            if setting not in PermissionMap['roleperm']:
                raise PreconditionFailed(self.context, 'Invalid Type')
            manager = IRolePermissionManager(context)
            operation = PermissionMap['roleperm'][setting]
            func = getattr(manager, operation)
            changed = True
            func(roleperm['permission'], roleperm['role'])

        if changed:
            context._p_register()  # make sure data is saved
            await notify(ObjectPermissionsModifiedEvent(context, data))
示例#4
0
 async def __call__(self, changed=False):
     """Change permissions"""
     context = self.context
     request = self.request
     data = await request.json()
     if ("prinrole" not in data and "roleperm" not in data
             and "prinperm" not in data and "perminhe" not in data):
         raise PreconditionFailed(
             self.context, "prinrole or roleperm or prinperm missing")
     return await apply_sharing(context, data)
示例#5
0
async def can_i_do(context, request):
    if 'permission' not in request.query and 'permissions' not in request.query:
        raise PreconditionFailed(context, 'No permission param')
    policy = get_security_policy()
    if 'permissions' in request.query:
        results = {}
        for perm in request.query['permissions'].split(','):
            results[perm] = policy.check_permission(perm, context)
        return results
    else:
        return policy.check_permission(request.query['permission'], context)
示例#6
0
async def can_i_do(context, request):
    if "permission" not in request.query and "permissions" not in request.query:
        raise PreconditionFailed(context, "No permission param")
    policy = get_security_policy()
    if "permissions" in request.query:
        results = {}
        for perm in request.query["permissions"].split(","):
            results[perm] = policy.check_permission(perm, context)
        return results
    else:
        return policy.check_permission(request.query["permission"], context)
示例#7
0
async def can_i_do(context, request):
    if 'permission' not in request.query and 'permissions' not in request.query:
        raise PreconditionFailed(context, 'No permission param')
    interaction = IInteraction(request)
    if 'permissions' in request.GET:
        results = {}
        for perm in request.GET['permissions'].split(','):
            results[perm] = interaction.check_permission(perm, context)
        return results
    else:
        return interaction.check_permission(request.GET['permission'], context)
示例#8
0
 async def __call__(self, changed=False):
     """Change permissions"""
     context = self.context
     request = self.request
     data = await request.json()
     if 'prinrole' not in data and \
             'roleperm' not in data and \
             'prinperm' not in data:
         raise PreconditionFailed(
             self.context, 'prinrole or roleperm or prinperm missing')
     return await apply_sharing(context, data)
示例#9
0
async def update_groups(group, event):
    container = get_current_container()
    users = group.users
    for user in users:
        try:
            context = await navigate_to(container, f"users/{user}")
        except KeyError:
            raise PreconditionFailed(container, "inexistent user")

        if group.id not in context.user_groups:
            context.user_groups.append(user)
            context.register()
示例#10
0
async def addPerms(obj, perms, changed=False):
    """apply some permissions. Copied almost verbatim from sharingPOST service
    """
    lroles = local_roles()
    groles = global_roles()
    if ("prinrole" not in perms and "roleperm" not in perms
            and "prinperm" not in perms):
        raise PreconditionFailed(obj,
                                 "prinrole or roleperm or prinperm missing")

    for prinrole in perms.get("prinrole") or []:
        setting = prinrole.get("setting")
        if setting not in PermissionMap["prinrole"]:
            raise PreconditionFailed(obj, "Invalid Type {}".format(setting))
        manager = IPrincipalRoleManager(obj)
        operation = PermissionMap["prinrole"][setting]
        func = getattr(manager, operation)

        if (obj.type_name == "Container"
                and prinrole["role"] not in groles + lroles):
            raise PreconditionFailed(
                obj, "Not a valid role: {}".format(prinrole["role"]))
        if obj.type_name != "Container" and prinrole["role"] not in lroles:
            raise PreconditionFailed(
                obj, "Not a valid local role: {}".format(prinrole["role"]))

        changed = True
        func(prinrole["role"], prinrole["principal"])

    for prinperm in perms.get("prinperm") or []:
        setting = prinperm["setting"]
        if setting not in PermissionMap["prinperm"]:
            raise PreconditionFailed(obj, "Invalid Type")
        manager = IPrincipalPermissionManager(obj)
        operation = PermissionMap["prinperm"][setting]
        func = getattr(manager, operation)
        changed = True
        func(prinperm["permission"], prinperm["principal"])

    for roleperm in perms.get("roleperm") or []:
        setting = roleperm["setting"]
        if setting not in PermissionMap["roleperm"]:
            raise PreconditionFailed(obj, "Invalid Type")
        manager = IRolePermissionManager(obj)
        operation = PermissionMap["roleperm"][setting]
        func = getattr(manager, operation)
        changed = True
        func(roleperm["permission"], roleperm["role"])

    if changed:
        obj._p_register()  # make sure data is saved
示例#11
0
async def duplicate(context, request):
    try:
        data = await request.json()
    except Exception:
        data = {}
    destination = data.get('destination')
    if destination is not None:
        destination_ob = await navigate_to(request.container, destination)
        if destination_ob is None:
            raise PreconditionFailed(
                context,
                'Could not find destination object',
            )
    else:
        destination_ob = context.__parent__

    security = IInteraction(request)
    if not security.check_permission('guillotina.AddContent', destination_ob):
        raise PreconditionFailed(
            context,
            'You do not have permission to add content to '
            'the destination object',
        )

    if 'new_id' in data:
        new_id = data['new_id']
        if await destination_ob.async_contains(new_id):
            raise PreconditionFailed(
                context,
                f'Destination already has object with the id {new_id}')
    else:
        count = 1
        new_id = f'{context.id}-duplicate-{count}'
        while await destination_ob.async_contains(new_id):
            count += 1
            new_id = f'{context.id}-duplicate-{count}'

    new_obj = await create_content_in_container(
        destination_ob,
        context.type_name,
        new_id,
        id=new_id,
        creators=context.creators,
        contributors=context.contributors)

    for key in context.__dict__.keys():
        if key.startswith('__') or key.startswith('_BaseObject'):
            continue
        if key in ('id', ):
            continue
        new_obj.__dict__[key] = context.__dict__[key]
    new_obj.__acl__ = context.__acl__
    for behavior in context.__behaviors__:
        new_obj.add_behavior(behavior)

    # need to copy annotation data as well...
    # load all annotations for context
    [b for b in await get_all_behaviors(context, load=True)]
    annotations_container = IAnnotations(new_obj)
    for anno_id, anno_data in context.__gannotations__.items():
        new_anno_data = AnnotationData()
        for key, value in anno_data.items():
            new_anno_data[key] = value
        await annotations_container.async_set(anno_id, new_anno_data)

    data['id'] = new_id
    await notify(
        ObjectDuplicatedEvent(new_obj,
                              context,
                              destination_ob,
                              new_id,
                              payload=data))

    get = DefaultGET(new_obj, request)
    return await get()
示例#12
0
async def duplicate(
    context: IResource,
    destination: Optional[Union[IResource, str]] = None,
    new_id: Optional[str] = None,
    check_permission: bool = True,
    reset_acl: bool = False,
) -> IResource:
    if destination is not None:
        if isinstance(destination, str):
            destination_ob = None
            if destination.startswith("/"):
                container = task_vars.container.get()
                if container:
                    try:
                        destination_ob = await navigate_to(container, destination)
                    except KeyError:
                        pass
            else:
                try:
                    destination_ob = await get_object_by_uid(destination)
                except KeyError:
                    pass
        else:
            destination_ob = destination

        if destination_ob is None:
            raise PreconditionFailed(context, "Could not find destination object")
    else:
        destination_ob = context.__parent__

    if check_permission:
        policy = get_security_policy()
        if not policy.check_permission("guillotina.AddContent", destination_ob):
            raise PreconditionFailed(
                context, "You do not have permission to add content to " "the destination object"
            )

    if new_id is not None:
        if await destination_ob.async_contains(new_id):
            raise PreconditionFailed(context, f"Destination already has object with the id {new_id}")
    else:
        count = 1
        new_id = f"{context.id}-duplicate-{count}"
        while await destination_ob.async_contains(new_id):
            count += 1
            new_id = f"{context.id}-duplicate-{count}"

    from guillotina.content import create_content_in_container

    creators = context.creators
    contributors = context.contributors
    user_id = get_authenticated_user_id()
    if reset_acl:
        creators = [user_id]
        contributors = [user_id]
    new_obj = await create_content_in_container(
        destination_ob,
        context.type_name,
        new_id,
        id=new_id,
        creators=creators,
        contributors=contributors,
        check_security=check_permission,
        check_constraints=True,
    )
    for key in context.__dict__.keys():
        if key.startswith("__") or key.startswith("_BaseObject"):
            continue
        if key in ("id", "creators", "contributors"):
            continue
        new_obj.__dict__[key] = context.__dict__[key]

    if reset_acl:
        new_obj.__acl__ = None
        get_owner = get_utility(IGetOwner)
        roleperm = IPrincipalRoleManager(new_obj)
        owner = await get_owner(new_obj, user_id)
        if owner is not None:
            roleperm.assign_role_to_principal("guillotina.Owner", owner)
    else:
        new_obj.__acl__ = context.__acl__

    for behavior in context.__behaviors__:
        new_obj.add_behavior(behavior)
    # need to copy annotation data as well...
    # load all annotations for context
    [b for b in await get_all_behaviors(context, load=True)]
    annotations_container = IAnnotations(new_obj)
    for anno_id, anno_data in context.__gannotations__.items():
        new_anno_data = AnnotationData()
        for key, value in anno_data.items():
            new_anno_data[key] = value
        await annotations_container.async_set(anno_id, new_anno_data)

    await notify(
        ObjectDuplicatedEvent(
            new_obj, context, destination_ob, new_id, payload={"id": new_id, "destination": destination}
        )
    )
    return new_obj
示例#13
0
async def move(
    context: IResource,
    destination: Optional[Union[IResource, str]] = None,
    new_id: Optional[str] = None,
    check_permission: bool = True,
) -> None:
    if destination is None:
        destination_ob = context.__parent__
    else:
        if isinstance(destination, str):
            destination_ob = None
            if destination.startswith("/"):
                container = task_vars.container.get()
                if container is not None:
                    try:
                        destination_ob = await navigate_to(container, destination)
                    except KeyError:
                        pass
            else:
                try:
                    destination_ob = await get_object_by_uid(destination)
                except KeyError:
                    pass
        else:
            destination_ob = destination

    if destination_ob is None:
        raise PreconditionFailed(context, "Could not find destination object")
    if destination_ob.__uuid__ == context.__uuid__:
        raise PreconditionFailed(context, "You can not move object to itself")
    if destination_ob.__uuid__ == context.__parent__.__uuid__ and new_id == context.id:
        raise PreconditionFailed(context, "Object already belongs to this parent with same id")

    txn = get_transaction()
    if txn is not None:
        cache_keys = txn._cache.get_cache_keys(context, "deleted")

    old_id = context.id
    if new_id is None:
        new_id = context.id
    else:
        id_checker = get_adapter(context, IIDChecker)
        if not isinstance(new_id, str) or not await id_checker(new_id, context.type_name):
            raise PreconditionFailed(new_id, "Invalid id")

    if check_permission:
        policy = get_security_policy()
        if not policy.check_permission("guillotina.AddContent", destination_ob):
            raise PreconditionFailed(
                context, "You do not have permission to add content to the destination object"
            )

    if await destination_ob.async_contains(new_id):
        raise HTTPConflict(content={"reason": f'Destination already has object with the id "{new_id}"'})

    original_parent = context.__parent__

    await notify(
        BeforeObjectMovedEvent(
            context,
            original_parent,
            old_id,
            destination_ob,
            new_id,
            payload={"id": new_id, "destination": destination},
        )
    )

    if new_id != old_id:
        context.id = context.__name__ = new_id
    context.__parent__ = destination_ob
    context.register()

    await notify(
        ObjectMovedEvent(
            context,
            original_parent,
            old_id,
            destination_ob,
            new_id,
            payload={"id": new_id, "destination": destination},
        )
    )

    if txn is not None:
        cache_keys += txn._cache.get_cache_keys(context, "added")
        await txn._cache.delete_all(cache_keys)
示例#14
0
async def duplicate(
    context: IResource,
    destination: Union[IResource, str] = None,
    new_id: str = None,
    check_permission: bool = True,
) -> IResource:
    if destination is not None:
        if isinstance(destination, str):
            container = task_vars.container.get()
            if container:
                destination_ob = await navigate_to(container, destination)
            else:
                raise PreconditionFailed(context, "Could not find destination object")
        else:
            destination_ob = destination

        if destination_ob is None:
            raise PreconditionFailed(context, "Could not find destination object")
    else:
        destination_ob = context.__parent__

    if check_permission:
        policy = get_security_policy()
        if not policy.check_permission("guillotina.AddContent", destination_ob):
            raise PreconditionFailed(
                context, "You do not have permission to add content to " "the destination object"
            )

    if new_id is not None:
        if await destination_ob.async_contains(new_id):
            raise PreconditionFailed(context, f"Destination already has object with the id {new_id}")
    else:
        count = 1
        new_id = f"{context.id}-duplicate-{count}"
        while await destination_ob.async_contains(new_id):
            count += 1
            new_id = f"{context.id}-duplicate-{count}"

    from guillotina.content import create_content_in_container

    new_obj = await create_content_in_container(
        destination_ob,
        context.type_name,
        new_id,
        id=new_id,
        creators=context.creators,
        contributors=context.contributors,
    )

    for key in context.__dict__.keys():
        if key.startswith("__") or key.startswith("_BaseObject"):
            continue
        if key in ("id",):
            continue
        new_obj.__dict__[key] = context.__dict__[key]
    new_obj.__acl__ = context.__acl__
    for behavior in context.__behaviors__:
        new_obj.add_behavior(behavior)

    # need to copy annotation data as well...
    # load all annotations for context
    [b for b in await get_all_behaviors(context, load=True)]
    annotations_container = IAnnotations(new_obj)
    for anno_id, anno_data in context.__gannotations__.items():
        new_anno_data = AnnotationData()
        for key, value in anno_data.items():
            new_anno_data[key] = value
        await annotations_container.async_set(anno_id, new_anno_data)

    await notify(
        ObjectDuplicatedEvent(
            new_obj, context, destination_ob, new_id, payload={"id": new_id, "destination": destination}
        )
    )
    return new_obj
示例#15
0
async def duplicate(context: IResource,
                    destination: Union[IResource, str] = None,
                    new_id: str = None,
                    check_permission: bool = True) -> IResource:
    if destination is not None:
        if isinstance(destination, str):
            request = get_current_request()
            destination_ob = await navigate_to(request.container, destination)
        else:
            destination_ob = destination

        if destination_ob is None:
            raise PreconditionFailed(
                context,
                'Could not find destination object',
            )
    else:
        destination_ob = context.__parent__

    if check_permission:
        request = get_current_request()
        security = IInteraction(request)
        if not security.check_permission('guillotina.AddContent',
                                         destination_ob):
            raise PreconditionFailed(
                context,
                'You do not have permission to add content to '
                'the destination object',
            )

    if new_id is not None:
        if await destination_ob.async_contains(new_id):
            raise PreconditionFailed(
                context,
                f'Destination already has object with the id {new_id}')
    else:
        count = 1
        new_id = f'{context.id}-duplicate-{count}'
        while await destination_ob.async_contains(new_id):
            count += 1
            new_id = f'{context.id}-duplicate-{count}'

    from guillotina.content import create_content_in_container
    new_obj = await create_content_in_container(
        destination_ob,
        context.type_name,
        new_id,
        id=new_id,
        creators=context.creators,
        contributors=context.contributors)

    for key in context.__dict__.keys():
        if key.startswith('__') or key.startswith('_BaseObject'):
            continue
        if key in ('id', ):
            continue
        new_obj.__dict__[key] = context.__dict__[key]
    new_obj.__acl__ = context.__acl__
    for behavior in context.__behaviors__:
        new_obj.add_behavior(behavior)

    # need to copy annotation data as well...
    # load all annotations for context
    [b for b in await get_all_behaviors(context, load=True)]
    annotations_container = IAnnotations(new_obj)
    for anno_id, anno_data in context.__gannotations__.items():
        new_anno_data = AnnotationData()
        for key, value in anno_data.items():
            new_anno_data[key] = value
        await annotations_container.async_set(anno_id, new_anno_data)

    await notify(
        ObjectDuplicatedEvent(new_obj,
                              context,
                              destination_ob,
                              new_id,
                              payload={
                                  'id': new_id,
                                  'destination': destination,
                              }))
    return new_obj
示例#16
0
async def apply_sharing(context, data):
    lroles = role.local_roles()
    changed = False
    for perminhe in data.get("perminhe") or []:
        if not isinstance(perminhe, dict):
            raise PreconditionFailed(
                context, "Invalid Type, must be list {}".format(perminhe))
        setting = perminhe.get("setting")
        if setting not in PermissionMap["perminhe"]:
            raise PreconditionFailed(context,
                                     "Invalid Type {}".format(setting))
        manager = IInheritPermissionManager(context)
        operation = PermissionMap["perminhe"][setting]
        func = getattr(manager, operation)
        changed = True
        func(perminhe["permission"])

    for prinrole in data.get("prinrole") or []:
        if not isinstance(prinrole, dict):
            raise PreconditionFailed(
                context, "Invalid Type, must be list {}".format(prinrole))
        setting = prinrole.get("setting")
        if setting not in PermissionMap["prinrole"]:
            raise PreconditionFailed(context,
                                     "Invalid Type {}".format(setting))
        manager = IPrincipalRoleManager(context)
        operation = PermissionMap["prinrole"][setting]
        func = getattr(manager, operation)
        if prinrole["role"] in lroles:
            changed = True
            func(prinrole["role"], prinrole["principal"])
        else:
            raise PreconditionFailed(context, "No valid local role")

    for prinperm in data.get("prinperm") or []:
        if not isinstance(prinperm, dict):
            raise PreconditionFailed(
                context, "Invalid Type, must be list {}".format(prinperm))
        setting = prinperm["setting"]
        if setting not in PermissionMap["prinperm"]:
            raise PreconditionFailed(context, "Invalid Type")
        manager = IPrincipalPermissionManager(context)
        operation = PermissionMap["prinperm"][setting]
        func = getattr(manager, operation)
        changed = True
        func(prinperm["permission"], prinperm["principal"])

    for roleperm in data.get("roleperm") or []:
        if not isinstance(roleperm, dict):
            raise PreconditionFailed(
                context, "Invalid Type, must be list {}".format(roleperm))
        setting = roleperm["setting"]
        if setting not in PermissionMap["roleperm"]:
            raise PreconditionFailed(context, "Invalid Type")
        manager = IRolePermissionManager(context)
        operation = PermissionMap["roleperm"][setting]
        func = getattr(manager, operation)
        changed = True
        func(roleperm["permission"], roleperm["role"])

    if changed:
        context.register()  # make sure data is saved
        await notify(ObjectPermissionsModifiedEvent(context, data))
示例#17
0
async def move(context: IResource,
               destination: Union[IResource, str] = None,
               new_id: str = None,
               check_permission: bool = True) -> None:
    if destination is None:
        destination_ob = context.__parent__
    else:
        if isinstance(destination, str):
            request = get_current_request()
            try:
                destination_ob = await navigate_to(request.container,
                                                   destination)
            except KeyError:
                destination_ob = None
        else:
            destination_ob = destination

    if destination_ob is None:
        raise PreconditionFailed(context, 'Could not find destination object')
    old_id = context.id
    if new_id is not None:
        context.id = context.__name__ = new_id
    else:
        new_id = context.id

    if check_permission:
        request = get_current_request()
        security = IInteraction(request)
        if not security.check_permission('guillotina.AddContent',
                                         destination_ob):
            raise PreconditionFailed(
                context, 'You do not have permission to add content to the '
                'destination object')

    if await destination_ob.async_contains(new_id):
        raise PreconditionFailed(
            context, f'Destination already has object with the id {new_id}')

    original_parent = context.__parent__

    txn = get_transaction(request)
    cache_keys = txn._cache.get_cache_keys(context, 'deleted')

    await notify(
        BeforeObjectMovedEvent(context,
                               original_parent,
                               old_id,
                               destination_ob,
                               new_id,
                               payload={
                                   'id': new_id,
                                   'destination': destination
                               }))

    context.__parent__ = destination_ob
    context._p_register()

    await notify(
        ObjectMovedEvent(context,
                         original_parent,
                         old_id,
                         destination_ob,
                         new_id,
                         payload={
                             'id': new_id,
                             'destination': destination
                         }))

    cache_keys += txn._cache.get_cache_keys(context, 'added')
    await txn._cache.delete_all(cache_keys)
示例#18
0
async def move(context: IResource,
               destination: Union[IResource, str] = None,
               new_id: str = None,
               check_permission: bool = True) -> None:
    if destination is None:
        destination_ob = context.__parent__
    else:
        if isinstance(destination, str):
            container = task_vars.container.get()
            if container is not None:
                try:
                    destination_ob = await navigate_to(container, destination)
                except KeyError:
                    destination_ob = None
            else:
                raise PreconditionFailed(context,
                                         'Could not find destination object')
        else:
            destination_ob = destination

    if destination_ob is None:
        raise PreconditionFailed(context, 'Could not find destination object')
    if destination_ob.__uuid__ == context.__uuid__:
        raise PreconditionFailed(context, 'You can not move object to itself')
    if destination_ob.__uuid__ == context.__parent__.__uuid__ and new_id == context.id:
        raise PreconditionFailed(
            context, 'Object already belongs to this parent with same id')

    txn = get_transaction()
    if txn is not None:
        cache_keys = txn._cache.get_cache_keys(context, 'deleted')

    old_id = context.id
    if new_id is not None:
        context.id = context.__name__ = new_id
    else:
        new_id = context.id

    if check_permission:
        policy = get_security_policy()
        if not policy.check_permission('guillotina.AddContent',
                                       destination_ob):
            raise PreconditionFailed(
                context, 'You do not have permission to add content to the '
                'destination object')

    if await destination_ob.async_contains(new_id):
        raise PreconditionFailed(
            context, f'Destination already has object with the id {new_id}')

    original_parent = context.__parent__

    await notify(
        BeforeObjectMovedEvent(context,
                               original_parent,
                               old_id,
                               destination_ob,
                               new_id,
                               payload={
                                   'id': new_id,
                                   'destination': destination
                               }))

    context.__parent__ = destination_ob
    context.register()

    await notify(
        ObjectMovedEvent(context,
                         original_parent,
                         old_id,
                         destination_ob,
                         new_id,
                         payload={
                             'id': new_id,
                             'destination': destination
                         }))

    if txn is not None:
        cache_keys += txn._cache.get_cache_keys(context, 'added')
        await txn._cache.delete_all(cache_keys)