Exemplo n.º 1
0
    async def __call__(self):
        """ data input : { 'interface': 'INTERFACE' }"""
        registry = await get_registry()
        if registry is None:
            return ErrorResponse("BadRequest",
                                 _("Not in a container request"),
                                 status=412)

        data = await self.request.json()
        interface = data.get("interface", None)
        initial_values = data.get("initial_values", {})
        if interface is None:
            return ErrorResponse("InvalidRequest",
                                 "Non existent Interface",
                                 status=412)

        iObject = import_class(interface)
        registry.register_interface(iObject)
        config = registry.for_interface(iObject)

        # Initialize values
        # If its defined on the guillotina.schema default will not be overwritten
        #  you will need to PATCH
        for key, field in get_fields(iObject).items():
            if key in initial_values and getattr(config, key,
                                                 _marker) == _marker:
                # We don't have a value
                config[key] = initial_values[key]

        await notify(
            RegistryEditedEvent(self.context, registry,
                                {interface: initial_values}))

        return Response(status=201)
Exemplo n.º 2
0
async def set_constraint(context, request):
    # validate input
    data = await request.json()
    if not isinstance(data, list):
        raise ErrorResponse(
            "MissingList",
            str("value type"),
            status=412,
            reason=error_reasons.DESERIALIZATION_FAILED,
        )

    tn = getattr(context, "type_name", None)
    factory = get_cached_factory(tn)
    allowed_types = factory.allowed_types
    for element in data:
        if allowed_types is not None and element not in allowed_types:
            raise ErrorResponse(
                "WrongType",
                str("wrong type"),
                status=412,
                reason=error_reasons.DESERIALIZATION_FAILED,
            )

    setattr(context, "__allowed_types__", data)
    context.register()
Exemplo n.º 3
0
    async def __call__(self):
        """ data input : { 'interface': 'INTERFACE' }"""
        if not hasattr(self.request, 'container_settings'):
            return ErrorResponse('BadRequest',
                                 _("Not in a container request"),
                                 status=412)

        data = await self.request.json()
        interface = data.get('interface', None)
        initial_values = data.get('initial_values', {})
        if interface is None:
            return ErrorResponse('InvalidRequest',
                                 'Non existent Interface',
                                 status=412)

        registry = self.request.container_settings
        iObject = import_class(interface)
        registry.register_interface(iObject)
        config = registry.for_interface(iObject)

        # Initialize values
        # If its defined on the guillotina.schema default will not be overwritten
        #  you will need to PATCH
        for key, field in get_fields(iObject).items():
            if key in initial_values and getattr(config, key,
                                                 _marker) == _marker:
                # We don't have a value
                config[key] = initial_values[key]

        return Response(status=201)
Exemplo n.º 4
0
    async def __call__(self):
        if self.key is _marker:
            # No option to write the root of registry
            return ErrorResponse("InvalidRequest",
                                 "Needs the registry key",
                                 status=412)

        data = await self.request.json()
        if "value" in data:
            value = data["value"]
        else:
            value = data

        assert "." in self.key, "Registry key must be dotted.iface.name.fieldname"  # noqa
        iface_name, name = self.key.rsplit(".", 1)
        iface = resolve_dotted_name(iface_name)

        assert iface is not None, "Must provide valid registry interface"  # noqa
        try:
            field = iface[name]
        except KeyError:
            return ErrorResponse("DeserializationError",
                                 "Invalid field name {}".format(str(name)),
                                 status=412)

        try:
            new_value = get_adapter((field),
                                    IJSONToValue,
                                    args=[value, self.context])
        except ComponentLookupError:
            return ErrorResponse("DeserializationError",
                                 "Cannot deserialize type {}".format(
                                     str(self.field)),
                                 status=412)

        try:
            registry = await get_registry()
            registry[self.key] = new_value
        except (DeserializationError, ValueDeserializationError) as e:
            return ErrorResponse("DeserializationError",
                                 str(e),
                                 exc=e,
                                 status=412)

        await notify(
            RegistryEditedEvent(self.context, registry,
                                {iface_name: {
                                    name: value
                                }}))

        return Response(status=204)
