cubicweb/pyramid/core.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Tue, 21 Feb 2017 08:54:20 +0100
changeset 11968 bb0dfc7d2d0e
parent 11967 83739be20fab
child 12028 08c866d2f11d
permissions -rw-r--r--
[skeleton,pyramid] Move pyramid app definition in cubicweb.pyramid module The application definition is actually not specific to the final "cube" being bootstrapped from skeleton. This patch thus move the pyramid application function into cubicweb.pyramid module and let cubicweb register the "paste.app_factory" entry point (instead of the bootstrapped cube). Useless call to `config.scan` is dropped along the way.
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):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    55
        super(Connection, self).__init__(session, *args, **kw)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
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):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    60
        return self._session.data
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
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    68
class Session(cwsession.Session):
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
        super(Session, self).__init__(user, repo)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    76
        self._pyramid_request = pyramid_request
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    77
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    78
    def get_data(self):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    79
        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
    80
            self._data_accessed = True
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    81
            return self._pyramid_request.session
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    82
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    83
    def set_data(self, data):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    84
        if getattr(self, '_data_accessed', False):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    85
            self._pyramid_request.session.clear()
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    86
            self._pyramid_request.session.update(data)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    87
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    88
    data = property(get_data, set_data)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    89
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    90
    def new_cnx(self):
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    91
        self._protect_data_access = True
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    92
        try:
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    93
            return Connection(self)
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    94
        finally:
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    95
            self._protect_data_access = False
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    96
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
    97
11556
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
    98
