cubicweb/pyramid/core.py
author Laurent Peuch <cortex@worlddomination.be>
Thu, 21 Feb 2019 18:51:36 +0100
changeset 12394 e847b5d1ffff
parent 12379 04348101688a
child 12491 540904e0ff0f
permissions -rw-r--r--
[doc] always put file name for code example and uses :file:`path` syntax everywhere
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: 11930
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: 11930
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: 11930
diff changeset
     3
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
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: 11930
diff changeset
     5
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
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: 11930
diff changeset
     7
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
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: 11930
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: 11930
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: 11930
diff changeset
    11
# any later version.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
diff changeset
    12
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
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: 11930
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: 11930
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: 11930
diff changeset
    16
# details.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
diff changeset
    17
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
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: 11930
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: 11930
diff changeset
    20
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
diff changeset
    21
"""Binding of CubicWeb connection to Pyramid request."""
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11930
diff changeset
    22
11556
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
    23
import itertools
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
    24
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    25
from contextlib import contextmanager
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    26
from warnings import warn
11508
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
    27
from cgi import FieldStorage
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    28
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    29
import rql
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    30
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    31
from cubicweb.web.request import CubicWebRequestBase
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
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    35
from cubicweb.server import session as cwsession
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    36
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents: 11492
diff changeset
    37
from pyramid import httpexceptions
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: 11630
diff changeset
    39
from cubicweb.pyramid import tools
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
import logging
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    42
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    43
log = logging.getLogger(__name__)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    44
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    45
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    46
class Connection(cwsession.Connection):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    47
    """ A specialised Connection that access the session data through a
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    48
    property.
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    49
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    50
    This behavior makes sure the actual session data is not loaded until
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    51
    actually accessed.
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    52
    """
11811
f09efeead7f9 Fix broken flake8 configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11701
diff changeset
    53
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    54
    def __init__(self, session, *args, **kw):
12043
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    55
        super(Connection, self).__init__(session._repo, session._user, *args, **kw)
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    56
        self.session = session
11824
d7ecf6dab085 Fix AttributeError for "lang" on repo/client connections
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
    57
        self.lang = session._cached_lang
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    58
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    59
    def _get_session_data(self):
12043
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    60
        return self.session.data
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    61
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    62
    def _set_session_data(self, data):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    63
        pass
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    64
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    65
    _session_data = property(_get_session_data, _set_session_data)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    66
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    67
12043
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    68
class Session(object):
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    69
    """ A Session that access the session data through a property.
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    70
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    71
    Along with :class:`Connection`, it avoid any load of the pyramid session
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    72
    data until it is actually accessed.
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    73
    """
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    74
    def __init__(self, pyramid_request, user, repo):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    75
        self._pyramid_request = pyramid_request
12043
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    76
        self._user = user
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    77
        self._repo = repo
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    78
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    79
    @property
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    80
    def anonymous_session(self):
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    81
        # XXX for now, anonymous_user only exists in webconfig (and testconfig).
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    82
        # It will only be present inside all-in-one instance.
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    83
        # there is plan to move it down to global config.
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    84
        if not hasattr(self._repo.config, 'anonymous_user'):
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    85
            # not a web or test config, no anonymous user
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    86
            return False
