server/hooksmanager.py
branchstable
changeset 3315 59220b704562
parent 3088 854a30d8c092
child 3090 8184bec7414d
child 3689 deb13e88e037
equal deleted inserted replaced
3298:caef98aa4a98 3315:59220b704562
   266 
   266 
   267 from logging import getLogger
   267 from logging import getLogger
   268 from cubicweb import set_log_methods
   268 from cubicweb import set_log_methods
   269 set_log_methods(HooksManager, getLogger('cubicweb.hooksmanager'))
   269 set_log_methods(HooksManager, getLogger('cubicweb.hooksmanager'))
   270 set_log_methods(Hook, getLogger('cubicweb.hooks'))
   270 set_log_methods(Hook, getLogger('cubicweb.hooks'))
       
   271 
       
   272 # base classes for relation propagation ########################################
       
   273 
       
   274 from cubicweb.server.pool import PreCommitOperation
       
   275 
       
   276 
       
   277 class PropagateSubjectRelationHook(Hook):
       
   278     """propagate permissions and nosy list when new entity are added"""
       
   279     events = ('after_add_relation',)
       
   280     # to set in concrete class
       
   281     rtype = None
       
   282     subject_relations = None
       
   283     object_relations = None
       
   284     accepts = None # subject_relations + object_relations
       
   285 
       
   286     def call(self, session, fromeid, rtype, toeid):
       
   287         for eid in (fromeid, toeid):
       
   288             etype = session.describe(eid)[0]
       
   289             if not self.schema.eschema(etype).has_subject_relation(self.rtype):
       
   290                 return
       
   291         if rtype in self.subject_relations:
       
   292             meid, seid = fromeid, toeid
       
   293         else:
       
   294             assert rtype in self.object_relations
       
   295             meid, seid = toeid, fromeid
       
   296         session.unsafe_execute(
       
   297             'SET E %s P WHERE X %s P, X eid %%(x)s, E eid %%(e)s, NOT E %s P'\
       
   298             % (self.rtype, self.rtype, self.rtype),
       
   299             {'x': meid, 'e': seid}, ('x', 'e'))
       
   300 
       
   301 
       
   302 class PropagateSubjectRelationAddHook(Hook):
       
   303     """propagate on existing entities when a permission or nosy list is added"""
       
   304     events = ('after_add_relation',)
       
   305     # to set in concrete class
       
   306     rtype = None
       
   307     subject_relations = None
       
   308     object_relations = None
       
   309     accepts = None # (self.rtype,)
       
   310 
       
   311     def call(self, session, fromeid, rtype, toeid):
       
   312         eschema = self.schema.eschema(session.describe(fromeid)[0])
       
   313         execute = session.unsafe_execute
       
   314         for rel in self.subject_relations:
       
   315             if eschema.has_subject_relation(rel):
       
   316                 execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
       
   317                         'X %s R, NOT R %s P' % (rtype, rel, rtype),
       
   318                         {'x': fromeid, 'p': toeid}, 'x')
       
   319         for rel in self.object_relations:
       
   320             if eschema.has_object_relation(rel):
       
   321                 execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
       
   322                         'R %s X, NOT R %s P' % (rtype, rel, rtype),
       
   323                         {'x': fromeid, 'p': toeid}, 'x')
       
   324 
       
   325 
       
   326 class PropagateSubjectRelationDelHook(Hook):
       
   327     """propagate on existing entities when a permission is deleted"""
       
   328     events = ('after_delete_relation',)
       
   329     # to set in concrete class
       
   330     rtype = None
       
   331     subject_relations = None
       
   332     object_relations = None
       
   333     accepts = None # (self.rtype,)
       
   334 
       
   335     def call(self, session, fromeid, rtype, toeid):
       
   336         eschema = self.schema.eschema(session.describe(fromeid)[0])
       
   337         execute = session.unsafe_execute
       
   338         for rel in self.subject_relations:
       
   339             if eschema.has_subject_relation(rel):
       
   340                 execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
       
   341                         'X %s R' % (rtype, rel),
       
   342                         {'x': fromeid, 'p': toeid}, 'x')
       
   343         for rel in self.object_relations:
       
   344             if eschema.has_object_relation(rel):
       
   345                 execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
       
   346                         'R %s X' % (rtype, rel),
       
   347                         {'x': fromeid, 'p': toeid}, 'x')