Exemplo n.º 5
0
    async def __call__(self):
        data = await self.get_data()

        behaviors = data.get("@behaviors", None)
        for behavior in behaviors or ():
            try:
                self.context.add_behavior(behavior)
            except (TypeError, ComponentLookupError):
                return HTTPPreconditionFailed(
                    content={"message": f"{behavior} is not a valid behavior", "behavior": behavior}
                )

        deserializer = query_multi_adapter((self.context, self.request), IResourceDeserializeFromJson)
        if deserializer is None:
            raise ErrorResponse(
                "DeserializationError",
                "Cannot deserialize type {}".format(self.context.type_name),
                status=412,
                reason=error_reasons.DESERIALIZATION_FAILED,
            )

        await notify(BeforeObjectModifiedEvent(self.context, payload=data))

        await deserializer(data)

        await notify(ObjectModifiedEvent(self.context, payload=data))

        return Response(status=204)
Exemplo n.º 6
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data or data['@type'] not in app_settings[
                'container_types']:
            raise HTTPNotFound(
                content={
                    'message': 'can not create this type %s' % data['@type']
                })

        if 'id' not in data:
            raise HTTPPreconditionFailed(content={'message': 'We need an id'})

        if not data.get('title'):
            data['title'] = data['id']

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            raise HTTPConflict(
                content={'message': 'Container with id already exists'})

        install_addons = data.pop('@addons', None) or []
        for addon in install_addons:
            # validate addon list
            if addon not in app_settings['available_addons']:
                return ErrorResponse(
                    'RequiredParam',
                    "Property '@addons' must refer to a valid addon",
                    status=412,
                    reason=error_reasons.INVALID_ID)

        owner_id = get_authenticated_user_id(self.request)

        container = await create_container(self.context,
                                           data.pop('id'),
                                           container_type=data.pop('@type'),
                                           owner_id=owner_id,
                                           **data)
        self.request._container_id = container.__name__
        self.request.container = container

        annotations_container = get_adapter(container, IAnnotations)
        self.request.container_settings = await annotations_container.async_get(
            REGISTRY_DATA_KEY)

        for addon in install_addons:
            await addons.install(container, addon)

        resp = {
            '@type': container.type_name,
            'id': container.id,
            'title': data['title']
        }
        headers = {'Location': posixpath.join(self.request.path, container.id)}

        return Response(content=resp, headers=headers)
Exemplo n.º 7
0
async def delete_comment(context, request):
    comment_id = request.matchdict["comment_id"]
    bhr = ICMSBehavior(context)
    if not bhr.allow_discussion:
        raise HTTPUnauthorized(content={"text": "Not available option"})
    await bhr.load()

    if comment_id not in bhr.comments:
        raise ErrorResponse("InvalidComment",
                            "This comment does not exist",
                            status=412)

    user_id = get_authenticated_user_id()
    comment = bhr.comments[comment_id]

    # TODO: We need ?
    policy = get_security_policy()
    if user_id != comment["author_username"] or not policy.check_permission(
            "guillotina.DeleteAllComments", context):
        raise HTTPUnauthorized(
            content={"text": "Not the author or permission"})

    list_to_delete = [comment_id]
    delete_from_list(bhr.comments, list_to_delete)
    for comment in list_to_delete:
        del bhr.comments[comment]

    bhr.register()

    return Response(status=204)
Exemplo n.º 8
0
async def modify_comment(context, request):
    payload = await request.json()
    comment_id = request.matchdict["comment_id"]
    bhr = ICMSBehavior(context)
    if not bhr.allow_discussion:
        raise HTTPUnauthorized(content={"text": "Not available option"})
    await bhr.load()

    if comment_id not in bhr.comments:
        raise ErrorResponse("InvalidComment",
                            "This comment does not exist",
                            status=412)

    user_id = get_authenticated_user_id()
    comment = bhr.comments[comment_id]

    # TODO: We need ?
    if user_id != comment["author_username"]:
        raise HTTPUnauthorized(content={"text": "Not the author"})

    comment["text"]["data"] = payload.get("text", "")
    comment["modification_date"] = datetime.now().isoformat()

    bhr.register()

    url = getMultiAdapter((context, request), IAbsoluteURL)()
    headers = {"Location": url + "/@comments/" + comment_id}
    return Response(status=204, headers=headers)
