Beispiel #1
0
async def default_get(context, request):
    """We show the available schemas."""
    result = {}
    factory = get_cached_factory(context.type_name)
    result["static"] = []
    for schema in factory.behaviors or ():
        result["static"].append(schema.__identifier__)

    # convert to list, could be frozenset
    result["dynamic"] = [b for b in context.__behaviors__]

    result["available"] = []

    factory = get_cached_factory(context.type_name)

    for name, utility in get_utilities_for(IBehavior):
        serialize = False
        if name not in result["dynamic"] and name not in result["static"]:
            adaptable = query_adapter(context,
                                      utility.interface,
                                      name="",
                                      default=None)
            if adaptable:
                result["available"].append(name)
                serialize = True
                schema_serializer = get_multi_adapter(
                    (utility.interface, request), ISchemaSerializeToJson)
                result[name] = await schema_serializer()
        else:
            serialize = True
        if serialize:
            schema_serializer = get_multi_adapter((utility.interface, request),
                                                  ISchemaSerializeToJson)
            result[name] = await schema_serializer()
    return result
Beispiel #2
0
async def default_get(context, request):
    """We show the available schemas."""
    result = {}
    factory = get_cached_factory(context.type_name)
    result['static'] = []
    for schema in factory.behaviors or ():
        result['static'].append(schema.__identifier__)

    # convert to list, could be frozenset
    result['dynamic'] = [b for b in context.__behaviors__]

    result['available'] = []

    factory = get_cached_factory(context.type_name)

    for name, utility in get_utilities_for(IBehavior):
        serialize = False
        if name not in result['dynamic'] and name not in result['static']:
            adaptable = query_adapter(
                context, utility.interface,
                name='', default=None)
            if adaptable:
                result['available'].append(name)
                serialize = True
                schema_serializer = get_multi_adapter(
                    (utility.interface, request),
                    ISchemaSerializeToJson)
                result[name] = await schema_serializer()
        else:
            serialize = True
        if serialize:
            schema_serializer = get_multi_adapter(
                (utility.interface, request), ISchemaSerializeToJson)
            result[name] = await schema_serializer()
    return result
Beispiel #3
0
    async def __call__(self):
        parent = self.context.__parent__
        if parent is not None:
            # We render the summary of the parent
            try:
                parent_summary = await getMultiAdapter(
                    (parent, self.request), IResourceSerializeToJsonSummary)()
            except ComponentLookupError:
                parent_summary = {}
        else:
            parent_summary = {}

        result = {
            '@id': IAbsoluteURL(self.context, self.request)(),
            '@type': self.context.type_name,
            'parent': parent_summary,
            'creation_date': json_compatible(self.context.creation_date),
            'modification_date':
            json_compatible(self.context.modification_date),
            'UID': self.context.uuid,
        }

        factory = get_cached_factory(self.context.type_name)

        main_schema = factory.schema
        await self.get_schema(main_schema, self.context, result, False)

        for behavior_schema, behavior in await get_all_behaviors(self.context):
            await self.get_schema(behavior_schema, behavior, result, True)

        return result
Beispiel #4
0
    async def __call__(self, data, validate_all=False, ignore_errors=False):
        errors = []

        factory = get_cached_factory(self.context.type_name)
        main_schema = factory.schema
        await self.set_schema(
            main_schema, self.context, data, errors, validate_all, False)

        for behavior_schema, behavior in await get_all_behaviors(self.context, load=False):
            dotted_name = behavior_schema.__identifier__
            if dotted_name not in data:
                # syntax {"namespace.IBehavior": {"foo": "bar"}}
                # we're not even patching this behavior if no iface found in payload
                continue
            if IAsyncBehavior.implementedBy(behavior.__class__):
                # providedBy not working here?
                await behavior.load(create=True)
            await self.set_schema(
                behavior_schema, behavior, data, errors,
                validate_all, True)

        if errors and not ignore_errors:
            raise DeserializationError(errors)

        self.context._p_register()

        return self.context
