test and fix wf history security
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 24 Jul 2009 19:40:46 +0200
changeset 2501 fa86d99c2c3a
parent 2500 e342a8662c8d
child 2502 324ec2056d56
test and fix wf history security
schemas/__init__.py
schemas/workflow.py
server/test/unittest_security.py
--- a/schemas/__init__.py	Fri Jul 24 19:39:53 2009 +0200
+++ b/schemas/__init__.py	Fri Jul 24 19:40:46 2009 +0200
@@ -11,3 +11,11 @@
     'add':    ('managers',),
     'delete': ('managers',),
     }
+
+# permissions for relation type that should only set by hooks using unsafe
+# execute, readable by anyone
+HOOKS_RTYPE_PERMS = {
+    'read':   ('managers', 'users', 'guests',),
+    'add':    (),
+    'delete': (),
+    }
--- a/schemas/workflow.py	Fri Jul 24 19:39:53 2009 +0200
+++ b/schemas/workflow.py	Fri Jul 24 19:40:46 2009 +0200
@@ -11,7 +11,7 @@
 from yams.buildobjs import (EntityType, RelationType, SubjectRelation,
                             ObjectRelation, RichString, String)
 from cubicweb.schema import RQLConstraint
-from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS
+from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS, HOOKS_RTYPE_PERMS
 
 class State(EntityType):
     """used to associate simple states to an entity type and/or to define
@@ -75,11 +75,12 @@
 
 
 class from_state(RelationType):
-    permissions = META_RTYPE_PERMS
+    permissions = HOOKS_RTYPE_PERMS
     inlined = True
 class to_state(RelationType):
-    permissions = META_RTYPE_PERMS
+    permissions = HOOKS_RTYPE_PERMS
     inlined = True
+
 class wf_info_for(RelationType):
     """link a transition information to its object"""
     permissions = {
--- a/server/test/unittest_security.py	Fri Jul 24 19:39:53 2009 +0200
+++ b/server/test/unittest_security.py	Fri Jul 24 19:40:46 2009 +0200
@@ -508,5 +508,25 @@
         # from the current state but Unauthorized if it exists but user can't pass it
         self.assertRaises(ValidationError, cu.execute, rql, {'x': cnx.user(self.current_session()).eid}, 'x')
 
+    def test_trinfo_security(self):
+        aff = self.execute('INSERT Affaire X: X ref "ARCT01"').get_entity(0, 0)
+        self.commit()
+        # can change tr info comment
+        self.execute('SET TI comment %(c)s WHERE TI wf_info_for X, X ref "ARCT01"',
+                     {'c': u'creation'})
+        self.commit()
+        self.assertEquals(aff.latest_trinfo().comment, 'creation')
+        # but not from_state/to_state
+        self.execute('SET X in_state S WHERE X ref "ARCT01", S name "ben non"')
+        self.commit()
+        aff.clear_related_cache('wf_info_for', role='object')
+        trinfo = aff.latest_trinfo()
+        self.assertRaises(Unauthorized,
+                          self.execute, 'SET TI from_state S WHERE TI eid %(ti)s, S name "ben non"',
+                          {'ti': trinfo.eid}, 'ti')
+        self.assertRaises(Unauthorized,
+                          self.execute, 'SET TI to_state S WHERE TI eid %(ti)s, S name "pitetre"',
+                          {'ti': trinfo.eid}, 'ti')
+
 if __name__ == '__main__':
     unittest_main()