cubicweb/pyramid/bwcompat.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Fri, 05 Apr 2019 17:58:19 +0200
changeset 12567 26744ad37953
parent 12355 c703dc95c82e
child 12741 90348f847b4b
permissions -rw-r--r--
Drop python2 support This mostly consists in removing the dependency on "six" and updating the code to use only Python3 idioms. Notice that we previously used TemporaryDirectory from cubicweb.devtools.testlib for compatibility with Python2. We now directly import it from tempfile.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11967
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     1
# copyright 2017 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     2
# copyright 2014-2016 UNLISH S.A.S. (Montpellier, FRANCE), all rights reserved.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     3
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     4
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     5
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     6
# This file is part of CubicWeb.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     7
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     8
# CubicWeb is free software: you can redistribute it and/or modify it under the
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
     9
# terms of the GNU Lesser General Public License as published by the Free
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    10
# Software Foundation, either version 2.1 of the License, or (at your option)
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    11
# any later version.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    12
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    13
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    14
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    15
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    16
# details.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    17
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    18
# You should have received a copy of the GNU Lesser General Public License along
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    19
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    20
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    21
"""Backward compatibility layer for CubicWeb to run as a Pyramid application."""
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11913
diff changeset
    22
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
    23
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
    24
import logging
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
    25
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    26
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
    27
from pyramid import tweens
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    28
from pyramid.httpexceptions import HTTPSeeOther
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    29
from pyramid import httpexceptions
11588
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
    30
from pyramid.settings import asbool
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    31
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    32
import cubicweb
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    33
import cubicweb.web
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    34
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    35
from cubicweb.web.application import CubicWebPublisher
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    36
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
    37
from cubicweb.web import LogOut, PublishException
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    38
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11619
diff changeset
    39
