pyramid_cubicweb/__init__.py
author Christophe de Vienne <christophe@unlish.com>
Sun, 06 Jul 2014 18:06:10 +0200
changeset 11482 151b8a4b9f3f
parent 11480 79ac26923432
child 11484 39768d122f97
permissions -rw-r--r--
Integration pyramid and cubicweb authentication. We use pyramid sessions to store the cubicweb sessionid so we can reuse it when needed, or regenerate it if it was lost. The cubicweb sessionid is obtained from a login in the repo OR directly from the user identified by pyramid. Related to #4291173
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     1
from cubicweb.web.request import CubicWebRequestBase
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     2
from cubicweb.cwconfig import CubicWebConfiguration
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     3
from cubicweb.web.application import CubicWebPublisher
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
     4
from cubicweb import repoapi
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
     5
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
     6
import cubicweb
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
     7
import cubicweb.web
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
     8
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
     9
from pyramid import security
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    10
from pyramid.httpexceptions import HTTPSeeOther
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    11
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    12
from pyramid_cubicweb import authplugin
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    13
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    14
import weakref
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
import logging
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
log = logging.getLogger(__name__)
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    19
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    20
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    21
class CubicWebPyramidRequest(CubicWebRequestBase):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    22
    def __init__(self, request):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    23
        self._request = request
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    24
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    25
        self.path = request.upath_info
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    26
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    27
        vreg = request.registry['cubicweb.appli'].vreg
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    28
        https = request.scheme == 'https'
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    29
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    30
        post = request.params
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    31
        headers_in = request.headers
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    32
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    33
        super(CubicWebPyramidRequest, self).__init__(vreg, https, post,
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    34
                                                     headers=headers_in)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    35
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    36
    def is_secure(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    37
        return self._request.scheme == 'https'
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    38
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    39
    def relative_path(self, includeparams=True):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    40
        path = self._request.path[1:]
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    41
        if includeparams and self._request.query_string:
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    42
            return '%s?%s' % (path, self._request.query_string)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    43
        return path
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    44
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    45
    def instance_uri(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    46
        return self._request.application_url
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    47
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    48
    def get_full_path(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    49
        path = self._request.path
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    50
        if self._request.query_string:
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    51
            return '%s?%s' % (path, self._request.query_string)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    52
        return path
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    53
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    54
    def http_method(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    55
        return self._request.method
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    56
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    57
    def _set_status_out(self, value):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    58
        self._request.response.status_int = value
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    59
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    60
    def _get_status_out(self):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    61
        return self._request.response.status_int
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    62
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    63
    status_out = property(_get_status_out, _set_status_out)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    64
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    65
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    66
class PyramidSessionHandler(object):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    67
    """A CW Session handler that rely on the pyramid API to fetch the needed
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    68
    informations"""
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    69
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    70
    def __init__(self, appli):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    71
        self.appli = appli
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    72
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    73
    def get_session(self, req):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    74
        return req._request.cw_session
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    75
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    76
    def logout(self, req, goto_url):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    77
        del req._request.session['cubicweb.sessionid']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    78
        if not req.session.closed:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    79
            req.session.repo.close(req.session.sessionid)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    80
        for name, value in security.forget(req._request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    81
            req.headers_out.setHeader(name, value)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    82
        raise cubicweb.web.LogOut(url=goto_url)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    83
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    84
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    85
def render_view(request, vid, **kwargs):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    86
    vreg = request.registry['cubicweb.registry']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    87
    # 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
    88
    # 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
    89
    # 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
    90
    # with a cnx, and never with a WebRequest
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    91
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    92
    view = vreg['views'].select(vid, request.cw_request(), **kwargs)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    93
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    94
    view.set_stream()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    95
    view.render()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    96
    return view._stream.getvalue()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    97
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    98
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
    99
def login(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   100
    repo = request.registry['cubicweb.repository']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   101
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   102
    response = request.response
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   103
    userid = None
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   104
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   105
    if '__login' in request.params:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   106
        login = request.params['__login']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   107
        password = request.params['__password']
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   108
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   109
        try:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   110
            sessionid = repo.connect(login, password=password)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   111
            request.session['cubicweb.sessionid'] = sessionid
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   112
            session = repo._sessions[sessionid]
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   113
            userid = session.user.eid
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   114
        except cubicweb.AuthenticationError:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   115
            raise
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
    if userid is not None:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   118
        headers = security.remember(request, userid)
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 'postlogin_path' in request.params:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   121
            raise HTTPSeeOther(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   122
                request.params['postlogin_path'],
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   123
                headers=headers)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   124
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   125
        response.headerlist.extend(headers)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   126
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   127
    response.text = render_view(request, 'login')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   128
    return response
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   129
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   130
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   131
class CubicWebPyramidHandler(object):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   132
    def __init__(self, appli):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   133
        self.appli = appli
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   134
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   135
    def __call__(self, request):
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   136
        req = request.cw_request()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   137
        result = self.appli.handle_request(req, req.path)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   138
        if result is not None:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   139
            request.response.body = result
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   140
        request.response.headers.clear()
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   141
        for k, v in req.headers_out.getAllRawHeaders():
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   142
            for item in v:
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   143
                request.response.headers.add(k, item)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   144
        return request.response
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   145
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   146
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   147
def _cw_cnx(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   148
    # XXX We should not need to use the session. A temporary one should be
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   149
    # enough. (by using repoapi.connect())
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   150
    cnx = repoapi.ClientConnection(request.cw_session)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   151
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   152
    def cleanup(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   153
        if request.exception is not None:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   154
            cnx.rollback()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   155
        else:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   156
            cnx.commit()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   157
        cnx.__exit__(None, None, None)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   158
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   159
    request.add_finished_callback(cleanup)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   160
    cnx.__enter__()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   161
    return cnx
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   162
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   163
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   164
def _cw_session(request):
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
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   168
    sessionid = request.session.get('cubicweb.sessionid')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   169
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   170
    if sessionid not in repo._sessions:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   171
        if not request.authenticated_userid:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   172
            login, password = config.anonymous_user()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   173
            sessionid = repo.connect(login, password=password)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   174
            request.session['cubicweb.sessionid'] = sessionid
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   175
        else:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   176
            sessionid = request.session.get('cubicweb.sessionid')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   177
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   178
    return repo._sessions[sessionid]
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   179
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   180
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   181
def _cw_request(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   182
    return weakref.ref(CubicWebPyramidRequest(request))
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   183
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   184
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   185
def get_principals(userid, request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   186
    repo = request.registry['cubicweb.repository']
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
    sessionid = request.session.get('cubicweb.sessionid')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   189
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   190
    if sessionid is None or sessionid not in repo._sessions:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   191
        try:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   192
            sessionid = repo.connect(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   193
                str(userid), __pyramid_directauth=authplugin.EXT_TOKEN)
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   194
        except:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   195
            log.exception("Failed")
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   196
            raise
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   197
        request.session['cubicweb.sessionid'] = sessionid
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   198
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   199
    #session = repo._session[sessionid]
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   200
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   201
    with repo.internal_cnx() as cnx:
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   202
        groupnames = [r[1] for r in cnx.execute(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   203
            'Any X, N WHERE X is CWGroup, X name N, '
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   204
            'U in_group X, U eid %(userid)s',
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   205
            {'userid': userid})]
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   206
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   207
    return groupnames
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
from pyramid.authentication import SessionAuthenticationPolicy
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   211
from pyramid.authorization import ACLAuthorizationPolicy
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   212
from pyramid.session import SignedCookieSessionFactory
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   213
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
def hello_world(request):
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   216
    request.response.text = \
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   217
        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
   218
    return request.response
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   219
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   220
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   221
def includeme(config):
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   222
    appid = config.registry.settings['cubicweb.instance']
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   223
    cwconfig = CubicWebConfiguration.config_for(appid)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   224
11482
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   225
    config.set_session_factory(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   226
        SignedCookieSessionFactory(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   227
            secret=config.registry.settings['session.secret']
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
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   230
    config.set_authentication_policy(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   231
        SessionAuthenticationPolicy(callback=get_principals))
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   232
    config.set_authorization_policy(ACLAuthorizationPolicy())
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   233
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   234
    config.registry['cubicweb.config'] = cwconfig
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   235
    config.registry['cubicweb.repository'] = repo = cwconfig.repository()
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   236
    config.registry['cubicweb.registry'] = repo.vreg
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   237
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   238
    repo.system_source.add_authentifier(authplugin.DirectAuthentifier())
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   239
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   240
    config.add_request_method(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   241
        _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
   242
    config.add_request_method(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   243
        _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
   244
    config.add_request_method(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   245
        _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
   246
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   247
    config.add_route('login', '/login')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   248
    config.add_view(login, route_name='login')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   249
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   250
    config.add_route('hello', '/hello')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   251
    config.add_view(hello_world, route_name='hello')
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   252
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   253
    # Set up a defaut route to handle non-catched urls.
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   254
    # This is to keep legacy compatibility for cubes that makes use of the
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   255
    # cubicweb controllers.
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   256
    cwappli = CubicWebPublisher(
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   257
        cwconfig.repository(), cwconfig,
151b8a4b9f3f Integration pyramid and cubicweb authentication.
Christophe de Vienne <christophe@unlish.com>
parents: 11480
diff changeset
   258
        session_handler_fact=PyramidSessionHandler)
11480
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   259
    handler = CubicWebPyramidHandler(cwappli)
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   260
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   261
    config.registry['cubicweb.appli'] = cwappli
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   262
    config.registry['cubicweb.handler'] = handler
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   263
79ac26923432 Initial implementation
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   264
    config.add_notfound_view(handler)