Exemplo n.º 9
0
    async def __call__(self):
        data = await self.request.json()
        if "@type" not in data or data["@type"] not in app_settings[
                "container_types"]:
            raise HTTPNotFound(
                content={
                    "message": "can not create this type %s" % data["@type"]
                })

        if "id" not in data:
            raise HTTPPreconditionFailed(content={"message": "We need an id"})

        if not data.get("title"):
            data["title"] = data["id"]

        if "description" not in data:
            data["description"] = ""

        value = await self.context.async_contains(data["id"])

        if value:
            # Already exist
            raise HTTPConflict(
                content={"message": "Container with id already exists"})

        install_addons = data.pop("@addons", None) or []
        for addon in install_addons:
            # validate addon list
            if addon not in app_settings["available_addons"]:
                return ErrorResponse(
                    "RequiredParam",
                    "Property '@addons' must refer to a valid addon",
                    status=412,
                    reason=error_reasons.INVALID_ID,
                )

        owner_id = get_authenticated_user_id()

        container = await create_container(self.context,
                                           data.pop("id"),
                                           container_type=data.pop("@type"),
                                           owner_id=owner_id,
                                           **data)
        task_vars.container.set(container)

        annotations_container = get_adapter(container, IAnnotations)
        task_vars.registry.set(
            await annotations_container.async_get(REGISTRY_DATA_KEY))

        for addon in install_addons:
            await addons.install(container, addon)

        resp = {
            "@type": container.type_name,
            "id": container.id,
            "title": data["title"]
        }
        headers = {"Location": posixpath.join(self.request.path, container.id)}

        return Response(content=resp, headers=headers)
Exemplo n.º 10
0
async def append_constraint(context, request):
    data = await request.json()
    if not isinstance(data, dict):
        raise ErrorResponse(
            "MissingLDict",
            str("value type"),
            status=412,
            reason=error_reasons.DESERIALIZATION_FAILED,
        )

    operation = data["op"]
    patch_data = data["types"]
    if operation == "add":
        tn = getattr(context, "type_name", None)
        factory = get_cached_factory(tn)
        allowed_types = factory.allowed_types
        for element in patch_data:
            if allowed_types is not None and element not in allowed_types:
                raise ErrorResponse(
                    "WrongType",
                    str("wrong type"),
                    status=412,
                    reason=error_reasons.DESERIALIZATION_FAILED,
                )

        at = getattr(context, "__allowed_types__", None)
        if at is None and allowed_types is not None:
            at = allowed_types.copy()
        elif at is None:
            at = []
        for element in patch_data:
            if element not in at:
                at.append(element)
        setattr(context, "__allowed_types__", at)
    elif operation == "del":
        at = getattr(context, "__allowed_types__", None)
        if at is None:
            factory = get_cached_factory(tn)
            if factory.allowed_types is None:
                at = []
            else:
                at = factory.allowed_types.copy()
        for element in patch_data:
            if element in at:
                at.remove(element)
        setattr(context, "__allowed_types__", at)
    context.register()
Exemplo n.º 11
0
async def uninstall_addon(context, request, id_to_uninstall):
    if id_to_uninstall not in app_settings['available_addons']:
        return ErrorResponse('RequiredParam',
                             _("Property 'id' is required to be valid"),
                             status=412,
                             reason=error_reasons.INVALID_ID)

    registry = request.container_settings
    config = registry.for_interface(IAddons)

    if id_to_uninstall not in config['enabled']:
        return ErrorResponse('Duplicate',
                             _("Addon not installed"),
                             status=412,
                             reason=error_reasons.NOT_INSTALLED)

    await addons.uninstall(context, id_to_uninstall)
