pyramid_cubicweb/__init__.py
author Christophe de Vienne <christophe@unlish.com>
Tue, 15 Jul 2014 18:25:48 +0200
changeset 11489 433fd3af7386
parent 11487 04252e9ff549
child 11492 b0b8942cdb80
permissions -rw-r--r--
Use the pyramid session object as the cubiweb session.data (needs a patched cw 3.19) Related to #4291173
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11487
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
     1
from contextlib import contextmanager
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
     2
from warnings import warn
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
     3
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
     4
import rql
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
     5
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     6
from cubicweb.web.request import CubicWebRequestBase
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     7
from cubicweb.cwconfig import CubicWebConfiguration
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
     8
from cubicweb import repoapi
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
     9
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    10
import cubicweb
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    11
import cubicweb.web
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    12
11487
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    13
from pyramid import security, httpexceptions
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    14
from pyramid.httpexceptions import HTTPSeeOther
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    15
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    16
from pyramid_cubicweb import authplugin
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    17
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    18
import logging
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    19
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    20
log = logging.getLogger(__name__)
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    21
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    22
11487
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    23
@contextmanager
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    24
def cw_to_pyramid(request):
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    25
    """Wrap a call to the cubicweb API.
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    26
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    27
    All CW exceptions will be transformed into their pyramid equivalent.
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    28
    When needed, some CW reponse bits may be converted too (mainly headers)"""
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    29
    try:
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    30
        yield
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    31
    except cubicweb.web.Redirect as ex:
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    32
        assert 300 <= ex.status < 400
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    33
        raise httpexceptions.status_map[ex.status](ex.location)
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    34
    except cubicweb.web.StatusResponse as ex:
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    35
        warn('[3.16] StatusResponse is deprecated use req.status_out',
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    36
             DeprecationWarning, stacklevel=2)
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    37
        request.body = ex.content
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    38
        request.status_int = ex.status
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    39
    except cubicweb.web.Unauthorized as ex:
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    40
        raise httpexceptions.HTTPForbidden(
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    41
            request.cw_request._(
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    42
                'You\'re not authorized to access this page. '
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    43
                'If you think you should, please contact the site '
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    44
                'administrator.'))
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    45
    except cubicweb.web.Forbidden:
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    46
        raise httpexceptions.HTTPForbidden(
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    47
            request.cw_request._(
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    48
                'This action is forbidden. '
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    49
                'If you think it should be allowed, please contact the site '
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    50
                'administrator.'))
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    51
    except (rql.BadRQLQuery, cubicweb.web.RequestError) as ex:
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    52
        raise
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    53
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
    54
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    55
class CubicWebPyramidRequest(CubicWebRequestBase):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    56
    def __init__(self, request):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    57
        self._request = request
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    58
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    59
        self.path = request.upath_info
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    60
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    61
        vreg = request.registry['cubicweb.appli'].vreg
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    62
        https = request.scheme == 'https'
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    63
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    64
        post = request.params
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    65
        headers_in = request.headers
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    66
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    67
        super(CubicWebPyramidRequest, self).__init__(vreg, https, post,
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    68
                                                     headers=headers_in)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    69
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    70
    def is_secure(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    71
        return self._request.scheme == 'https'
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    72
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    73
    def relative_path(self, includeparams=True):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    74
        path = self._request.path[1:]
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    75
        if includeparams and self._request.query_string:
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    76
            return '%s?%s' % (path, self._request.query_string)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    77
        return path
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    78
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    79
    def instance_uri(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    80
        return self._request.application_url
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    81
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    82
    def get_full_path(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    83
        path = self._request.path
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    84
        if self._request.query_string:
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    85
            return '%s?%s' % (path, self._request.query_string)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    86
        return path
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    87
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    88
    def http_method(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    89
        return self._request.method
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    90
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    91
    def _set_status_out(self, value):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    92
        self._request.response.status_int = value
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    93
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    94
    def _get_status_out(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    95
        return self._request.response.status_int
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    96
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    97
    status_out = property(_get_status_out, _set_status_out)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    98
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    99
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   100
def render_view(request, vid, **kwargs):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   101
    vreg = request.registry['cubicweb.registry']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   102
    # XXX The select() function could, know how to handle a pyramid
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   103
    # request, and feed it directly to the views that supports it.
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   104
    # On the other hand, we could refine the View concept and decide it works
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   105
    # with a cnx, and never with a WebRequest
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   106
11487
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
   107
    with cw_to_pyramid(request):
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
   108
        view = vreg['views'].select(vid, request.cw_request, **kwargs)
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
   109
        view.set_stream()
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
   110
        view.render()
04252e9ff549 Skip core_handle, add a context manager to handle cubicweb errors
Christophe de Vienne <christophe@unlish.com>
parents: 11485
diff changeset
   111
        return view._stream.getvalue()
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   112
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   113
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   114
def login(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   115
    repo = request.registry['cubicweb.repository']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   116
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   117
    response = request.response
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   118
    user_eid = None
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   119
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   120
    if '__login' in request.params:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   121
        login = request.params['__login']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   122
        password = request.params['__password']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   123
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   124
        try:
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   125
            with repo.internal_cnx() as cnx:
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   126
                user = repo.authenticate_user(cnx, login, password=password)
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   127
                user_eid = user.eid
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   128
        except cubicweb.AuthenticationError:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   129
            raise
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   130
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   131
    if user_eid is not None:
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   132
        headers = security.remember(request, user_eid)
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   133
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   134
        raise HTTPSeeOther(
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   135
            request.params.get('postlogin_path', '/'),
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   136
            headers=headers)
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   137
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   138
        response.headerlist.extend(headers)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   139
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   140
    response.text = render_view(request, 'login')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   141
    return response
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   142
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   143
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   144
def _cw_cnx(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   145
    cnx = repoapi.ClientConnection(request.cw_session)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   146
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   147
    def cleanup(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   148
        if request.exception is not None:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   149
            cnx.rollback()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   150
        else:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   151
            cnx.commit()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   152
        cnx.__exit__(None, None, None)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   153
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   154
    request.add_finished_callback(cleanup)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   155
    cnx.__enter__()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   156
    return cnx
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   157
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   158
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   159
def _cw_close_session(request):
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   160
    request.cw_session.close()
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   161
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   162
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   163
def _cw_session(request):
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   164
    """Obtains a cw session from a pyramid request"""
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   165
    repo = request.registry['cubicweb.repository']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   166
    config = request.registry['cubicweb.config']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   167
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   168
    if not request.authenticated_userid:
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   169
        login, password = config.anonymous_user()
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   170
        sessionid = repo.connect(login, password=password)
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   171
        session = repo._sessions[sessionid]
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   172
        request.add_finished_callback(_cw_close_session)
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   173
    else:
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   174
        session = request._cw_cached_session
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   175
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   176
    # XXX Ideally we store the cw session data in the pyramid session.
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   177
    # BUT some data in the cw session data dictionnary makes pyramid fail.
11489
433fd3af7386 Use the pyramid session object as the cubiweb session.data (needs a patched cw 3.19)
Christophe de Vienne <christophe@unlish.com>
parents: 11487
diff changeset
   178
    session.data = request.session
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   179
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   180
    return session
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   181
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   182
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   183
def _cw_request(request):
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   184
    req = CubicWebPyramidRequest(request)
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   185
    req.set_cnx(request.cw_cnx)
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   186
    return req
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   187
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   188
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   189
def get_principals(login, request):
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   190
    repo = request.registry['cubicweb.repository']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   191
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   192
    try:
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   193
        sessionid = repo.connect(
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   194
            str(login), __pyramid_directauth=authplugin.EXT_TOKEN)
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   195
        session = repo._sessions[sessionid]
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   196
        request._cw_cached_session = session
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   197
        request.add_finished_callback(_cw_close_session)
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   198
    except:
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   199
        log.exception("Failed")
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   200
        raise
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   201
11485
3905c9f06d0e Use short-lived cubicweb sessions to let pyramid actually handle the web sessions
Christophe de Vienne <christophe@unlish.com>
parents: 11484
diff changeset
   202
    return session.user.groups
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   203
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   204
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   205
from pyramid.authentication import SessionAuthenticationPolicy
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   206
from pyramid.authorization import ACLAuthorizationPolicy
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   207
from pyramid.session import SignedCookieSessionFactory
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   208
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   209
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   210
def hello_world(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   211
    request.response.text = \
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   212
        u"<html><body>Hello %s</body></html>" % request.cw_cnx.user.login
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   213
    return request.response
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   214
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   215
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   216
def includeme(config):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   217
    appid = config.registry.settings['cubicweb.instance']
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   218
    cwconfig = CubicWebConfiguration.config_for(appid)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   219
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   220
    config.set_session_factory(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   221
        SignedCookieSessionFactory(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   222
            secret=config.registry.settings['session.secret']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   223
        ))
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   224
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   225
    config.set_authentication_policy(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   226
        SessionAuthenticationPolicy(callback=get_principals))
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   227
    config.set_authorization_policy(ACLAuthorizationPolicy())
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   228
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   229
    config.registry['cubicweb.config'] = cwconfig
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   230
    config.registry['cubicweb.repository'] = repo = cwconfig.repository()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   231
    config.registry['cubicweb.registry'] = repo.vreg
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   232
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   233
    repo.system_source.add_authentifier(authplugin.DirectAuthentifier())
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   234
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   235
    config.add_request_method(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   236
        _cw_session, name='cw_session', property=True, reify=True)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   237
    config.add_request_method(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   238
        _cw_cnx, name='cw_cnx', property=True, reify=True)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   239
    config.add_request_method(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   240
        _cw_request, name='cw_request', property=True, reify=True)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   241
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   242
    config.add_route('login', '/login')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   243
    config.add_view(login, route_name='login')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   244
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   245
    config.add_route('hello', '/hello')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   246
    config.add_view(hello_world, route_name='hello')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   247
11484
39768d122f97 Isolate the default handler and extend its role
Christophe de Vienne <christophe@unlish.com>
parents: 11482
diff changeset
   248
    config.include('pyramid_cubicweb.handler')