Announcement Announcement Module
Collapse
No announcement yet.
How do I write "around" style handler for CherryPy 3? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How do I write "around" style handler for CherryPy 3?

    Sylvain,

    I'm trying to follow the path of the new style filters you built in your sample app. I recently started trying to migrate springpython.security.web.FilterSecurityIntercepto r to something similar. FilterSecurityInterceptor is like MethodSecurityInterceptor, in that it uses an AccessDecisionManager to determine if you are authorized to do something in particular. Typically this filter is put in the chain after the one that determines you have been properly authenticated.

    I noticed that FilterSecurityInterceptor has behavior before AND after calling the cherrypy function, and I don't know how to translate that to a "before_handler" cherrypy filter.

    From https://fisheye.springframework.org/...ecurity/web.py in FilterSecurityInterceptor,
    Code:
            httpSession = self.sessionStrategy.getHttpSession(environ)
            fi = FilterInvocation(environ)
            token = self.beforeInvocation(fi)
            if httpSession is not None:
                httpSession[self.SPRINGPYTHON_FILTER_SECURITY_INTERCEPTOR_KEY] = token
    
            return self.doNextFilter(environ, start_response)
    
            if httpSession is not None and self.SPRINGPYTHON_FILTER_SECURITY_INTERCEPTOR_KEY in httpSession:
                token = httpSession[self.SPRINGPYTHON_FILTER_SECURITY_INTERCEPTOR_KEY]
                self.afterInvocation(token, None)
    
            return results
    The idea is to perform a before-action, call the main feature (which in this case is doNextFilter), then call an after-action, and then finally return the results, assuming you got that far.

    I'm wondering whether or not cherrypy's filter mechanism is a chain of function calls that are looped through, or whether they are nested. The paradigm springpython's security web filters are is the assumption of making nested calls.

    When I first read about WSGI, that seemed to be the mechanism they were offering, so I jumped on that quickly instead of determining if cherrypy could handle it out-of-the-box.

  • #2
    Hi Greg,

    The reason of my branch was to remove everything that was coming into my way to:

    1. Make CherryPy 3.1 and SpringPython play nice together
    2. Understand the way you had designed SpringPython

    The way you had mix WSGI and the doNextFilter function in SpringPython was misleading to me and the second demo (the module named app2.py) was trying to show that you could remove the WSGI dependency and go with a simple decorator instead. I guess that's a personal taste here.

    Anyway, about your specific point, CherryPy 3 has the following principles:

    1. Hooks are specific points in the request processing at which you can attach specific behavior.
    2. Those behaviors are described into Tools.

    For instance, to perform a task before the actual page handler is called:

    Code:
    cherrypy.tools.securityFilterBefore = cherrypy.Tool('before_handler', some_func, priority=75)
    Now to attach a tool after:

    Code:
    cherrypy.tools.securityFilterAfter = cherrypy.Tool('before_finalize', some_other_func)
    Then to apply it for a given path:

    Code:
    conf = {'/admin': {'cherrypy.tools.securityFilterBefore.on': true, '
    cherrypy.tools.securityFilterAfter.on': True}}
    Now it seems not very clean to creat two distinct tools when both serve a common purpose, in that case you may do this:

    Code:
    class SecurityFilter(cherrypy.Tool):
          def _do_before(self, *args, **kwargs):
               ...
    
          def _do_after(self, *args, **kwargs):
               ...
    
          def _setup(self):
               conf = self._merged_args()
               cherrypy.request.hooks.attach('before_handler', self._do_before, **conf)
               cherrypy.request.hooks.attach('before_finalize', self._do_after, **conf)
    
    cherrypy.tools.securityFilter = SecurityFilter()
    conf = {'/admin': {'cherrypy.tools.securityFilter.on': True}}
    Automatically CherryPy will apply your tool at the right hook point.

    CherryPy tools are not nested. That's why there is a priority value you can set if you want tools to be applied in a certain order for a given hook point (otherwise they are run in the order they've been declared).

    I hope that helps.

    Comment

    Working...
    X