equal
deleted
inserted
replaced
1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
1 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
3 # |
3 # |
4 # This file is part of CubicWeb. |
4 # This file is part of CubicWeb. |
5 # |
5 # |
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
32 |
32 |
33 |
33 |
34 def check_entity_attributes(cnx, entity, action, editedattrs=None): |
34 def check_entity_attributes(cnx, entity, action, editedattrs=None): |
35 eid = entity.eid |
35 eid = entity.eid |
36 eschema = entity.e_schema |
36 eschema = entity.e_schema |
|
37 if action == 'delete': |
|
38 eschema.check_perm(session, action, eid=eid) |
|
39 return |
37 # ._cw_skip_security_attributes is there to bypass security for attributes |
40 # ._cw_skip_security_attributes is there to bypass security for attributes |
38 # set by hooks by modifying the entity's dictionary |
41 # set by hooks by modifying the entity's dictionary |
39 if editedattrs is None: |
42 if editedattrs is None: |
40 editedattrs = entity.cw_edited |
43 editedattrs = entity.cw_edited |
41 dontcheck = editedattrs.skip_security |
44 dontcheck = editedattrs.skip_security |
|
45 etypechecked = False |
42 for attr in editedattrs: |
46 for attr in editedattrs: |
43 if attr in dontcheck: |
47 if attr in dontcheck: |
44 continue |
48 continue |
45 rdef = eschema.rdef(attr, takefirst=True) |
49 rdef = eschema.rdef(attr, takefirst=True) |
46 if rdef.final: # non final relation are checked by standard hooks |
50 if rdef.final: # non final relation are checked by standard hooks |
52 # |
56 # |
53 # is deserialized in this order (groups first), and ERQLExpression |
57 # is deserialized in this order (groups first), and ERQLExpression |
54 # implements comparison by rql expression. |
58 # implements comparison by rql expression. |
55 if perms == buildobjs.DEFAULT_ATTRPERMS[action]: |
59 if perms == buildobjs.DEFAULT_ATTRPERMS[action]: |
56 # The default rule is to delegate to the entity |
60 # The default rule is to delegate to the entity |
57 # rule. This is an historical artefact. Hence we take |
61 # rule. This needs to be checked only once. |
58 # this object as a marker saying "no specific" |
62 if not etypechecked: |
59 # permission rule for this attribute. Thus we just do |
63 entity.cw_check_perm(action) |
60 # nothing. |
64 etypechecked = True |
61 continue |
65 continue |
62 if perms == (): |
66 if perms == (): |
63 # That means an immutable attribute; as an optimization, avoid |
67 # That means an immutable attribute; as an optimization, avoid |
64 # going through check_perm. |
68 # going through check_perm. |
65 raise Unauthorized(action, str(rdef)) |
69 raise Unauthorized(action, str(rdef)) |
69 class CheckEntityPermissionOp(hook.DataOperationMixIn, hook.LateOperation): |
73 class CheckEntityPermissionOp(hook.DataOperationMixIn, hook.LateOperation): |
70 def precommit_event(self): |
74 def precommit_event(self): |
71 cnx = self.cnx |
75 cnx = self.cnx |
72 for eid, action, edited in self.get_data(): |
76 for eid, action, edited in self.get_data(): |
73 entity = cnx.entity_from_eid(eid) |
77 entity = cnx.entity_from_eid(eid) |
74 entity.cw_check_perm(action) |
|
75 check_entity_attributes(cnx, entity, action, edited) |
78 check_entity_attributes(cnx, entity, action, edited) |
76 |
79 |
77 |
80 |
78 class CheckRelationPermissionOp(hook.DataOperationMixIn, hook.LateOperation): |
81 class CheckRelationPermissionOp(hook.DataOperationMixIn, hook.LateOperation): |
79 def precommit_event(self): |
82 def precommit_event(self): |