Beispiel #5
0
    async def get_field(self, field_name):
        context = self.context
        if '.' in field_name:
            schema_klass, field_name = field_name.rsplit('.', 1)
            if schema_klass not in self.context.__behaviors__:
                self.ws.send_str(
                    json.dumps({
                        't': 'e',
                        'v': 'Not a valid field on a behavior'
                    }))
                return
            schema = resolve_dotted_name(schema_klass)
            if schema is None:
                self.ws.send_str(
                    json.dumps({
                        't': 'e',
                        'v': 'Could not find specified schema'
                    }))
                return
            behavior = schema(context)
            context = behavior
        else:
            factory = get_cached_factory(self.context.type_name)
            schema = factory.schema

        try:
            field = schema[field_name]
        except KeyError:
            self.ws.send_str(
                json.dumps({
                    't': 'e',
                    'v': 'Not a valid field on a behavior'
                }))
            return
        return context, field
Beispiel #6
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()
Beispiel #7
0
    async def __call__(self):
        '''
        PUT means we're completely replacing the content
        so we need to delete data from existing behaviors
        and content schemas.
        Then do the regular patch serialization
        '''
        annotations_container = IAnnotations(self.context)
        for schema, behavior in await get_all_behaviors(self.context,
                                                        load=False):
            if hasattr(behavior, '__annotations_data_key__'):
                await annotations_container.async_del(
                    behavior.__annotations_data_key__)
            try:
                behavior.data.clear()
                for local_prop in behavior.__local__properties__:
                    if local_prop in self.context.__dict__:
                        del self.context.__dict__[local_prop]
            except AttributeError:
                pass
        self.context.__behaviors__ = frozenset({})

        factory = get_cached_factory(self.context.type_name)
        if factory.schema is not None:
            for name in factory.schema.names():
                if name in self.context.__dict__:
                    del self.context.__dict__[name]
        return await super().__call__()
Beispiel #8
0
    async def get_field(self, field_name):
        context = self.context
        if "." in field_name:
            schema_klass, field_name = field_name.rsplit(".", 1)
            if schema_klass not in self.context.__behaviors__:
                self.ws.send_bytes(
                    json.dumps({
                        "t": "e",
                        "v": "Not a valid field on a behavior"
                    }))
                return
            schema = resolve_dotted_name(schema_klass)
            if schema is None:
                self.ws.send_bytes(
                    json.dumps({
                        "t": "e",
                        "v": "Could not find specified schema"
                    }))
                return
            behavior = schema(context)
            context = behavior
        else:
            factory = get_cached_factory(self.context.type_name)
            schema = factory.schema

        try:
            field = schema[field_name]
        except KeyError:
            self.ws.send_bytes(
                json.dumps({
                    "t": "e",
                    "v": "Not a valid field on a behavior"
                }))
            return
        return context, field
Beispiel #9
0
async def get_constraints(context, request):
    at = getattr(context, '__allowed_types__', None)
    if at is None:
        tn = getattr(context, 'type_name', None)
        factory = get_cached_factory(tn)
        at = factory.allowed_types if factory.allowed_types is not None else []
    return at
