cubicweb/pyramid/bwcompat.py
author Laurent Peuch <cortex@worlddomination.be>
Wed, 12 Jun 2019 19:58:00 +0200
changeset 12741 90348f847b4b
parent 12355 c703dc95c82e
child 12764 fb97669efcaa
permissions -rw-r--r--
[pyramid/debug] on every request display request path and selected controller This will display lines like: 2019-06-12 16:26:57 - (cubicweb.pyramid.bwcompat) INFO: REQUEST [view] '/wiki/334037' selected controller <cubicweb.web.views.basecontrollers.ViewController object at 0x7f133802ae90> at /root/.virtualenvs/abreton/local/lib/python2.7/site-packages/cubicweb/web/views/basecontrollers.py:120 2019-06-12 16:26:59 - (cubicweb.pyramid.bwcompat) INFO: REQUEST [data] '/data/ea5eb3b6f89fba0ff4b671093c88d3dd/images/cartouche-mur.jpg' selected controller <cubicweb.web.views.staticcontrollers.DataController object at 0x7f1332a84d50> at /root/.virtualenvs/abreton/local/lib/python2.7/site-packages/cubicweb/web/views/staticcontrollers.py:179 The make debugging easier as this isn't done already. Most other web frameworks do something similar for the developper to be able to understand what is happening right now. Closes #17219741
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
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    37
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])
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    96
                    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
    97
                        log.warn("WARNING '%s' unauthorized request", req.path)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    98
                        raise httpexceptions.HTTPUnauthorized(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    99
                            req._('not authorized'))
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   100
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   101
                    req.update_search_state()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   102
                    content = controller.publish(rset=rset)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   103
11539
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
   104
                    # XXX this auto-commit should be handled by the cw_request
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
   105
                    # cleanup or the pyramid transaction manager.
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   106
                    # It is kept here to have the ValidationError handling bw
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   107
                    # compatible
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   108
                    if req.cnx:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   109
                        txuuid = req.cnx.commit()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   110
                        # commited = True
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   111
                        if txuuid is not None:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   112
                            req.data['last_undoable_transaction'] = txuuid
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   113
            except cubicweb.web.ValidationError as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   114
                # XXX The validation_error_handler implementation is light, we
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   115
                # 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
   116
                # handled when raised from a cubicweb view.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   117
                # BUT the real handling of validation errors should be done
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   118
                # earlier in the controllers, not here. In the end, the
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   119
                # ValidationError should never by handled here.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   120
                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
   121
            except cubicweb.web.RemoteCallFailed:
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   122
                # 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
   123
                # for this exception) should be enough
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   124
                # content = self.appli.ajax_error_handler(req, ex)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   125
                raise
11607
5b36399b6b21 [bwcompat] also set response headers in error cases
Julien Cristau <julien.cristau@logilab.fr>
parents: 11588
diff changeset
   126
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   127
            if content is not None:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   128
                request.response.body = content
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   129
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   130
        except LogOut as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   131
            # The actual 'logging out' logic should be in separated function
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   132
            # that is accessible by the pyramid views
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   133
            headers = security.forget(request)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   134
            raise HTTPSeeOther(ex.url, headers=headers)
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   135
        except cubicweb.AuthenticationError:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   136
            # 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
   137
            # cubicweb.dbapi._NeedAuthAccessMock.
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   138
            if not content:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   139
                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
   140
                request.response.status_code = 403
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11539
diff changeset
   141
                request.response.body = content
11812
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   142
        except cubicweb.web.NotFound as ex:
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   143
            view = vreg['views'].select('404', req)
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   144
            content = vreg['views'].main_template(req, view=view)
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   145
            request.response.status_code = ex.status
4e0829ade86f [pyramid] Fix 404 handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   146
            request.response.body = content
11614
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   147
        finally:
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   148
            # XXX CubicWebPyramidRequest.headers_out should
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   149
            # 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
   150
            request.response.headers.clear()
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   151
            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
   152
                for item in v:
171e70a7b121 [bwcompat] set response headers on AuthenticationError (closes #12219860)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11608
diff changeset
   153
                    request.response.headers.add(k, item)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   154
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   155
        return request.response
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   156
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   157
    def error_handler(self, exc, request):
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   158
        req = request.cw_request
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   159
        if isinstance(exc, httpexceptions.HTTPException):
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   160
            request.response = exc
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   161
        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
   162
            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
   163
        else:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   164
            request.response = httpexceptions.HTTPInternalServerError()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   165
        request.response.cache_control = 'no-cache'
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   166
        vreg = request.registry['cubicweb.registry']
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   167
        excinfo = sys.exc_info()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   168
        req.reset_message()
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   169
        if req.ajax_request:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   170
            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
   171
        else:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   172
            try:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   173
                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
   174
                req.data['excinfo'] = excinfo
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   175
                errview = vreg['views'].select('error', req)
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   176
                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
   177
                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
   178
            except Exception:
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   179
                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
   180
        log.exception(exc)
11578
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   181
        request.response.body = content
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   182
        return request.response
fcba04437236 [bwcompat] use cubicweb error views (closes #4545130)
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   183
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   184
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   185
class TweenHandler(object):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   186
    """ A Pyramid tween handler that submit unhandled requests to a Cubicweb
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   187
    handler.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   188
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   189
    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
   190
    key ``'cubicweb.handler'``.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   191
    """
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   192
    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
   193
        self.handler = handler
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   194
        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
   195
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   196
    def __call__(self, request):
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   197
        try:
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   198
            response = self.handler(request)
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   199
        except httpexceptions.HTTPNotFound:
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   200
            response = self.cwhandler(request)
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   201
        return response
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   202
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   203
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   204
def includeme(config):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   205
    """ 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
   206
    raises a HTTPNotFound exception.
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
    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
   209
    cubicweb urlresolvers.
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
    It provides, for now, support for cubicweb controllers, but this feature
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   212
    will be reimplemented separatly in a less compatible way.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   213
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   214
    It is automatically included by the configuration system, but can be
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   215
    disabled in the :ref:`pyramid_settings`:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   216
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   217
    .. code-block:: ini
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   218
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   219
        cubicweb.bwcompat = no
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11511
diff changeset
   220
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   221
    cwconfig = config.registry['cubicweb.config']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   222
    repository = config.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   223
    cwappli = CubicWebPublisher(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   224
        repository, cwconfig,
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   225
        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
   226
    cwhandler = CubicWebPyramidHandler(cwappli)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   227
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   228
    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
   229
    config.registry['cubicweb.handler'] = cwhandler
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   230
11496
500615e26063 Use a tween application instead of a catchall route.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
   231
    config.add_tween(
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11619
diff changeset
   232
        '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
   233
    if asbool(config.registry.settings.get(
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   234
            'cubicweb.bwcompat.errorhandler', True)):
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   235
        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
   236
        # XXX why do i need this?
50e1fda83837 [bwcompat] Make the error handler optional
Christophe de Vienne <christophe@unlish.com>
parents: 11578
diff changeset
   237
        config.add_view(cwhandler.error_handler, context=httpexceptions.HTTPForbidden)