Esempio n. 1
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()
Esempio n. 2
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
Esempio n. 3
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
Esempio n. 4
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