Code

search permissions must allow transitive properties
[roundup.git] / test / test_security.py
index 00a8a24223094deb78fe7ff2315a77856abaa152..595dad322156951063b4f6bf687f84e95cbd5209 100644 (file)
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
-# $Id: test_security.py,v 1.6 2003-10-25 22:53:26 richard Exp $
+# $Id: test_security.py,v 1.10 2006-02-03 04:04:37 richard Exp $
 
 import os, unittest, shutil
 
+from roundup import backends
 from roundup.password import Password
 from db_test_base import setupSchema, MyTestCase, config
 
 class PermissionTest(MyTestCase):
     def setUp(self):
-        from roundup.backends import anydbm
+        backend = backends.get_backend('anydbm')
         # remove previous test, ignore errors
         if os.path.exists(config.DATABASE):
             shutil.rmtree(config.DATABASE)
         os.makedirs(config.DATABASE + '/files')
-        self.db = anydbm.Database(config, 'admin')
-        setupSchema(self.db, 1, anydbm)
+        self.db = backend.Database(config, 'admin')
+        setupSchema(self.db, 1, backend)
 
     def testInterfaceSecurity(self):
         ' test that the CGI and mailgw have initialised security OK '
         # TODO: some asserts
 
     def testInitialiseSecurity(self):
-        ''' Create some Permissions and Roles on the security object
-
-            This function is directly invoked by security.Security.__init__()
-            as a part of the Security object instantiation.
-        '''
         ei = self.db.security.addPermission(name="Edit", klass="issue",
                         description="User is allowed to edit issues")
         self.db.security.addPermissionToRole('User', ei)
@@ -52,52 +48,162 @@ class PermissionTest(MyTestCase):
                         description="User is allowed to access issues")
         self.db.security.addPermissionToRole('User', ai)
 
+    def testAdmin(self):
+        ei = self.db.security.addPermission(name="Edit", klass="issue",
+                        description="User is allowed to edit issues")
+        self.db.security.addPermissionToRole('User', ei)
+        ei = self.db.security.addPermission(name="Edit", klass=None,
+                        description="User is allowed to edit issues")
+        self.db.security.addPermissionToRole('Admin', ei)
+
+        u1 = self.db.user.create(username='one', roles='Admin')
+        u2 = self.db.user.create(username='two', roles='User')
+
+        self.assert_(self.db.security.hasPermission('Edit', u1, None))
+        self.assert_(not self.db.security.hasPermission('Edit', u2, None))
+
+
     def testGetPermission(self):
         self.db.security.getPermission('Edit')
         self.db.security.getPermission('View')
         self.assertRaises(ValueError, self.db.security.getPermission, 'x')
         self.assertRaises(ValueError, self.db.security.getPermission, 'Edit',
             'fubar')
-        ei = self.db.security.addPermission(name="Edit", klass="issue",
-                        description="User is allowed to edit issues")
-        self.db.security.getPermission('Edit', 'issue')
-        ai = self.db.security.addPermission(name="View", klass="issue",
-                        description="User is allowed to access issues")
-        self.db.security.getPermission('View', 'issue')
+
+        add = self.db.security.addPermission
+        get = self.db.security.getPermission
+
+        # class
+        ei = add(name="Edit", klass="issue")
+        self.assertEquals(get('Edit', 'issue'), ei)
+        ai = add(name="View", klass="issue")
+        self.assertEquals(get('View', 'issue'), ai)
+
+        # property
+        epi = add(name="Edit", klass="issue", properties=['title'])
+        self.assertEquals(get('Edit', 'issue', properties=['title']), epi)
+        api = add(name="View", klass="issue", properties=['title'])
+        self.assertEquals(get('View', 'issue', properties=['title']), api)
+        
+        # check function
+        dummy = lambda: 0
+        eci = add(name="Edit", klass="issue", check=dummy)
+        self.assertEquals(get('Edit', 'issue', check=dummy), eci)
+        aci = add(name="View", klass="issue", check=dummy)
+        self.assertEquals(get('View', 'issue', check=dummy), aci)
+
+        # all
+        epci = add(name="Edit", klass="issue", properties=['title'],
+            check=dummy)
+        self.assertEquals(get('Edit', 'issue', properties=['title'],
+            check=dummy), epci)
+        apci = add(name="View", klass="issue", properties=['title'],
+            check=dummy)
+        self.assertEquals(get('View', 'issue', properties=['title'],
+            check=dummy), apci)
 
     def testDBinit(self):
-        self.db.user.create(username="anonymous", roles='User')
+        self.db.user.create(username="demo", roles='User')
+        self.db.user.create(username="anonymous", roles='Anonymous')
 
     def testAccessControls(self):
-        self.testDBinit()
-        ei = self.db.security.addPermission(name="Edit", klass="issue",
-                        description="User is allowed to edit issues")
-        self.db.security.addPermissionToRole('User', ei)
+        add = self.db.security.addPermission
+        has = self.db.security.hasPermission
+        addRole = self.db.security.addRole
+        addToRole = self.db.security.addPermissionToRole
+
+        none = self.db.user.create(username='none', roles='None')
+
+        # test admin access
+        addRole(name='Super')
+        addToRole('Super', add(name="Test"))
+        super = self.db.user.create(username='super', roles='Super')
 
         # test class-level access
