cubicweb/pyramid/bwcompat.py
author Yann Voté <yann.vote@logilab.fr>
Mon, 26 Sep 2016 14:52:12 +0200
changeset 11631 faf279e33298
parent 11619 pyramid_cubicweb/bwcompat.py@be13b3ea71de
child 11811 f09efeead7f9
permissions -rw-r--r--
Merge with pyramid-cubicweb The following tasks have been done: - merge packaging files - merge documentation - move pyramid_cubicweb package at cubicweb/pyramid and update imports accordingly - rename tests directory into test - move pyramid-cubicweb README.rst into README.pyramid.rst until better idea - add a test dependency on unreleased cubicweb-pyramid to have both py27 and py34 tests pass Closes #14023058.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
     1
import sys
11619
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
     2
import logging
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
     3
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     4
from pyramid import security
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
     5
from pyramid import tweens
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     6
from pyramid.httpexceptions import HTTPSeeOther
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     7
from pyramid import httpexceptions
11588
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
     8
from pyramid.settings import asbool
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     9
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    10
import cubicweb
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    11
import cubicweb.web
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    12
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    13
from cubicweb.web.application import CubicWebPublisher
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    14
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
    15
from cubicweb.web import LogOut, PublishException
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    16
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11619
diff changeset
    17
from cubicweb.pyramid.core import cw_to_pyramid
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    18
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    19
11619
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
    20
log = logging.getLogger(__name__)
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
    21
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
    22
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    23
class PyramidSessionHandler(object):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    24
    """A CW Session handler that rely on the pyramid API to fetch the needed
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    25
    informations.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    26
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    27
    It implements the :class:`cubicweb.web.application.CookieSessionHandler`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    28
    API.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    29
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    30
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    31
    def __init__(self, appli):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    32
        self.appli = appli
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    33
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    34
    def get_session(self, req):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    35
        return req._request.cw_session
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    36
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    37
    def logout(self, req, goto_url):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    38
        raise LogOut(url=goto_url)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    39
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    40
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    41
class CubicWebPyramidHandler(object):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    42
    """ A Pyramid request handler that rely on a cubicweb instance to do the
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    43
    whole job
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    44
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    45
    :param appli: A CubicWeb 'Application' object.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    46
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    47
    def __init__(self, appli):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    48
        self.appli = appli
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    49
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    50
    def __call__(self, request):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    51
        """
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    52
        Handler that mimics what CubicWebPublisher.main_handle_request and
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    53
        CubicWebPublisher.core_handle do
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    54
        """
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    55
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    56
        # XXX The main handler of CW forbid anonymous https connections
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    57
        # I guess we can drop this "feature" but in doubt I leave this comment
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    58
        # so we don't forget about it. (cdevienne)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    59
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    60
        req = request.cw_request
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    61
        vreg = request.registry['cubicweb.registry']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    62
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    63
        try:
11511
13e0f569684c Use 'wsgicors' for CORS handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11505
diff changeset
    64
            content = None
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    65
            try:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    66
                with cw_to_pyramid(request):
11539
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    67
                    ctrlid, rset = self.appli.url_resolver.process(req,
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    68
                                                                   req.path)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    69
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    70
                    try:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    71
                        controller = vreg['controllers'].select(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    72
                            ctrlid, req, appli=self.appli)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    73
                    except cubicweb.NoSelectableObject:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    74
                        raise httpexceptions.HTTPUnauthorized(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    75
                            req._('not authorized'))
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    76
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    77
                    req.update_search_state()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    78
                    content = controller.publish(rset=rset)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    79
11539
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    80
                    # XXX this auto-commit should be handled by the cw_request
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    81
                    # cleanup or the pyramid transaction manager.
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    82
                    # It is kept here to have the ValidationError handling bw
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    83
                    # compatible
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    84
                    if req.cnx:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    85
                        txuuid = req.cnx.commit()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    86
                        # commited = True
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    87
                        if txuuid is not None:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    88
                            req.data['last_undoable_transaction'] = txuuid
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    89
            except cubicweb.web.ValidationError as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    90
                # XXX The validation_error_handler implementation is light, we
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    91
                # should redo it better in cw_to_pyramid, so it can be properly
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    92
                # handled when raised from a cubicweb view.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    93
                # BUT the real handling of validation errors should be done
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    94
                # earlier in the controllers, not here. In the end, the
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    95
                # ValidationError should never by handled here.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    96
                content = self.appli.validation_error_handler(req, ex)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    97
            except cubicweb.web.RemoteCallFailed as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    98
                # XXX The default pyramid error handler (or one that we provide
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    99
                # for this exception) should be enough
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   100
                # content = self.appli.ajax_error_handler(req, ex)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   101
                raise
11607
5b36399b6b21 [bwcompat] also set response headers in error cases
Julien Cristau <julien.cristau@logilab.fr>
parents: 11588
diff changeset
   102
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   103
            if content is not None:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   104
                request.response.body = content
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   105
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   106
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   107
        except LogOut as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   108
            # The actual 'logging out' logic should be in separated function
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   109
            # that is accessible by the pyramid views
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   110
            headers = security.forget(request)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   111
            raise HTTPSeeOther(ex.url, headers=headers)
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   112
        except cubicweb.AuthenticationError:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   113
            # Will occur upon access to req.cnx which is a
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   114
            # cubicweb.dbapi._NeedAuthAccessMock.
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   115
            if not content:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   116
                content = vreg['views'].main_template(req, 'login')
