async def __call__(self): """ data input : { 'interface': 'INTERFACE' }""" if not hasattr(self.request, 'container_settings'): return ErrorResponse('BadRequest', _("Not in a container request")) 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') 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(response={}, status=201)
async def __call__(self): if self.key is _marker: # No option to write the root of registry return ErrorResponse('InvalidRequest', 'Needs the registry key') 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) field = iface[name] try: new_value = get_adapter((field), IJSONToValue, args=[value, self.context]) except ComponentLookupError: return ErrorResponse('DeserializationError', 'Cannot deserialize type {}'.format( str(self.field)), status=501) try: self.request.container_settings[self.key] = new_value except DeserializationError as e: return ErrorResponse('DeserializationError', str(e), exc=e, status=400) return Response(response='', status=204)
async def __call__(self): data = await self.get_data() if 'id' in data and data['id'] != self.context.id: return ErrorResponse('DeserializationError', 'Not allowed to change id of content.', status=412) 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: return ErrorResponse('DeserializationError', 'Cannot deserialize type {}'.format( self.context.type_name), status=412) try: await deserializer(data) except DeserializationError as e: return ErrorResponse('DeserializationError', str(e), status=422) await notify(ObjectModifiedEvent(self.context, payload=data)) return Response(response='', status=204)
async def __call__(self): data = await self.request.json() if '@type' not in data or data['@type'] != 'Container': return ErrorResponse('NotAllowed', 'can not create this type %s' % data['@type'], status=401) if 'id' not in data: return ErrorResponse('NotAllowed', 'We need an id', status=401) 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 return ErrorResponse('ConflictId', 'Container with id already exists', status=409) container = await create_content('Container', 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) await notify( ObjectAddedEvent(container, self.context, container.__name__, payload=data)) resp = {'@type': 'Container', 'id': data['id'], 'title': data['title']} headers = {'Location': self.request.path + data['id']} return Response(response=resp, headers=headers)
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")) registry = request.container_settings config = registry.for_interface(IAddons) if id_to_install not in config['enabled']: return ErrorResponse('Duplicate', _("Addon not installed")) handler = app_settings['available_addons'][id_to_install]['handler'] await apply_coroutine(handler.uninstall, context, request) config['enabled'] -= {id_to_install}
async def __call__(self): data = await self.request.json() if '@type' not in data and data['@type'] != 'Site': return ErrorResponse('NotAllowed', 'can not create this type %s' % data['@type'], status=401) if 'title' not in data and not data['title']: return ErrorResponse('NotAllowed', 'We need a title', status=401) if 'id' not in data: return ErrorResponse('NotAllowed', 'We need an id', status=401) if 'description' not in data: data['description'] = '' value = await self.context.async_contains(data['id']) if value: # Already exist return ErrorResponse('NotAllowed', 'Duplicate id', status=401) site = await create_content('Site', id=data['id'], title=data['title'], description=data['description']) # Special case we don't want the parent pointer site.__name__ = data['id'] await self.context.async_set(data['id'], site) await site.install() self.request._site_id = site.__name__ user = get_authenticated_user_id(self.request) # Local Roles assign owner as the creator user roleperm = IPrincipalRoleManager(site) roleperm.assign_role_to_principal('guillotina.Owner', user) await notify(ObjectAddedEvent(site, self.context, site.__name__)) resp = {'@type': 'Site', 'id': data['id'], 'title': data['title']} headers = {'Location': self.request.path + data['id']} return Response(response=resp, headers=headers)
def generate_error_response(e, request, error, status=400): # We may need to check the roles of the users to show the real error eid = uuid.uuid4().hex message = _('Error on execution of view') + ' ' + eid user = get_authenticated_user_id(request) extra = {'r': _url(request), 'u': user} logger.error(message, exc_info=e, extra=extra) return ErrorResponse(error, message, status)
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 = queryMultiAdapter((self.context, self.request), IResourceDeserializeFromJson) if deserializer is None: return ErrorResponse('DeserializationError', 'Cannot deserialize type {}'.format( self.context.type_name), status=501) try: await deserializer(data) except DeserializationError as e: return ErrorResponse('DeserializationError', str(e), status=400) await notify(ObjectModifiedEvent(self.context, payload=data)) return Response(response={}, status=204)
async def query( self, container, query, doc_type=None, size=10, request=None): """ transform into query... right now, it's just passing through into elasticsearch """ t1 = time.time() if request is None: request = get_current_request() q = await self._build_security_query( container, query, doc_type, size, request) result = await self.conn.search(**q) if result.get('_shards', {}).get('failed', 0) > 0: logger.warning(f'Error running query: {result["_shards"]}') error_message = 'Unknown' for failure in result["_shards"].get('failures') or []: error_message = failure['reason'] return ErrorResponse('QueryError', error_message, status=488) items = self._get_items_from_result(container, request, result) final = { 'items_count': result['hits']['total'], 'member': items } if 'aggregations' in result: final['aggregations'] = result['aggregations'] if 'suggest' in result: final['suggest'] = result['suggest'] if 'profile' in result: final['profile'] = result['profile'] tdif = time.time() - t1 logger.debug(f'Time ELASTIC {tdif}') await notify(SearchDoneEvent( query, result['hits']['total'], request, tdif)) return final
async def __call__(self): return ErrorResponse('NotImplemented', 'Function not implemented', status=501)
async def duplicate(context, request): try: data = await request.json() except Exception: data = {} destination = data.get('destination') if destination is not None: destination_ob = await navigate_to(request.container, destination) if destination_ob is None: return ErrorResponse('Configuration', 'Could not find destination object', status=400) else: destination_ob = context.__parent__ security = IInteraction(request) if not security.check_permission('guillotina.AddContent', destination_ob): return ErrorResponse( 'Configuration', 'You do not have permission to add content to the destination object', status=400) if 'new_id' in data: new_id = data['new_id'] if await destination_ob.async_contains(new_id): return ErrorResponse( 'Configuration', f'Destination already has object with the id {new_id}', status=400) else: count = 1 new_id = f'{context.id}-duplicate-{count}' while await destination_ob.async_contains(new_id): count += 1 new_id = f'{context.id}-duplicate-{count}' new_obj = await create_content_in_container( destination_ob, context.type_name, new_id, id=new_id, creators=context.creators, contributors=context.contributors) for key in context.__dict__.keys(): if key.startswith('__') or key.startswith('_BaseObject'): continue if key in ('id', ): continue new_obj.__dict__[key] = context.__dict__[key] new_obj.__acl__ = context.__acl__ new_obj.__behaviors__ = context.__behaviors__ # need to copy annotation data as well... # load all annotations for context [b for b in await get_all_behaviors(context, load=True)] annotations_container = IAnnotations(new_obj) for anno_id, anno_data in context.__annotations__.items(): new_anno_data = AnnotationData() for key, value in anno_data.items(): new_anno_data[key] = value await annotations_container.async_set(anno_id, new_anno_data) await notify( ObjectDuplicatedEvent(new_obj, context, destination_ob, new_id, payload=data)) get = DefaultGET(new_obj, request) return await get()
async def move(context, request): try: data = await request.json() except Exception: data = {} destination = data.get('destination') if not destination: return ErrorResponse('Configuration', 'Missing destination option', status=400) try: destination_ob = await navigate_to(request.container, destination) except KeyError: destination_ob = None if destination_ob is None: return ErrorResponse('Configuration', 'Could not find destination object', status=400) old_id = context.id if 'new_id' in data: new_id = data['new_id'] context.id = context.__name__ = new_id else: new_id = context.id security = IInteraction(request) if not security.check_permission('guillotina.AddContent', destination_ob): return ErrorResponse( 'Configuration', 'You do not have permission to add content to the destination object', status=400) if await destination_ob.async_contains(new_id): return ErrorResponse( 'Configuration', f'Destination already has object with the id {new_id}', status=400) 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=data)) context.__parent__ = destination_ob context._p_register() await notify( ObjectMovedEvent(context, original_parent, old_id, destination_ob, new_id, payload=data)) cache_keys += txn._cache.get_cache_keys(context, 'added') await txn._cache.delete_all(cache_keys) absolute_url = queryMultiAdapter((context, request), IAbsoluteURL) return {'@url': absolute_url()}
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 '__acl__' in data: # we don't allow to change the permisions on this patch del data['__acl__'] if not type_: return ErrorResponse('RequiredParam', _("Property '@type' is required")) # Generate a temporary id if the id is not given if not id_: new_id = None else: if not valid_id(id_): return ErrorResponse('PreconditionFailed', str('Invalid id'), status=412) new_id = id_ user = get_authenticated_user_id(self.request) # Create object try: obj = await create_content_in_container(self.context, type_, new_id, id=new_id, creators=(user, ), contributors=(user, )) except (PreconditionFailed, NotAllowedContentType) as e: return ErrorResponse('PreconditionFailed', str(e), status=412) except ConflictIdOnContainer as e: return ErrorResponse('ConflictId', str(e), status=409) except ValueError as e: return ErrorResponse('CreatingObject', str(e), status=400) for behavior in behaviors or (): obj.add_behavior(behavior) # Update fields deserializer = queryMultiAdapter((obj, self.request), IResourceDeserializeFromJson) if deserializer is None: return ErrorResponse('DeserializationError', 'Cannot deserialize type {}'.format( obj.type_name), status=501) try: await deserializer(data, validate_all=True) except DeserializationError as e: return ErrorResponse('DeserializationError', str(e), exc=e, status=400) # Local Roles assign owner as the creator user get_owner = getUtility(IGetOwner) roleperm = IPrincipalRoleManager(obj) roleperm.assign_role_to_principal('guillotina.Owner', await get_owner(obj, user)) await notify(ObjectAddedEvent(obj, self.context, obj.id, payload=data)) absolute_url = queryMultiAdapter((obj, self.request), IAbsoluteURL) headers = { 'Access-Control-Expose-Headers': 'Location', 'Location': absolute_url() } serializer = queryMultiAdapter((obj, self.request), IResourceSerializeToJson) response = await serializer() return Response(response=response, headers=headers, status=201)
def generate_error_response(e, request, error, status=500): # We may need to check the roles of the users to show the real error eid = uuid.uuid4().hex message = _('Error on execution of view') + ' ' + eid logger.error(message, exc_info=e, eid=eid, request=request) return ErrorResponse(error, message, status)