Code

search permissions must allow transitive properties
authorschlatterbeck <schlatterbeck@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 20 Oct 2010 08:58:52 +0000 (08:58 +0000)
committerschlatterbeck <schlatterbeck@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 20 Oct 2010 08:58:52 +0000 (08:58 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/roundup/trunk@4547 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/security.py
test/test_security.py

index 9bfb0ecdd773777011f7ee4e7634a9e51745526a..6ce330fa0e882361a1f4af187d88f754ec4430b7 100644 (file)
@@ -54,12 +54,12 @@ class Permission:
         # we have a winner
         return 1
 
-    def searchable(self, db, permission, classname, property):
+    def searchable(self, classname, property):
         """ A Permission is searchable for the given permission if it
             doesn't include a check method and otherwise matches the
             given parameters.
         """
-        if permission != self.name:
+        if self.name not in ('View', 'Search'):
             return 0
 
         # are we checking the correct class
@@ -198,13 +198,29 @@ class Security:
         return 0
 
     def roleHasSearchPermission(self, rolename, classname, property):
-        """ for each of the user's Roles, check the permissions
+        """ For each of the user's Roles, check the permissions.
+            Property can be a transitive property.
         """
-        for perm in self.role[rolename].permissions:
-            # permission match?
-            for p in 'View', 'Search':
-                if perm.searchable(self.db, p, classname, property):
-                    return 1
+        cn = classname
+        last = None
+        # Note: break from inner loop means "found"
+        #       break from outer loop means "not found"
+        for propname in property.split('.'):
+            if last:
+                try:
+                    cls = self.db.getclass(cn)
+                    lprop = cls.getprops()[last]
+                except KeyError:
+                    break
+                cn = lprop.classname
+            last = propname
+            for perm in self.role[rolename].permissions:
+                if perm.searchable(cn, propname):
+                    break
+            else:
+                break
+        else:
+            return 1
         return 0
 
     def hasSearchPermission(self, userid, classname, property):
index 825b582483058d9bafd534ed91493f2c015aefb9..595dad322156951063b4f6bf687f84e95cbd5209 100644 (file)
@@ -178,6 +178,33 @@ class PermissionTest(MyTestCase):
         self.assertEquals(has('Test', none, 'test', itemid='1'), 0)
         self.assertEquals(has('Test', none, 'test', itemid='2'), 0)
 
+    def testTransitiveSearchPermissions(self):
+        add = self.db.security.addPermission
+        has = self.db.security.hasSearchPermission
+        addRole = self.db.security.addRole
+        addToRole = self.db.security.addPermissionToRole
+        user = self.db.user.create(username='user1', roles='User')
+        anon = self.db.user.create(username='anonymous', roles='Anonymous')
+        addRole(name='User')
+        addRole(name='Anonymous')
+        iv = add(name="View", klass="issue")
+        addToRole('User', iv)
+        addToRole('Anonymous', iv)
+        ms = add(name="Search", klass="msg")
+        addToRole('User', ms)
+        addToRole('Anonymous', ms)
+        addToRole('User', add(name="View", klass="user"))
+        self.assertEquals(has(anon, 'issue', 'messages'), 1)
+        self.assertEquals(has(anon, 'issue', 'messages.author'), 1)
+        self.assertEquals(has(anon, 'issue', 'messages.author.username'), 0)
+        self.assertEquals(has(anon, 'issue', 'messages.recipients'), 1)
+        self.assertEquals(has(anon, 'issue', 'messages.recipients.username'), 0)
+        self.assertEquals(has(user, 'issue', 'messages'), 1)
+        self.assertEquals(has(user, 'issue', 'messages.author'), 1)
+        self.assertEquals(has(user, 'issue', 'messages.author.username'), 1)
+        self.assertEquals(has(user, 'issue', 'messages.recipients'), 1)
+        self.assertEquals(has(user, 'issue', 'messages.recipients.username'), 1)
+
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(PermissionTest))