hooks/security.py
changeset 9984 793377697c81
parent 9612 24460d4d64bf
parent 9981 7099bbd685aa
child 10114 6f4b4567b77d
equal deleted inserted replaced
9979:9ccdb3751fbe 9984:793377697c81
     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):