Beispiel #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()
    async def __call__(self, include=[], omit=[]):
        self.include = include
        self.omit = omit

        parent = self.context.__parent__
        if parent is not None:
            # We render the summary of the parent
            try:
                parent_summary = await get_multi_adapter(
                    (parent, self.request), IResourceSerializeToJsonSummary)()
            except ComponentLookupError:
                parent_summary = {}
        else:
            parent_summary = {}

        factory = get_cached_factory(self.context.type_name)
        behaviors = []
        for behavior_schema in factory.behaviors or ():
            behaviors.append(behavior_schema.__identifier__)

        result = {
            '@id': IAbsoluteURL(self.context, self.request)(),
            '@type': self.context.type_name,
            '@name': self.context.__name__,
            '@uid': self.context.uuid,
            '@static_behaviors': behaviors,
            'parent': parent_summary,  # should be @parent
            'is_folderish': IFolder.providedBy(self.context),  # eek, should be @folderish?
            'creation_date': json_compatible(self.context.creation_date),
            'modification_date': json_compatible(self.context.modification_date),
            'UID': self.context.uuid,  # should be removed
        }

        main_schema = factory.schema
        await self.get_schema(main_schema, self.context, result, False)

        # include can be one of:
        # - <field name> on content schema
        # - namespace.IBehavior
        # - namespace.IBehavior.field_name
        included_ifaces = [name for name in self.include if '.' in name]
        included_ifaces.extend([name.rsplit('.', 1)[0] for name in self.include
                                if '.' in name])
        for behavior_schema, behavior in await get_all_behaviors(self.context, load=False):
            if '*' not in self.include:
                dotted_name = behavior_schema.__identifier__
                if (dotted_name in self.omit or
                        (len(included_ifaces) > 0 and dotted_name not in included_ifaces)):
                    # make sure the schema isn't filtered
                    continue
                if (not getattr(behavior, 'auto_serialize', True) and
                        dotted_name not in included_ifaces):
                    continue
            if IAsyncBehavior.implementedBy(behavior.__class__):
                # providedBy not working here?
                await behavior.load(create=False)
            await self.get_schema(behavior_schema, behavior, result, True)

        return result
    async def __call__(self, include=[], omit=[]):
        self.include = include
        self.omit = omit

        parent = self.context.__parent__
        if parent is not None:
            # We render the summary of the parent
            try:
                parent_summary = await get_multi_adapter(
                    (parent, self.request), IResourceSerializeToJsonSummary)()
            except ComponentLookupError:
                parent_summary = {}
        else:
            parent_summary = {}

        result = {
            '@id': IAbsoluteURL(self.context, self.request)(),
            '@type': self.context.type_name,
            '@name': self.context.__name__,
            '@uid': self.context.uuid,
            'parent': parent_summary,
            'is_folderish': IFolder.providedBy(self.context),
            'creation_date': json_compatible(self.context.creation_date),
            'modification_date':
            json_compatible(self.context.modification_date),
            'UID': self.context.uuid,
        }

        factory = get_cached_factory(self.context.type_name)

        main_schema = factory.schema
        await self.get_schema(main_schema, self.context, result, False)

        # include can be one of:
        # - <field name> on content schema
        # - namespace.IBehavior
        # - namespace.IBehavior.field_name
        included_ifaces = [name for name in self.include if '.' in name]
        included_ifaces.extend(
            [name.rsplit('.', 1)[0] for name in self.include if '.' in name])
        for behavior_schema, behavior in await get_all_behaviors(self.context,
                                                                 load=False):
            dotted_name = behavior_schema.__identifier__
            if (dotted_name in self.omit
                    or (len(included_ifaces) > 0
                        and dotted_name not in included_ifaces)):
                # make sure the schema isn't filtered
                continue
            if (not getattr(behavior, 'auto_serialize', True)
                    and dotted_name not in included_ifaces):
                continue
            if IAsyncBehavior.implementedBy(behavior.__class__):
                # providedBy not working here?
                await behavior.load(create=False)
            await self.get_schema(behavior_schema, behavior, result, True)

        return result
Beispiel #13
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()
Beispiel #14
0
async def get_field_value(context, request):
    field_name = request.matchdict["dotted_name"]

    if "." in field_name:
        # behavior field lookup
        iface_dotted = ".".join(field_name.split(".")[:-1])
        field_name = field_name.split(".")[-1]

        try:
            schema = resolve_dotted_name(iface_dotted)
        except ModuleNotFoundError:
            return HTTPNotFound(
                content={"reason": f"Could resolve: {iface_dotted}"})
        try:
            field = schema[field_name]
        except KeyError:
            return HTTPNotFound(content={"reason": f"No field: {field_name}"})

        try:
            behavior = await get_behavior(context, schema)
        except AttributeError:
            return HTTPNotFound(
                content={"reason": f"Could not load behavior: {iface_dotted}"})
        if behavior is None:
            return HTTPNotFound(
                content={"reason": f"Not valid behavior: {iface_dotted}"})
        field = field.bind(behavior)
        field_context = behavior
    else:
        # main object field
        factory = get_cached_factory(context.type_name)
        schema = factory.schema
        try:
            field = schema[field_name]
        except KeyError:
            return HTTPNotFound(content={"reason": f"No field: {field_name}"})
        field = field.bind(context)
        field_context = context

    # check permission
    read_permissions = merged_tagged_value_dict(schema, read_permission.key)
    serializer = get_multi_adapter((context, request),
                                   IResourceSerializeToJson)

    if not serializer.check_permission(read_permissions.get(field_name)):
        return HTTPUnauthorized(
            content={"reason": "You are not authorized to render this field"})

    field_renderer = query_multi_adapter((context, request, field),
                                         IFieldValueRenderer)
    if field_renderer is None:
        return await serializer.serialize_field(field_context, field)
    else:
        return await field_renderer()
