[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