cubicweb/pyramid/bwcompat.py
author Philippe Pepiot <ph@itsalwaysdns.eu>
Tue, 31 Mar 2020 19:15:03 +0200
changeset 12957 0c973204033a
parent 12766 682d0790997f
permissions -rw-r--r--
[server] prevent returning closed cursor to the database pool In since c8c6ad8 init_repository use repo.internal_cnx() instead of repo.system_source.get_connection() so it use the pool and we should not close cursors from the pool before returning it back. Otherwise we may have "connection already closed" error. This bug only trigger when connection-pool-size = 1. Since we are moving to use a dynamic pooler we need to get this fixed. This does not occur with sqlite since the connection wrapper instantiate new cursor everytime, but this occur with other databases.
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
12741
90348f847b4b [pyramid/debug] on every request display request path and selected controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12355
diff changeset
    24
import inspect
11619
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
    25
import logging
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
    26
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    27
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
    28
from pyramid import tweens
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    29
from pyramid.httpexceptions import HTTPSeeOther
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    30
from pyramid import httpexceptions
11588
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
    31
from pyramid.settings import asbool
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    32
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    33
import cubicweb
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    34
import cubicweb.web
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    35
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    36
from cubicweb.web.application import CubicWebPublisher
12764
fb97669efcaa [debug-toolbar] add cw general panel with controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12741
diff changeset
    37
from cubicweb.debug import emit_to_debug_channel
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
    38
from cubicweb.web import LogOut, PublishException
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    39
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11619
diff changeset
    40
from cubicweb.pyramid.core import cw_to_pyramid
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    41
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    42
11619
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
    43
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
    44
