Security internals, was Re: [Zope-dev] LOTS of roles?

Paul Winkler pw_lists@slinkp.com
Wed, 5 Mar 2003 16:53:31 -0500


OK, now I am really confused. Please Help!

I've been trying to understand how to implement dynamic local roles,
and this has got me into trying to understand how authorization works.
Brief background from the "Lots of roles" discussion:

> > Leonardo Rochael Almeida  <leo@hiper.com.br> wrote:
> > > So I think you need dynamically calculated local roles. This can be
> > > achieved by a user folder that returns a user object that overrides
> > > ".getRolesInContext(object)" 
(snip)

OK, that much is pretty easy, I've got a proof of concept
based on SimpleUserFolder which works fine AFAICT. 

but then...

> Florent Guillaume wrote:
> > Note that you'll also want to change validate() if you go that route.
> > It has a short-circuited version of getRolesInContext in it.

The same thing was mentioned to me on #zope by Kosh.
In addition, Chris Withers mentioned validate() in a private email
in regard to dynamic local roles. So there's some consensus that
this is what I need to do.  But  AFAICT this is just not true.
Looking around in lib/python/AccessControl  I observe that:
(PLEASE correct me if anything below is wrong!!!!)

    *  User.BasicUser.allowed() is the only method that
       "has a short-circuited version of getRolesInContext in it"

    * There are lots of "validate" methods, related as follows:

        BasicUserFolder.validate() calls self.authorize()
    
        which calls SecurityManager.validate()

        which calls ZopeSecurityPolicy.validate()

        which calls BasicUser.allowed()

        ... so I'm back where I started.

        AFAICT, none of these validate() methods do anything
        with roles, it's left up to .allowed() to figure out the roles.

        
    * Some logging experimentation confirms that my UserFolder.validate()
      is called EVERY time an object deeper in the zope object tree
      is accessed; often it just returns None thereby bubbling up
      the validation to higher user folders.  This makes sense.

    * Also on Kosh's advice I looked at 
      ZPublisher.BaseRequest.traverse()
      which seems to be the thing that kicks off the whole validation
      process. Skipping to the "# Do authorization checks"
      comment, it seems i'm looking in the right place.
      Ugh, this is possibly the snarliest method
      I've ever seen in python source. 
        
        -  __allow_groups__?? what the heck is this?
          what kind of groups are these?  the only places i can
          find __allow_groups are in OFS/Application.py where it's 
          used to refer to an emergency UserFolder (in case you 
          delete your top-level acl_users), and in User.py
          where it refers to self of BasicUserFolder ... 
          is this odd name possibly a bit of old bobo cruft?

        - after the allow_groups weirdness I think we've got
          hold of a UserFolder's validate method, which is our
          entry point into the authenticate / authorize process.


     One more thing: AFAICT, ZopeSecurityPolicy.checkPermission()
     and User.has_permission() are purely for informational purposes -
     e.g. you can call them in your app to find out something,
     but they are not used by the internals to grant or deny access.
     True?

If anybody could confirm or deny any of teh above it would really
help me grok what i'm doing here.

-- 

Paul Winkler
http://www.slinkp.com