server/test/unittest_security.py
branch3.5
changeset 2920 64322aa83a1d
parent 2608 21856eda34f6
child 2968 0e3460341023
child 3252 c0e10da6f1cf
equal deleted inserted replaced
2919:662f35236d1c 2920:64322aa83a1d
   263         card1 = self.execute("INSERT Card X: X title 'cool'")[0][0]
   263         card1 = self.execute("INSERT Card X: X title 'cool'")[0][0]
   264         self.execute('SET X owned_by U WHERE X eid %(x)s, U login "iaminusersgrouponly"', {'x': card1}, 'x')
   264         self.execute('SET X owned_by U WHERE X eid %(x)s, U login "iaminusersgrouponly"', {'x': card1}, 'x')
   265         self.commit()
   265         self.commit()
   266         cnx = self.login('iaminusersgrouponly')
   266         cnx = self.login('iaminusersgrouponly')
   267         cu = cnx.cursor()
   267         cu = cnx.cursor()
   268         aff2 = cu.execute("INSERT Affaire X: X sujet 'cool', X in_state S WHERE S name 'pitetre'")[0][0]
   268         aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
   269         soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0]
   269         soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0]
   270         cu.execute("SET A concerne S WHERE A eid %(a)s, S eid %(s)s", {'a': aff2, 's': soc1},
   270         cu.execute("SET A concerne S WHERE A eid %(a)s, S eid %(s)s", {'a': aff2, 's': soc1},
   271                    ('a', 's'))
   271                    ('a', 's'))
   272         cnx.commit()
   272         cnx.commit()
   273         self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x':aff1}, 'x')
   273         self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x':aff1}, 'x')
   345         cnx.commit()
   345         cnx.commit()
   346         cnx.close()
   346         cnx.close()
   347 
   347 
   348     def test_attribute_security_rqlexpr(self):
   348     def test_attribute_security_rqlexpr(self):
   349         # Note.para attribute editable by managers or if the note is in "todo" state
   349         # Note.para attribute editable by managers or if the note is in "todo" state
   350         eid = self.execute("INSERT Note X: X para 'bidule', X in_state S WHERE S name 'done'")[0][0]
   350         note = self.execute("INSERT Note X: X para 'bidule'").get_entity(0, 0)
   351         self.commit()
   351         self.commit()
   352         self.execute('SET X para "truc" WHERE X eid %(x)s', {'x': eid}, 'x')
   352         note.fire_transition('markasdone')
   353         self.commit()
   353         self.execute('SET X para "truc" WHERE X eid %(x)s', {'x': note.eid}, 'x')
   354         cnx = self.login('iaminusersgrouponly')
   354         self.commit()
   355         cu = cnx.cursor()
   355         cnx = self.login('iaminusersgrouponly')
   356         cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': eid}, 'x')
   356         cu = cnx.cursor()
   357         self.assertRaises(Unauthorized, cnx.commit)
   357         cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note.eid}, 'x')
   358         eid2 = cu.execute("INSERT Note X: X para 'bidule'")[0][0]
   358         self.assertRaises(Unauthorized, cnx.commit)
   359         cnx.commit()
   359         note2 = cu.execute("INSERT Note X: X para 'bidule'").get_entity(0, 0)
   360         cu.execute("SET X in_state S WHERE X eid %(x)s, S name 'done'", {'x': eid2}, 'x')
   360         cnx.commit()
   361         cnx.commit()
   361         note2.fire_transition('markasdone')
   362         self.assertEquals(len(cu.execute('Any X WHERE X in_state S, S name "todo", X eid %(x)s', {'x': eid2}, 'x')),
   362         cnx.commit()
       
   363         self.assertEquals(len(cu.execute('Any X WHERE X in_state S, S name "todo", X eid %(x)s', {'x': note2.eid}, 'x')),
   363                           0)
   364                           0)
   364         cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': eid2}, 'x')
   365         cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note2.eid}, 'x')
   365         self.assertRaises(Unauthorized, cnx.commit)
   366         self.assertRaises(Unauthorized, cnx.commit)
   366         cu.execute("SET X in_state S WHERE X eid %(x)s, S name 'todo'", {'x': eid2}, 'x')
   367         note2.fire_transition('redoit')
   367         cnx.commit()
   368         cnx.commit()
   368         cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': eid2}, 'x')
   369         cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note2.eid}, 'x')
   369         cnx.commit()
   370         cnx.commit()
   370 
   371 
   371     def test_attribute_read_security(self):
   372     def test_attribute_read_security(self):
   372         # anon not allowed to see users'login, but they can see users
   373         # anon not allowed to see users'login, but they can see users
   373         self.repo.schema['CWUser'].set_groups('read', ('guests', 'users', 'managers'))
   374         self.repo.schema['CWUser'].set_groups('read', ('guests', 'users', 'managers'))
   396         # due to security test, affaire has to concerne a societe the user owns
   397         # due to security test, affaire has to concerne a societe the user owns
   397         cu.execute('INSERT Societe X: X nom "ARCTIA"')
   398         cu.execute('INSERT Societe X: X nom "ARCTIA"')
   398         cu.execute('INSERT Affaire X: X ref "ARCT01", X concerne S WHERE S nom "ARCTIA"')
   399         cu.execute('INSERT Affaire X: X ref "ARCT01", X concerne S WHERE S nom "ARCTIA"')
   399         cnx.commit()
   400         cnx.commit()
   400         self.restore_connection()
   401         self.restore_connection()
   401         self.execute('SET X in_state S WHERE X ref "ARCT01", S name "ben non"')
   402         affaire = self.execute('Any X WHERE X ref "ARCT01"').get_entity(0, 0)
       
   403         affaire.fire_transition('abort')
   402         self.commit()
   404         self.commit()
   403         self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01"')),
   405         self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01"')),
   404                           2)
   406                           1)
   405         self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01",'
   407         self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01",'
   406                                            'X owned_by U, U login "admin"')),
   408                                            'X owned_by U, U login "admin"')),
   407                           1) # TrInfo at the above state change
   409                           1) # TrInfo at the above state change
   408         self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01",'
       
   409                                            'X owned_by U, U login "iaminusersgrouponly"')),
       
   410                           1) # TrInfo created at creation time
       
   411         cnx = self.login('iaminusersgrouponly')
   410         cnx = self.login('iaminusersgrouponly')
   412         cu = cnx.cursor()
   411         cu = cnx.cursor()
   413         cu.execute('DELETE Affaire X WHERE X ref "ARCT01"')
   412         cu.execute('DELETE Affaire X WHERE X ref "ARCT01"')
   414         cnx.commit()
   413         cnx.commit()
   415         self.failIf(cu.execute('Affaire X'))
   414         self.failIf(cu.execute('Affaire X'))
   497         # needed to remove rql expr granting update perm to the user
   496         # needed to remove rql expr granting update perm to the user
   498         self.schema['Affaire'].set_rqlexprs('update', ())
   497         self.schema['Affaire'].set_rqlexprs('update', ())
   499         self.assertRaises(Unauthorized,
   498         self.assertRaises(Unauthorized,
   500                           self.schema['Affaire'].check_perm, session, 'update', eid)
   499                           self.schema['Affaire'].check_perm, session, 'update', eid)
   501         cu = cnx.cursor()
   500         cu = cnx.cursor()
   502         cu.execute('SET X in_state S WHERE X ref "ARCT01", S name "ben non"')
   501         self.schema['Affaire'].set_groups('read', ('users',))
   503         cnx.commit()
   502         try:
   504         # though changing a user state (even logged user) is reserved to managers
   503             aff = cu.execute('Any X WHERE X ref "ARCT01"').get_entity(0, 0)
   505         rql = u"SET X in_state S WHERE X eid %(x)s, S name 'deactivated'"
   504             aff.fire_transition('abort')
   506         # XXX wether it should raise Unauthorized or ValidationError is not clear
   505             cnx.commit()
   507         # the best would probably ValidationError if the transition doesn't exist
   506             # though changing a user state (even logged user) is reserved to managers
   508         # from the current state but Unauthorized if it exists but user can't pass it
   507             user = cnx.user(self.current_session())
   509         self.assertRaises(ValidationError, cu.execute, rql, {'x': cnx.user(self.current_session()).eid}, 'x')
   508             # XXX wether it should raise Unauthorized or ValidationError is not clear
       
   509             # the best would probably ValidationError if the transition doesn't exist
       
   510             # from the current state but Unauthorized if it exists but user can't pass it
       
   511             self.assertRaises(ValidationError, user.fire_transition, 'deactivate')
       
   512         finally:
       
   513             self.schema['Affaire'].set_groups('read', ('managers',))
   510 
   514 
   511     def test_trinfo_security(self):
   515     def test_trinfo_security(self):
   512         aff = self.execute('INSERT Affaire X: X ref "ARCT01"').get_entity(0, 0)
   516         aff = self.execute('INSERT Affaire X: X ref "ARCT01"').get_entity(0, 0)
   513         self.commit()
   517         self.commit()
       
   518         aff.fire_transition('abort')
       
   519         self.commit()
   514         # can change tr info comment
   520         # can change tr info comment
   515         self.execute('SET TI comment %(c)s WHERE TI wf_info_for X, X ref "ARCT01"',
   521         self.execute('SET TI comment %(c)s WHERE TI wf_info_for X, X ref "ARCT01"',
   516                      {'c': u'creation'})
   522                      {'c': u'bouh!'})
   517         self.commit()
   523         self.commit()
   518         aff.clear_related_cache('wf_info_for', 'object')
   524         aff.clear_related_cache('wf_info_for', 'object')
   519         self.assertEquals(aff.latest_trinfo().comment, 'creation')
   525         trinfo = aff.latest_trinfo()
       
   526         self.assertEquals(trinfo.comment, 'bouh!')
   520         # but not from_state/to_state
   527         # but not from_state/to_state
   521         self.execute('SET X in_state S WHERE X ref "ARCT01", S name "ben non"')
       
   522         self.commit()
       
   523         aff.clear_related_cache('wf_info_for', role='object')
   528         aff.clear_related_cache('wf_info_for', role='object')
   524         trinfo = aff.latest_trinfo()
       
   525         self.assertRaises(Unauthorized,
   529         self.assertRaises(Unauthorized,
   526                           self.execute, 'SET TI from_state S WHERE TI eid %(ti)s, S name "ben non"',
   530                           self.execute, 'SET TI from_state S WHERE TI eid %(ti)s, S name "ben non"',
   527                           {'ti': trinfo.eid}, 'ti')
   531                           {'ti': trinfo.eid}, 'ti')
   528         self.assertRaises(Unauthorized,
   532         self.assertRaises(Unauthorized,
   529                           self.execute, 'SET TI to_state S WHERE TI eid %(ti)s, S name "pitetre"',
   533                           self.execute, 'SET TI to_state S WHERE TI eid %(ti)s, S name "pitetre"',