"""Security hooks: check permissions to add/delete/update entities according tothe user connected to a session:organization: Logilab:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr"""__docformat__="restructuredtext en"fromcubicwebimportUnauthorizedfromcubicweb.server.poolimportLateOperationfromcubicweb.serverimportBEFORE_ADD_RELATIONS,ON_COMMIT_ADD_RELATIONSdefcheck_entity_attributes(session,entity):eid=entity.eideschema=entity.e_schema# ._default_set is only there on entity creation to indicate unspecified# attributes which has been set to a default value defined in the schemadefaults=getattr(entity,'_default_set',())forattrinentity.keys():ifattrindefaults:continuerschema=eschema.subject_relation(attr)ifrschema.is_final():# non final relation are checked by other hooks# add/delete should be equivalent (XXX: unify them into 'update' ?)rschema.check_perm(session,'add',eid)classCheckEntityPermissionOp(LateOperation):defprecommit_event(self):#print 'CheckEntityPermissionOp', self.session.user, self.entity, self.actionself.entity.check_perm(self.action)check_entity_attributes(self.session,self.entity)defcommit_event(self):passclassCheckRelationPermissionOp(LateOperation):defprecommit_event(self):self.rschema.check_perm(self.session,self.action,self.fromeid,self.toeid)defcommit_event(self):passdefafter_add_entity(session,entity):ifnotsession.is_super_session:CheckEntityPermissionOp(session,entity=entity,action='add')defafter_update_entity(session,entity):ifnotsession.is_super_session:try:# check user has permission right now, if not retry at commit timeentity.check_perm('update')check_entity_attributes(session,entity)exceptUnauthorized:CheckEntityPermissionOp(session,entity=entity,action='update')defbefore_del_entity(session,eid):ifnotsession.is_super_session:eschema=session.repo.schema[session.describe(eid)[0]]eschema.check_perm(session,'delete',eid)defbefore_add_relation(session,fromeid,rtype,toeid):ifrtypeinBEFORE_ADD_RELATIONSandnotsession.is_super_session:rschema=session.repo.schema[rtype]rschema.check_perm(session,'add',fromeid,toeid)defafter_add_relation(session,fromeid,rtype,toeid):ifnotrtypeinBEFORE_ADD_RELATIONSandnotsession.is_super_session:rschema=session.repo.schema[rtype]ifrtypeinON_COMMIT_ADD_RELATIONS:CheckRelationPermissionOp(session,action='add',rschema=rschema,fromeid=fromeid,toeid=toeid)else:rschema.check_perm(session,'add',fromeid,toeid)defbefore_del_relation(session,fromeid,rtype,toeid):ifnotsession.is_super_session:session.repo.schema[rtype].check_perm(session,'delete',fromeid,toeid)defregister_security_hooks(hm):"""register meta-data related hooks on the hooks manager"""hm.register_hook(after_add_entity,'after_add_entity','')hm.register_hook(after_update_entity,'after_update_entity','')hm.register_hook(before_del_entity,'before_delete_entity','')hm.register_hook(before_add_relation,'before_add_relation','')hm.register_hook(after_add_relation,'after_add_relation','')hm.register_hook(before_del_relation,'before_delete_relation','')