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 {}
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 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 {}
async def default_delete(context, request): data = await request.json() behavior = data.get('behavior', None) if behavior not in context.__behaviors__: return Response(response={}, status=201) context.remove_behavior(behavior) return {}
async def default_patch(context, request): data = await request.json() behavior = data.get('behavior', None) if behavior in context.__behaviors__: return Response(response={}, status=201) context.add_behavior(behavior) return {}
async def tus_options(self): resp = Response(headers={ 'Tus-Resumable': '1.0.0', 'Tus-Version': '1.0.0', 'Tus-Max-Size': '1073741824', 'Tus-Extension': 'creation,expiration' }) return resp
async def __call__(self): """Apply CORS on the OPTIONS view.""" headers = await self.preflight() resp = await self.render() if isinstance(resp, Response): headers.update(resp.headers) resp.headers = headers return resp return Response(response=resp, headers=headers, status=200)
async def tus_create(self): try: self.field.context.data._p_register() # register change... except AttributeError: self.context._p_register() # This only happens in tus-java-client, redirect this POST to a PATCH if self.request.headers.get('X-HTTP-Method-Override') == 'PATCH': return await self.tus_patch() file = self.field.get(self.field.context or self.context) if not isinstance(file, self.file_class): file = self.file_class(content_type=self.request.content_type) self.field.set(self.field.context or self.context, file) if 'CONTENT-LENGTH' in self.request.headers: file._current_upload = int(self.request.headers['CONTENT-LENGTH']) else: file._current_upload = 0 if 'UPLOAD-LENGTH' in self.request.headers: file._size = int(self.request.headers['UPLOAD-LENGTH']) else: raise AttributeError('We need upload-length header') if 'UPLOAD-MD5' in self.request.headers: file._md5 = self.request.headers['UPLOAD-MD5'] if 'UPLOAD-EXTENSION' in self.request.headers: file._extension = self.request.headers['UPLOAD-EXTENSION'] if 'TUS-RESUMABLE' not in self.request.headers: raise AttributeError('TUS needs a TUS version') if 'UPLOAD-METADATA' not in self.request.headers: file.filename = uuid.uuid4().hex else: filename = self.request.headers['UPLOAD-METADATA'] file.filename = base64.b64decode( filename.split()[1]).decode('utf-8') file._resumable_uri_date = datetime.now(tz=tzutc()) await file.init_upload(self.context) # Location will need to be adapted on aiohttp 1.1.x resp = Response( headers={ 'Location': IAbsoluteURL(self.context, self.request)() + '/@tusupload/' + self.field.__name__, # noqa 'Tus-Resumable': '1.0.0', 'Access-Control-Expose-Headers': 'Location,Tus-Resumable' }, status=201) return resp
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 tus_head(self): file = self.field.get(self.field.context or self.context) if not isinstance(file, self.file_class): raise KeyError('No file on this context') head_response = { 'Upload-Offset': str(file.get_actual_size()), 'Tus-Resumable': '1.0.0', 'Access-Control-Expose-Headers': 'Upload-Offset,Upload-Length,Tus-Resumable' } if file.size: head_response['Upload-Length'] = str(file._size) resp = Response(headers=head_response) return resp
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)
async def tus_patch(self): try: self.field.context.data._p_register() # register change... except AttributeError: self.context._p_register() file = self.field.get(self.field.context or self.context) if 'CONTENT-LENGTH' in self.request.headers: to_upload = int(self.request.headers['CONTENT-LENGTH']) else: raise AttributeError('No content-length header') try: self.field.context.data._p_register() # register change... except AttributeError: self.context._p_register() if 'UPLOAD-OFFSET' in self.request.headers: file._current_upload = int(self.request.headers['UPLOAD-OFFSET']) else: raise AttributeError('No upload-offset header') self.request._last_read_pos = 0 data = await read_request_data(self.request, to_upload) while data: await file.append_data(self.context, data) data = await read_request_data(self.request, CHUNK_SIZE) await file.finish_upload(self.context) expiration = file._resumable_uri_date + timedelta(days=7) resp = Response( headers={ 'Upload-Offset': str(file.get_actual_size()), 'Tus-Resumable': '1.0.0', 'Upload-Expires': expiration.isoformat(), 'Access-Control-Expose-Headers': 'Upload-Offset,Upload-Expires,Tus-Resumable' }) return resp
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 handler(self, request): """Main handler function for aiohttp.""" if request.method in WRITING_VERBS: try: request._db_write_enabled = True # We try to avoid collisions on the same instance of # guillotina view_result = await self.view() if isinstance(view_result, ErrorResponse) or \ isinstance(view_result, UnauthorizedResponse): # If we don't throw an exception and return an specific # ErrorReponse just abort await abort(request) else: await commit(request) except Unauthorized as e: await abort(request) view_result = generate_unauthorized_response(e, request) except ConflictError as e: view_result = generate_error_response(e, request, 'ConflictDB', 409) except Exception as e: await abort(request) view_result = generate_error_response(e, request, 'ServiceError') else: try: view_result = await self.view() await abort(request) except Unauthorized as e: await abort(request) view_result = generate_unauthorized_response(e, request) except Exception as e: await abort(request) view_result = generate_error_response(e, request, 'ViewError') # Make sure its a Response object to send to renderer if not isinstance(view_result, Response): view_result = Response(view_result) elif view_result is None: # Always provide some response to work with view_result = Response({}) # Apply cors if its needed cors_headers = apply_cors(request) cors_headers.update(view_result.headers) view_result.headers = cors_headers resp = await self.rendered(view_result) if not resp.prepared: await resp.prepare(request) await resp.write_eof() resp._body = None resp.force_close() futures_to_wait = request._futures.values() if futures_to_wait: await asyncio.gather(*list(futures_to_wait)) return resp
async def __call__(self): return Response({'foo': 'bar'})
async def handler(self, request): """Main handler function for aiohttp.""" request._view_error = False request.record('viewrender') if app_settings['check_writable_request'](request): try: # We try to avoid collisions on the same instance of # guillotina view_result = await self.view() if isinstance(view_result, ErrorResponse) or \ isinstance(view_result, UnauthorizedResponse): # If we don't throw an exception and return an specific # ErrorReponse just abort await abort(request) request._view_error = True else: await commit(request, warn=False) except Unauthorized as e: await abort(request) view_result = generate_unauthorized_response(e, request) request._view_error = True except (ConflictError, TIDConflictError) as e: # bubble this error up raise except HTTPException as exc: await abort(request) return exc except Exception as e: await abort(request) view_result = generate_error_response(e, request, 'ServiceError') request._view_error = True else: try: view_result = await self.view() except Unauthorized as e: request._view_error = True view_result = generate_unauthorized_response(e, request) except HTTPException as exc: return exc except Exception as e: request._view_error = True view_result = generate_error_response(e, request, 'ViewError') finally: await abort(request) request.record('viewrendered') # Make sure its a Response object to send to renderer if not isinstance(view_result, Response): view_result = Response(view_result) elif view_result is None: # Always provide some response to work with view_result = Response({}) # Apply cors if its needed cors_renderer = app_settings['cors_renderer'](request) cors_headers = await cors_renderer.get_headers() cors_headers.update(view_result.headers) view_result.headers = cors_headers retry_attempts = getattr(request, '_retry_attempt', 0) if retry_attempts > 0: view_result.headers['X-Retry-Transaction-Count'] = str( retry_attempts) request.record('headers') resp = await self.rendered(view_result) request.record('rendered') request.execute_futures() self.debug(request, resp) request.record('finish') return resp
async def handler(self, request): """Main handler function for aiohttp.""" if request.method in WRITING_VERBS: try: # We try to avoid collisions on the same instance of # guillotina view_result = await self.view() if isinstance(view_result, ErrorResponse) or \ isinstance(view_result, UnauthorizedResponse): # If we don't throw an exception and return an specific # ErrorReponse just abort await abort(request) else: await commit(request, warn=False) except Unauthorized as e: await abort(request) view_result = generate_unauthorized_response(e, request) except (ConflictError, TIDConflictError) as e: # bubble this error up raise except Exception as e: await abort(request) view_result = generate_error_response( e, request, 'ServiceError') else: try: view_result = await self.view() except Unauthorized as e: view_result = generate_unauthorized_response(e, request) except Exception as e: view_result = generate_error_response(e, request, 'ViewError') finally: await abort(request) # Make sure its a Response object to send to renderer if not isinstance(view_result, Response): view_result = Response(view_result) elif view_result is None: # Always provide some response to work with view_result = Response({}) # Apply cors if its needed cors_renderer = app_settings['cors_renderer'](request) cors_headers = await cors_renderer.get_headers() cors_headers.update(view_result.headers) view_result.headers = cors_headers retry_attempts = getattr(request, '_retry_attempt', 0) if retry_attempts > 0: view_result.headers['X-Retry-Transaction-Count'] = str(retry_attempts) resp = await self.rendered(view_result) if not resp.prepared: await resp.prepare(request) await resp.write_eof() resp._body = None resp.force_close() futures_to_wait = request._futures.values() if futures_to_wait: await asyncio.gather(*[f for f in futures_to_wait]) return resp
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)