Exemplo n.º 12
0
async def uninstall_addon(context, request, id_to_uninstall):
    if id_to_uninstall not in app_settings["available_addons"]:
        return ErrorResponse(
            "RequiredParam",
            _("Property 'id' is required to be valid"),
            status=412,
            reason=error_reasons.INVALID_ID,
        )

    registry = await get_registry()
    config = registry.for_interface(IAddons)

    if id_to_uninstall not in config["enabled"]:
        return ErrorResponse(
            "Duplicate", _("Addon not installed"), status=412, reason=error_reasons.NOT_INSTALLED
        )

    await addons.uninstall(context, id_to_uninstall)
Exemplo n.º 13
0
    async def __call__(self):
        if self.key is _marker:
            # No option to write the root of registry
            return ErrorResponse('InvalidRequest',
                                 'Needs the registry key',
                                 status=412)

        data = await self.request.json()
        if 'value' in data:
            value = data['value']
        else:
            value = data

        assert '.' in self.key, 'Registry key must be dotted.iface.name.fieldname'  # noqa
        iface, name = self.key.rsplit('.', 1)
        iface = resolve_dotted_name(iface)

        assert iface is not None, 'Must provide valid registry interface'  # noqa
        try:
            field = iface[name]
        except KeyError:
            return ErrorResponse('DeserializationError',
                                 'Invalid field name {}'.format(str(name)),
                                 status=412)

        try:
            new_value = get_adapter((field),
                                    IJSONToValue,
                                    args=[value, self.context])
        except ComponentLookupError:
            return ErrorResponse('DeserializationError',
                                 'Cannot deserialize type {}'.format(
                                     str(self.field)),
                                 status=412)

        try:
            self.request.container_settings[self.key] = new_value
        except DeserializationError as e:
            return ErrorResponse('DeserializationError',
                                 str(e),
                                 exc=e,
                                 status=412)

        return Response(status=204)
Exemplo n.º 14
0
async def append_constraint(context, request):
    data = await request.json()
    if not isinstance(data, dict):
        raise ErrorResponse('MissingLDict',
                            str('value type'),
                            status=412,
                            reason=error_reasons.DESERIALIZATION_FAILED)

    operation = data['op']
    patch_data = data['types']
    if operation == 'add':
        tn = getattr(context, 'type_name', None)
        factory = get_cached_factory(tn)
        allowed_types = factory.allowed_types
        for element in patch_data:
            if allowed_types is not None and element not in allowed_types:
                raise ErrorResponse(
                    'WrongType',
                    str('wrong type'),
                    status=412,
                    reason=error_reasons.DESERIALIZATION_FAILED)

        at = getattr(context, '__allowed_types__', None)
        if at is None and allowed_types is not None:
            at = allowed_types.copy()
        elif at is None:
            at = []
        for element in patch_data:
            if element not in at:
                at.append(element)
        setattr(context, '__allowed_types__', at)
    elif operation == 'del':
        at = getattr(context, '__allowed_types__', None)
        if at is None:
            factory = get_cached_factory(tn)
            if factory.allowed_types is None:
                at = []
            else:
                at = factory.allowed_types.copy()
        for element in patch_data:
            if element in at:
                at.remove(element)
        setattr(context, '__allowed_types__', at)
    context.register()
Exemplo n.º 15
0
async def install(context, request):
    data = await request.json()
    id_to_install = data.get('id', None)
    if id_to_install not in app_settings['available_addons']:
        return ErrorResponse('RequiredParam',
                             _("Property 'id' is required to be valid"),
                             status=412,
                             reason=error_reasons.INVALID_ID)

    registry = request.container_settings
    config = registry.for_interface(IAddons)

    if id_to_install in config['enabled']:
        return ErrorResponse('Duplicate',
                             _("Addon already installed"),
                             status=412,
                             reason=error_reasons.ALREADY_INSTALLED)

    await addons.install(context, id_to_install)
    return await get_addons(context, request)
