--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyramid_cubicweb/bwcompat.py Thu Jul 31 17:48:32 2014 +0200
@@ -0,0 +1,123 @@
+from pyramid import security
+from pyramid.httpexceptions import HTTPSeeOther
+from pyramid import httpexceptions
+
+import cubicweb
+import cubicweb.web
+
+from cubicweb.web.application import CubicWebPublisher
+
+from cubicweb.web import LogOut, cors
+
+from pyramid_cubicweb.core import cw_to_pyramid
+
+
+class PyramidSessionHandler(object):
+ """A CW Session handler that rely on the pyramid API to fetch the needed
+ informations"""
+
+ def __init__(self, appli):
+ self.appli = appli
+
+ def get_session(self, req):
+ return req._request.cw_session
+
+ def logout(self, req, goto_url):
+ raise LogOut(url=goto_url)
+
+
+class CubicWebPyramidHandler(object):
+ def __init__(self, appli):
+ self.appli = appli
+
+ def __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_request
+ vreg = request.registry['cubicweb.registry']
+
+ try:
+ try:
+ with cw_to_pyramid(request):
+ cors.process_request(req, vreg.config)
+ ctrlid, rset = self.appli.url_resolver.process(req, req.path)
+
+ try:
+ controller = vreg['controllers'].select(
+ ctrlid, req, appli=self.appli)
+ except cubicweb.NoSelectableObject:
+ raise httpexceptions.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
+ # compatible
+ if req.cnx:
+ txuuid = req.cnx.commit()
+ # commited = True
+ if txuuid is not None:
+ req.data['last_undoable_transaction'] = txuuid
+ except cors.CORSPreflight:
+ request.response.status_int = 200
+ except cubicweb.web.ValidationError as ex:
+ # 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)
+ except cubicweb.web.RemoteCallFailed as ex:
+ # 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)
+ raise
+
+ if content is not None:
+ request.response.body = content
+
+ # XXX CubicWebPyramidRequest.headers_out should
+ # access directly the pyramid response headers.
+ request.response.headers.clear()
+ for k, v in req.headers_out.getAllRawHeaders():
+ for item in v:
+ request.response.headers.add(k, item)
+
+ except LogOut as ex:
+ # The actual 'logging out' logic should be in separated function
+ # that is accessible by the pyramid views
+ headers = security.forget(request)
+ raise HTTPSeeOther(ex.url, headers=headers)
+ # except AuthenticationError:
+ # XXX I don't think it makes sens to catch this ex here (cdevienne)
+
+ return request.response
+
+
+def includeme(config):
+ # Set up a defaut route to handle non-catched urls.
+ # This is to keep legacy compatibility for cubes that makes use of the
+ # cubicweb controllers.
+ cwconfig = config.registry['cubicweb.config']
+ repository = config.registry['cubicweb.repository']
+ cwappli = CubicWebPublisher(
+ repository, cwconfig,
+ session_handler_fact=PyramidSessionHandler)
+ handler = CubicWebPyramidHandler(cwappli)
+
+ config.registry['cubicweb.appli'] = cwappli
+ config.registry['cubicweb.handler'] = handler
+
+ config.add_route('catchall', pattern='*path')
+ config.add_view(handler, route_name='catchall')