be13b3ea71de [bwcompat] log execption even when cubicweb.bwcompat.errorhandler = True (closes #13421901)
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11615
diff changeset
    45
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    46
class PyramidSessionHandler(object):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    47
    """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
    48
    informations.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    49
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    50
    It implements the :class:`cubicweb.web.application.CookieSessionHandler`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    51
    API.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    52
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    53
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    54
    def __init__(self, appli):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    55
        self.appli = appli
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    56
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    57
    def get_session(self, req):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    58
        return req._request.cw_session
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
    def logout(self, req, goto_url):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    61
        raise LogOut(url=goto_url)
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
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    64
class CubicWebPyramidHandler(object):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    65
    """ 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
    66
    whole job
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    67
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    68
    :param appli: A CubicWeb 'Application' object.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
    69
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    70
    def __init__(self, appli):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    71
        self.appli = appli
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    72
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    73
    def __call__(self, request):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    74
        """
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    75
        Handler that mimics what CubicWebPublisher.main_handle_request and
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    76
        CubicWebPublisher.core_handle do
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
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    79
        req = request.cw_request
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    80
        vreg = request.registry['cubicweb.registry']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    81
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    82
        try:
11511
13e0f569684c Use 'wsgicors' for CORS handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11505
diff changeset
    83
            content = None
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    84
            try:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    85
                with cw_to_pyramid(request):
11539
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    86
                    ctrlid, rset = self.appli.url_resolver.process(req,
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    87
                                                                   req.path)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    88
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    89
                    try:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    90
                        controller = vreg['controllers'].select(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    91
                            ctrlid, req, appli=self.appli)
12741
90348f847b4b [pyramid/debug] on every request display request path and selected controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12355
diff changeset
    92
                        log.info("REQUEST [%s] '%s' selected controller %s at %s:%s",
90348f847b4b [pyramid/debug] on every request display request path and selected controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12355
diff changeset
    93
                                 ctrlid, req.path, controller,
90348f847b4b [pyramid/debug] on every request display request path and selected controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12355
diff changeset
    94
                                 inspect.getsourcefile(controller.__class__),
90348f847b4b [pyramid/debug] on every request display request path and selected controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12355
diff changeset
    95
                                 inspect.getsourcelines(controller.__class__)[1])
12766
682d0790997f [debug-toolbar] add registry panel
Laurent Peuch <cortex@worlddomination.be>
parents: 12764
diff changeset
    96
                        emit_to_debug_channel("vreg", {
682d0790997f [debug-toolbar] add registry panel
Laurent Peuch <cortex@worlddomination.be>
parents: 12764
diff changeset
    97
                            "vreg": vreg,
682d0790997f [debug-toolbar] add registry panel
Laurent Peuch <cortex@worlddomination.be>
parents: 12764
diff changeset
    98
                        })
12764
fb97669efcaa [debug-toolbar] add cw general panel with controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12741
diff changeset
    99
                        emit_to_debug_channel("controller", {
fb97669efcaa [debug-toolbar] add cw general panel with controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12741
diff changeset
   100
                            "kind": ctrlid,
fb97669efcaa [debug-toolbar] add cw general panel with controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12741
diff changeset
   101
                            "request": req,
fb97669efcaa [debug-toolbar] add cw general panel with controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12741
diff changeset
   102
                            "path": req.path,
fb97669efcaa [debug-toolbar] add cw general panel with controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12741
diff changeset
   103
                            "controller": controller,
fb97669efcaa [debug-toolbar] add cw general panel with controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12741
diff changeset
   104
                            "config": self.appli.repo.config,
fb97669efcaa [debug-toolbar] add cw general panel with controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12741
diff changeset
   105
                        })
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   106
                    except cubicweb.NoSelectableObject:
12741
90348f847b4b [pyramid/debug] on every request display request path and selected controller
Laurent Peuch <cortex@worlddomination.be>
parents: 12355
diff changeset
   107
                        log.warn("WARNING '%s' unauthorized request", req.path)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   108
                        raise httpexceptions.HTTPUnauthorized(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   109
                            req._('not authorized'))
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   110
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   111
                    req.update_search_state()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   112
                    content = controller.publish(rset=rset)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   113
11539
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
   114
                    # XXX this auto-commit should be handled by the cw_request
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
   115
                    # cleanup or the pyramid transaction manager.
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   116
                    # It is kept here to have the ValidationError handling bw
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   117
                    # compatible
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   118
                    if req.cnx:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   119
                        txuuid = req.cnx.commit()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   120
                        # commited = True
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   121
                        if txuuid is not None:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   122
                            req.data['last_undoable_transaction'] = txuuid
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   123
            except cubicweb.web.ValidationError as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   124
                # XXX The validation_error_handler implementation is light, we
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   125
                # 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
   126
                # handled when raised from a cubicweb view.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   127
                # BUT the real handling of validation errors should be done
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   128
                # earlier in the controllers, not here. In the end, the
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   129
                # ValidationError should never by handled here.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   130
                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
   131
            except cubicweb.web.RemoteCallFailed:
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   132
                # 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
   133
                # for this exception) should be enough
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   134
                # content = self.appli.ajax_error_handler(req, ex)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   135
                raise
11607
5b36399b6b21 [bwcompat] also set response headers in error cases
Julien Cristau <julien.cristau@logilab.fr>
parents: 11588
diff changeset
   136
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   137
            if content is not None:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   138
                request.response.body = content
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   139
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   140
        except LogOut as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   141
            # The actual 'logging out' logic should be in separated function
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   142
            # that is accessible by the pyramid views
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   143
            headers = security.forget(request)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   144
            raise HTTPSeeOther(ex.url, headers=headers)
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   145
        except cubicweb.AuthenticationError:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   146
            # 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
   147
            # cubicweb.dbapi._NeedAuthAccessMock.
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   148
            if not content:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   149
                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
   150
                request.response.status_code = 403
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   151
                request.response.body = content
11812
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   152
        except cubicweb.web.NotFound as ex:
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   153
            view = vreg['views'].select('404', req)
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   154
            content = vreg['views'].main_template(req, view=view)
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   155
            request.response.status_code = ex.status
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   156
            request.response.body = content
11614
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   157
        finally:
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   158
            # XXX CubicWebPyramidRequest.headers_out should
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   159
            # 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
   160
            request.response.headers.clear()
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   161
            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
   162
                for item in v:
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   163
                    request.response.headers.add(k, item)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   164
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   165
        return request.response
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   166
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   167
    def error_handler(self, exc, request):
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   168
        req = request.cw_request
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   169
        if isinstance(exc, httpexceptions.HTTPException):
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   170
            request.response = exc
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   171
        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
   172
            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
   173
        else:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   174
            request.response = httpexceptions.HTTPInternalServerError()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   175
        request.response.cache_control = 'no-cache'
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   176
        vreg = request.registry['cubicweb.registry']
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   177
        excinfo = sys.exc_info()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   178
        req.reset_message()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   179
        if req.ajax_request:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   180
            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
   181
        else:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   182
            try:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   183
                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
   184
                req.data['excinfo'] = excinfo
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   185
                errview = vreg['views'].select('error', req)
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   186
                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
   187
                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
   188
            except Exception:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   189
                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
   190
        log.exception(exc)
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   191
        request.response.body = content
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   192
        return request.response
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   193
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   194
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   195
class TweenHandler(object):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   196
    """ A Pyramid tween handler that submit unhandled requests to a Cubicweb
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   197
    handler.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   198
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   199
    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
   200
    key ``'cubicweb.handler'``.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   201
    """
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   202
    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
   203
        self.handler = handler
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   204
        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
   205
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   206
    def __call__(self, request):
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   207
        try:
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   208
            response = self.handler(request)
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   209
        except httpexceptions.HTTPNotFound:
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   210
            response = self.cwhandler(request)
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   211
        return response
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   212
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   213
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   214
def includeme(config):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   215
    """ 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
   216
    raises a HTTPNotFound exception.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   217
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   218
    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
   219
    cubicweb urlresolvers.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   220
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   221
    It provides, for now, support for cubicweb controllers, but this feature
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   222
    will be reimplemented separatly in a less compatible way.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   223
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   224
    It is automatically included by the configuration system, but can be
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   225
    disabled in the :ref:`pyramid_settings`:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   226
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   227
    .. code-block:: ini
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   228
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   229
        cubicweb.bwcompat = no
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   230
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   231
    cwconfig = config.registry['cubicweb.config']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   232
    repository = config.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   233
    cwappli = CubicWebPublisher(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   234
        repository, cwconfig,
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   235
        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
   236
    cwhandler = CubicWebPyramidHandler(cwappli)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   237
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   238
    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
   239
    config.registry['cubicweb.handler'] = cwhandler
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   240
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   241
    config.add_tween(
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11619
diff changeset
   242
        '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
   243
    if asbool(config.registry.settings.get(
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   244
            'cubicweb.bwcompat.errorhandler', True)):
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   245
        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
   246
        # XXX why do i need this?
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   247
        config.add_view(cwhandler.error_handler, context=httpexceptions.HTTPForbidden)