[Zope-dev] Re: Strange security issue with Zope 2.8.1

Jens Vagelpohl jens at dataflake.org
Fri Sep 30 05:27:33 EDT 2005


> My understanding (and the way we use it when monkey patching for  
> instance) is that whenevery you apply new security to a class, you  
> create a new ClassSecurityInfo on it. It only defines "new stuff"  
> to do. The real synthesized security is still stored in  
> __ac_permissions__.

Yes, your understanding matches what I know now. Part of my earlier  
diagnosis was wrong, the behavior of class_init has not changed  
between Zope 2.7 and Zope 2.8, just the behavior of Archetypes.

What Archetypes seems to do is to generate a new ClassSecurityInfo  
during the call to registerType, which does not contain "added"  
information, but information about every single method on the class.  
It does try to look at the already existing __ac_permissions__ to  
make sure already set permissions don't get stomped, but when a name  
is declared private or public it will not be part of  
__ac_permissions__ and Archetypes will gladly stomp all over it.

I have applied a patch locally (and submitted it on the Archetypes  
bug tracker on sf.net) that seems to solve the problem. I honestly  
don't know if there are other dangerous consequences because the way  
Archetypes works is just really dark magic which I don't want to get  
into too far. Basically, at the point where it tries to find already- 
set permissions, I am also trying to find a name "<method>__roles__"  
to determine if something has already been declared private or  
public, and then re-declare it private or public on the  
ClassSecurityInfo object that Archetypes creates:

Index: Archetypes/ClassGen.py
===================================================================
--- Archetypes/ClassGen.py  (revision 6167)
+++ Archetypes/ClassGen.py  (working copy)
@@ -103,6 +103,8 @@

          perm = _modes[mode]['security']
          perm = getattr(field, perm, None)
+        method__roles__ = getattr(klass, '%s__roles__' % methodName, 0)
+
          # Check copied from SecurityInfo to avoid stomping over
          # existing permissions.
          if security.names.get(methodName, perm) != perm:
@@ -112,6 +114,10 @@
                   'permission declared is the correct one and '
                   'has preference over the permission declared '
                   'on the field.' % methodName)
+        elif method__roles__ is None:
+            security.declarePublic(methodName)
+        elif method__roles__ == ():
+            security.declarePrivate(methodName)
          else:
              security.declareProtected(perm, methodName)

jens



More information about the Zope-Dev mailing list