From 7cf02acb464a4a46708e7bd710c2994f757add25 Mon Sep 17 00:00:00 2001 From: schlatterbeck Date: Wed, 20 Oct 2010 08:58:52 +0000 Subject: [PATCH] search permissions must allow transitive properties git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/roundup/trunk@4547 57a73879-2fb5-44c3-a270-3262357dd7e2 --- roundup/security.py | 32 ++++++++++++++++++++++++-------- test/test_security.py | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/roundup/security.py b/roundup/security.py index 9bfb0ec..6ce330f 100644 --- a/roundup/security.py +++ b/roundup/security.py @@ -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): diff --git a/test/test_security.py b/test/test_security.py index 825b582..595dad3 100644 --- a/test/test_security.py +++ b/test/test_security.py @@ -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)) -- 2.30.2