pyramid_cubicweb/core.py
changeset 11537 caf268942436
parent 11536 6618408c0629
child 11552 d92a608c1a16
equal deleted inserted replaced
11536:6618408c0629 11537:caf268942436
    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(