[Checkins] SVN: AccessControl/trunk/src/AccessControl/ make sure generated protected decorators are used
Florian Friesdorf
flo at chaoflow.net
Thu Nov 17 03:25:17 UTC 2011
Log message for revision 123399:
make sure generated protected decorators are used
Changed:
U AccessControl/trunk/src/AccessControl/SecurityInfo.py
U AccessControl/trunk/src/AccessControl/tests/testClassSecurityInfo.py
-=-
Modified: AccessControl/trunk/src/AccessControl/SecurityInfo.py
===================================================================
--- AccessControl/trunk/src/AccessControl/SecurityInfo.py 2011-11-17 03:25:08 UTC (rev 123398)
+++ AccessControl/trunk/src/AccessControl/SecurityInfo.py 2011-11-17 03:25:16 UTC (rev 123399)
@@ -66,6 +66,7 @@
def __init__(self):
self.names = {}
self.roles = {}
+ self._unused_protected_decorators = set()
def _setaccess(self, names, access):
for name in names:
@@ -119,9 +120,18 @@
protected__roles__=ACCESS_PRIVATE
def protected(self, permission_name):
"""Return a decorator to associate a function with a permission."""
+ # the decorator returned is remembered in a set and will
+ # remove itself upon call. self.apply will check for an empty
+ # set and raise an AssertionError otherwise.
+ key = "'%s':%s" % (permission_name, id(lambda x:x))
def decor(func):
self.declareProtected(permission_name, func.__name__)
+ self._unused_protected_decorators.remove(key)
return func
+ # make sure our key algo creates unique-enough keys
+ if key in self._unused_protected_decorators:
+ raise KeyError("Duplicate key: %s" % (key,))
+ self._unused_protected_decorators.add(key)
return decor
setPermissionDefault__roles__=ACCESS_PRIVATE
@@ -163,6 +173,12 @@
def apply(self, classobj):
"""Apply security information to the given class object."""
+ # make sure all decorators handed out by security.protected were used
+ if self._unused_protected_decorators:
+ msg = "Class '%r' has %d non-decorator security.protected calls!"
+ raise AssertionError(msg % (classobj,
+ len(self._unused_protected_decorators)))
+
dict = classobj.__dict__
# Check the class for an existing __ac_permissions__ and
Modified: AccessControl/trunk/src/AccessControl/tests/testClassSecurityInfo.py
===================================================================
--- AccessControl/trunk/src/AccessControl/tests/testClassSecurityInfo.py 2011-11-17 03:25:08 UTC (rev 123398)
+++ AccessControl/trunk/src/AccessControl/tests/testClassSecurityInfo.py 2011-11-17 03:25:16 UTC (rev 123399)
@@ -112,7 +112,36 @@
self.assertEquals([t for t in Test.__ac_permissions__ if not t[1]],
[('Make food', (), ('Chef',))])
+ def test_EnsureProtectedDecoCall(self):
+ from AccessControl.class_init import InitializeClass
+ from ExtensionClass import Base
+ ClassSecurityInfo = self._getTargetClass()
+
+ class Test(Base):
+ """Test class
+ """
+ meta_type = "Test"
+
+ security = ClassSecurityInfo()
+
+ security.protected('Test permission 1')
+ def unprotected1(self, REQUEST=None):
+ """ """
+
+ security.protected('Test permission 2')
+ def unprotected2(self, REQUEST=None):
+ """ """
+
+ @security.protected('Test permission 3')
+ def protected(self, REQUEST=None):
+ """ """
+
+ # Do class initialization.
+ with self.assertRaisesRegexp(AssertionError, 'has 2 non-decorator'):
+ InitializeClass(Test)
+
+
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(ClassSecurityInfoTests))
More information about the checkins
mailing list