10 |
10 |
11 from cubicweb import Unauthorized |
11 from cubicweb import Unauthorized |
12 from cubicweb.server import BEFORE_ADD_RELATIONS, ON_COMMIT_ADD_RELATIONS, hook |
12 from cubicweb.server import BEFORE_ADD_RELATIONS, ON_COMMIT_ADD_RELATIONS, hook |
13 |
13 |
14 |
14 |
15 def check_entity_attributes(session, entity): |
15 def check_entity_attributes(session, entity, editedattrs=None): |
16 eid = entity.eid |
16 eid = entity.eid |
17 eschema = entity.e_schema |
17 eschema = entity.e_schema |
18 # ._default_set is only there on entity creation to indicate unspecified |
18 # ._default_set is only there on entity creation to indicate unspecified |
19 # attributes which has been set to a default value defined in the schema |
19 # attributes which has been set to a default value defined in the schema |
20 defaults = getattr(entity, '_default_set', ()) |
20 defaults = getattr(entity, '_default_set', ()) |
21 try: |
21 if editedattrs is None: |
22 editedattrs = entity.edited_attributes |
22 try: |
23 except AttributeError: |
23 editedattrs = entity.edited_attributes |
24 editedattrs = entity |
24 except AttributeError: |
|
25 editedattrs = entity |
25 for attr in editedattrs: |
26 for attr in editedattrs: |
26 if attr in defaults: |
27 if attr in defaults: |
27 continue |
28 continue |
28 rdef = eschema.rdef(attr) |
29 rdef = eschema.rdef(attr) |
29 if rdef.final: # non final relation are checked by other hooks |
30 if rdef.final: # non final relation are checked by other hooks |
33 |
34 |
34 class _CheckEntityPermissionOp(hook.LateOperation): |
35 class _CheckEntityPermissionOp(hook.LateOperation): |
35 def precommit_event(self): |
36 def precommit_event(self): |
36 #print 'CheckEntityPermissionOp', self.session.user, self.entity, self.action |
37 #print 'CheckEntityPermissionOp', self.session.user, self.entity, self.action |
37 self.entity.check_perm(self.action) |
38 self.entity.check_perm(self.action) |
38 check_entity_attributes(self.session, self.entity) |
39 check_entity_attributes(self.session, self.entity, self.editedattrs) |
39 |
40 |
40 def commit_event(self): |
41 def commit_event(self): |
41 pass |
42 pass |
42 |
43 |
43 |
44 |
61 class AfterAddEntitySecurityHook(SecurityHook): |
62 class AfterAddEntitySecurityHook(SecurityHook): |
62 __regid__ = 'securityafteraddentity' |
63 __regid__ = 'securityafteraddentity' |
63 events = ('after_add_entity',) |
64 events = ('after_add_entity',) |
64 |
65 |
65 def __call__(self): |
66 def __call__(self): |
66 _CheckEntityPermissionOp(self._cw, entity=self.entity, action='add') |
67 _CheckEntityPermissionOp(self._cw, entity=self.entity, |
|
68 editedattrs=tuple(self.entity.edited_attributes), |
|
69 action='add') |
67 |
70 |
68 |
71 |
69 class AfterUpdateEntitySecurityHook(SecurityHook): |
72 class AfterUpdateEntitySecurityHook(SecurityHook): |
70 __regid__ = 'securityafterupdateentity' |
73 __regid__ = 'securityafterupdateentity' |
71 events = ('after_update_entity',) |
74 events = ('after_update_entity',) |
75 # check user has permission right now, if not retry at commit time |
78 # check user has permission right now, if not retry at commit time |
76 self.entity.check_perm('update') |
79 self.entity.check_perm('update') |
77 check_entity_attributes(self._cw, self.entity) |
80 check_entity_attributes(self._cw, self.entity) |
78 except Unauthorized: |
81 except Unauthorized: |
79 self.entity.clear_local_perm_cache('update') |
82 self.entity.clear_local_perm_cache('update') |
80 _CheckEntityPermissionOp(self._cw, entity=self.entity, action='update') |
83 # save back editedattrs in case the entity is reedited later in the |
|
84 # same transaction, which will lead to edited_attributes being |
|
85 # overwritten |
|
86 _CheckEntityPermissionOp(self._cw, entity=self.entity, |
|
87 editedattrs=tuple(self.entity.edited_attributes), |
|
88 action='update') |
81 |
89 |
82 |
90 |
83 class BeforeDelEntitySecurityHook(SecurityHook): |
91 class BeforeDelEntitySecurityHook(SecurityHook): |
84 __regid__ = 'securitybeforedelentity' |
92 __regid__ = 'securitybeforedelentity' |
85 events = ('before_delete_entity',) |
93 events = ('before_delete_entity',) |