async def handle_ws_request(self, ws, message): method = app_settings['http_methods']['GET'] path = tuple(p for p in message['value'].split('/') if p) from guillotina.traversal import traverse obj, tail = await traverse(self.request, self.request.container, path) if tail and len(tail) > 0: # convert match lookups view_name = routes.path_to_view_name(tail) elif not tail: view_name = '' else: raise permission = get_utility(IPermission, name='guillotina.AccessContent') security = get_adapter(self.request, IInteraction) allowed = security.check_permission(permission.id, obj) if not allowed: return ws.send_str(ujson.dumps({'error': 'Not allowed'})) try: view = query_multi_adapter((obj, self.request), method, name=view_name) except AttributeError: view = None try: view.__route__.matches(self.request, tail or []) except (KeyError, IndexError): view = None if view is None: return ws.send_str(ujson.dumps({'error': 'Not found'})) ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if not security.check_permission(view_permission, view): return ws.send_str(ujson.dumps({'error': 'No view access'})) if hasattr(view, 'prepare'): view = (await view.prepare()) or view view_result = await view() if IAioHTTPResponse.providedBy(view_result): raise Exception('Do not accept raw aiohttp exceptions in ws') else: from guillotina.traversal import apply_rendering resp = await apply_rendering(view, self.request, view_result) # Return the value, body is always encoded ws.send_str(resp.body.decode('utf-8')) # Wait for possible value self.request.execute_futures()
async def real_resolve(self, request: IRequest) -> Optional[MatchInfo]: """Main function to resolve a request.""" if request.method not in app_settings['http_methods']: raise HTTPMethodNotAllowed( method=request.method, allowed_methods=[ k for k in app_settings['http_methods'].keys() ]) method = app_settings['http_methods'][request.method] try: resource, tail = await self.traverse(request) except ConflictError: # can also happen from connection errors so we bubble this... raise except Exception as _exc: logger.error('Unhandled exception occurred', exc_info=True) request.resource = request.tail = None request.exc = _exc data = { 'success': False, 'exception_message': str(_exc), 'exception_type': getattr(type(_exc), '__name__', str(type(_exc))), # noqa } if app_settings.get('debug'): data['traceback'] = traceback.format_exc() raise HTTPBadRequest(content={'reason': data}) request.record('traversed') await notify(ObjectLoadedEvent(resource)) request.resource = resource request.tail = tail if request.resource is None: await notify(TraversalResourceMissEvent(request, tail)) raise HTTPNotFound(content={"reason": 'Resource not found'}) if tail and len(tail) > 0: # convert match lookups view_name = routes.path_to_view_name(tail) elif not tail: view_name = '' request.record('beforeauthentication') authenticated = await authenticate_request(request) # Add anonymous participation if authenticated is None: authenticated = AnonymousUser() set_authenticated_user(authenticated) request.record('authentication') policy = get_security_policy(authenticated) for language in get_acceptable_languages(request): translator = query_adapter((resource, request), ILanguage, name=language) if translator is not None: resource = translator.translate() break # container registry lookup try: view = query_multi_adapter((resource, request), method, name=view_name) except AttributeError: view = None if view is None and method == IOPTIONS: view = DefaultOPTIONS(resource, request) # Check security on context to AccessContent unless # is view allows explicit or its OPTIONS permission = get_utility(IPermission, name='guillotina.AccessContent') if not policy.check_permission(permission.id, resource): # Check if its a CORS call: if IOPTIONS != method: # Check if the view has permissions explicit if view is None or not view.__allow_access__: logger.info( "No access content {content} with {auth}".format( content=resource, auth=authenticated.id), request=request) raise HTTPUnauthorized( content={ "reason": "You are not authorized to access content", "content": str(resource), "auth": authenticated.id }) if not view and len(tail) > 0: # we should have a view in this case because we are matching routes await notify(TraversalViewMissEvent(request, tail)) return None request.found_view = view request.view_name = view_name request.record('viewfound') ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if view_permission is None: # use default view permission view_permission = app_settings['default_permission'] if not policy.check_permission(view_permission, view): if IOPTIONS != method: raise HTTPUnauthorized( content={ "reason": "You are not authorized to view", "content": str(resource), "auth": authenticated.id }) try: view.__route__.matches(request, tail or []) except (KeyError, IndexError): await notify(TraversalRouteMissEvent(request, tail)) return None except AttributeError: pass if hasattr(view, 'prepare'): view = (await view.prepare()) or view request.record('authorization') return MatchInfo(resource, request, view)
async def handle_ws_request(self, ws, message): method = app_settings["http_methods"]["GET"] try: frame_id = message["id"] except KeyError: frame_id = "0" parsed = parse.urlparse(message.get("path", message.get("value"))) path = tuple(p for p in parsed.path.split("/") if p) from guillotina.traversal import traverse obj, tail = await traverse(self.request, task_vars.container.get(), path) if tail and len(tail) > 0: # convert match lookups view_name = routes.path_to_view_name(tail) elif not tail: view_name = "" else: raise permission = get_utility(IPermission, name="guillotina.AccessContent") security = get_security_policy() allowed = security.check_permission(permission.id, obj) if not allowed: return await ws.send_bytes(orjson.dumps({"error": "Not allowed"})) try: view = query_multi_adapter((obj, self.request), method, name=view_name) except AttributeError: view = None try: view.__route__.matches(self.request, tail or []) except (KeyError, IndexError): view = None if view is None: return await ws.send_bytes( orjson.dumps({ "error": "Not found", "id": frame_id })) ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if not security.check_permission(view_permission, view): return await ws.send_bytes( orjson.dumps({ "error": "No view access", "id": frame_id })) if hasattr(view, "prepare"): view = (await view.prepare()) or view view_result = await view() if IResponse.providedBy(view_result): raise Exception("Do not accept raw ASGI exceptions in ws") else: from guillotina.traversal import apply_rendering resp = await apply_rendering(view, self.request, view_result) # Return the value, body is always encoded response_object = orjson.dumps({ "data": resp.body.decode("utf-8"), "id": frame_id }) await ws.send_bytes(response_object) # Wait for possible value self.request.execute_futures()
async def real_resolve(self, request: IRequest) -> MatchInfo: """Main function to resolve a request.""" security = get_adapter(request, IInteraction) if request.method not in app_settings['http_methods']: raise HTTPMethodNotAllowed() method = app_settings['http_methods'][request.method] language = language_negotiation(request) language_object = language(request) try: resource, tail = await self.traverse(request) except ConflictError: # can also happen from connection errors so we bubble this... raise except Exception as _exc: logger.error('Unhandled exception occurred', exc_info=True) request.resource = request.tail = None request.exc = _exc data = { 'success': False, 'exception_message': str(_exc), 'exception_type': getattr(type(_exc), '__name__', str(type(_exc))), # noqa } if app_settings.get('debug'): data['traceback'] = traceback.format_exc() raise HTTPBadRequest(text=ujson.dumps(data)) request.record('traversed') await notify(ObjectLoadedEvent(resource)) request.resource = resource request.tail = tail if request.resource is None: raise HTTPBadRequest(text='Resource not found') traverse_to = None if tail and len(tail) == 1: view_name = tail[0] elif tail is None or len(tail) == 0: view_name = '' else: view_name = tail[0] traverse_to = tail[1:] request.record('beforeauthentication') await self.apply_authorization(request) request.record('authentication') translator = query_adapter(language_object, ITranslated, args=[resource, request]) if translator is not None: resource = translator.translate() # Add anonymous participation if len(security.participations) == 0: security.add(AnonymousParticipation(request)) # container registry lookup try: view = query_multi_adapter((resource, request), method, name=view_name) except AttributeError: view = None request.found_view = view request.view_name = view_name # Traverse view if its needed if traverse_to is not None and view is not None: if not ITraversableView.providedBy(view): return None else: try: view = await view.publish_traverse(traverse_to) except KeyError: return None # not found, it's okay. except Exception as e: logger.error("Exception on view execution", exc_info=e, request=request) return None request.record('viewfound') permission = get_utility(IPermission, name='guillotina.AccessContent') if not security.check_permission(permission.id, resource): # Check if its a CORS call: if IOPTIONS != method: # Check if the view has permissions explicit if view is None or not view.__allow_access__: logger.info( "No access content {content} with {auths}".format( content=resource, auths=str([ x.principal.id for x in security.participations ])), request=request) raise HTTPUnauthorized() if view is None and method == IOPTIONS: view = DefaultOPTIONS(resource, request) if view: ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if not security.check_permission(view_permission, view): logger.info("No access for view {content} with {auths}".format( content=resource, auths=str( [x.principal.id for x in security.participations])), request=request) raise HTTPUnauthorized() request.record('authorization') renderer = content_type_negotiation(request, resource, view) renderer_object = renderer(request) rendered = query_multi_adapter((renderer_object, view, request), IRendered) request.record('renderer') if rendered is not None: return MatchInfo(resource, request, view, rendered) else: return None
async def _handle(self, request, message): tm = get_tm() txn = get_transaction() if txn.status in (Status.ABORTED, Status.COMMITTED, Status.CONFLICT): # start txn txn = await tm.begin() method = app_settings["http_methods"][message["method"].upper()] endpoint = urlparse(message["endpoint"]).path path = tuple(p for p in endpoint.split("/") if p) obj, tail = await traverse(request, task_vars.container.get(), path) if tail and len(tail) > 0: # convert match lookups view_name = routes.path_to_view_name(tail) # remove query params from view name view_name = view_name.split("?")[0] elif not tail: view_name = "" else: raise permission = get_utility(IPermission, name="guillotina.AccessContent") security = get_security_policy() allowed = security.check_permission(permission.id, obj) if not allowed: return { "success": False, "body": { "reason": "Not allowed" }, "status": 401 } try: view = query_multi_adapter((obj, request), method, name=view_name) except AttributeError: view = None try: view.__route__.matches(request, tail or []) except (KeyError, IndexError, AttributeError): view = None if view is None: return { "success": False, "body": { "reason": "Not found" }, "status": 404 } ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if not security.check_permission(view_permission, view): return { "success": False, "body": { "reason": "No view access" }, "status": 401, } if hasattr(view, "prepare"): view = (await view.prepare()) or view view_result = await view() if self.eager_commit: await tm.commit() return self._gen_result(view_result)
async def _handle(self, request, message): method = app_settings['http_methods'][message['method'].upper()] endpoint = urlparse(message['endpoint']).path path = tuple(p for p in endpoint.split('/') if p) obj, tail = await traverse(request, self.request.container, path) if tail and len(tail) > 0: # convert match lookups view_name = routes.path_to_view_name(tail) # remove query params from view name view_name = view_name.split('?')[0] elif not tail: view_name = '' else: raise permission = get_utility(IPermission, name='guillotina.AccessContent') security = get_adapter(self.request, IInteraction) allowed = security.check_permission(permission.id, obj) if not allowed: return { 'success': False, 'body': { 'reason': 'Not allowed' }, 'status': 401 } try: view = query_multi_adapter((obj, request), method, name=view_name) except AttributeError: view = None try: view.__route__.matches(request, tail or []) except (KeyError, IndexError, AttributeError): view = None if view is None: return { 'success': False, 'body': { 'reason': 'Not found' }, 'status': 404 } ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if not security.check_permission(view_permission, view): return { 'success': False, 'body': { 'reason': 'No view access' }, 'status': 401 } if hasattr(view, 'prepare'): view = (await view.prepare()) or view # Include request's security in view view.request.security = self.request.security view_result = await view() if self.eager_commit: await request._tm.commit(request) return self._gen_result(view_result)
async def real_resolve(self, request): """Main function to resolve a request.""" alsoProvides(request, IRequest) alsoProvides(request, IDefaultLayer) request._futures = {} request.security = IInteraction(request) method = app_settings['http_methods'][request.method] language = language_negotiation(request) language_object = language(request) try: resource, tail = await self.traverse(request) except Exception as _exc: request.resource = request.tail = None request.exc = _exc # XXX should only should traceback if in some sort of dev mode? raise HTTPBadRequest(text=json.dumps({ 'success': False, 'exception_message': str(_exc), 'exception_type': getattr(type(_exc), '__name__', str(type(_exc))), # noqa 'traceback': traceback.format_exc() })) request.resource = resource request.tail = tail if request.resource is None: raise HTTPBadRequest(text='Resource not found') traverse_to = None if tail and len(tail) == 1: view_name = tail[0] elif tail is None or len(tail) == 0: view_name = '' else: view_name = tail[0] traverse_to = tail[1:] await self.apply_authorization(request) translator = queryMultiAdapter((language_object, resource, request), ITranslated) if translator is not None: resource = translator.translate() # Add anonymous participation if len(request.security.participations) == 0: # logger.info("Anonymous User") request.security.add(AnonymousParticipation(request)) # Site registry lookup try: view = queryMultiAdapter((resource, request), method, name=view_name) except AttributeError: view = None # Traverse view if its needed if traverse_to is not None and view is not None: if not ITraversableView.providedBy(view): return None else: try: view = await view.publish_traverse(traverse_to) except Exception as e: logger.error("Exception on view execution", exc_info=e) return None permission = getUtility(IPermission, name='guillotina.AccessContent') interaction = IInteraction(request) allowed = interaction.check_permission(permission.id, resource) if not allowed: # Check if its a CORS call: if IOPTIONS != method or not app_settings['cors']: # Check if the view has permissions explicit if view is None or not view.__allow_access__: logger.warn( "No access content {content} with {auths}".format( content=resource, auths=str([ x.principal.id for x in request.security.participations ]))) raise HTTPUnauthorized() if view is None and method == IOPTIONS: view = DefaultOPTIONS(resource, request) if view: ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if not interaction.check_permission(view_permission, view): logger.warn("No access for view {content} with {auths}".format( content=resource, auths=str([ x.principal.id for x in request.security.participations ]))) raise HTTPUnauthorized() renderer = content_type_negotiation(request, resource, view) renderer_object = renderer(request) rendered = queryMultiAdapter((renderer_object, view, request), IRendered) if rendered is not None: return MatchInfo(resource, request, view, rendered) else: return None
async def handle_ws_request(self, ws, message): method = app_settings['http_methods']['GET'] try: frame_id = message['id'] except KeyError: frame_id = '0' parsed = parse.urlparse(message.get('path', message.get('value'))) path = tuple(p for p in parsed.path.split('/') if p) from guillotina.traversal import traverse obj, tail = await traverse(self.request, self.request.container, path) if tail and len(tail) > 0: # convert match lookups view_name = routes.path_to_view_name(tail) elif not tail: view_name = '' else: raise permission = get_utility( IPermission, name='guillotina.AccessContent') security = get_adapter(self.request, IInteraction) allowed = security.check_permission(permission.id, obj) if not allowed: return await ws.send_str(ujson.dumps({ 'error': 'Not allowed' })) try: view = query_multi_adapter( (obj, self.request), method, name=view_name) except AttributeError: view = None try: view.__route__.matches(self.request, tail or []) except (KeyError, IndexError): view = None if view is None: return await ws.send_str(ujson.dumps({ 'error': 'Not found', 'id': frame_id })) ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if not security.check_permission(view_permission, view): return await ws.send_str(ujson.dumps({ 'error': 'No view access', 'id': frame_id })) if hasattr(view, 'prepare'): view = (await view.prepare()) or view view_result = await view() if IAioHTTPResponse.providedBy(view_result): raise Exception('Do not accept raw aiohttp exceptions in ws') else: from guillotina.traversal import apply_rendering resp = await apply_rendering(view, self.request, view_result) # Return the value, body is always encoded response_object = ujson.dumps({ 'data': resp.body.decode('utf-8'), 'id': frame_id }) await ws.send_str(response_object) # Wait for possible value self.request.execute_futures()
async def real_resolve(self, request: IRequest) -> Optional[MatchInfo]: """Main function to resolve a request.""" security = get_adapter(request, IInteraction) if request.method not in app_settings['http_methods']: raise HTTPMethodNotAllowed( method=request.method, allowed_methods=[k for k in app_settings['http_methods'].keys()]) method = app_settings['http_methods'][request.method] try: resource, tail = await self.traverse(request) except ConflictError: # can also happen from connection errors so we bubble this... raise except Exception as _exc: logger.error('Unhandled exception occurred', exc_info=True) request.resource = request.tail = None request.exc = _exc data = { 'success': False, 'exception_message': str(_exc), 'exception_type': getattr(type(_exc), '__name__', str(type(_exc))), # noqa } if app_settings.get('debug'): data['traceback'] = traceback.format_exc() raise HTTPBadRequest(content={ 'reason': data }) request.record('traversed') await notify(ObjectLoadedEvent(resource)) request.resource = resource request.tail = tail if request.resource is None: await notify(TraversalResourceMissEvent(request, tail)) raise HTTPNotFound(content={ "reason": 'Resource not found' }) if tail and len(tail) > 0: # convert match lookups view_name = routes.path_to_view_name(tail) elif not tail: view_name = '' request.record('beforeauthentication') await self.apply_authorization(request) request.record('authentication') for language in get_acceptable_languages(request): translator = query_adapter((resource, request), ILanguage, name=language) if translator is not None: resource = translator.translate() break # Add anonymous participation if len(security.participations) == 0: security.add(AnonymousParticipation(request)) # container registry lookup try: view = query_multi_adapter( (resource, request), method, name=view_name) except AttributeError: view = None if view is None and method == IOPTIONS: view = DefaultOPTIONS(resource, request) # Check security on context to AccessContent unless # is view allows explicit or its OPTIONS permission = get_utility(IPermission, name='guillotina.AccessContent') if not security.check_permission(permission.id, resource): # Check if its a CORS call: if IOPTIONS != method: # Check if the view has permissions explicit if view is None or not view.__allow_access__: logger.info( "No access content {content} with {auths}".format( content=resource, auths=str([x.principal.id for x in security.participations])), request=request) raise HTTPUnauthorized( content={ "reason": "You are not authorized to access content", "content": str(resource), "auths": [x.principal.id for x in security.participations] } ) if not view and len(tail) > 0: # we should have a view in this case because we are matching routes await notify(TraversalViewMissEvent(request, tail)) return None request.found_view = view request.view_name = view_name request.record('viewfound') ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if not security.check_permission(view_permission, view): if IOPTIONS != method: raise HTTPUnauthorized( content={ "reason": "You are not authorized to view", "content": str(resource), "auths": [x.principal.id for x in security.participations] } ) try: view.__route__.matches(request, tail or []) except (KeyError, IndexError): await notify(TraversalRouteMissEvent(request, tail)) return None except AttributeError: pass if hasattr(view, 'prepare'): view = (await view.prepare()) or view request.record('authorization') return MatchInfo(resource, request, view)