-        userid = self.db.user.lookup('admin')
-        self.assertEquals(self.db.security.hasPermission('Edit', userid,
-            'issue'), 1)
-        self.assertEquals(self.db.security.hasPermission('Edit', userid,
-            'user'), 1)
-        userid = self.db.user.lookup('anonymous')
-        self.assertEquals(self.db.security.hasPermission('Edit', userid,
-            'issue'), 1)
-        self.assertEquals(self.db.security.hasPermission('Edit', userid,
-            'user'), 0)
-        self.assertEquals(self.db.security.hasPermission('View', userid,
-            'issue'), 0)
-
-        # test node-level access
-        issueid = self.db.issue.create(title='foo', assignedto='admin')
-        userid = self.db.user.lookup('admin')
-        self.assertEquals(self.db.security.hasNodePermission('issue',
-            issueid, assignedto=userid), 1)
-        self.assertEquals(self.db.security.hasNodePermission('issue',
-            issueid, nosy=userid), 0)
-        self.db.issue.set(issueid, nosy=[userid])
-        self.assertEquals(self.db.security.hasNodePermission('issue',
-            issueid, nosy=userid), 1)
+        addRole(name='Role1')
+        addToRole('Role1', add(name="Test", klass="test"))
+        user1 = self.db.user.create(username='user1', roles='Role1')
+        self.assertEquals(has('Test', user1, 'test'), 1)
+        self.assertEquals(has('Test', super, 'test'), 1)
+        self.assertEquals(has('Test', none, 'test'), 0)
+
+        # property
+        addRole(name='Role2')
+        addToRole('Role2', add(name="Test", klass="test", properties=['a','b']))
+        user2 = self.db.user.create(username='user2', roles='Role2')
+        # *any* access to class
+        self.assertEquals(has('Test', user1, 'test'), 1)
+        self.assertEquals(has('Test', user2, 'test'), 1)
+
+        # *any* access to item
+        self.assertEquals(has('Test', user1, 'test', itemid='1'), 1)
+        self.assertEquals(has('Test', user2, 'test', itemid='1'), 1)
+        self.assertEquals(has('Test', super, 'test', itemid='1'), 1)
+        self.assertEquals(has('Test', none, 'test', itemid='1'), 0)
+
+        # now property test
+        self.assertEquals(has('Test', user2, 'test', property='a'), 1)
+        self.assertEquals(has('Test', user2, 'test', property='b'), 1)
+        self.assertEquals(has('Test', user2, 'test', property='c'), 0)
+        self.assertEquals(has('Test', user1, 'test', property='a'), 1)
+        self.assertEquals(has('Test', user1, 'test', property='b'), 1)
+        self.assertEquals(has('Test', user1, 'test', property='c'), 1)
+        self.assertEquals(has('Test', super, 'test', property='a'), 1)
+        self.assertEquals(has('Test', super, 'test', property='b'), 1)
+        self.assertEquals(has('Test', super, 'test', property='c'), 1)
+        self.assertEquals(has('Test', none, 'test', property='a'), 0)
+        self.assertEquals(has('Test', none, 'test', property='b'), 0)
+        self.assertEquals(has('Test', none, 'test', property='c'), 0)
+        self.assertEquals(has('Test', none, 'test'), 0)
+
+        # check function
+        check = lambda db, userid, itemid: itemid == '1'
+        addRole(name='Role3')
+        addToRole('Role3', add(name="Test", klass="test", check=check))
+        user3 = self.db.user.create(username='user3', roles='Role3')
+        # *any* access to class
+        self.assertEquals(has('Test', user1, 'test'), 1)
+        self.assertEquals(has('Test', user2, 'test'), 1)
+        self.assertEquals(has('Test', user3, 'test'), 1)
+        self.assertEquals(has('Test', none, 'test'), 0)
+        # now check function
+        self.assertEquals(has('Test', user3, 'test', itemid='1'), 1)
+        self.assertEquals(has('Test', user3, 'test', itemid='2'), 0)
+        self.assertEquals(has('Test', user2, 'test', itemid='1'), 1)
+        self.assertEquals(has('Test', user2, 'test', itemid='2'), 1)
+        self.assertEquals(has('Test', user1, 'test', itemid='2'), 1)
+        self.assertEquals(has('Test', user1, 'test', itemid='2'), 1)
+        self.assertEquals(has('Test', super, 'test', itemid='1'), 1)
+        self.assertEquals(has('Test', super, 'test', itemid='2'), 1)
+        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()
@@ -108,4 +214,4 @@ if __name__ == '__main__':
     runner = unittest.TextTestRunner()
     unittest.main(testRunner=runner)
 
-# vim: set filetype=python ts=4 sw=4 et si
+# vim: set filetype=python sts=4 sw=4 et si :