cubicweb/pyramid/bwcompat.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Fri, 10 Feb 2017 17:13:44 +0100
changeset 11967 83739be20fab
parent 11913 4516c3956d46
child 12355 c703dc95c82e
permissions -rw-r--r--
[pyramid] Add a copyright and docstring to all modules We add copyright statements for both UNLISH (original author) and LOGILAB.
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)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   115
            except cubicweb.web.RemoteCallFailed as ex:
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)