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

2005-09-30 Thread Jens Vagelpohl
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

___
Zope-Dev maillist  -  Zope-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
http://mail.zope.org/mailman/listinfo/zope-announce

http://mail.zope.org/mailman/listinfo/zope )


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

2005-09-29 Thread Florent Guillaume

Jens Vagelpohl wrote:
I have found a strange security issue with Zope 2.8.1 that seems to  
stem from code not doing what it was supposed to do in Zope 2.7.x,  but 
which works in 2.8.1 and then causes other side effects in code  that 
relied on the broken behavior.


Symptom: In Zope 2.8.1 it is *impossible* to override a  
ClassSecurityInfo security declaration in an Archetypes-derived  content 
item. (I have a small set of unit tests that proves the  behavior under 
Zope 2.8.1 if anyone is interested)


A little background: When you register an Archetypes-derived content  
type, it will do all the generated accessor/setter method magic and  
then call InitializeClass a second time.


The code in lib/python/App/class_init.py has changed between Zope  2.7.x 
and Zope 2.8 in order to support new-style classes. To be more  precise, 
instead of manipulating the class __dict__ directly we now  use 
setattr/delattr/etc. This change seems to have un-broken code  which 
did not do what the code comments suggest. Namely, when a class  is sent 
through class_init.default_class_init__ (better known as  
Globals.InitializeClass) the class __dict__ is searched to find  objects 
that look like ClassSecurityInfo instances in order to read  and apply 
the security settings. After finding the ClassSecurityInfo  instance, it 
is force-deleted from the object (the comments say, out  of paranoia). 
However, somehow this did not work correctly in Zope  2.7.x, where the 
deletion call looked like...


del dict[key]

(dict being the class __dict__, and key being the name of the  
ClassSecurityInfo instance). Under Zope 2.8, it looks like this:


delattr(self, key)

(self being the class object).

Under Zope 2.7, the security object *would still be there* when  hitting 
InitializeClass for the second time via Archetypes'  registerType, which 
in turn meant Archetypes would not instantiate  its own 
ClassSecurityInfo instance and stuff it with the declarations  from 
whatever Archetypes-derived base class you used.


In Zope 2.8, the deletion actually works as intended - but due to  that 
fact Archetypes will instantiate its own ClassSecurityInfo and  populate 
it with the declarations from the base class that I am  trying to 
override. So the overridden settings are all overwritten  again by the 
base class declaration.


My question is, what is the reasoning behind deleting the  
ClassSecurityInfo object from the class after it has been read the  
first time? How can this be implemented in a sane way so that custom  
security declarations can be retained?


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__.


class C(SimpleItem):
security = ClassSecurityInfo()
security.declareProtected(...)
def foo(): ...

InitializeClass(C)

then later on:

security = ClassSecurityInfo()
C.security = security
security.declareProtected(...)
C.newmethod = something
InitializeClass(C)

Anyway that's what I do. I never relied on a preexisting C.security.

Florent


--
Florent Guillaume, Nuxeo (Paris, France)   CTO, Director of RD
+33 1 40 33 71 59   http://nuxeo.com   [EMAIL PROTECTED]
___
Zope-Dev maillist  -  Zope-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
http://mail.zope.org/mailman/listinfo/zope-announce

http://mail.zope.org/mailman/listinfo/zope )