Beispiel #15
0
async def default_delete(context, request):
    data = await request.json()
    behavior = data.get('behavior', None)
    factory = get_cached_factory(context.type_name)
    behavior_class = resolve_dotted_name(behavior)
    if behavior_class is not None:
        if behavior_class in factory.behaviors:
            return Response(response={}, status=201)
    if behavior not in context.__behaviors__:
        return Response(response={}, status=201)
    context.remove_behavior(behavior)
    return {}
Beispiel #16
0
async def delete_behavior(context, behavior):
    factory = get_cached_factory(context.type_name)
    behavior_class = resolve_dotted_name(behavior)
    if behavior_class is not None:
        if behavior_class in factory.behaviors:
            return Response(content={
                'reason':
                'Behaviors defined on this type must be present and cannot be dynamically removed'
            },
                            status=412)
    if behavior not in context.__behaviors__:
        return Response(content={'reason': 'Not in behaviors'}, status=412)
    context.remove_behavior(behavior)
    return {}
Beispiel #17
0
async def delete_behavior(context, behavior):
    factory = get_cached_factory(context.type_name)
    behavior_class = resolve_dotted_name(behavior)
    if behavior_class is not None:
        if behavior_class in factory.behaviors:
            return Response(content={
                'reason': 'Behaviors defined on this type must be present and cannot be dynamically removed'
            }, status=412)
    if behavior not in context.__behaviors__:
        return Response(content={
            'reason': 'Not in behaviors'
        }, status=412)
    context.remove_behavior(behavior)
    return {}
Beispiel #18
0
async def delete_behavior(context, behavior):
    factory = get_cached_factory(context.type_name)
    behavior_class = resolve_dotted_name(behavior)
    if behavior_class is not None:
        if behavior_class in factory.behaviors:
            return Response(content={
                'reason': 'Not not remove this type of behavior'
            }, status=412)
    if behavior not in context.__behaviors__:
        return Response(content={
            'reason': 'Not in behaviors'
        }, status=412)
    context.remove_behavior(behavior)
    return {}
Beispiel #19
0
async def default_patch(context, request):
    data = await request.json()
    behavior = data.get('behavior', None)
    try:
        behavior_class = resolve_dotted_name(behavior)
    except ModuleNotFoundError:
        behavior_class = None
    if behavior_class is None:
        return Response(response={}, status=404)
    factory = get_cached_factory(context.type_name)
    if behavior_class in factory.behaviors:
        return Response(response={}, status=201)
    if behavior in context.__behaviors__:
        return Response(response={}, status=201)
    context.add_behavior(behavior)
    return {}
Beispiel #20
0
async def default_patch(context, request):
    data = await request.json()
    behavior = data.get("behavior", None)
    try:
        behavior_class = resolve_dotted_name(behavior)
    except ModuleNotFoundError:
        behavior_class = None
    if behavior_class is None:
        return Response(content={"reason": "Could not find behavior"},
                        status=404)
    factory = get_cached_factory(context.type_name)
    if behavior_class in factory.behaviors:
        return Response(content={"reason": "Already in behaviors"}, status=412)
    if behavior in context.__behaviors__:
        return Response(content={"reason": "Already in behaviors"}, status=412)
    context.add_behavior(behavior)
    return {}
Beispiel #21
0
    async def __call__(
        self,
        data: Dict[str, Any],
        validate_all: bool = False,
        ignore_errors: bool = False,
        create: bool = False,
    ) -> IResource:
        errors: List[Dict[str, Any]] = []

        # do behavior first in case they modify context values
        for behavior_schema, behavior in await get_all_behaviors(self.context,
                                                                 load=False):
            dotted_name = behavior_schema.__identifier__
            if dotted_name not in data:
                # syntax {"namespace.IBehavior": {"foo": "bar"}}
                # we're not even patching this behavior if no iface found in payload
                if create:
                    # signal to caching engine to cache no data here so
                    # we prevent a future lookup
                    try:
                        txn = self.context.__txn__
                        await txn._cache.set(
                            _EMPTY,
                            container=self.context,
                            id=behavior.__annotations_data_key__,
                            variant="annotation",
                        )
                    except AttributeError:
                        pass
                continue
            if IAsyncBehavior.implementedBy(behavior.__class__):
                # providedBy not working here?
                await behavior.load(create=True)
            await self.set_schema(behavior_schema, behavior, data, errors,
                                  validate_all, True)

        factory = get_cached_factory(self.context.type_name)
        main_schema = factory.schema
        await self.set_schema(main_schema, self.context, data, errors,
                              validate_all, False)

        if errors and not ignore_errors:
            raise DeserializationError(errors)

        return self.context
    async def __call__(self, data, validate_all=False, ignore_errors=False):
        errors = []

        factory = get_cached_factory(self.context.type_name)
        main_schema = factory.schema
        await self.set_schema(main_schema, self.context, data, errors,
                              validate_all, False)

        for behavior_schema, behavior in await get_all_behaviors(
                self.context, True):
            await self.set_schema(behavior_schema, behavior, data, errors,
                                  validate_all, True)

        if errors and not ignore_errors:
            raise DeserializationError(errors)

        self.context._p_register()

        return self.context
