You are not logged in Log in Join
You are here: Home » Members » karl » MyWiki » PublishNotes

Log in
Name

Password

 
 

History for PublishNotes

??changed:
-
**Traversal and security with the default publisher**

This is an incomplete sliver of the traversal and security checks
involved in publishing.  I had to step through this a few times and
finally decided I'd take notes for the next time I have to relearn it.

*Traversal to the object*

 ZPublisher.BaseRequest:traverse()

 - Break up the URL into objects, starting at the root, which is the
 app object.  At each object, the publisher attempts to find the next
 object in the path by calling methods on the current object; at the
 last object, the publisher attempts to return a string to put in the
 response.

  - __before_publishing_traverse__ is called if it exists, but
    return values are ignored

  - methods that return the next object:

   - __bobo_traverse__, which returns the next object (or does it
     stop the publishing after returning?)

   - __getattr__
 
   - __getitem__

  - methods that short-circuit the publishing process:

   - __call__

   - index_html attribute

   - __str__

 - The methods that short-circuit the publishng process stop the
   publisher from finding further subobjects; for example, if your
   __call__ method doesn't return a string to be published, you'll
   get a cryptic error message.  This means that you can't use a
   random method to find the next object to return, but you can use
   __getitem__ or a ComputedAttribute.

   Methods *can* do funny things and read the rest of the URL that won't
   be traversed with the standard publishing process, though.  This is
   one way to avoid obvious variables in the URL.


*Security*

At each step, when an object is found, the security machinery decides
whether it is accessible and publishing can proceed.

   ZopeSecurityPolicy.validate()

   - gets the aq_base of the objects

   - tries to get __roles__ from the object

    - tries to get __roles__ from the object's container if not there

    - checks for to see if the container is a list, dict, or tuple with Containers() (line 154); these grant access

    - tries to get __allow_access_to_unprotected_subobjects__ if not there

      - this can be true, in which case access is granted, or a dict,
        in which case we grant if the value for the key of the object's name
        is true, or a callable object, in which case we grant if the
        function called with the name and the value (?) returns true.

   - if __roles__ is None or contains Anonymous, grant access

   - does some narrowing with the object's owner and proxy roles (?)

   - otherwise, get the user from the security context and ask the
     user if it is allowed: context.user.allowed(value, roles)

    User.BasicUser.allowed():

    - For the first user's role that intersects the object's roles:

      - get the user folder, which is the aq_parent of the user object

      - get the context, which is the aq_parent of the user folder.
        This is the user folder's container, except in cases that I
        don't know about.  For the default Zope user folder, this is
        the Application object.

        The context can be None, in which case grant access.

      - if the object has an im_self (i.e. it's a method), use that
        for the object

      - If the context is in the acquisition hierarchy of the
        unwrapped object, grant access.  Otherwise, deny access.

        This is checked by calling object.aq_inContextOf(ucontext, 1).

        This is to prevent sneaking a different user folder into the
        security check somehow.