[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Security - protectClass.py:1.1.2.8
Jim Fulton
jim@zope.com
Mon, 4 Mar 2002 11:58:04 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/Security
In directory cvs.zope.org:/tmp/cvs-serv15633
Modified Files:
Tag: Zope-3x-branch
protectClass.py
Log Message:
Added logic to protectClass to make sure that inherited methods were
protected correctly.
=== Zope3/lib/python/Zope/App/Security/protectClass.py 1.1.2.7 => 1.1.2.8 ===
pass
+
+
class protectClass:
__class_implements__ = INonEmptyDirective
@@ -63,13 +65,6 @@
else:
return permission_id
- def __checkPermission(self, permission_id):
- """Check to make sure that the permission is valid.
- """
-
- if not permissionRegistry.definedPermission(permission_id):
- raise UndefinedPermissionError(permission_id)
-
def protect(self, permission_id=None, interface=None,
method=None, methods=None):
"Protect a specific aspect"
@@ -100,36 +95,18 @@
self.__instances(permission_id, r)
return r
- def __inst(self, permission_id):
- self.__checkPermission(permission_id)
- self.__class.__permission__ = permission_id
-
def __instances(self, permission_id, r):
"Protect instances of the class, as opposed to methods"
permission_id = self._getPermission(permission_id)
r.append((
('protectInstances', self.__class),
- self.__inst, (permission_id,)))
+ protectInstancesOfClass, (self.__class, permission_id,)))
def __protectMethod(self, method, permission_id, r):
"Set a permission on a particular method."
r.append((
('protectMethod', self.__class, method),
- self.__method, (method, permission_id)))
-
- def __method(self, method, permission_id):
- "Set a permission on a particular method."
- self.__checkPermission(permission_id)
- m = getattr(self.__class, method)
- try:
- setattr(m, "__permission__", permission_id)
- except AttributeError, TypeError:
- if hasattr(m, "im_func"):
- setattr(m.im_func, "__permission__", permission_id)
- else:
- raise ProtectionDeclarationException(
- "Couldn't assign permission to method %s of class %s"
- % (m, self.__class.__name__))
+ protectMethod, (self.__class, method, permission_id)))
def __protectMethods(self, methods, permission_id, r):
"Set a permission on a bunch of methods."
@@ -150,3 +127,66 @@
if self.__empty:
self.__instances(self.__permission_id, r)
return r
+
+def _checkPermission(permission_id):
+ """Check to make sure that the permission is valid.
+ """
+
+ if not permissionRegistry.definedPermission(permission_id):
+ raise UndefinedPermissionError(permission_id)
+
+
+def protectInstancesOfClass(class_, permission_id):
+ _checkPermission(permission_id)
+ class_.__permission__ = permission_id
+
+def protectMethod(class_, method, permission_id):
+ "Set a permission on a particular method."
+ _checkPermission(permission_id)
+
+ m = getattr(class_, method)
+
+ d = class_.__dict__
+ if not d.has_key(method):
+ # Hm, we inherit the method. Dang, we need to insert a stub
+
+ # Make sure we have new style class:
+ if not issubclass(class_, object):
+ raise TypeError(
+ "Can only protected inherited methods of new "
+ "style classes", class_)
+
+ f = Protected(class_, method, permission_id)
+ setattr(class_, method, f)
+ return
+
+ try:
+ setattr(m, "__permission__", permission_id)
+ except (AttributeError, TypeError):
+ if hasattr(m, "im_func"):
+ setattr(m.im_func, "__permission__", permission_id)
+ else:
+ raise ProtectionDeclarationException(
+ "Couldn't assign permission to method %s of class %s"
+ % (m, class_.__name__))
+
+# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Hack!!!!!!!!!!
+
+class Protected(object):
+
+ def __init__(self, *args):
+ self.__args = args # class_, method, permission_id
+
+ def __get__(self, instance, type=None):
+ return ProtectedMethod(self.__args, instance)
+
+
+class ProtectedMethod(object):
+
+ def __init__(self, args, instance):
+ class_, method, self.__permission__ = args
+ m = getattr(super(class_, instance), method)
+ self.__m = self.__call__ = m
+
+ def __call__(self, *args, **kw):
+ return self.__m(*args, **kw)