Exemplo n.º 16
0
async def uninstall(context, request):
    data = await request.json()
    id_to_install = data.get('id', None)
    if id_to_install not in app_settings['available_addons']:
        return ErrorResponse('RequiredParam',
                             _("Property 'id' is required to be valid"),
                             status=412,
                             reason=error_reasons.INVALID_ID)

    registry = request.container_settings
    config = registry.for_interface(IAddons)

    if id_to_install not in config['enabled']:
        return ErrorResponse('Duplicate',
                             _("Addon not installed"),
                             status=412,
                             reason=error_reasons.NOT_INSTALLED)

    handler = app_settings['available_addons'][id_to_install]['handler']
    await apply_coroutine(handler.uninstall, context, request)
    config['enabled'] -= {id_to_install}
Exemplo n.º 17
0
async def install(context, request):
    data = await request.json()
    id_to_install = data.get("id", None)
    if id_to_install not in app_settings["available_addons"]:
        return ErrorResponse(
            "RequiredParam",
            _("Property 'id' is required to be valid"),
            status=412,
            reason=error_reasons.INVALID_ID,
        )

    registry = await get_registry()
    config = registry.for_interface(IAddons)

    if id_to_install in config["enabled"]:
        return ErrorResponse(
            "Duplicate", _("Addon already installed"), status=412, reason=error_reasons.ALREADY_INSTALLED
        )

    await addons.install(context, id_to_install)
    return await get_addons(context, request)
Exemplo n.º 18
0
async def move(context, request):
    try:
        data = await request.json()
    except Exception:
        data = {}

    try:
        await content.move(context, **data)
    except TypeError:
        raise ErrorResponse('RequiredParam',
                            _("Invalid params"),
                            reason=error_reasons.REQUIRED_PARAM_MISSING,
                            status=412)

    return {'@url': get_object_url(context, request)}
Exemplo n.º 19
0
async def duplicate(context, request):
    try:
        data = await request.json()
    except Exception:
        data = {}

    try:
        new_obj = await content.duplicate(context, **data)
    except TypeError:
        raise ErrorResponse('RequiredParam',
                            _("Invalid params"),
                            reason=error_reasons.REQUIRED_PARAM_MISSING,
                            status=412)

    get = DefaultGET(new_obj, request)
    return await get()
Exemplo n.º 20
0
async def move(context, request):
    try:
        data = await request.json()
    except Exception:
        data = {}

    try:
        await content.move(
            context, destination=data.get("destination"), new_id=data.get("new_id"), check_permission=True
        )
    except TypeError:
        raise ErrorResponse(
            "RequiredParam", _("Invalid params"), reason=error_reasons.REQUIRED_PARAM_MISSING, status=412
        )

    return {"@url": get_object_url(context, request)}
Exemplo n.º 21
0
async def move(context, request):
    try:
        data = await request.json()
    except Exception:
        data = {}

    try:
        await content.move(context, **data)
    except TypeError:
        raise ErrorResponse('RequiredParam',
                            _("Invalid params"),
                            reason=error_reasons.REQUIRED_PARAM_MISSING,
                            status=412)

    absolute_url = query_multi_adapter((context, request), IAbsoluteURL)
    return {'@url': absolute_url()}
Exemplo n.º 22
0
async def duplicate(context, request):
    try:
        data = await request.json()
    except Exception:
        data = {}
    try:
        new_obj = await content.duplicate(
            context,
            destination=data.get("destination"),
            new_id=data.get("new_id"),
            check_permission=True,
            reset_acl=data.get("reset_acl", False),
        )
    except TypeError:
        raise ErrorResponse(
            "RequiredParam", _("Invalid params"), reason=error_reasons.REQUIRED_PARAM_MISSING, status=412
        )

    get = DefaultGET(new_obj, request)
    return await get()
Exemplo n.º 23
0
    async def __call__(self):
        data = await self.get_data()

        behaviors = data.get('@behaviors', None)
        for behavior in behaviors or ():
            self.context.add_behavior(behavior)

        deserializer = query_multi_adapter((self.context, self.request),
                                           IResourceDeserializeFromJson)
        if deserializer is None:
            raise ErrorResponse('DeserializationError',
                                'Cannot deserialize type {}'.format(
                                    self.context.type_name),
                                status=412,
                                reason=error_reasons.DESERIALIZATION_FAILED)

        await deserializer(data)

        await notify(ObjectModifiedEvent(self.context, payload=data))

        return Response(status=204)