Beispiel #23
0
    async def __call__(self):
        parent = self.context.__parent__
        if parent is not None:
            # We render the summary of the parent
            try:
                parent_summary = await getMultiAdapter(
                    (parent, self.request), IResourceSerializeToJsonSummary)()
            except ComponentLookupError:
                parent_summary = {}
        else:
            parent_summary = {}

        result = {
            '@id': IAbsoluteURL(self.context, self.request)(),
            '@type': self.context.portal_type,
            'parent': parent_summary,
            'created': json_compatible(self.context.created),
            'modified': json_compatible(self.context.modified),
            'UID': self.context.uuid,
        }

        factory = get_cached_factory(self.context.portal_type)

        main_schema = factory.schema
        await self.get_schema(main_schema, self.context, result, False)

        for behavior_schema in factory.behaviors or ():
            behavior = behavior_schema(self.context)
            if IAsyncBehavior.implementedBy(behavior.__class__):
                # providedBy not working here?
                await behavior.load()
            await self.get_schema(behavior_schema, behavior, result, True)

        for dynamic_behavior in self.context.__behaviors__ or ():
            dynamic_behavior_obj = BEHAVIOR_CACHE[dynamic_behavior]
            behavior = dynamic_behavior_obj(self.context)
            if IAsyncBehavior.implementedBy(dynamic_behavior_obj.__class__):
                # providedBy not working here?
                await behavior.load()
            await self.get_schema(dynamic_behavior_obj, behavior, result, True)

        return result
Beispiel #24
0
async def default_patch(context, request):
    data = await request.json()
    behavior = data.get('behavior', None)
    try:
        behavior_class = resolve_dotted_name(behavior)
    except ModuleNotFoundError:
        behavior_class = None
    if behavior_class is None:
        return Response(content={
            'reason': 'Could not find behavior'
        }, status=404)
    factory = get_cached_factory(context.type_name)
    if behavior_class in factory.behaviors:
        return Response(content={
            'reason': 'Already in behaviors'
        }, status=412)
    if behavior in context.__behaviors__:
        return Response(content={
            'reason': 'Already in behaviors'
        }, status=412)
    context.add_behavior(behavior)
    return {}
    async def __call__(self, data, validate_all=False, ignore_errors=False, create=False):
        errors = []

        # do behavior first in case they modify context values
        for behavior_schema, behavior in await get_all_behaviors(self.context, load=False):
            dotted_name = behavior_schema.__identifier__
            if dotted_name not in data:
                # syntax {"namespace.IBehavior": {"foo": "bar"}}
                # we're not even patching this behavior if no iface found in payload
                if create:
                    # signal to caching engine to cache no data here so
                    # we prevent a future lookup
                    try:
                        txn = self.context._p_jar
                        await txn._cache.set(
                            _EMPTY, container=self.context,
                            id=behavior.__annotations_data_key__,
                            variant='annotation')
                    except AttributeError:
                        pass
                continue
            if IAsyncBehavior.implementedBy(behavior.__class__):
                # providedBy not working here?
                await behavior.load(create=True)
            await self.set_schema(
                behavior_schema, behavior, data, errors,
                validate_all, True)

        factory = get_cached_factory(self.context.type_name)
        main_schema = factory.schema
        await self.set_schema(
            main_schema, self.context, data, errors, validate_all, False)

        if errors and not ignore_errors:
            raise DeserializationError(errors)

        self.context._p_register()

        return self.context
