Skip to content

Commit d95d8d0

Browse files
author
Ralf Schlatterbeck
committed
search permissions must allow transitive properties
1 parent b267853 commit d95d8d0

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

roundup/security.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ def test(self, db, permission, classname, property, userid, itemid):
5454
# we have a winner
5555
return 1
5656

57-
def searchable(self, db, permission, classname, property):
57+
def searchable(self, classname, property):
5858
""" A Permission is searchable for the given permission if it
5959
doesn't include a check method and otherwise matches the
6060
given parameters.
6161
"""
62-
if permission != self.name:
62+
if self.name not in ('View', 'Search'):
6363
return 0
6464

6565
# are we checking the correct class
@@ -198,13 +198,29 @@ def hasPermission(self, permission, userid, classname=None,
198198
return 0
199199

200200
def roleHasSearchPermission(self, rolename, classname, property):
201-
""" for each of the user's Roles, check the permissions
201+
""" For each of the user's Roles, check the permissions.
202+
Property can be a transitive property.
202203
"""
203-
for perm in self.role[rolename].permissions:
204-
# permission match?
205-
for p in 'View', 'Search':
206-
if perm.searchable(self.db, p, classname, property):
207-
return 1
204+
cn = classname
205+
last = None
206+
# Note: break from inner loop means "found"
207+
# break from outer loop means "not found"
208+
for propname in property.split('.'):
209+
if last:
210+
try:
211+
cls = self.db.getclass(cn)
212+
lprop = cls.getprops()[last]
213+
except KeyError:
214+
break
215+
cn = lprop.classname
216+
last = propname
217+
for perm in self.role[rolename].permissions:
218+
if perm.searchable(cn, propname):
219+
break
220+
else:
221+
break
222+
else:
223+
return 1
208224
return 0
209225

210226
def hasSearchPermission(self, userid, classname, property):

test/test_security.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,33 @@ def testAccessControls(self):
178178
self.assertEquals(has('Test', none, 'test', itemid='1'), 0)
179179
self.assertEquals(has('Test', none, 'test', itemid='2'), 0)
180180

181+
def testTransitiveSearchPermissions(self):
182+
add = self.db.security.addPermission
183+
has = self.db.security.hasSearchPermission
184+
addRole = self.db.security.addRole
185+
addToRole = self.db.security.addPermissionToRole
186+
user = self.db.user.create(username='user1', roles='User')
187+
anon = self.db.user.create(username='anonymous', roles='Anonymous')
188+
addRole(name='User')
189+
addRole(name='Anonymous')
190+
iv = add(name="View", klass="issue")
191+
addToRole('User', iv)
192+
addToRole('Anonymous', iv)
193+
ms = add(name="Search", klass="msg")
194+
addToRole('User', ms)
195+
addToRole('Anonymous', ms)
196+
addToRole('User', add(name="View", klass="user"))
197+
self.assertEquals(has(anon, 'issue', 'messages'), 1)
198+
self.assertEquals(has(anon, 'issue', 'messages.author'), 1)
199+
self.assertEquals(has(anon, 'issue', 'messages.author.username'), 0)
200+
self.assertEquals(has(anon, 'issue', 'messages.recipients'), 1)
201+
self.assertEquals(has(anon, 'issue', 'messages.recipients.username'), 0)
202+
self.assertEquals(has(user, 'issue', 'messages'), 1)
203+
self.assertEquals(has(user, 'issue', 'messages.author'), 1)
204+
self.assertEquals(has(user, 'issue', 'messages.author.username'), 1)
205+
self.assertEquals(has(user, 'issue', 'messages.recipients'), 1)
206+
self.assertEquals(has(user, 'issue', 'messages.recipients.username'), 1)
207+
181208
def test_suite():
182209
suite = unittest.TestSuite()
183210
suite.addTest(unittest.makeSuite(PermissionTest))

0 commit comments

Comments
 (0)