Exemplo n.º 24
0
async def add_child_comment(context, request):
    payload = await request.json()
    comment_id = request.matchdict["comment_id"]
    bhr = ICMSBehavior(context)
    if not bhr.allow_discussion:
        raise HTTPUnauthorized(content={"text": "Not available option"})
    await bhr.load()

    if comment_id not in bhr.comments:
        raise ErrorResponse("InvalidComment",
                            "This comment does not exist",
                            status=412)

    user_id = get_authenticated_user_id()
    new_comment_uuid = uuid.uuid4().hex
    bhr.comments[new_comment_uuid] = {
        "@parent": comment_id,
        "author_name": None,
        "author_username": user_id,
        "creation_date": datetime.now().isoformat(),
        "in_reply_to": None,
        "is_deletable": True,
        "is_editable": True,
        "modification_date": datetime.now().isoformat(),
        "text": {
            "data": payload.get("text", ""),
            "mime-type": "text/plain"
        },
        "user_notification": None,
    }

    bhr.register()

    url = getMultiAdapter((context, request), IAbsoluteURL)()
    headers = {"Location": url + "/@comments/" + new_comment_uuid}
    return Response(status=204, headers=headers)
Exemplo n.º 25
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data or data['@type'] not in app_settings['container_types']:
            raise HTTPNotFound(content={
                'message': 'can not create this type %s' % data['@type']
            })

        if 'id' not in data:
            raise HTTPPreconditionFailed(content={
                'message': 'We need an id'
            })

        if not data.get('title'):
            data['title'] = data['id']

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            raise HTTPConflict(content={
                'message': 'Container with id already exists'
            })

        container = await create_content(
            data['@type'],
            id=data['id'],
            title=data['title'],
            description=data['description'])

        # Special case we don't want the parent pointer
        container.__name__ = data['id']

        await self.context.async_set(data['id'], container)
        await container.install()

        self.request._container_id = container.__name__
        self.request.container = container

        user = get_authenticated_user_id(self.request)

        # Local Roles assign owner as the creator user
        roleperm = IPrincipalRoleManager(container)
        roleperm.assign_role_to_principal('guillotina.Owner', user)

        annotations_container = get_adapter(container, IAnnotations)
        self.request.container_settings = await annotations_container.async_get(REGISTRY_DATA_KEY)

        for addon in data.get('@addons') or []:
            if addon not in app_settings['available_addons']:
                return ErrorResponse(
                    'RequiredParam',
                    "Property '@addons' must refer to a valid addon",
                    status=412, reason=error_reasons.INVALID_ID)
            await addons.install(container, addon)

        await notify(ObjectAddedEvent(container, self.context, container.__name__,
                                      payload=data))

        resp = {
            '@type': data['@type'],
            'id': data['id'],
            'title': data['title']
        }
        headers = {
            'Location': posixpath.join(self.request.path, data['id'])
        }

        return Response(content=resp, headers=headers)
