Beispiel #1
0
 async def async_set(self, key: str, value: IResource) -> None:
     """
     Asynchronously set an object in this folder
     """
     value.__parent__ = self
     value.__name__ = key
     if self._p_jar is not None:
         value._p_jar = self._p_jar
         self._p_jar.register(value)
Beispiel #2
0
 async def async_set(self, key: str, value: IResource) -> None:
     """
     Asynchronously set an object in this folder
     """
     value.__parent__ = self
     value.__name__ = key
     trns = self._get_transaction()
     if trns is not None:
         value._p_jar = trns
         trns.register(value)
Beispiel #3
0
 def __init__(self, context):
     self.context = context
     self.utility = get_utility(IWorkflowUtility)
     if not IResource.providedBy(context):
         self.states = IWorkflow(context.context).states
     else:
         self.states = IWorkflow(context).states
Beispiel #4
0
 async def __call__(self):
     result = []
     container = self.request.container
     async for content in container.async_values():
         if IResource.providedBy(content):
             result.append({
                 'title': content.title,
                 '@id': IAbsoluteURL(content, self.request)()
             })
     return {"@id": self.request.url.human_repr(), "items": result}
Beispiel #5
0
 def __init__(self, context):
     self.context = context
     self.utility = get_utility(IWorkflowUtility)
     adapter = None
     if not IResource.providedBy(context):
         adapter = query_adapter(context.context, IWorkflow)
     else:
         adapter = query_adapter(context, IWorkflow)
     if adapter is not None:
         self.states = adapter.states
     else:
         self.states = {}
Beispiel #6
0
    async def set_schema(
        self,
        schema: Type[Interface],
        obj: IResource,
        data: Dict[str, Any],
        errors: List[Dict[str, Any]],
        validate_all: bool = False,
        behavior: bool = False,
    ):
        write_permissions = merged_tagged_value_dict(schema,
                                                     write_permission.key)
        changed = False
        for name, field in get_fields(schema).items():

            if name in RESERVED_ATTRS:
                continue

            if field.readonly:
                continue

            if behavior:
                found = False
                if data.get(schema.__identifier__):
                    sdata = data[schema.__identifier__]
                    data_value = sdata[name] if name in sdata else None
                    found = True if name in sdata else False
            else:
                data_value = data[name] if name in data else None
                found = True if name in data else False
            if found:

                if not self.check_permission(write_permissions.get(name)):
                    raise Unauthorized("Write permission not allowed")

                try:
                    field = field.bind(obj)
                    value = await self.get_value(field, obj, data_value)
                except ValueError as e:
                    errors.append({
                        "message": "Value error",
                        "field": name,
                        "error": e
                    })
                except ValidationError as e:
                    errors.append(e.json())
                except ValueDeserializationError as e:
                    errors.append({
                        "message": e.message,
                        "field": name,
                        "error": e
                    })
                except Invalid as e:
                    errors.append({
                        "message": e.args[0],
                        "field": name,
                        "error": e
                    })
                else:
                    # record object changes for potential future conflict resolution
                    try:
                        await apply_coroutine(field.set, obj, value)
                        changed = True
                    except ValidationError as e:
                        errors.append(e.json())
                    except ValueDeserializationError as e:
                        errors.append({
                            "message": e.message,
                            "field": name,
                            "error": e
                        })
                    except AttributeError:
                        logger.warning(
                            f"AttributeError setting data on field {name}",
                            exc_info=True)
                    except Exception:
                        logger.warning(
                            f"Unhandled error setting data on field, {schema} {name}",
                            exc_info=True)
                        errors.append({
                            "message":
                            "Unhandled exception",
                            "field":
                            name,
                            "error":
                            ValueDeserializationError(field, value,
                                                      "Unhandled error"),
                        })
            else:
                if validate_all and field.required and getattr(
                        obj, name, None) is None:
                    errors.append({
                        "message": "Required parameter",
                        "field": name,
                        "error": ValueError("Required parameter"),
                    })

        for error in await validate_invariants(schema, obj):
            if isinstance(error, ValidationError):
                errors.append({
                    "message": error.doc(),
                    "value": error.value,
                    "field": error.field_name,
                    "error": error.errors,
                })
            else:
                if len(getattr(error, "args", [])) > 0 and isinstance(
                        error.args[0], str):
                    message = error.args[0]
                else:
                    message = error.__doc__
                errors.append({"message": message, "error": error})

        if changed:
            obj.register()
Beispiel #7
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)
Beispiel #8
0
def iter_schemata(obj):
    type_name = IResource(obj).type_name
    for schema in iter_schemata_for_type(type_name):
        yield schema
    for schema in obj.__behaviors_schemas__:
        yield schema
Beispiel #9
0
def iter_schemata(obj):
    portal_type = IResource(obj).portal_type
    for schema in iter_schemata_for_type(portal_type):
        yield schema
    for schema in obj.__behaviors_schemas__:
        yield schema
Beispiel #10
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)
Beispiel #11
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)