b8d2e6b9f548 Stop using Session on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12036
diff changeset
    87
        return self._user.login == self._repo.config.anonymous_user()[0]
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    88
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    89
    def get_data(self):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    90
        if not getattr(self, '_protect_data_access', False):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    91
            self._data_accessed = True
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    92
            return self._pyramid_request.session
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    93
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    94
    def set_data(self, data):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    95
        if getattr(self, '_data_accessed', False):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    96
            self._pyramid_request.session.clear()
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    97
            self._pyramid_request.session.update(data)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    98
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    99
    data = property(get_data, set_data)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   100
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   101
    def new_cnx(self):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   102
        self._protect_data_access = True
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   103
        try:
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   104
            return Connection(self)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   105
        finally:
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   106
            self._protect_data_access = False
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   107
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   108
11556
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   109
def cw_headers(request):
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   110
    return itertools.chain(
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   111
        *[[(k, item) for item in v]
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   112
          for k, v in request.cw_request.headers_out.getAllRawHeaders()])
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   113
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   114
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   115
@contextmanager
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   116
def cw_to_pyramid(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   117
    """ Context manager to wrap a call to the cubicweb API.
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   118
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   119
    All CW exceptions will be transformed into their pyramid equivalent.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   120
    When needed, some CW reponse bits may be converted too (mainly headers)"""
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   121
    try:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   122
        yield
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   123
    except cubicweb.web.Redirect as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   124
        assert 300 <= ex.status < 400
11556
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   125
        raise httpexceptions.status_map[ex.status](
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   126
            ex.location, headers=cw_headers(request))
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   127
    except cubicweb.web.StatusResponse as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   128
        warn('[3.16] StatusResponse is deprecated use req.status_out',
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   129
             DeprecationWarning, stacklevel=2)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   130
        request.body = ex.content
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   131
        request.status_int = ex.status
12355
c703dc95c82e Fix flake8 issues since release 3.6.0
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   132
    except cubicweb.web.Unauthorized:
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   133
        raise httpexceptions.HTTPForbidden(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   134
            request.cw_request._(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   135
                'You\'re not authorized to access this page. '
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   136
                'If you think you should, please contact the site '
11556
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   137
                'administrator.'),
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   138
            headers=cw_headers(request))
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   139
    except cubicweb.web.Forbidden:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   140
        raise httpexceptions.HTTPForbidden(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   141
            request.cw_request._(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   142
                'This action is forbidden. '
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   143
                'If you think it should be allowed, please contact the site '
11556
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   144
                'administrator.'),
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   145
            headers=cw_headers(request))
12355
c703dc95c82e Fix flake8 issues since release 3.6.0
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   146
    except (rql.BadRQLQuery, cubicweb.web.RequestError):
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   147
        raise
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
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   150
class CubicWebPyramidRequest(CubicWebRequestBase):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   151
    """ A CubicWeb request that only wraps a pyramid request.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   152
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   153
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   154
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   155
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   156
    def __init__(self, request):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   157
        self._request = request
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   158
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   159
        self.path = request.upath_info
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   160
11498
a8aaff87c1fc Use registry['cubicweb.registry'] instead of registry['cubicweb.appli'].vreg because the application may not be present.
Christophe de Vienne <christophe@unlish.com>
parents: 11493
diff changeset
   161
        vreg = request.registry['cubicweb.registry']
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   162
11504
8701caf9edf0 Correctly pass the multiple parameters to the cubicweb request
Christophe de Vienne <christophe@unlish.com>
parents: 11502
diff changeset
   163
        post = request.params.mixed()
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   164
        headers_in = request.headers
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   165
11913
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   166
        super(CubicWebPyramidRequest, self).__init__(vreg, post,
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   167
                                                     headers=headers_in)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   168
11508
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   169
        self.content = request.body_file_seekable
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   170
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   171
    def setup_params(self, params):
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   172
        self.form = {}
11630
1400aee10df4 Port to Python3 (closes #14159555)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11622
diff changeset
   173
        for param, val in params.items():
11508
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   174
            if param in self.no_script_form_params and val:
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   175
                val = self.no_script_form_param(param, val)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   176
            if isinstance(val, FieldStorage) and val.file:
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   177
                val = (val.filename, val.file)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   178
            if param == '_cwmsgid':
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   179
                self.set_message_id(val)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   180
            elif param == '__message':
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   181
                warn('[3.13] __message in request parameter is deprecated '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   182
                     '(may only be given to .build_url). Seeing this message '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   183
                     'usualy means your application hold some <form> where '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   184
                     'you should replace use of __message hidden input by '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   185
                     'form.set_message, so new _cwmsgid mechanism is properly '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   186
                     'used',
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   187
                     DeprecationWarning)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   188
                self.set_message(val)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   189
            else:
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   190
                self.form[param] = val
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   191
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   192
    def relative_path(self, includeparams=True):
11925
b75fc687c730 [pyramid] use pyramid.request `path_info` property instead of `path`
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11824
diff changeset
   193
        path = self._request.path_info[1:]
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   194
        if includeparams and self._request.query_string:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   195
            return '%s?%s' % (path, self._request.query_string)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   196
        return path
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   197
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   198
    def instance_uri(self):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   199
        return self._request.application_url
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   200
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   201
    def get_full_path(self):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   202
        path = self._request.path
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   203
        if self._request.query_string:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   204
            return '%s?%s' % (path, self._request.query_string)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   205
        return path
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   206
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   207
    def http_method(self):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   208
        return self._request.method
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   209
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   210
    def _set_status_out(self, value):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   211
        self._request.response.status_int = value
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   212
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   213
    def _get_status_out(self):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   214
        return self._request.response.status_int
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   215
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   216
    status_out = property(_get_status_out, _set_status_out)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   217
11566
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   218
    @property
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   219
    def message(self):
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   220
        """Returns a '<br>' joined list of the cubicweb current message and the
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   221
        default pyramid flash queue messages.
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   222
        """
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   223
        return u'\n<br>\n'.join(
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   224
            self._request.session.pop_flash()
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   225
            + self._request.session.pop_flash('cubicweb'))
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   226
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   227
    def set_message(self, msg):
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   228
        self.reset_message()
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   229
        self._request.session.flash(msg, 'cubicweb')
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   230
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   231
    def set_message_id(self, msgid):
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   232
        self.reset_message()
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   233
        self.set_message(
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   234
            self._request.session.pop(msgid, u''))
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   235
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   236
    def reset_message(self):
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   237
        self._request.session.pop_flash('cubicweb')
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   238
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   239
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   240
def render_view(request, vid, **kwargs):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   241
    """ Helper function to render a CubicWeb view.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   242
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   243
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   244
    :param vid: A CubicWeb view id
11930
83a921bae21c [pkg] Fix some error on building documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11929
diff changeset
   245
    :param kwargs: Keyword arguments to select and instanciate the view
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   246
    :returns: The rendered view content
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   247
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   248
    vreg = request.registry['cubicweb.registry']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   249
    # XXX The select() function could, know how to handle a pyramid
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   250
    # request, and feed it directly to the views that supports it.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   251
    # On the other hand, we could refine the View concept and decide it works
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   252
    # with a cnx, and never with a WebRequest
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   253
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   254
    with cw_to_pyramid(request):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   255
        view = vreg['views'].select(vid, request.cw_request, **kwargs)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   256
        view.set_stream()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   257
        view.render()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   258
        return view._stream.getvalue()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   259
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   260
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   261
def _cw_cnx(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   262
    """ Obtains a cw session from a pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   263
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   264
    The connection will be commited or rolled-back in a request finish
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   265
    callback (this is temporary, we should make use of the transaction manager
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   266
    in a later version).
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   267
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   268
    Not meant for direct use, use ``request.cw_cnx`` instead.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   269
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   270
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   271
    :returns type: :class:`cubicweb.server.session.Connection`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   272
    """
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   273
    session = request.cw_session
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   274
    if session is None:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   275
        return None
11589
7079ba70c2a7 [core] Adjust cw<3.21 compatibility
Christophe de Vienne <christophe@unlish.com>
parents: 11580
diff changeset
   276
11686
41d4f0f3855c [pyramid] Drop guard of old cubicweb version
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
   277
    cnx = session.new_cnx()
11589
7079ba70c2a7 [core] Adjust cw<3.21 compatibility
Christophe de Vienne <christophe@unlish.com>
parents: 11580
diff changeset
   278
11686
41d4f0f3855c [pyramid] Drop guard of old cubicweb version
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
   279
    def commit_state(cnx):
41d4f0f3855c [pyramid] Drop guard of old cubicweb version
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
   280
        return cnx.commit_state
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   281
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   282
    def cleanup(request):
11580
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   283
        try:
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   284
            if (request.exception is not None and not isinstance(
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   285
                request.exception, (
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   286
                    httpexceptions.HTTPSuccessful,
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   287
                    httpexceptions.HTTPRedirection))):
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   288
                cnx.rollback()
11589
7079ba70c2a7 [core] Adjust cw<3.21 compatibility
Christophe de Vienne <christophe@unlish.com>
parents: 11580
diff changeset
   289
            elif commit_state(cnx) == 'uncommitable':
11580
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   290
                cnx.rollback()
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   291
            else:
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   292
                cnx.commit()
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   293
        finally:
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   294
            cnx.__exit__(None, None, None)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   295
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   296
    request.add_finished_callback(cleanup)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   297
    cnx.__enter__()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   298
    return cnx
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   299
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   300
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   301
def repo_connect(request, repo, eid):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   302
    """A lightweight version of
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   303
    :meth:`cubicweb.server.repository.Repository.connect` that does not keep
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   304
    track of opened sessions, removing the need of closing them"""
11824
d7ecf6dab085 Fix AttributeError for "lang" on repo/client connections
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   305
    user, lang = tools.cached_build_user(repo, eid)
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   306
    session = Session(request, user, repo)
11824
d7ecf6dab085 Fix AttributeError for "lang" on repo/client connections
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11811
diff changeset
   307
    session._cached_lang = lang
11552
d92a608c1a16 [core] Use tools.cached_user_build for better performances
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
   308
    tools.cnx_attach_entity(session, user)
11512
bb548010b390 Use lightweight sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11508
diff changeset
   309
    return session
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   310
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   311
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   312
def _cw_session(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   313
    """Obtains a cw session from a pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   314
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   315
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   316
    :returns type: :class:`cubicweb.server.session.Session`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   317
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   318
    Not meant for direct use, use ``request.cw_session`` instead.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   319
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   320
    repo = request.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   321
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   322
    if not request.authenticated_userid:
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   323
        eid = request.registry.get('cubicweb.anonymous_eid')
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   324
        if eid is None:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   325
            return None
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   326
        session = repo_connect(request, repo, eid=eid)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   327
    else:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   328
        session = request._cw_cached_session
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   329
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   330
    return session
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   331
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   332
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   333
def _cw_request(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   334
    """ Obtains a CubicWeb request wrapper for the pyramid request.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   335
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   336
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   337
    :return: A CubicWeb request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   338
    :returns type: :class:`CubicWebPyramidRequest`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   339
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   340
    Not meant for direct use, use ``request.cw_request`` instead.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   341
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   342
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   343
    req = CubicWebPyramidRequest(request)
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   344
    cnx = request.cw_cnx
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   345
    if cnx is not None:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   346
        req.set_cnx(request.cw_cnx)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   347
    return req
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   348
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   349
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   350
def get_principals(login, request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   351
    """ Returns the group names of the authenticated user.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   352
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   353
    This function is meant to be used as an authentication policy callback.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   354
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   355
    It also pre-open the cubicweb session and put it in
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   356
    request._cw_cached_session for later usage by :func:`_cw_session`.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   357
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   358
    .. note::
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   359
11622
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11589
diff changeset
   360
        If the default authentication policy is not used, make sure this
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   361
        function gets called by the active authentication policy.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   362
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   363
    :param login: A cubicweb user eid
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   364
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   365
    :returns: A list of group names
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   366
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   367
    repo = request.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   368
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   369
    try:
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   370
        session = repo_connect(request, repo, eid=login)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   371
        request._cw_cached_session = session
12225
a8ed10f80a85 [pyramid] Get rid of a couple of bare "except"
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12043
diff changeset
   372
    except Exception:
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   373
        log.exception("Failed")
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   374
        raise
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   375
11701
ca536eec556b [pyramid] Retrieve user's groups using a custom RQL instead of user's groups property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11686
diff changeset
   376
    with session.new_cnx() as cnx:
ca536eec556b [pyramid] Retrieve user's groups using a custom RQL instead of user's groups property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11686
diff changeset
   377
        with cnx.security_enabled(read=False):
ca536eec556b [pyramid] Retrieve user's groups using a custom RQL instead of user's groups property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11686
diff changeset
   378
            return set(group for group, in cnx.execute(
ca536eec556b [pyramid] Retrieve user's groups using a custom RQL instead of user's groups property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11686
diff changeset
   379
                'Any GN WHERE U in_group G, G name GN, U eid %(userid)s',
ca536eec556b [pyramid] Retrieve user's groups using a custom RQL instead of user's groups property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11686
diff changeset
   380
                {'userid': login}))
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   381
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   382
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   383
def includeme(config):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   384
    """ Enables the core features of Pyramid CubicWeb.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   385
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   386
    Automatically called by the 'pyramid' command, or via
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11630
diff changeset
   387
    ``config.include('cubicweb.pyramid.code')``. In the later case,
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   388
    the following registry entries must be defined first:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   389
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   390
    'cubicweb.config'
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   391
        A cubicweb 'config' instance.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   392
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   393
    'cubicweb.repository'
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   394
        The correponding cubicweb repository.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   395
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   396
    'cubicweb.registry'
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   397
        The vreg.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   398
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   399
    repo = config.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   400
11513
0170f8a55620 Optimise repo_connect by skipping authenticate_user
Christophe de Vienne <christophe@unlish.com>
parents: 11512
diff changeset
   401
    with repo.internal_cnx() as cnx:
0170f8a55620 Optimise repo_connect by skipping authenticate_user
Christophe de Vienne <christophe@unlish.com>
parents: 11512
diff changeset
   402
        login = config.registry['cubicweb.config'].anonymous_user()[0]
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   403
        if login is not None:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   404
            config.registry['cubicweb.anonymous_eid'] = cnx.find(
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   405
                'CWUser', login=login).one().eid
11513
0170f8a55620 Optimise repo_connect by skipping authenticate_user
Christophe de Vienne <christophe@unlish.com>
parents: 11512
diff changeset
   406
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   407
    config.add_request_method(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   408
        _cw_session, name='cw_session', property=True, reify=True)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   409
    config.add_request_method(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   410
        _cw_cnx, name='cw_cnx', property=True, reify=True)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   411
    config.add_request_method(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   412
        _cw_request, name='cw_request', property=True, reify=True)
11502
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   413
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   414
    cwcfg = config.registry['cubicweb.config']
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   415
    for cube in cwcfg.cubes():
12349
7e670235174f Fix possible double import of cubes
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   416
        try:
7e670235174f Fix possible double import of cubes
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   417
            pkgname = 'cubicweb_{}'.format(cube)
7e670235174f Fix possible double import of cubes
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   418
            mod = __import__(pkgname)
7e670235174f Fix possible double import of cubes
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   419
        except ImportError:
7e670235174f Fix possible double import of cubes
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   420
            pkgname = 'cubes.{}'.format(cube)
7e670235174f Fix possible double import of cubes
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   421
            mod = __import__(pkgname)
7e670235174f Fix possible double import of cubes
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   422
            mod = getattr(mod, cube)
11502
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   423
        if hasattr(mod, 'includeme'):
12349
7e670235174f Fix possible double import of cubes
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12225
diff changeset
   424
            config.include(pkgname)