hooks/security.py
branchstable
changeset 4577 049d92fc8614
parent 4570 ede247bbbf62
child 4835 13b0b96d7982
equal deleted inserted replaced
4576:f8c48a495a6b 4577:049d92fc8614
    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',)