from cubicweb.pyramid.core import cw_to_pyramid
11492
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
11619
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
    42
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
    43
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
    44
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    45
class PyramidSessionHandler(object):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    46
    """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
    47
    informations.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    48
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    49
    It implements the :class:`cubicweb.web.application.CookieSessionHandler`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    50
    API.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    51
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    52
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    53
    def __init__(self, appli):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    54
        self.appli = appli
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
    def get_session(self, req):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    57
        return req._request.cw_session
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    58
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    59
    def logout(self, req, goto_url):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    60
        raise LogOut(url=goto_url)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    61
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
class CubicWebPyramidHandler(object):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    64
    """ 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
    65
    whole job
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    66
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    67
    :param appli: A CubicWeb 'Application' object.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    68
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    69
    def __init__(self, appli):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    70
        self.appli = appli
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    71
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    72
    def __call__(self, request):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    73
        """
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    74
        Handler that mimics what CubicWebPublisher.main_handle_request and
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    75
        CubicWebPublisher.core_handle do
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
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    78
        req = request.cw_request
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    79
        vreg = request.registry['cubicweb.registry']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    80
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    81
        try:
11511
13e0f569684c Use 'wsgicors' for CORS handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11505
diff changeset
    82
            content = None
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    83
            try:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    84
                with cw_to_pyramid(request):
11539
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    85
                    ctrlid, rset = self.appli.url_resolver.process(req,
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    86
                                                                   req.path)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    87
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    88
                    try:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    89
                        controller = vreg['controllers'].select(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    90
                            ctrlid, req, appli=self.appli)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    91
                    except cubicweb.NoSelectableObject:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    92
                        raise httpexceptions.HTTPUnauthorized(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    93
                            req._('not authorized'))
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    94
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    95
                    req.update_search_state()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    96
                    content = controller.publish(rset=rset)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    97
11539
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    98
                    # XXX this auto-commit should be handled by the cw_request
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    99
                    # cleanup or the pyramid transaction manager.
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   100
                    # It is kept here to have the ValidationError handling bw
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   101
                    # compatible
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   102
                    if req.cnx:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   103
                        txuuid = req.cnx.commit()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   104
                        # commited = True
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   105
                        if txuuid is not None:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   106
                            req.data['last_undoable_transaction'] = txuuid
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   107
            except cubicweb.web.ValidationError as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   108
                # XXX The validation_error_handler implementation is light, we
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   109
                # 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
   110
                # handled when raised from a cubicweb view.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   111
                # BUT the real handling of validation errors should be done
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   112
                # earlier in the controllers, not here. In the end, the
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   113
                # ValidationError should never by handled here.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   114
                content = self.appli.validation_error_handler(req, ex)
12355
c703dc95c82e Fix flake8 issues since release 3.6.0
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11967
diff changeset
   115
            except cubicweb.web.RemoteCallFailed:
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   116
                # 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
   117
                # for this exception) should be enough
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   118
                # content = self.appli.ajax_error_handler(req, ex)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   119
                raise
11607
5b36399b6b21 [bwcompat] also set response headers in error cases
Julien Cristau <julien.cristau@logilab.fr>
parents: 11588
diff changeset
   120
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   121
            if content is not None:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   122
                request.response.body = content
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   123
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   124
        except LogOut as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   125
            # The actual 'logging out' logic should be in separated function
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   126
            # that is accessible by the pyramid views
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   127
            headers = security.forget(request)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   128
            raise HTTPSeeOther(ex.url, headers=headers)
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   129
        except cubicweb.AuthenticationError:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   130
            # 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
   131
            # cubicweb.dbapi._NeedAuthAccessMock.
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   132
            if not content:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   133
                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
   134
                request.response.status_code = 403
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   135
                request.response.body = content
11812
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   136
        except cubicweb.web.NotFound as ex:
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   137
            view = vreg['views'].select('404', req)
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   138
            content = vreg['views'].main_template(req, view=view)
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   139
            request.response.status_code = ex.status
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   140
            request.response.body = content
11614
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   141
        finally:
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   142
            # XXX CubicWebPyramidRequest.headers_out should
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   143
            # 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
   144
            request.response.headers.clear()
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   145
            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
   146
                for item in v:
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   147
                    request.response.headers.add(k, item)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   148
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   149
        return request.response
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   150
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   151
    def error_handler(self, exc, request):
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   152
        req = request.cw_request
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   153
        if isinstance(exc, httpexceptions.HTTPException):
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   154
            request.response = exc
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   155
        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
   156
            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
   157
        else:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   158
            request.response = httpexceptions.HTTPInternalServerError()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   159
        request.response.cache_control = 'no-cache'
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   160
        vreg = request.registry['cubicweb.registry']
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   161
        excinfo = sys.exc_info()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   162
        req.reset_message()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   163
        if req.ajax_request:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   164
            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
   165
        else:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   166
            try:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   167
                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
   168
                req.data['excinfo'] = excinfo
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   169
                errview = vreg['views'].select('error', req)
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   170
                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
   171
                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
   172
            except Exception:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   173
                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
   174
        log.exception(exc)
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   175
        request.response.body = content
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   176
        return request.response
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   177
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   178
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   179
class TweenHandler(object):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   180
    """ A Pyramid tween handler that submit unhandled requests to a Cubicweb
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   181
    handler.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   182
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   183
    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
   184
    key ``'cubicweb.handler'``.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   185
    """
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   186
    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
   187
        self.handler = handler
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   188
        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
   189
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   190
    def __call__(self, request):
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   191
        try:
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   192
            response = self.handler(request)
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   193
        except httpexceptions.HTTPNotFound:
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   194
            response = self.cwhandler(request)
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   195
        return response
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   196
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   197
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   198
def includeme(config):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   199
    """ 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
   200
    raises a HTTPNotFound exception.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   201
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   202
    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
   203
    cubicweb urlresolvers.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   204
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   205
    It provides, for now, support for cubicweb controllers, but this feature
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   206
    will be reimplemented separatly in a less compatible way.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   207
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   208
    It is automatically included by the configuration system, but can be
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   209
    disabled in the :ref:`pyramid_settings`:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   210
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   211
    .. code-block:: ini
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   212
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   213
        cubicweb.bwcompat = no
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   214
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   215
    cwconfig = config.registry['cubicweb.config']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   216
    repository = config.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   217
    cwappli = CubicWebPublisher(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   218
        repository, cwconfig,
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   219
        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
   220
    cwhandler = CubicWebPyramidHandler(cwappli)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   221
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   222
    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
   223
    config.registry['cubicweb.handler'] = cwhandler
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   224
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   225
    config.add_tween(
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11619
diff changeset
   226
        '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
   227
    if asbool(config.registry.settings.get(
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   228
            'cubicweb.bwcompat.errorhandler', True)):
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   229
        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
   230
        # XXX why do i need this?
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   231
        config.add_view(cwhandler.error_handler, context=httpexceptions.HTTPForbidden)