[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Security - protectClass.py:1.1.2.3
Ken Manheimer
klm@zope.com
Fri, 30 Nov 2001 14:39:28 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/Security
In directory cvs.zope.org:/tmp/cvs-serv22687
Modified Files:
Tag: Zope-3x-branch
protectClass.py
Log Message:
Implement some baseline configuration directives -
protectClass.protect() and .instances - and __call__().
=== Zope3/lib/python/Zope/App/Security/protectClass.py 1.1.2.2 => 1.1.2.3 ===
# FOR A PARTICULAR PURPOSE.
-class protectClass:
- __complex=0
+"""Create the protection declarations object.
+
+Protection declarations are assert as part of the configuration process to map
+permissions to objects, ie to specific classes, class instances, and methods.
+\(Method permissions apply to both the class and class instance manifestations
+of the methods.)
+
+When the declarations are expressed as a simple (ie, empty) tag, they are
+applied to both the class and the instances of the class. When the tags have
+subtags, then the instances are not inherently affected - the subtag directive
+"instances" can then be used. [XXX this needs to be fleshed out.]
+
+Invalid protection declarations provoke instances of the
+ProtectionDeclarationException class."""
+from Zope.Configuration.name import resolve
+from Interface.Method import Method
+
+class ProtectionDeclarationException(Exception):
+ """Security-protection-specific exceptions."""
+ pass
+
+class protectClass:
def __init__(self, name, permission=None, interface=None,
method=None, methods=None):
+ self.__class = resolve(name)
self.__name=name
self.__permission=permission
- self.__interface=interface
- self.__method=method
- self.__methods=methods
+ self.protect(permission, interface, method, methods)
+ # So subsequent simple-declaration-style self() calls process instances
+ self.__empty = 1
def protect(self, permission=None, interface=None,
- method=None, methods=None, instances=None):
+ method=None, methods=None):
"Protect a specific aspect"
- # stub
- self.__complex=1
+
+ self.__empty = 0
+
+ if not (interface or method or methods):
+ return
+ if permission is None:
+ permission = self.__permission
+ if permission is None:
+ raise ProtectionDeclarationException("No permission specified")
+
+ if interface:
+ self.__protectInterface(interface, permission)
+ if method:
+ self.__protectMethod(method, permission)
+ if methods:
+ self.__protectMethods(methods, permission)
def instances(self, permission=None):
"Protect instances of the class, as opposed to methods"
- # stub
- self.__complex=1
+ self.__empty = 0
- def __call__(self):
- "Handle empty case"
+ if permission is None:
+ permission = self.__permission
+ if permission is None:
+ raise ProtectionDeclarationException("No permission specified")
+ self.__class.__permission__ = permission
+
+ def __protectMethod(self, method, permission):
+ "Set a permission on a particular method."
+ m = getattr(self.__class, method)
+ try:
+ setattr(m, "__permission__", permission)
+ except AttributeError, TypeError:
+ if hasattr(m, "im_func"):
+ setattr(m.im_func, "__permission__", permission)
+ else:
+ raise ProtectionDeclarationException(
+ "Couldn't assign permission to method %s of class %s"
+ % (m, self.__class.__name__))
+ def __protectMethods(self, methods, permission):
+ "Set a permission on a bunch of methods."
+ for method in methods.split(","):
+ self.__protectMethod(method.strip(), permission)
+
+
+ def __protectInterface(self, interface, permission):
+ "Set a permission on methods in an interface."
+ interface = resolve(interface)
+ for n, d in interface.namesAndDescriptions():
+ if isinstance(d, Method):
+ self.__protectMethod(n, permission)
+
+ def __call__(self):
+ "Handle empty/simple declaration."
+ if self.__empty:
+ self.instances(self.__permission)
def publicClass(name, interface=None, method=None, methods=None):
"Declare a class and some of it's methods to be public"