server/hooksmanager.py
branch3.5
changeset 3088 854a30d8c092
parent 2918 452b4c9ee61d
child 3090 8184bec7414d
child 3689 deb13e88e037
equal deleted inserted replaced
3084:096d680c9da2 3088:854a30d8c092
   271 
   271 
   272 # base classes for relation propagation ########################################
   272 # base classes for relation propagation ########################################
   273 
   273 
   274 from cubicweb.server.pool import PreCommitOperation
   274 from cubicweb.server.pool import PreCommitOperation
   275 
   275 
   276 class RQLPrecommitOperation(PreCommitOperation):
       
   277     def precommit_event(self):
       
   278         execute = self.session.unsafe_execute
       
   279         for rql in self.rqls:
       
   280             execute(*rql)
       
   281 
       
   282 
   276 
   283 class PropagateSubjectRelationHook(Hook):
   277 class PropagateSubjectRelationHook(Hook):
   284     """propagate permissions and nosy list when new entity are added"""
   278     """propagate permissions and nosy list when new entity are added"""
   285     events = ('after_add_relation',)
   279     events = ('after_add_relation',)
   286     # to set in concrete class
   280     # to set in concrete class
   297         if rtype in self.subject_relations:
   291         if rtype in self.subject_relations:
   298             meid, seid = fromeid, toeid
   292             meid, seid = fromeid, toeid
   299         else:
   293         else:
   300             assert rtype in self.object_relations
   294             assert rtype in self.object_relations
   301             meid, seid = toeid, fromeid
   295             meid, seid = toeid, fromeid
   302         rql = 'SET E %s P WHERE X %s P, X eid %%(x)s, E eid %%(e)s, NOT E %s P'\
   296         session.unsafe_execute(
   303               % (self.rtype, self.rtype, self.rtype)
   297             'SET E %s P WHERE X %s P, X eid %%(x)s, E eid %%(e)s, NOT E %s P'\
   304         rqls = [(rql, {'x': meid, 'e': seid}, ('x', 'e'))]
   298             % (self.rtype, self.rtype, self.rtype),
   305         RQLPrecommitOperation(session, rqls=rqls)
   299             {'x': meid, 'e': seid}, ('x', 'e'))
   306 
   300 
   307 
   301 
   308 class PropagateSubjectRelationAddHook(Hook):
   302 class PropagateSubjectRelationAddHook(Hook):
   309     """propagate on existing entities when a permission or nosy list is added"""
   303     """propagate on existing entities when a permission or nosy list is added"""
   310     events = ('after_add_relation',)
   304     events = ('after_add_relation',)
   314     object_relations = None
   308     object_relations = None
   315     accepts = None # (self.rtype,)
   309     accepts = None # (self.rtype,)
   316 
   310 
   317     def call(self, session, fromeid, rtype, toeid):
   311     def call(self, session, fromeid, rtype, toeid):
   318         eschema = self.schema.eschema(session.describe(fromeid)[0])
   312         eschema = self.schema.eschema(session.describe(fromeid)[0])
   319         rqls = []
   313         execute = session.unsafe_execute
   320         for rel in self.subject_relations:
   314         for rel in self.subject_relations:
   321             if eschema.has_subject_relation(rel):
   315             if eschema.has_subject_relation(rel):
   322                 rqls.append(('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
   316                 execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
   323                              'X %s R, NOT R %s P' % (rtype, rel, rtype),
   317                         'X %s R, NOT R %s P' % (rtype, rel, rtype),
   324                              {'x': fromeid, 'p': toeid}, 'x'))
   318                         {'x': fromeid, 'p': toeid}, 'x')
   325         for rel in self.object_relations:
   319         for rel in self.object_relations:
   326             if eschema.has_object_relation(rel):
   320             if eschema.has_object_relation(rel):
   327                 rqls.append(('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
   321                 execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
   328                              'R %s X, NOT R %s P' % (rtype, rel, rtype),
   322                         'R %s X, NOT R %s P' % (rtype, rel, rtype),
   329                              {'x': fromeid, 'p': toeid}, 'x'))
   323                         {'x': fromeid, 'p': toeid}, 'x')
   330         if rqls:
       
   331             RQLPrecommitOperation(session, rqls=rqls)
       
   332 
   324 
   333 
   325 
   334 class PropagateSubjectRelationDelHook(Hook):
   326 class PropagateSubjectRelationDelHook(Hook):
   335     """propagate on existing entities when a permission is deleted"""
   327     """propagate on existing entities when a permission is deleted"""
   336     events = ('after_delete_relation',)
   328     events = ('after_delete_relation',)
   340     object_relations = None
   332     object_relations = None
   341     accepts = None # (self.rtype,)
   333     accepts = None # (self.rtype,)
   342 
   334 
   343     def call(self, session, fromeid, rtype, toeid):
   335     def call(self, session, fromeid, rtype, toeid):
   344         eschema = self.schema.eschema(session.describe(fromeid)[0])
   336         eschema = self.schema.eschema(session.describe(fromeid)[0])
   345         rqls = []
   337         execute = session.unsafe_execute
   346         for rel in self.subject_relations:
   338         for rel in self.subject_relations:
   347             if eschema.has_subject_relation(rel):
   339             if eschema.has_subject_relation(rel):
   348                 rqls.append(('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
   340                 execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
   349                              'X %s R' % (rtype, rel),
   341                         'X %s R' % (rtype, rel),
   350                              {'x': fromeid, 'p': toeid}, 'x'))
   342                         {'x': fromeid, 'p': toeid}, 'x')
   351         for rel in self.object_relations:
   343         for rel in self.object_relations:
   352             if eschema.has_object_relation(rel):
   344             if eschema.has_object_relation(rel):
   353                 rqls.append(('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
   345                 execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
   354                              'R %s X' % (rtype, rel),
   346                         'R %s X' % (rtype, rel),
   355                              {'x': fromeid, 'p': toeid}, 'x'))
   347                         {'x': fromeid, 'p': toeid}, 'x')
   356         if rqls:
       
   357             RQLPrecommitOperation(session, rqls=rqls)