def cw_headers(request):
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
    99
    return itertools.chain(
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   100
        *[[(k, item) for item in v]
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   101
          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
   102
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   103
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   104
@contextmanager
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   105
def cw_to_pyramid(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   106
    """ 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
   107
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   108
    All CW exceptions will be transformed into their pyramid equivalent.
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   109
    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
   110
    try:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   111
        yield
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   112
    except cubicweb.web.Redirect as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   113
        assert 300 <= ex.status < 400
11556
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   114
        raise httpexceptions.status_map[ex.status](
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   115
            ex.location, headers=cw_headers(request))
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   116
    except cubicweb.web.StatusResponse as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   117
        warn('[3.16] StatusResponse is deprecated use req.status_out',
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   118
             DeprecationWarning, stacklevel=2)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   119
        request.body = ex.content
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   120
        request.status_int = ex.status
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   121
    except cubicweb.web.Unauthorized as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   122
        raise httpexceptions.HTTPForbidden(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   123
            request.cw_request._(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   124
                'You\'re not authorized to access this page. '
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   125
                '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
   126
                'administrator.'),
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   127
            headers=cw_headers(request))
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   128
    except cubicweb.web.Forbidden:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   129
        raise httpexceptions.HTTPForbidden(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   130
            request.cw_request._(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   131
                'This action is forbidden. '
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   132
                '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
   133
                'administrator.'),
1eeba41a2e95 On exceptions from CW, copy headers
Christophe de Vienne <christophe@unlish.com>
parents: 11553
diff changeset
   134
            headers=cw_headers(request))
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   135
    except (rql.BadRQLQuery, cubicweb.web.RequestError) as ex:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   136
        raise
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   137
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   138
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   139
class CubicWebPyramidRequest(CubicWebRequestBase):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   140
    """ A CubicWeb request that only wraps a pyramid request.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   141
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   142
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   143
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   144
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   145
    def __init__(self, request):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   146
        self._request = request
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   147
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   148
        self.path = request.upath_info
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   149
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
   150
        vreg = request.registry['cubicweb.registry']
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   151
11504
8701caf9edf0 Correctly pass the multiple parameters to the cubicweb request
Christophe de Vienne <christophe@unlish.com>
parents: 11502
diff changeset
   152
        post = request.params.mixed()
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   153
        headers_in = request.headers
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   154
11913
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   155
        super(CubicWebPyramidRequest, self).__init__(vreg, post,
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   156
                                                     headers=headers_in)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   157
11508
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   158
        self.content = request.body_file_seekable
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   159
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   160
    def setup_params(self, params):
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   161
        self.form = {}
11630
1400aee10df4 Port to Python3 (closes #14159555)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11622
diff changeset
   162
        for param, val in params.items():
11508
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   163
            if param in self.no_script_form_params and val:
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   164
                val = self.no_script_form_param(param, val)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   165
            if isinstance(val, FieldStorage) and val.file:
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   166
                val = (val.filename, val.file)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   167
            if param == '_cwmsgid':
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   168
                self.set_message_id(val)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   169
            elif param == '__message':
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   170
                warn('[3.13] __message in request parameter is deprecated '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   171
                     '(may only be given to .build_url). Seeing this message '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   172
                     'usualy means your application hold some <form> where '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   173
                     'you should replace use of __message hidden input by '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   174
                     'form.set_message, so new _cwmsgid mechanism is properly '
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   175
                     'used',
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   176
                     DeprecationWarning)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   177
                self.set_message(val)
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   178
            else:
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   179
                self.form[param] = val
ef8b9021b47b Fix POST handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11504
diff changeset
   180
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   181
    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
   182
        path = self._request.path_info[1:]
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   183
        if includeparams and self._request.query_string:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   184
            return '%s?%s' % (path, self._request.query_string)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   185
        return path
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   186
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   187
    def instance_uri(self):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   188
        return self._request.application_url
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   189
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   190
    def get_full_path(self):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   191
        path = self._request.path
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   192
        if self._request.query_string:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   193
            return '%s?%s' % (path, self._request.query_string)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   194
        return path
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   195
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   196
    def http_method(self):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   197
        return self._request.method
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   198
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   199
    def _set_status_out(self, value):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   200
        self._request.response.status_int = value
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   201
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   202
    def _get_status_out(self):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   203
        return self._request.response.status_int
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   204
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   205
    status_out = property(_get_status_out, _set_status_out)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   206
11566
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   207
    @property
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   208
    def message(self):
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   209
        """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
   210
        default pyramid flash queue messages.
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   211
        """
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   212
        return u'\n<br>\n'.join(
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   213
            self._request.session.pop_flash()
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   214
            + self._request.session.pop_flash('cubicweb'))
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   215
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   216
    def set_message(self, msg):
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   217
        self.reset_message()
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   218
        self._request.session.flash(msg, 'cubicweb')
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   219
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   220
    def set_message_id(self, msgid):
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   221
        self.reset_message()
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   222
        self.set_message(
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   223
            self._request.session.pop(msgid, u''))
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   224
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   225
    def reset_message(self):
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   226
        self._request.session.pop_flash('cubicweb')
59548227ecc9 Use pyramid flash queue for messages
Christophe de Vienne <christophe@unlish.com>
parents: 11560
diff changeset
   227
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   228
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   229
def render_view(request, vid, **kwargs):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   230
    """ Helper function to render a CubicWeb view.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   231
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   232
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   233
    :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
   234
    :param kwargs: Keyword arguments to select and instanciate the view
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   235
    :returns: The rendered view content
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   236
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   237
    vreg = request.registry['cubicweb.registry']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   238
    # 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
   239
    # 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
   240
    # 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
   241
    # with a cnx, and never with a WebRequest
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   242
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   243
    with cw_to_pyramid(request):
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   244
        view = vreg['views'].select(vid, request.cw_request, **kwargs)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   245
        view.set_stream()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   246
        view.render()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   247
        return view._stream.getvalue()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   248
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   249
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   250
def _cw_cnx(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   251
    """ Obtains a cw session from a pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   252
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   253
    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
   254
    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
   255
    in a later version).
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   256
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   257
    Not meant for direct use, use ``request.cw_cnx`` instead.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   258
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   259
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   260
    :returns type: :class:`cubicweb.server.session.Connection`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   261
    """
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   262
    session = request.cw_session
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   263
    if session is None:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   264
        return None
11589
7079ba70c2a7 [core] Adjust cw<3.21 compatibility
Christophe de Vienne <christophe@unlish.com>
parents: 11580
diff changeset
   265
11686
41d4f0f3855c [pyramid] Drop guard of old cubicweb version
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
   266
    cnx = session.new_cnx()
11589
7079ba70c2a7 [core] Adjust cw<3.21 compatibility
Christophe de Vienne <christophe@unlish.com>
parents: 11580
diff changeset
   267
11686
41d4f0f3855c [pyramid] Drop guard of old cubicweb version
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
   268
    def commit_state(cnx):
41d4f0f3855c [pyramid] Drop guard of old cubicweb version
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
   269
        return cnx.commit_state
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   270
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   271
    def cleanup(request):
11580
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   272
        try:
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   273
            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
   274
                request.exception, (
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   275
                    httpexceptions.HTTPSuccessful,
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   276
                    httpexceptions.HTTPRedirection))):
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   277
                cnx.rollback()
11589
7079ba70c2a7 [core] Adjust cw<3.21 compatibility
Christophe de Vienne <christophe@unlish.com>
parents: 11580
diff changeset
   278
            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
   279
                cnx.rollback()
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   280
            else:
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   281
                cnx.commit()
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   282
        finally:
e8f8a211e503 [core] adjust cnx handling for cubicweb 3.21
Julien Cristau <julien.cristau@logilab.fr>
parents: 11575
diff changeset
   283
            cnx.__exit__(None, None, None)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   284
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   285
    request.add_finished_callback(cleanup)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   286
    cnx.__enter__()
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   287
    return cnx
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   288
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   289
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   290
def repo_connect(request, repo, eid):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   291
    """A lightweight version of
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   292
    :meth:`cubicweb.server.repository.Repository.connect` that does not keep
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   293
    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
   294
    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
   295
    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
   296
    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
   297
    tools.cnx_attach_entity(session, user)
11512
bb548010b390 Use lightweight sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11508
diff changeset
   298
    # Calling the hooks should be done only once, disabling it completely for
bb548010b390 Use lightweight sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11508
diff changeset
   299
    # now
11811
f09efeead7f9 Fix broken flake8 configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11701
diff changeset
   300
    # with session.new_cnx() as cnx:
f09efeead7f9 Fix broken flake8 configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11701
diff changeset
   301
    #     repo.hm.call_hooks('session_open', cnx)
f09efeead7f9 Fix broken flake8 configuration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11701
diff changeset
   302
    #     cnx.commit()
11512
bb548010b390 Use lightweight sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11508
diff changeset
   303
    # repo._sessions[session.sessionid] = session
bb548010b390 Use lightweight sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11508
diff changeset
   304
    return session
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   305
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   306
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   307
def _cw_session(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   308
    """Obtains a cw session from a pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   309
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   310
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   311
    :returns type: :class:`cubicweb.server.session.Session`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   312
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   313
    Not meant for direct use, use ``request.cw_session`` instead.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   314
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   315
    repo = request.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   316
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   317
    if not request.authenticated_userid:
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   318
        eid = request.registry.get('cubicweb.anonymous_eid')
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   319
        if eid is None:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   320
            return None
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   321
        session = repo_connect(request, repo, eid=eid)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   322
    else:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   323
        session = request._cw_cached_session
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   324
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   325
    return session
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   326
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   327
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   328
def _cw_request(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   329
    """ Obtains a CubicWeb request wrapper for the pyramid request.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   330
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   331
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   332
    :return: A CubicWeb request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   333
    :returns type: :class:`CubicWebPyramidRequest`
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   334
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   335
    Not meant for direct use, use ``request.cw_request`` instead.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   336
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   337
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   338
    req = CubicWebPyramidRequest(request)
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   339
    cnx = request.cw_cnx
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   340
    if cnx is not None:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   341
        req.set_cnx(request.cw_cnx)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   342
    return req
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   343
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   344
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   345
def get_principals(login, request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   346
    """ Returns the group names of the authenticated user.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   347
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   348
    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
   349
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   350
    It also pre-open the cubicweb session and put it in
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   351
    request._cw_cached_session for later usage by :func:`_cw_session`.
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
    .. note::
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   354
11622
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11589
diff changeset
   355
        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
   356
        function gets called by the active authentication policy.
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
    :param login: A cubicweb user eid
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   359
    :param request: A pyramid request
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   360
    :returns: A list of group names
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   361
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   362
    repo = request.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   363
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   364
    try:
11553
a322a02ca301 [core] Protect session data from unwanted loading.
Christophe de Vienne <christophe@unlish.com>
parents: 11552
diff changeset
   365
        session = repo_connect(request, repo, eid=login)
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   366
        request._cw_cached_session = session
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   367
    except:
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   368
        log.exception("Failed")
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   369
        raise
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   370
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
   371
    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
   372
        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
   373
            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
   374
                '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
   375
                {'userid': login}))
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   376
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   377
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   378
def includeme(config):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   379
    """ Enables the core features of Pyramid CubicWeb.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   380
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   381
    Automatically called by the 'pyramid' command, or via
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11630
diff changeset
   382
    ``config.include('cubicweb.pyramid.code')``. In the later case,
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   383
    the following registry entries must be defined first:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   384
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   385
    'cubicweb.config'
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   386
        A cubicweb 'config' instance.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   387
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   388
    'cubicweb.repository'
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   389
        The correponding cubicweb repository.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   390
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   391
    'cubicweb.registry'
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   392
        The vreg.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11536
diff changeset
   393
    """
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   394
    repo = config.registry['cubicweb.repository']
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   395
11513
0170f8a55620 Optimise repo_connect by skipping authenticate_user
Christophe de Vienne <christophe@unlish.com>
parents: 11512
diff changeset
   396
    with repo.internal_cnx() as cnx:
0170f8a55620 Optimise repo_connect by skipping authenticate_user
Christophe de Vienne <christophe@unlish.com>
parents: 11512
diff changeset
   397
        login = config.registry['cubicweb.config'].anonymous_user()[0]
11575
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   398
        if login is not None:
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   399
            config.registry['cubicweb.anonymous_eid'] = cnx.find(
97110b4af42f Handle absence of anonymous user
Denis Laxalde <denis@laxalde.org>
parents: 11568
diff changeset
   400
                'CWUser', login=login).one().eid
11513
0170f8a55620 Optimise repo_connect by skipping authenticate_user
Christophe de Vienne <christophe@unlish.com>
parents: 11512
diff changeset
   401
11492
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   402
    config.add_request_method(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   403
        _cw_session, name='cw_session', property=True, reify=True)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   404
    config.add_request_method(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   405
        _cw_cnx, name='cw_cnx', property=True, reify=True)
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   406
    config.add_request_method(
b0b8942cdb80 Separate into 4 modules
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   407
        _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
   408
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   409
    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
   410
    for cube in cwcfg.cubes():
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   411
        pkgname = 'cubes.' + cube
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   412
        mod = __import__(pkgname)
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   413
        mod = getattr(mod, cube)
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   414
        if hasattr(mod, 'includeme'):
e4682c567e86 If any cube has a 'includeme' attribute, call config.include on it
Christophe de Vienne <christophe@unlish.com>
parents: 11500
diff changeset
   415
            config.include('cubes.' + cube)