importsysfrompyramidimportsecurityfrompyramidimporttweensfrompyramid.httpexceptionsimportHTTPSeeOtherfrompyramidimporthttpexceptionsfrompyramid.settingsimportasboolimportcubicwebimportcubicweb.webfromcubicweb.web.applicationimportCubicWebPublisherfromcubicweb.webimportLogOut,PublishExceptionfrompyramid_cubicweb.coreimportcw_to_pyramidclassPyramidSessionHandler(object):"""A CW Session handler that rely on the pyramid API to fetch the needed informations. It implements the :class:`cubicweb.web.application.CookieSessionHandler` API. """def__init__(self,appli):self.appli=applidefget_session(self,req):returnreq._request.cw_sessiondeflogout(self,req,goto_url):raiseLogOut(url=goto_url)classCubicWebPyramidHandler(object):""" A Pyramid request handler that rely on a cubicweb instance to do the whole job :param appli: A CubicWeb 'Application' object. """def__init__(self,appli):self.appli=applidef__call__(self,request):""" Handler that mimics what CubicWebPublisher.main_handle_request and CubicWebPublisher.core_handle do """# XXX The main handler of CW forbid anonymous https connections# I guess we can drop this "feature" but in doubt I leave this comment# so we don't forget about it. (cdevienne)req=request.cw_requestvreg=request.registry['cubicweb.registry']try:content=Nonetry:withcw_to_pyramid(request):ctrlid,rset=self.appli.url_resolver.process(req,req.path)try:controller=vreg['controllers'].select(ctrlid,req,appli=self.appli)exceptcubicweb.NoSelectableObject:raisehttpexceptions.HTTPUnauthorized(req._('not authorized'))req.update_search_state()content=controller.publish(rset=rset)# XXX this auto-commit should be handled by the cw_request# cleanup or the pyramid transaction manager.# It is kept here to have the ValidationError handling bw# compatibleifreq.cnx:txuuid=req.cnx.commit()# commited = TrueiftxuuidisnotNone:req.data['last_undoable_transaction']=txuuidexceptcubicweb.web.ValidationErrorasex:# XXX The validation_error_handler implementation is light, we# should redo it better in cw_to_pyramid, so it can be properly# handled when raised from a cubicweb view.# BUT the real handling of validation errors should be done# earlier in the controllers, not here. In the end, the# ValidationError should never by handled here.content=self.appli.validation_error_handler(req,ex)exceptcubicweb.web.RemoteCallFailedasex:# XXX The default pyramid error handler (or one that we provide# for this exception) should be enough# content = self.appli.ajax_error_handler(req, ex)raiseifcontentisnotNone:request.response.body=content# XXX CubicWebPyramidRequest.headers_out should# access directly the pyramid response headers.request.response.headers.clear()fork,vinreq.headers_out.getAllRawHeaders():foriteminv:request.response.headers.add(k,item)exceptLogOutasex:# The actual 'logging out' logic should be in separated function# that is accessible by the pyramid viewsheaders=security.forget(request)raiseHTTPSeeOther(ex.url,headers=headers)exceptcubicweb.AuthenticationError:# Will occur upon access to req.cnx which is a# cubicweb.dbapi._NeedAuthAccessMock.ifnotcontent:content=vreg['views'].main_template(req,'login')request.response.body=contentreturnrequest.responsedeferror_handler(self,exc,request):req=request.cw_requestifisinstance(exc,httpexceptions.HTTPException):request.response=excelifisinstance(exc,PublishException)andexc.statusisnotNone:request.response=httpexceptions.exception_response(exc.status)else:request.response=httpexceptions.HTTPInternalServerError()request.response.cache_control='no-cache'vreg=request.registry['cubicweb.registry']excinfo=sys.exc_info()req.reset_message()ifreq.ajax_request:content=self.appli.ajax_error_handler(req,exc)else:try:req.data['ex']=excerrview=vreg['views'].select('error',req)template=self.appli.main_template_id(req)content=vreg['views'].main_template(req,template,view=errview)exceptException:content=vreg['views'].main_template(req,'error-template')request.response.body=contentreturnrequest.responseclassTweenHandler(object):""" A Pyramid tween handler that submit unhandled requests to a Cubicweb handler. The CubicWeb handler to use is expected to be in the pyramid registry, at key ``'cubicweb.handler'``. """def__init__(self,handler,registry):self.handler=handlerself.cwhandler=registry['cubicweb.handler']def__call__(self,request):ifrequest.path.startswith('/https/'):request.environ['PATH_INFO']=request.environ['PATH_INFO'][6:]assertnotrequest.path.startswith('/https/')request.scheme='https'try:response=self.handler(request)excepthttpexceptions.HTTPNotFound:response=self.cwhandler(request)returnresponsedefincludeme(config):""" Set up a tween app that will handle the request if the main application raises a HTTPNotFound exception. This is to keep legacy compatibility for cubes that makes use of the cubicweb urlresolvers. It provides, for now, support for cubicweb controllers, but this feature will be reimplemented separatly in a less compatible way. It is automatically included by the configuration system, but can be disabled in the :ref:`pyramid_settings`: .. code-block:: ini cubicweb.bwcompat = no """cwconfig=config.registry['cubicweb.config']repository=config.registry['cubicweb.repository']cwappli=CubicWebPublisher(repository,cwconfig,session_handler_fact=PyramidSessionHandler)cwhandler=CubicWebPyramidHandler(cwappli)config.registry['cubicweb.appli']=cwappliconfig.registry['cubicweb.handler']=cwhandlerconfig.add_tween('pyramid_cubicweb.bwcompat.TweenHandler',under=tweens.EXCVIEW)ifasbool(config.registry.settings.get('cubicweb.bwcompat.errorhandler',True)):config.add_view(cwhandler.error_handler,context=Exception)# XXX why do i need this?config.add_view(cwhandler.error_handler,context=httpexceptions.HTTPForbidden)