|
1 from pyramid import security |
|
2 from pyramid.httpexceptions import HTTPSeeOther |
|
3 |
|
4 from cubicweb.web.application import CubicWebPublisher |
|
5 |
|
6 from cubicweb.web import ( |
|
7 StatusResponse, DirectResponse, Redirect, NotFound, LogOut, |
|
8 RemoteCallFailed, InvalidSession, RequestError, PublishException) |
|
9 |
|
10 |
|
11 class PyramidSessionHandler(object): |
|
12 """A CW Session handler that rely on the pyramid API to fetch the needed |
|
13 informations""" |
|
14 |
|
15 def __init__(self, appli): |
|
16 self.appli = appli |
|
17 |
|
18 def get_session(self, req): |
|
19 return req._request.cw_session |
|
20 |
|
21 def logout(self, req, goto_url): |
|
22 raise LogOut(url=goto_url) |
|
23 |
|
24 |
|
25 class CubicWebPyramidHandler(object): |
|
26 def __init__(self, appli): |
|
27 self.appli = appli |
|
28 |
|
29 def __call__(self, request): |
|
30 """ |
|
31 Handler that mimics what CubicWebPublisher.main_handle_request does and |
|
32 call CubicWebPyramidHandler.core_handle. |
|
33 |
|
34 """ |
|
35 # XXX In a later version of this handler, we need to by-pass |
|
36 # core_handle and CubicWebPublisher altogether so that the various CW |
|
37 # exceptions are converted to their pyramid equivalent. |
|
38 |
|
39 req = request.cw_request() |
|
40 req.set_cnx(request.cw_cnx) |
|
41 |
|
42 # XXX The main handler of CW forbid anonymous https connections |
|
43 # I guess we can drop this "feature" but in doubt I leave this comment |
|
44 # so we don't forget about it. (cdevienne) |
|
45 |
|
46 try: |
|
47 content = self.appli.core_handle(req, req.path) |
|
48 |
|
49 if content is not None: |
|
50 request.response.body = content |
|
51 request.response.headers.clear() |
|
52 for k, v in req.headers_out.getAllRawHeaders(): |
|
53 for item in v: |
|
54 request.response.headers.add(k, item) |
|
55 except LogOut as ex: |
|
56 # The actual 'logging out' logic should be in separated function |
|
57 # that is accessible by the pyramid views |
|
58 del req._request.session['cubicweb.sessionid'] |
|
59 if not req.session.closed: |
|
60 req.session.repo.close(req.session.sessionid) |
|
61 headers = security.forget(request) |
|
62 raise HTTPSeeOther(ex.url, headers=headers) |
|
63 except Redirect as ex: |
|
64 raise HTTPSeeOther(ex.url) |
|
65 # except AuthenticationError: |
|
66 # XXX I don't think it makes sens to catch this ex here (cdevienne) |
|
67 |
|
68 return request.response |
|
69 |
|
70 |
|
71 def includeme(config): |
|
72 # Set up a defaut route to handle non-catched urls. |
|
73 # This is to keep legacy compatibility for cubes that makes use of the |
|
74 # cubicweb controllers. |
|
75 cwconfig = config.registry['cubicweb.config'] |
|
76 repository = config.registry['cubicweb.repository'] |
|
77 cwappli = CubicWebPublisher( |
|
78 repository, cwconfig, |
|
79 session_handler_fact=PyramidSessionHandler) |
|
80 handler = CubicWebPyramidHandler(cwappli) |
|
81 |
|
82 config.registry['cubicweb.appli'] = cwappli |
|
83 config.registry['cubicweb.handler'] = handler |
|
84 |
|
85 config.add_route('catchall', pattern='*path') |
|
86 config.add_view(handler, route_name='catchall') |