[security] we should save back edited_attributes in case of multiple modification of an entity during the same transaction stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 15 Feb 2010 15:14:27 +0100
branchstable
changeset 4577 049d92fc8614
parent 4576 f8c48a495a6b
child 4578 060c91ced72f
[security] we should save back edited_attributes in case of multiple modification of an entity during the same transaction
hooks/security.py
--- a/hooks/security.py	Mon Feb 15 15:13:47 2010 +0100
+++ b/hooks/security.py	Mon Feb 15 15:14:27 2010 +0100
@@ -12,16 +12,17 @@
 from cubicweb.server import BEFORE_ADD_RELATIONS, ON_COMMIT_ADD_RELATIONS, hook
 
 
-def check_entity_attributes(session, entity):
+def check_entity_attributes(session, entity, editedattrs=None):
     eid = entity.eid
     eschema = entity.e_schema
     # ._default_set is only there on entity creation to indicate unspecified
     # attributes which has been set to a default value defined in the schema
     defaults = getattr(entity, '_default_set', ())
-    try:
-        editedattrs = entity.edited_attributes
-    except AttributeError:
-        editedattrs = entity
+    if editedattrs is None:
+        try:
+            editedattrs = entity.edited_attributes
+        except AttributeError:
+            editedattrs = entity
     for attr in editedattrs:
         if attr in defaults:
             continue
@@ -35,7 +36,7 @@
     def precommit_event(self):
         #print 'CheckEntityPermissionOp', self.session.user, self.entity, self.action
         self.entity.check_perm(self.action)
-        check_entity_attributes(self.session, self.entity)
+        check_entity_attributes(self.session, self.entity, self.editedattrs)
 
     def commit_event(self):
         pass
@@ -63,7 +64,9 @@
     events = ('after_add_entity',)
 
     def __call__(self):
-        _CheckEntityPermissionOp(self._cw, entity=self.entity, action='add')
+        _CheckEntityPermissionOp(self._cw, entity=self.entity,
+                                 editedattrs=tuple(self.entity.edited_attributes),
+                                 action='add')
 
 
 class AfterUpdateEntitySecurityHook(SecurityHook):
@@ -77,7 +80,12 @@
             check_entity_attributes(self._cw, self.entity)
         except Unauthorized:
             self.entity.clear_local_perm_cache('update')
-            _CheckEntityPermissionOp(self._cw, entity=self.entity, action='update')
+            # save back editedattrs in case the entity is reedited later in the
+            # same transaction, which will lead to edited_attributes being
+            # overwritten
+            _CheckEntityPermissionOp(self._cw, entity=self.entity,
+                                     editedattrs=tuple(self.entity.edited_attributes),
+                                     action='update')
 
 
 class BeforeDelEntitySecurityHook(SecurityHook):