equal
deleted
inserted
replaced
23 from cubicweb import Unauthorized |
23 from cubicweb import Unauthorized |
24 from cubicweb.selectors import objectify_selector, lltrace |
24 from cubicweb.selectors import objectify_selector, lltrace |
25 from cubicweb.server import BEFORE_ADD_RELATIONS, ON_COMMIT_ADD_RELATIONS, hook |
25 from cubicweb.server import BEFORE_ADD_RELATIONS, ON_COMMIT_ADD_RELATIONS, hook |
26 |
26 |
27 |
27 |
28 def check_entity_attributes(session, entity, editedattrs=None): |
28 def check_entity_attributes(session, entity, editedattrs=None, creation=False): |
29 eid = entity.eid |
29 eid = entity.eid |
30 eschema = entity.e_schema |
30 eschema = entity.e_schema |
31 # ._cw_skip_security_attributes is there to bypass security for attributes |
31 # ._cw_skip_security_attributes is there to bypass security for attributes |
32 # set by hooks by modifying the entity's dictionnary |
32 # set by hooks by modifying the entity's dictionnary |
33 dontcheck = entity._cw_skip_security_attributes |
33 dontcheck = entity._cw_skip_security_attributes |
40 if attr in dontcheck: |
40 if attr in dontcheck: |
41 continue |
41 continue |
42 rdef = eschema.rdef(attr) |
42 rdef = eschema.rdef(attr) |
43 if rdef.final: # non final relation are checked by other hooks |
43 if rdef.final: # non final relation are checked by other hooks |
44 # add/delete should be equivalent (XXX: unify them into 'update' ?) |
44 # add/delete should be equivalent (XXX: unify them into 'update' ?) |
|
45 if creation and not rdef.permissions.get('update'): |
|
46 continue |
45 rdef.check_perm(session, 'update', eid=eid) |
47 rdef.check_perm(session, 'update', eid=eid) |
46 # don't update dontcheck until everything went fine: see usage in |
48 # don't update dontcheck until everything went fine: see usage in |
47 # after_update_entity, where if we got an Unauthorized at hook time, we will |
49 # after_update_entity, where if we got an Unauthorized at hook time, we will |
48 # retry and commit time |
50 # retry and commit time |
49 dontcheck |= frozenset(editedattrs) |
51 dontcheck |= frozenset(editedattrs) |
56 for values in session.transaction_data.pop('check_entity_perm_op'): |
58 for values in session.transaction_data.pop('check_entity_perm_op'): |
57 entity = session.entity_from_eid(values[0]) |
59 entity = session.entity_from_eid(values[0]) |
58 action = values[1] |
60 action = values[1] |
59 entity.cw_check_perm(action) |
61 entity.cw_check_perm(action) |
60 check_entity_attributes(session, entity, values[2:]) |
62 check_entity_attributes(session, entity, values[2:]) |
|
63 creation=self.creation) |
61 |
64 |
62 def commit_event(self): |
65 def commit_event(self): |
63 pass |
66 pass |
64 |
67 |
65 |
68 |
92 events = ('after_add_entity',) |
95 events = ('after_add_entity',) |
93 |
96 |
94 def __call__(self): |
97 def __call__(self): |
95 hook.set_operation(self._cw, 'check_entity_perm_op', |
98 hook.set_operation(self._cw, 'check_entity_perm_op', |
96 (self.entity.eid, 'add') + tuple(self.entity.edited_attributes), |
99 (self.entity.eid, 'add') + tuple(self.entity.edited_attributes), |
97 _CheckEntityPermissionOp) |
100 _CheckEntityPermissionOp, creation=True) |
98 |
101 |
99 |
102 |
100 class AfterUpdateEntitySecurityHook(SecurityHook): |
103 class AfterUpdateEntitySecurityHook(SecurityHook): |
101 __regid__ = 'securityafterupdateentity' |
104 __regid__ = 'securityafterupdateentity' |
102 events = ('after_update_entity',) |
105 events = ('after_update_entity',) |
111 # save back editedattrs in case the entity is reedited later in the |
114 # save back editedattrs in case the entity is reedited later in the |
112 # same transaction, which will lead to edited_attributes being |
115 # same transaction, which will lead to edited_attributes being |
113 # overwritten |
116 # overwritten |
114 hook.set_operation(self._cw, 'check_entity_perm_op', |
117 hook.set_operation(self._cw, 'check_entity_perm_op', |
115 (self.entity.eid, 'update') + tuple(self.entity.edited_attributes), |
118 (self.entity.eid, 'update') + tuple(self.entity.edited_attributes), |
116 _CheckEntityPermissionOp) |
119 _CheckEntityPermissionOp, creation=False) |
117 |
120 |
118 |
121 |
119 class BeforeDelEntitySecurityHook(SecurityHook): |
122 class BeforeDelEntitySecurityHook(SecurityHook): |
120 __regid__ = 'securitybeforedelentity' |
123 __regid__ = 'securitybeforedelentity' |
121 events = ('before_delete_entity',) |
124 events = ('before_delete_entity',) |