Beispiel #26
0
    async def __call__(self, data, validate_all=False):

        modified = False
        errors = []

        factory = get_cached_factory(self.context.portal_type)
        main_schema = factory.schema
        await self.set_schema(main_schema, self.context, data, errors,
                              validate_all, False)

        for behavior_schema in factory.behaviors or ():
            if behavior_schema.__identifier__ in data:
                behavior = behavior_schema(self.context)
                if IAsyncBehavior.implementedBy(behavior.__class__):
                    # providedBy not working here?
                    await behavior.load(create=True)
                await self.set_schema(behavior_schema, behavior, data, errors,
                                      validate_all, True)

        for dynamic_behavior in self.context.__behaviors__ or ():
            dynamic_behavior_obj = BEHAVIOR_CACHE[dynamic_behavior]
            if dynamic_behavior_obj.__identifier__ in data:
                behavior = dynamic_behavior_obj(self.context)
                if IAsyncBehavior.implementedBy(
                        dynamic_behavior_obj.__class__):
                    # providedBy not working here?
                    await behavior.load(create=True)
                await self.set_schema(dynamic_behavior_obj, behavior, data,
                                      errors, validate_all, True)

        if errors:
            raise DeserializationError(errors)

        if modified:
            self.context._p_register()
            await notify(ObjectModifiedEvent(self.context, data))

        return self.context
Beispiel #27
0
async def default_get(context, request):
    """We show the available schemas."""
    result = {}
    factory = get_cached_factory(context.type_name)
    result['static'] = []
    for schema in factory.behaviors or ():
        result['static'].append(schema.__identifier__)

    # convert to list, could be frozenset
    result['dynamic'] = [b for b in context.__behaviors__]

    result['available'] = []

    for iface, utility in getUtilitiesFor(IBehavior):
        serialize = False
        if isinstance(iface, str):
            name = iface
        else:
            name = iface.__identifier__
        if name not in result['dynamic'] and name not in result['static']:
            adaptable = queryAdapter(context,
                                     utility.interface,
                                     name='',
                                     default=None)
            if adaptable:
                result['available'].append(name)
                serialize = True
                schema_serializer = getMultiAdapter(
                    (utility.interface, request), ISchemaSerializeToJson)
                result[name] = await schema_serializer()
        else:
            serialize = True
        if serialize:
            schema_serializer = getMultiAdapter((utility.interface, request),
                                                ISchemaSerializeToJson)
            result[name] = await schema_serializer()
    return result
Beispiel #28
0
 def get_allowed_types(self) -> list:
     pt = getattr(self.context, 'portal_type', None)
     if pt:
         factory = get_cached_factory(pt)
         return factory.allowed_types
     return None
Beispiel #29
0
    async def __call__(self, include=None, omit=None):
        self.include = include or []
        self.omit = omit or []

        parent = self.context.__parent__
        if parent is not None:
            # We render the summary of the parent
            try:
                parent_summary = await get_multi_adapter(
                    (parent, self.request), IResourceSerializeToJsonSummary)()
            except ComponentLookupError:
                parent_summary = {}
        else:
            parent_summary = {}

        factory = get_cached_factory(self.context.type_name)
        behaviors = []
        for behavior_schema in factory.behaviors or ():
            behaviors.append(behavior_schema.__identifier__)

        result = {
            "@id": get_object_url(self.context, self.request),
            "@type": self.context.type_name,
            "@name": self.context.__name__,
            "@uid": self.context.uuid,
            "@static_behaviors": behaviors,
            "parent": parent_summary,  # should be @parent
            "is_folderish":
            IFolder.providedBy(self.context),  # eek, should be @folderish?
            "creation_date": json_compatible(self.context.creation_date),
            "modification_date":
            json_compatible(self.context.modification_date),
        }

        main_schema = factory.schema
        await self.get_schema(main_schema, self.context, result, False)

        # include can be one of:
        # - <field name> on content schema
        # - namespace.IBehavior
        # - namespace.IBehavior.field_name
        included_ifaces = [name for name in self.include if "." in name]
        included_ifaces.extend(
            [name.rsplit(".", 1)[0] for name in self.include if "." in name])
        for behavior_schema, behavior in await get_all_behaviors(self.context,
                                                                 load=False):
            if "*" not in self.include:
                dotted_name = behavior_schema.__identifier__
                if dotted_name in self.omit or (len(included_ifaces) > 0
                                                and dotted_name
                                                not in included_ifaces):
                    # make sure the schema isn't filtered
                    continue
                if not getattr(behavior, "auto_serialize",
                               True) and dotted_name not in included_ifaces:
                    continue
            if IAsyncBehavior.implementedBy(behavior.__class__):
                # providedBy not working here?
                await behavior.load(create=False)
            await self.get_schema(behavior_schema, behavior, result, True)

        for post_serialize_processors in app_settings["post_serialize"]:
            await apply_coroutine(post_serialize_processors, self.context,
                                  result)

        return result
