20 log = logging.getLogger(__name__) |
20 log = logging.getLogger(__name__) |
21 |
21 |
22 |
22 |
23 @contextmanager |
23 @contextmanager |
24 def cw_to_pyramid(request): |
24 def cw_to_pyramid(request): |
25 """Wrap a call to the cubicweb API. |
25 """ Context manager to wrap a call to the cubicweb API. |
26 |
26 |
27 All CW exceptions will be transformed into their pyramid equivalent. |
27 All CW exceptions will be transformed into their pyramid equivalent. |
28 When needed, some CW reponse bits may be converted too (mainly headers)""" |
28 When needed, some CW reponse bits may be converted too (mainly headers)""" |
29 try: |
29 try: |
30 yield |
30 yield |
51 except (rql.BadRQLQuery, cubicweb.web.RequestError) as ex: |
51 except (rql.BadRQLQuery, cubicweb.web.RequestError) as ex: |
52 raise |
52 raise |
53 |
53 |
54 |
54 |
55 class CubicWebPyramidRequest(CubicWebRequestBase): |
55 class CubicWebPyramidRequest(CubicWebRequestBase): |
|
56 """ A CubicWeb request that only wraps a pyramid request. |
|
57 |
|
58 :param request: A pyramid request |
|
59 |
|
60 """ |
56 def __init__(self, request): |
61 def __init__(self, request): |
57 self._request = request |
62 self._request = request |
58 |
63 |
59 self.path = request.upath_info |
64 self.path = request.upath_info |
60 |
65 |
119 |
124 |
120 status_out = property(_get_status_out, _set_status_out) |
125 status_out = property(_get_status_out, _set_status_out) |
121 |
126 |
122 |
127 |
123 def render_view(request, vid, **kwargs): |
128 def render_view(request, vid, **kwargs): |
|
129 """ Helper function to render a CubicWeb view. |
|
130 |
|
131 :param request: A pyramid request |
|
132 :param vid: A CubicWeb view id |
|
133 :param **kwargs: Keyword arguments to select and instanciate the view |
|
134 :returns: The rendered view content |
|
135 """ |
124 vreg = request.registry['cubicweb.registry'] |
136 vreg = request.registry['cubicweb.registry'] |
125 # XXX The select() function could, know how to handle a pyramid |
137 # XXX The select() function could, know how to handle a pyramid |
126 # request, and feed it directly to the views that supports it. |
138 # request, and feed it directly to the views that supports it. |
127 # On the other hand, we could refine the View concept and decide it works |
139 # On the other hand, we could refine the View concept and decide it works |
128 # with a cnx, and never with a WebRequest |
140 # with a cnx, and never with a WebRequest |
133 view.render() |
145 view.render() |
134 return view._stream.getvalue() |
146 return view._stream.getvalue() |
135 |
147 |
136 |
148 |
137 def _cw_cnx(request): |
149 def _cw_cnx(request): |
|
150 """ Obtains a cw session from a pyramid request |
|
151 |
|
152 The connection will be commited or rolled-back in a request finish |
|
153 callback (this is temporary, we should make use of the transaction manager |
|
154 in a later version). |
|
155 |
|
156 Not meant for direct use, use ``request.cw_cnx`` instead. |
|
157 |
|
158 :param request: A pyramid request |
|
159 :returns type: :class:`cubicweb.server.session.Connection` |
|
160 """ |
138 cnx = repoapi.ClientConnection(request.cw_session) |
161 cnx = repoapi.ClientConnection(request.cw_session) |
139 |
162 |
140 def cleanup(request): |
163 def cleanup(request): |
141 if (request.exception is not None and not isinstance( |
164 if (request.exception is not None and not isinstance( |
142 request.exception, ( |
165 request.exception, ( |
151 cnx.__enter__() |
174 cnx.__enter__() |
152 return cnx |
175 return cnx |
153 |
176 |
154 |
177 |
155 def repo_connect(repo, eid): |
178 def repo_connect(repo, eid): |
156 """A lightweight version of repo.connect that does not keep track of opened |
179 """A lightweight version of |
157 sessions, removing the need of closing them""" |
180 :meth:`cubicweb.server.repository.Repository.connect` that does not keep |
|
181 track of opened sessions, removing the need of closing them""" |
158 with repo.internal_cnx() as cnx: |
182 with repo.internal_cnx() as cnx: |
159 user = repo._build_user(cnx, eid=eid) |
183 user = repo._build_user(cnx, eid=eid) |
160 session = Session(user, repo, None) |
184 session = Session(user, repo, None) |
161 user._cw = user.cw_rset.req = session |
185 user._cw = user.cw_rset.req = session |
162 user.cw_clear_relation_cache() |
186 user.cw_clear_relation_cache() |
168 # repo._sessions[session.sessionid] = session |
192 # repo._sessions[session.sessionid] = session |
169 return session |
193 return session |
170 |
194 |
171 |
195 |
172 def _cw_session(request): |
196 def _cw_session(request): |
173 """Obtains a cw session from a pyramid request""" |
197 """Obtains a cw session from a pyramid request |
|
198 |
|
199 :param request: A pyramid request |
|
200 :returns type: :class:`cubicweb.server.session.Session` |
|
201 |
|
202 Not meant for direct use, use ``request.cw_session`` instead. |
|
203 """ |
174 repo = request.registry['cubicweb.repository'] |
204 repo = request.registry['cubicweb.repository'] |
175 |
205 |
176 if not request.authenticated_userid: |
206 if not request.authenticated_userid: |
177 session = repo_connect( |
207 session = repo_connect( |
178 repo, eid=request.registry['cubicweb.anonymous_eid']) |
208 repo, eid=request.registry['cubicweb.anonymous_eid']) |
185 |
215 |
186 return session |
216 return session |
187 |
217 |
188 |
218 |
189 def _cw_request(request): |
219 def _cw_request(request): |
|
220 """ Obtains a CubicWeb request wrapper for the pyramid request. |
|
221 |
|
222 :param request: A pyramid request |
|
223 :return: A CubicWeb request |
|
224 :returns type: :class:`CubicWebPyramidRequest` |
|
225 |
|
226 Not meant for direct use, use ``request.cw_request`` instead. |
|
227 |
|
228 """ |
190 req = CubicWebPyramidRequest(request) |
229 req = CubicWebPyramidRequest(request) |
191 req.set_cnx(request.cw_cnx) |
230 req.set_cnx(request.cw_cnx) |
192 return req |
231 return req |
193 |
232 |
194 |
233 |
195 def get_principals(login, request): |
234 def get_principals(login, request): |
|
235 """ Returns the group names of the authenticated user. |
|
236 |
|
237 This function is meant to be used as an authentication policy callback. |
|
238 |
|
239 It also pre-open the cubicweb session and put it in |
|
240 request._cw_cached_session for later usage by :func:`_cw_session`. |
|
241 |
|
242 .. note:: |
|
243 |
|
244 It the default authentication policy is not used, make sure this |
|
245 function gets called by the active authentication policy. |
|
246 |
|
247 :param login: A cubicweb user eid |
|
248 :param request: A pyramid request |
|
249 :returns: A list of group names |
|
250 """ |
196 repo = request.registry['cubicweb.repository'] |
251 repo = request.registry['cubicweb.repository'] |
197 |
252 |
198 try: |
253 try: |
199 session = repo_connect(repo, eid=login) |
254 session = repo_connect(repo, eid=login) |
200 request._cw_cached_session = session |
255 request._cw_cached_session = session |
204 |
259 |
205 return session.user.groups |
260 return session.user.groups |
206 |
261 |
207 |
262 |
208 def includeme(config): |
263 def includeme(config): |
|
264 """ Enables the core features of Pyramid CubicWeb. |
|
265 |
|
266 Automatically called by the 'pyramid' command, or via |
|
267 ``config.include('pyramid_cubicweb.code')``. In the later case, |
|
268 the following registry entries must be defined first: |
|
269 |
|
270 'cubicweb.config' |
|
271 A cubicweb 'config' instance. |
|
272 |
|
273 'cubicweb.repository' |
|
274 The correponding cubicweb repository. |
|
275 |
|
276 'cubicweb.registry' |
|
277 The vreg. |
|
278 """ |
209 repo = config.registry['cubicweb.repository'] |
279 repo = config.registry['cubicweb.repository'] |
210 |
280 |
211 with repo.internal_cnx() as cnx: |
281 with repo.internal_cnx() as cnx: |
212 login = config.registry['cubicweb.config'].anonymous_user()[0] |
282 login = config.registry['cubicweb.config'].anonymous_user()[0] |
213 config.registry['cubicweb.anonymous_eid'] = cnx.find( |
283 config.registry['cubicweb.anonymous_eid'] = cnx.find( |