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