11615
7e798fe70014 [bwcompat] send 403 on authentication errors (closes #12219849)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11614
diff changeset
   117
                request.response.status_code = 403
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   118
                request.response.body = content
11614
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   119
        finally:
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   120
            # XXX CubicWebPyramidRequest.headers_out should
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   121
            # access directly the pyramid response headers.
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   122
            request.response.headers.clear()
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   123
            for k, v in req.headers_out.getAllRawHeaders():
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   124
                for item in v:
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   125
                    request.response.headers.add(k, item)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   126
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   127
        return request.response
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   128
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   129
    def error_handler(self, exc, request):
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   130
        req = request.cw_request
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   131
        if isinstance(exc, httpexceptions.HTTPException):
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   132
            request.response = exc
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   133
        elif isinstance(exc, PublishException) and exc.status is not None:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   134
            request.response = httpexceptions.exception_response(exc.status)
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   135
        else:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   136
            request.response = httpexceptions.HTTPInternalServerError()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   137
        request.response.cache_control = 'no-cache'
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   138
        vreg = request.registry['cubicweb.registry']
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   139
        excinfo = sys.exc_info()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   140
        req.reset_message()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   141
        if req.ajax_request:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   142
            content = self.appli.ajax_error_handler(req, exc)
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   143
        else:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   144
            try:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   145
                req.data['ex'] = exc
11608
259fa3391c7b keep track of all traceback in error handling, not just the exception message (closes #11689093)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 11607
diff changeset
   146
                req.data['excinfo'] = excinfo
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   147
                errview = vreg['views'].select('error', req)
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   148
                template = self.appli.main_template_id(req)
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   149
                content = vreg['views'].main_template(req, template, view=errview)
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   150
            except Exception:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   151
                content = vreg['views'].main_template(req, 'error-template')
11619
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
   152
        log.exception(exc)
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   153
        request.response.body = content
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   154
        return request.response
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   155
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   156
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   157
class TweenHandler(object):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   158
    """ A Pyramid tween handler that submit unhandled requests to a Cubicweb
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   159
    handler.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   160
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   161
    The CubicWeb handler to use is expected to be in the pyramid registry, at
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   162
    key ``'cubicweb.handler'``.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   163
    """
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   164
    def __init__(self, handler, registry):
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   165
        self.handler = handler
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   166
        self.cwhandler = registry['cubicweb.handler']
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   167
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   168
    def __call__(self, request):
11505
eca6387f5b87 Handle properly the '/https/*' urls
Christophe de Vienne <christophe@unlish.com>
parents: 11499
diff changeset
   169
        if request.path.startswith('/https/'):
eca6387f5b87 Handle properly the '/https/*' urls
Christophe de Vienne <christophe@unlish.com>
parents: 11499
diff changeset
   170
            request.environ['PATH_INFO'] = request.environ['PATH_INFO'][6:]
eca6387f5b87 Handle properly the '/https/*' urls
Christophe de Vienne <christophe@unlish.com>
parents: 11499
diff changeset
   171
            assert not request.path.startswith('/https/')
eca6387f5b87 Handle properly the '/https/*' urls
Christophe de Vienne <christophe@unlish.com>
parents: 11499
diff changeset
   172
            request.scheme = 'https'
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   173
        try:
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   174
            response = self.handler(request)
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   175
        except httpexceptions.HTTPNotFound:
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   176
            response = self.cwhandler(request)
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   177
        return response
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   178
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   179
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   180
def includeme(config):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   181
    """ Set up a tween app that will handle the request if the main application
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   182
    raises a HTTPNotFound exception.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   183
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   184
    This is to keep legacy compatibility for cubes that makes use of the
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   185
    cubicweb urlresolvers.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   186
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   187
    It provides, for now, support for cubicweb controllers, but this feature
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   188
    will be reimplemented separatly in a less compatible way.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   189
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   190
    It is automatically included by the configuration system, but can be
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   191
    disabled in the :ref:`pyramid_settings`:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   192
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   193
    .. code-block:: ini
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   194
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   195
        cubicweb.bwcompat = no
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   196
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   197
    cwconfig = config.registry['cubicweb.config']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   198
    repository = config.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   199
    cwappli = CubicWebPublisher(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   200
        repository, cwconfig,
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   201
        session_handler_fact=PyramidSessionHandler)
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   202
    cwhandler = CubicWebPyramidHandler(cwappli)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   203
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   204
    config.registry['cubicweb.appli'] = cwappli
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   205
    config.registry['cubicweb.handler'] = cwhandler
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   206
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   207
    config.add_tween(
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11619
diff changeset
   208
        'cubicweb.pyramid.bwcompat.TweenHandler', under=tweens.EXCVIEW)
11588
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   209
    if asbool(config.registry.settings.get(
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   210
            'cubicweb.bwcompat.errorhandler', True)):
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   211
        config.add_view(cwhandler.error_handler, context=Exception)
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   212
        # XXX why do i need this?
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   213
        config.add_view(cwhandler.error_handler, context=httpexceptions.HTTPForbidden)