Beispiel #30
0
 def is_globally_allowed(self, type_id: str) -> bool:
     factory = get_cached_factory(type_id)
     return factory.globally_addable
Beispiel #31
0
 def get_allowed_types(self) -> list:
     tn = getattr(self.context, 'type_name', None)
     if tn:
         factory = get_cached_factory(tn)
         return factory.allowed_types
     return None
 def get_allowed_types(self) -> list:
     tn = getattr(self.context, 'type_name', None)
     if tn:
         factory = get_cached_factory(tn)
         return factory.allowed_types
     return []
Beispiel #33
0
 def get_allowed_types(self) -> Optional[list]:
     tn = getattr(self.context, "type_name", None)
     if tn:
         factory = get_cached_factory(tn)
         return factory.allowed_types
     return []
Beispiel #34
0
def create_content_factory(proto_name, proto_definition):
    parent_interface = import_class(
        proto_definition.get('inherited_interface',
                             'guillotina.interfaces.content.IFolder'))
    parent_class = import_class(
        proto_definition.get('inherited_class', 'guillotina.content.Folder'))

    schema_fields, tags = get_fields(
        properties=proto_definition.get('properties'))

    for fieldset_id, fieldset_list in proto_definition.get('fieldsets',
                                                           {}).items():
        for field_id in fieldset_list:
            tags.setdefault(field_id, {})['fieldset'] = fieldset_id

    class_interface = InterfaceClass('I' + proto_name, (parent_interface, ),
                                     schema_fields,
                                     __module__='guillotina_cms.interfaces')

    for field_id, tag in tags.items():
        for tag_id, tag_metadata in tag.items():
            if tag_id in SUPPORTED_DIRECTIVES:
                if tag_metadata is None:
                    SUPPORTED_DIRECTIVES[tag_id].apply(class_interface,
                                                       field_id)
                elif isinstance(tag_metadata, dict):
                    SUPPORTED_DIRECTIVES[tag_id].apply(class_interface,
                                                       field_id,
                                                       **tag_metadata)
                elif isinstance(tag_metadata, list):
                    SUPPORTED_DIRECTIVES[tag_id].apply(class_interface,
                                                       field_id, *tag_metadata)
                elif tag_id == 'fieldset':
                    SUPPORTED_DIRECTIVES[tag_id].apply(class_interface,
                                                       field_id, tag_metadata)
                elif isinstance(tag_metadata, str):
                    SUPPORTED_DIRECTIVES[tag_id].apply(
                        class_interface, **{field_id: tag_metadata})

    klass = type(proto_name, (parent_class, ), {})

    klass.__module__ = 'guillotina_cms.dyncontent'
    setattr(dyncontent, proto_name, klass)

    behaviors = []
    for bhr in proto_definition.get('behaviors', []):
        if bhr in BEHAVIOR_CACHE:
            behaviors.append(BEHAVIOR_CACHE[bhr])
        else:
            raise Exception(f"Behavior not found {bhr}")

    contenttype = {
        'schema':
        class_interface,
        'type_name':
        proto_name,
        'allowed_types':
        proto_definition.get('allowed_types', []),
        'add_permission':
        proto_definition.get('add_permission', 'guillotina.AddContent'),
        'behaviors':
        behaviors
    }

    utility = query_utility(IResourceFactory, name=proto_name)
    if utility is not None:
        sm = get_global_components()
        sm.unregisterUtility(utility, IResourceFactory, proto_name)

    configure.register_configuration(klass, contenttype, 'contenttype')

    root = get_utility(IApplication, name='root')
    configure.load_configuration(root.app.config, 'guillotina_cms.dyncontent',
                                 'contenttype')
    root.app.config.execute_actions()
    configure.clear()
    load_cached_schema()

    # Verify its created
    if proto_name in FACTORY_CACHE:
        del FACTORY_CACHE[proto_name]
    get_cached_factory(proto_name)