79 |
79 |
80 def test_not_relation_read_security(self): |
80 def test_not_relation_read_security(self): |
81 cnx = self.login('iaminusersgrouponly') |
81 cnx = self.login('iaminusersgrouponly') |
82 self.hijack_source_execute() |
82 self.hijack_source_execute() |
83 self.execute('Any U WHERE NOT A todo_by U, A is Affaire') |
83 self.execute('Any U WHERE NOT A todo_by U, A is Affaire') |
84 self.assertEquals(self.query[0][1].as_string(), |
84 self.assertEqual(self.query[0][1].as_string(), |
85 'Any U WHERE NOT EXISTS(A todo_by U), A is Affaire') |
85 'Any U WHERE NOT EXISTS(A todo_by U), A is Affaire') |
86 self.execute('Any U WHERE NOT EXISTS(A todo_by U), A is Affaire') |
86 self.execute('Any U WHERE NOT EXISTS(A todo_by U), A is Affaire') |
87 self.assertEquals(self.query[0][1].as_string(), |
87 self.assertEqual(self.query[0][1].as_string(), |
88 'Any U WHERE NOT EXISTS(A todo_by U), A is Affaire') |
88 'Any U WHERE NOT EXISTS(A todo_by U), A is Affaire') |
89 |
89 |
90 class SecurityTC(BaseSecurityTC): |
90 class SecurityTC(BaseSecurityTC): |
91 |
91 |
92 def setUp(self): |
92 def setUp(self): |
101 def test_insert_security(self): |
101 def test_insert_security(self): |
102 cnx = self.login('anon') |
102 cnx = self.login('anon') |
103 cu = cnx.cursor() |
103 cu = cnx.cursor() |
104 cu.execute("INSERT Personne X: X nom 'bidule'") |
104 cu.execute("INSERT Personne X: X nom 'bidule'") |
105 self.assertRaises(Unauthorized, cnx.commit) |
105 self.assertRaises(Unauthorized, cnx.commit) |
106 self.assertEquals(cu.execute('Personne X').rowcount, 1) |
106 self.assertEqual(cu.execute('Personne X').rowcount, 1) |
107 |
107 |
108 def test_insert_rql_permission(self): |
108 def test_insert_rql_permission(self): |
109 # test user can only add une affaire related to a societe he owns |
109 # test user can only add une affaire related to a societe he owns |
110 cnx = self.login('iaminusersgrouponly') |
110 cnx = self.login('iaminusersgrouponly') |
111 cu = cnx.cursor() |
111 cu = cnx.cursor() |
112 cu.execute("INSERT Affaire X: X sujet 'cool'") |
112 cu.execute("INSERT Affaire X: X sujet 'cool'") |
113 self.assertRaises(Unauthorized, cnx.commit) |
113 self.assertRaises(Unauthorized, cnx.commit) |
114 # test nothing has actually been inserted |
114 # test nothing has actually been inserted |
115 self.restore_connection() |
115 self.restore_connection() |
116 self.assertEquals(self.execute('Affaire X').rowcount, 1) |
116 self.assertEqual(self.execute('Affaire X').rowcount, 1) |
117 cnx = self.login('iaminusersgrouponly') |
117 cnx = self.login('iaminusersgrouponly') |
118 cu = cnx.cursor() |
118 cu = cnx.cursor() |
119 cu.execute("INSERT Affaire X: X sujet 'cool'") |
119 cu.execute("INSERT Affaire X: X sujet 'cool'") |
120 cu.execute("INSERT Societe X: X nom 'chouette'") |
120 cu.execute("INSERT Societe X: X nom 'chouette'") |
121 cu.execute("SET A concerne S WHERE A sujet 'cool', S nom 'chouette'") |
121 cu.execute("SET A concerne S WHERE A sujet 'cool', S nom 'chouette'") |
126 cu = cnx.cursor() |
126 cu = cnx.cursor() |
127 # local security check |
127 # local security check |
128 cu.execute( "SET X nom 'bidulechouette' WHERE X is Personne") |
128 cu.execute( "SET X nom 'bidulechouette' WHERE X is Personne") |
129 self.assertRaises(Unauthorized, cnx.commit) |
129 self.assertRaises(Unauthorized, cnx.commit) |
130 self.restore_connection() |
130 self.restore_connection() |
131 self.assertEquals(self.execute('Personne X WHERE X nom "bidulechouette"').rowcount, 0) |
131 self.assertEqual(self.execute('Personne X WHERE X nom "bidulechouette"').rowcount, 0) |
132 |
132 |
133 def test_update_security_2(self): |
133 def test_update_security_2(self): |
134 cnx = self.login('anon') |
134 cnx = self.login('anon') |
135 cu = cnx.cursor() |
135 cu = cnx.cursor() |
136 self.repo.schema['Personne'].set_action_permissions('read', ('users', 'managers')) |
136 self.repo.schema['Personne'].set_action_permissions('read', ('users', 'managers')) |
137 self.repo.schema['Personne'].set_action_permissions('add', ('guests', 'users', 'managers')) |
137 self.repo.schema['Personne'].set_action_permissions('add', ('guests', 'users', 'managers')) |
138 self.assertRaises(Unauthorized, cu.execute, "SET X nom 'bidulechouette' WHERE X is Personne") |
138 self.assertRaises(Unauthorized, cu.execute, "SET X nom 'bidulechouette' WHERE X is Personne") |
139 #self.assertRaises(Unauthorized, cnx.commit) |
139 #self.assertRaises(Unauthorized, cnx.commit) |
140 # test nothing has actually been inserted |
140 # test nothing has actually been inserted |
141 self.restore_connection() |
141 self.restore_connection() |
142 self.assertEquals(self.execute('Personne X WHERE X nom "bidulechouette"').rowcount, 0) |
142 self.assertEqual(self.execute('Personne X WHERE X nom "bidulechouette"').rowcount, 0) |
143 |
143 |
144 def test_update_security_3(self): |
144 def test_update_security_3(self): |
145 cnx = self.login('iaminusersgrouponly') |
145 cnx = self.login('iaminusersgrouponly') |
146 cu = cnx.cursor() |
146 cu = cnx.cursor() |
147 cu.execute("INSERT Personne X: X nom 'biduuule'") |
147 cu.execute("INSERT Personne X: X nom 'biduuule'") |
208 # should raise Unauthorized since user don't own S |
208 # should raise Unauthorized since user don't own S |
209 # though this won't actually do anything since the selection query won't return anything |
209 # though this won't actually do anything since the selection query won't return anything |
210 cnx.commit() |
210 cnx.commit() |
211 # to actually get Unauthorized exception, try to insert a relation were we can read both entities |
211 # to actually get Unauthorized exception, try to insert a relation were we can read both entities |
212 rset = cu.execute('Personne P') |
212 rset = cu.execute('Personne P') |
213 self.assertEquals(len(rset), 1) |
213 self.assertEqual(len(rset), 1) |
214 ent = rset.get_entity(0, 0) |
214 ent = rset.get_entity(0, 0) |
215 session.set_pool() # necessary |
215 session.set_pool() # necessary |
216 self.assertRaises(Unauthorized, ent.cw_check_perm, 'update') |
216 self.assertRaises(Unauthorized, ent.cw_check_perm, 'update') |
217 self.assertRaises(Unauthorized, |
217 self.assertRaises(Unauthorized, |
218 cu.execute, "SET P travaille S WHERE P is Personne, S is Societe") |
218 cu.execute, "SET P travaille S WHERE P is Personne, S is Societe") |
219 # test nothing has actually been inserted: |
219 # test nothing has actually been inserted: |
220 self.assertEquals(cu.execute('Any P,S WHERE P travaille S,P is Personne, S is Societe').rowcount, 0) |
220 self.assertEqual(cu.execute('Any P,S WHERE P travaille S,P is Personne, S is Societe').rowcount, 0) |
221 cu.execute("INSERT Societe X: X nom 'chouette'") |
221 cu.execute("INSERT Societe X: X nom 'chouette'") |
222 cu.execute("SET A concerne S WHERE A is Affaire, S nom 'chouette'") |
222 cu.execute("SET A concerne S WHERE A is Affaire, S nom 'chouette'") |
223 cnx.commit() |
223 cnx.commit() |
224 |
224 |
225 def test_delete_relation_rql_permission(self): |
225 def test_delete_relation_rql_permission(self): |
276 eid = self.execute("INSERT Affaire X: X sujet 'cool'")[0][0] |
276 eid = self.execute("INSERT Affaire X: X sujet 'cool'")[0][0] |
277 self.commit() |
277 self.commit() |
278 cnx = self.login('iaminusersgrouponly') |
278 cnx = self.login('iaminusersgrouponly') |
279 cu = cnx.cursor() |
279 cu = cnx.cursor() |
280 rset = cu.execute('Affaire X') |
280 rset = cu.execute('Affaire X') |
281 self.assertEquals(rset.rows, []) |
281 self.assertEqual(rset.rows, []) |
282 self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid}) |
282 self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid}) |
283 # cache test |
283 # cache test |
284 self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid}) |
284 self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid}) |
285 aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0] |
285 aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0] |
286 soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0] |
286 soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0] |
287 cu.execute("SET A concerne S WHERE A is Affaire, S is Societe") |
287 cu.execute("SET A concerne S WHERE A is Affaire, S is Societe") |
288 cnx.commit() |
288 cnx.commit() |
289 rset = cu.execute('Any X WHERE X eid %(x)s', {'x': aff2}) |
289 rset = cu.execute('Any X WHERE X eid %(x)s', {'x': aff2}) |
290 self.assertEquals(rset.rows, [[aff2]]) |
290 self.assertEqual(rset.rows, [[aff2]]) |
291 # more cache test w/ NOT eid |
291 # more cache test w/ NOT eid |
292 rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': eid}) |
292 rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': eid}) |
293 self.assertEquals(rset.rows, [[aff2]]) |
293 self.assertEqual(rset.rows, [[aff2]]) |
294 rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': aff2}) |
294 rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': aff2}) |
295 self.assertEquals(rset.rows, []) |
295 self.assertEqual(rset.rows, []) |
296 # test can't update an attribute of an entity that can't be readen |
296 # test can't update an attribute of an entity that can't be readen |
297 self.assertRaises(Unauthorized, cu.execute, 'SET X sujet "hacked" WHERE X eid %(x)s', {'x': eid}) |
297 self.assertRaises(Unauthorized, cu.execute, 'SET X sujet "hacked" WHERE X eid %(x)s', {'x': eid}) |
298 |
298 |
299 |
299 |
300 def test_entity_created_in_transaction(self): |
300 def test_entity_created_in_transaction(self): |
327 cnx.commit() |
327 cnx.commit() |
328 self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x':aff1}) |
328 self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x':aff1}) |
329 self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2})) |
329 self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2})) |
330 self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':card1})) |
330 self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':card1})) |
331 rset = cu.execute("Any X WHERE X has_text 'cool'") |
331 rset = cu.execute("Any X WHERE X has_text 'cool'") |
332 self.assertEquals(sorted(eid for eid, in rset.rows), |
332 self.assertEqual(sorted(eid for eid, in rset.rows), |
333 [card1, aff2]) |
333 [card1, aff2]) |
334 |
334 |
335 def test_read_erqlexpr_has_text2(self): |
335 def test_read_erqlexpr_has_text2(self): |
336 self.execute("INSERT Personne X: X nom 'bidule'") |
336 self.execute("INSERT Personne X: X nom 'bidule'") |
337 self.execute("INSERT Societe X: X nom 'bidule'") |
337 self.execute("INSERT Societe X: X nom 'bidule'") |
338 self.commit() |
338 self.commit() |
339 self.schema['Personne'].set_action_permissions('read', ('managers',)) |
339 self.schema['Personne'].set_action_permissions('read', ('managers',)) |
340 cnx = self.login('iaminusersgrouponly') |
340 cnx = self.login('iaminusersgrouponly') |
341 cu = cnx.cursor() |
341 cu = cnx.cursor() |
342 rset = cu.execute('Any N WHERE N has_text "bidule"') |
342 rset = cu.execute('Any N WHERE N has_text "bidule"') |
343 self.assertEquals(len(rset.rows), 1, rset.rows) |
343 self.assertEqual(len(rset.rows), 1, rset.rows) |
344 rset = cu.execute('Any N WITH N BEING (Any N WHERE N has_text "bidule")') |
344 rset = cu.execute('Any N WITH N BEING (Any N WHERE N has_text "bidule")') |
345 self.assertEquals(len(rset.rows), 1, rset.rows) |
345 self.assertEqual(len(rset.rows), 1, rset.rows) |
346 |
346 |
347 def test_read_erqlexpr_optional_rel(self): |
347 def test_read_erqlexpr_optional_rel(self): |
348 self.execute("INSERT Personne X: X nom 'bidule'") |
348 self.execute("INSERT Personne X: X nom 'bidule'") |
349 self.execute("INSERT Societe X: X nom 'bidule'") |
349 self.execute("INSERT Societe X: X nom 'bidule'") |
350 self.commit() |
350 self.commit() |
351 self.schema['Personne'].set_action_permissions('read', ('managers',)) |
351 self.schema['Personne'].set_action_permissions('read', ('managers',)) |
352 cnx = self.login('anon') |
352 cnx = self.login('anon') |
353 cu = cnx.cursor() |
353 cu = cnx.cursor() |
354 rset = cu.execute('Any N,U WHERE N has_text "bidule", N owned_by U?') |
354 rset = cu.execute('Any N,U WHERE N has_text "bidule", N owned_by U?') |
355 self.assertEquals(len(rset.rows), 1, rset.rows) |
355 self.assertEqual(len(rset.rows), 1, rset.rows) |
356 |
356 |
357 def test_read_erqlexpr_aggregat(self): |
357 def test_read_erqlexpr_aggregat(self): |
358 self.execute("INSERT Affaire X: X sujet 'cool'")[0][0] |
358 self.execute("INSERT Affaire X: X sujet 'cool'")[0][0] |
359 self.commit() |
359 self.commit() |
360 cnx = self.login('iaminusersgrouponly') |
360 cnx = self.login('iaminusersgrouponly') |
361 cu = cnx.cursor() |
361 cu = cnx.cursor() |
362 rset = cu.execute('Any COUNT(X) WHERE X is Affaire') |
362 rset = cu.execute('Any COUNT(X) WHERE X is Affaire') |
363 self.assertEquals(rset.rows, [[0]]) |
363 self.assertEqual(rset.rows, [[0]]) |
364 aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0] |
364 aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0] |
365 soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0] |
365 soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0] |
366 cu.execute("SET A concerne S WHERE A is Affaire, S is Societe") |
366 cu.execute("SET A concerne S WHERE A is Affaire, S is Societe") |
367 cnx.commit() |
367 cnx.commit() |
368 rset = cu.execute('Any COUNT(X) WHERE X is Affaire') |
368 rset = cu.execute('Any COUNT(X) WHERE X is Affaire') |
369 self.assertEquals(rset.rows, [[1]]) |
369 self.assertEqual(rset.rows, [[1]]) |
370 rset = cu.execute('Any ETN, COUNT(X) GROUPBY ETN WHERE X is ET, ET name ETN') |
370 rset = cu.execute('Any ETN, COUNT(X) GROUPBY ETN WHERE X is ET, ET name ETN') |
371 values = dict(rset) |
371 values = dict(rset) |
372 self.assertEquals(values['Affaire'], 1) |
372 self.assertEqual(values['Affaire'], 1) |
373 self.assertEquals(values['Societe'], 2) |
373 self.assertEqual(values['Societe'], 2) |
374 rset = cu.execute('Any ETN, COUNT(X) GROUPBY ETN WHERE X is ET, ET name ETN WITH X BEING ((Affaire X) UNION (Societe X))') |
374 rset = cu.execute('Any ETN, COUNT(X) GROUPBY ETN WHERE X is ET, ET name ETN WITH X BEING ((Affaire X) UNION (Societe X))') |
375 self.assertEquals(len(rset), 2) |
375 self.assertEqual(len(rset), 2) |
376 values = dict(rset) |
376 values = dict(rset) |
377 self.assertEquals(values['Affaire'], 1) |
377 self.assertEqual(values['Affaire'], 1) |
378 self.assertEquals(values['Societe'], 2) |
378 self.assertEqual(values['Societe'], 2) |
379 |
379 |
380 |
380 |
381 def test_attribute_security(self): |
381 def test_attribute_security(self): |
382 # only managers should be able to edit the 'test' attribute of Personne entities |
382 # only managers should be able to edit the 'test' attribute of Personne entities |
383 eid = self.execute("INSERT Personne X: X nom 'bidule', X web 'http://www.debian.org', X test TRUE")[0][0] |
383 eid = self.execute("INSERT Personne X: X nom 'bidule', X web 'http://www.debian.org', X test TRUE")[0][0] |
431 cnx = self.login('anon') |
431 cnx = self.login('anon') |
432 cu = cnx.cursor() |
432 cu = cnx.cursor() |
433 rset = cu.execute('CWUser X') |
433 rset = cu.execute('CWUser X') |
434 self.failUnless(rset) |
434 self.failUnless(rset) |
435 x = rset.get_entity(0, 0) |
435 x = rset.get_entity(0, 0) |
436 self.assertEquals(x.login, None) |
436 self.assertEqual(x.login, None) |
437 self.failUnless(x.creation_date) |
437 self.failUnless(x.creation_date) |
438 x = rset.get_entity(1, 0) |
438 x = rset.get_entity(1, 0) |
439 x.complete() |
439 x.complete() |
440 self.assertEquals(x.login, None) |
440 self.assertEqual(x.login, None) |
441 self.failUnless(x.creation_date) |
441 self.failUnless(x.creation_date) |
442 cnx.rollback() |
442 cnx.rollback() |
443 |
443 |
444 class BaseSchemaSecurityTC(BaseSecurityTC): |
444 class BaseSchemaSecurityTC(BaseSecurityTC): |
445 """tests related to the base schema permission configuration""" |
445 """tests related to the base schema permission configuration""" |
454 cnx.commit() |
454 cnx.commit() |
455 self.restore_connection() |
455 self.restore_connection() |
456 affaire = self.execute('Any X WHERE X ref "ARCT01"').get_entity(0, 0) |
456 affaire = self.execute('Any X WHERE X ref "ARCT01"').get_entity(0, 0) |
457 affaire.cw_adapt_to('IWorkflowable').fire_transition('abort') |
457 affaire.cw_adapt_to('IWorkflowable').fire_transition('abort') |
458 self.commit() |
458 self.commit() |
459 self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01"')), |
459 self.assertEqual(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01"')), |
460 1) |
460 1) |
461 self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01",' |
461 self.assertEqual(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01",' |
462 'X owned_by U, U login "admin"')), |
462 'X owned_by U, U login "admin"')), |
463 1) # TrInfo at the above state change |
463 1) # TrInfo at the above state change |
464 cnx = self.login('iaminusersgrouponly') |
464 cnx = self.login('iaminusersgrouponly') |
465 cu = cnx.cursor() |
465 cu = cnx.cursor() |
466 cu.execute('DELETE Affaire X WHERE X ref "ARCT01"') |
466 cu.execute('DELETE Affaire X WHERE X ref "ARCT01"') |
471 cnx = self.login('anon') |
471 cnx = self.login('anon') |
472 anon = cnx.user(self.session) |
472 anon = cnx.user(self.session) |
473 cu = cnx.cursor() |
473 cu = cnx.cursor() |
474 # anonymous user can only read itself |
474 # anonymous user can only read itself |
475 rset = cu.execute('Any L WHERE X owned_by U, U login L') |
475 rset = cu.execute('Any L WHERE X owned_by U, U login L') |
476 self.assertEquals(rset.rows, [['anon']]) |
476 self.assertEqual(rset.rows, [['anon']]) |
477 rset = cu.execute('CWUser X') |
477 rset = cu.execute('CWUser X') |
478 self.assertEquals(rset.rows, [[anon.eid]]) |
478 self.assertEqual(rset.rows, [[anon.eid]]) |
479 # anonymous user can read groups (necessary to check allowed transitions for instance) |
479 # anonymous user can read groups (necessary to check allowed transitions for instance) |
480 self.assert_(cu.execute('CWGroup X')) |
480 self.assert_(cu.execute('CWGroup X')) |
481 # should only be able to read the anonymous user, not another one |
481 # should only be able to read the anonymous user, not another one |
482 origuser = self.adminsession.user |
482 origuser = self.adminsession.user |
483 self.assertRaises(Unauthorized, |
483 self.assertRaises(Unauthorized, |
486 #self.assertRaises(Unauthorized, |
486 #self.assertRaises(Unauthorized, |
487 # cu.execute, 'SET X login "toto" WHERE X eid %(x)s', |
487 # cu.execute, 'SET X login "toto" WHERE X eid %(x)s', |
488 # {'x': self.user.eid}) |
488 # {'x': self.user.eid}) |
489 |
489 |
490 rset = cu.execute('CWUser X WHERE X eid %(x)s', {'x': anon.eid}) |
490 rset = cu.execute('CWUser X WHERE X eid %(x)s', {'x': anon.eid}) |
491 self.assertEquals(rset.rows, [[anon.eid]]) |
491 self.assertEqual(rset.rows, [[anon.eid]]) |
492 # but can't modify it |
492 # but can't modify it |
493 cu.execute('SET X login "toto" WHERE X eid %(x)s', {'x': anon.eid}) |
493 cu.execute('SET X login "toto" WHERE X eid %(x)s', {'x': anon.eid}) |
494 self.assertRaises(Unauthorized, cnx.commit) |
494 self.assertRaises(Unauthorized, cnx.commit) |
495 |
495 |
496 def test_in_group_relation(self): |
496 def test_in_group_relation(self): |
514 beid2 = self.execute('INSERT Bookmark B: B path "?vid=index", B title "index", B bookmarked_by U WHERE U login "anon"')[0][0] |
514 beid2 = self.execute('INSERT Bookmark B: B path "?vid=index", B title "index", B bookmarked_by U WHERE U login "anon"')[0][0] |
515 self.commit() |
515 self.commit() |
516 cnx = self.login('anon') |
516 cnx = self.login('anon') |
517 cu = cnx.cursor() |
517 cu = cnx.cursor() |
518 anoneid = self.session.user.eid |
518 anoneid = self.session.user.eid |
519 self.assertEquals(cu.execute('Any T,P ORDERBY lower(T) WHERE B is Bookmark,B title T,B path P,' |
519 self.assertEqual(cu.execute('Any T,P ORDERBY lower(T) WHERE B is Bookmark,B title T,B path P,' |
520 'B bookmarked_by U, U eid %s' % anoneid).rows, |
520 'B bookmarked_by U, U eid %s' % anoneid).rows, |
521 [['index', '?vid=index']]) |
521 [['index', '?vid=index']]) |
522 self.assertEquals(cu.execute('Any T,P ORDERBY lower(T) WHERE B is Bookmark,B title T,B path P,' |
522 self.assertEqual(cu.execute('Any T,P ORDERBY lower(T) WHERE B is Bookmark,B title T,B path P,' |
523 'B bookmarked_by U, U eid %(x)s', {'x': anoneid}).rows, |
523 'B bookmarked_by U, U eid %(x)s', {'x': anoneid}).rows, |
524 [['index', '?vid=index']]) |
524 [['index', '?vid=index']]) |
525 # can read others bookmarks as well |
525 # can read others bookmarks as well |
526 self.assertEquals(cu.execute('Any B where B is Bookmark, NOT B bookmarked_by U').rows, |
526 self.assertEqual(cu.execute('Any B where B is Bookmark, NOT B bookmarked_by U').rows, |
527 [[beid1]]) |
527 [[beid1]]) |
528 self.assertRaises(Unauthorized, cu.execute,'DELETE B bookmarked_by U') |
528 self.assertRaises(Unauthorized, cu.execute,'DELETE B bookmarked_by U') |
529 self.assertRaises(Unauthorized, |
529 self.assertRaises(Unauthorized, |
530 cu.execute, 'SET B bookmarked_by U WHERE U eid %(x)s, B eid %(b)s', |
530 cu.execute, 'SET B bookmarked_by U WHERE U eid %(x)s, B eid %(b)s', |
531 {'x': anoneid, 'b': beid1}) |
531 {'x': anoneid, 'b': beid1}) |
580 self.execute('SET TI comment %(c)s WHERE TI wf_info_for X, X ref "ARCT01"', |
580 self.execute('SET TI comment %(c)s WHERE TI wf_info_for X, X ref "ARCT01"', |
581 {'c': u'bouh!'}) |
581 {'c': u'bouh!'}) |
582 self.commit() |
582 self.commit() |
583 aff.cw_clear_relation_cache('wf_info_for', 'object') |
583 aff.cw_clear_relation_cache('wf_info_for', 'object') |
584 trinfo = iworkflowable.latest_trinfo() |
584 trinfo = iworkflowable.latest_trinfo() |
585 self.assertEquals(trinfo.comment, 'bouh!') |
585 self.assertEqual(trinfo.comment, 'bouh!') |
586 # but not from_state/to_state |
586 # but not from_state/to_state |
587 aff.cw_clear_relation_cache('wf_info_for', role='object') |
587 aff.cw_clear_relation_cache('wf_info_for', role='object') |
588 self.assertRaises(Unauthorized, |
588 self.assertRaises(Unauthorized, |
589 self.execute, 'SET TI from_state S WHERE TI eid %(ti)s, S name "ben non"', |
589 self.execute, 'SET TI from_state S WHERE TI eid %(ti)s, S name "ben non"', |
590 {'ti': trinfo.eid}) |
590 {'ti': trinfo.eid}) |