Exemplo n.º 26
0
    async def __call__(self):
        """To create a content."""
        data = await self.get_data()
        type_ = data.get('@type', None)
        id_ = data.get('id', None)
        behaviors = data.get('@behaviors', None)

        if not type_:
            raise ErrorResponse('RequiredParam',
                                _("Property '@type' is required"),
                                reason=error_reasons.REQUIRED_PARAM_MISSING,
                                status=412)

        # Generate a temporary id if the id is not given
        new_id = None
        if not id_:
            generator = query_adapter(self.request, IIDGenerator)
            if generator is not None:
                new_id = generator(data)
        else:
            if not isinstance(id_, str) or not valid_id(id_):
                raise ErrorResponse('PreconditionFailed',
                                    str('Invalid id'),
                                    status=412,
                                    reason=error_reasons.INVALID_ID)
            new_id = id_

        user = get_authenticated_user_id(self.request)

        options = {'creators': (user, ), 'contributors': (user, )}
        if 'uid' in data:
            options['_p_oid'] = data.pop('uid')

        # Create object
        try:
            obj = await create_content_in_container(self.context, type_,
                                                    new_id, **options)
        except ValueError as e:
            return ErrorResponse('CreatingObject', str(e), status=412)

        for behavior in behaviors or ():
            obj.add_behavior(behavior)

        # Update fields
        deserializer = query_multi_adapter((obj, self.request),
                                           IResourceDeserializeFromJson)
        if deserializer is None:
            return ErrorResponse('DeserializationError',
                                 'Cannot deserialize type {}'.format(
                                     obj.type_name),
                                 status=412,
                                 reason=error_reasons.DESERIALIZATION_FAILED)

        await deserializer(data, validate_all=True, create=True)

        # Local Roles assign owner as the creator user
        get_owner = get_utility(IGetOwner)
        roleperm = IPrincipalRoleManager(obj)
        owner = await get_owner(obj, user)
        if owner is not None:
            roleperm.assign_role_to_principal('guillotina.Owner', owner)

        data['id'] = obj.id
        await notify(ObjectAddedEvent(obj, self.context, obj.id, payload=data))

        absolute_url = query_multi_adapter((obj, self.request), IAbsoluteURL)

        headers = {
            'Access-Control-Expose-Headers': 'Location',
            'Location': absolute_url()
        }

        serializer = query_multi_adapter((obj, self.request),
                                         IResourceSerializeToJsonSummary)
        response = await serializer()
        return Response(content=response, status=201, headers=headers)
Exemplo n.º 27
0
    async def __call__(self):
        """To create a content."""
        data = await self.get_data()
        type_ = data.get("@type", None)
        id_ = data.get("id", None)
        behaviors = data.get("@behaviors", None)

        if not type_:
            raise ErrorResponse(
                "RequiredParam",
                _("Property '@type' is required"),
                reason=error_reasons.REQUIRED_PARAM_MISSING,
                status=412,
            )

        id_checker = get_adapter(self.context, IIDChecker)
        # Generate a temporary id if the id is not given
        new_id = None
        if not id_:
            generator = query_adapter(self.request, IIDGenerator)
            if generator is not None:
                new_id = await apply_coroutine(generator, data)
                if isinstance(new_id, str) and not await id_checker(new_id, type_):
                    raise ErrorResponse(
                        "PreconditionFailed",
                        "Invalid id: {}".format(new_id),
                        status=412,
                        reason=error_reasons.INVALID_ID,
                    )
        else:
            if not isinstance(id_, str) or not await id_checker(id_, type_):
                raise ErrorResponse(
                    "PreconditionFailed",
                    "Invalid id: {}".format(id_),
                    status=412,
                    reason=error_reasons.INVALID_ID,
                )
            new_id = id_

        user = get_authenticated_user_id()

        options = {"creators": (user,), "contributors": (user,)}
        if "uid" in data:
            options["__uuid__"] = data.pop("uid")

        # Create object
        try:
            obj = await create_content_in_container(
                self.context, type_, new_id, check_constraints=True, **options
            )
        except ValueError as e:
            return ErrorResponse("CreatingObject", str(e), status=412)

        for behavior in behaviors or ():
            obj.add_behavior(behavior)

        # Update fields
        deserializer = query_multi_adapter((obj, self.request), IResourceDeserializeFromJson)
        if deserializer is None:
            return ErrorResponse(
                "DeserializationError",
                "Cannot deserialize type {}".format(obj.type_name),
                status=412,
                reason=error_reasons.DESERIALIZATION_FAILED,
            )

        await deserializer(data, validate_all=True, create=True)

        # Local Roles assign owner as the creator user
        get_owner = IGetOwner(obj)
        roleperm = IPrincipalRoleManager(obj)
        owner = await get_owner(user)
        if owner is not None:
            roleperm.assign_role_to_principal("guillotina.Owner", owner)

        data["id"] = obj.id
        await notify(ObjectAddedEvent(obj, self.context, obj.id, payload=data))

        headers = {"Access-Control-Expose-Headers": "Location", "Location": get_object_url(obj, self.request)}

        serializer = query_multi_adapter((obj, self.request), IResourceSerializeToJsonSummary)
        response = await serializer()
        return Response(content=response, status=201, headers=headers)