163 super(Hook, self).__init__(req, **kwargs) |
163 super(Hook, self).__init__(req, **kwargs) |
164 self.event = event |
164 self.event = event |
165 |
165 |
166 def __call__(self): |
166 def __call__(self): |
167 if hasattr(self, 'call'): |
167 if hasattr(self, 'call'): |
168 warn('[3.5] %s: call is deprecated, implements __call__' % self.__class__) |
168 warn('[3.6] %s: call is deprecated, implements __call__' % self.__class__) |
169 if self.event.endswith('_relation'): |
169 if self.event.endswith('_relation'): |
170 self.call(self._cw, self.eidfrom, self.rtype, self.eidto) |
170 self.call(self._cw, self.eidfrom, self.rtype, self.eidto) |
171 elif 'delete' in self.event: |
171 elif 'delete' in self.event: |
172 self.call(self._cw, self.entity.eid) |
172 self.call(self._cw, self.entity.eid) |
173 elif self.event.startswith('server_'): |
173 elif self.event.startswith('server_'): |
178 self.call(self._cw, self.entity) |
178 self.call(self._cw, self.entity) |
179 |
179 |
180 set_log_methods(Hook, getLogger('cubicweb.hook')) |
180 set_log_methods(Hook, getLogger('cubicweb.hook')) |
181 |
181 |
182 |
182 |
|
183 # base classes for relation propagation ######################################## |
|
184 |
|
185 class PropagateSubjectRelationHook(Hook): |
|
186 """propagate permissions and nosy list when new entity are added""" |
|
187 events = ('after_add_relation',) |
|
188 # to set in concrete class |
|
189 rtype = None |
|
190 subject_relations = None |
|
191 object_relations = None |
|
192 accepts = None # subject_relations + object_relations |
|
193 |
|
194 def call(self, session, fromeid, rtype, toeid): |
|
195 for eid in (fromeid, toeid): |
|
196 etype = session.describe(eid)[0] |
|
197 if not self.schema.eschema(etype).has_subject_relation(self.rtype): |
|
198 return |
|
199 if rtype in self.subject_relations: |
|
200 meid, seid = fromeid, toeid |
|
201 else: |
|
202 assert rtype in self.object_relations |
|
203 meid, seid = toeid, fromeid |
|
204 rql = 'SET E %s P WHERE X %s P, X eid %%(x)s, E eid %%(e)s, NOT E %s P'\ |
|
205 % (self.rtype, self.rtype, self.rtype) |
|
206 rqls = [(rql, {'x': meid, 'e': seid}, ('x', 'e'))] |
|
207 RQLPrecommitOperation(session, rqls=rqls) |
|
208 |
|
209 |
|
210 class PropagateSubjectRelationAddHook(Hook): |
|
211 """propagate on existing entities when a permission or nosy list is added""" |
|
212 events = ('after_add_relation',) |
|
213 # to set in concrete class |
|
214 rtype = None |
|
215 subject_relations = None |
|
216 object_relations = None |
|
217 accepts = None # (self.rtype,) |
|
218 |
|
219 def call(self, session, fromeid, rtype, toeid): |
|
220 eschema = self.schema.eschema(session.describe(fromeid)[0]) |
|
221 rqls = [] |
|
222 for rel in self.subject_relations: |
|
223 if eschema.has_subject_relation(rel): |
|
224 rqls.append(('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, ' |
|
225 'X %s R, NOT R %s P' % (rtype, rel, rtype), |
|
226 {'x': fromeid, 'p': toeid}, 'x')) |
|
227 for rel in self.object_relations: |
|
228 if eschema.has_object_relation(rel): |
|
229 rqls.append(('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, ' |
|
230 'R %s X, NOT R %s P' % (rtype, rel, rtype), |
|
231 {'x': fromeid, 'p': toeid}, 'x')) |
|
232 if rqls: |
|
233 RQLPrecommitOperation(session, rqls=rqls) |
|
234 |
|
235 |
|
236 class PropagateSubjectRelationDelHook(Hook): |
|
237 """propagate on existing entities when a permission is deleted""" |
|
238 events = ('after_delete_relation',) |
|
239 # to set in concrete class |
|
240 rtype = None |
|
241 subject_relations = None |
|
242 object_relations = None |
|
243 accepts = None # (self.rtype,) |
|
244 |
|
245 def call(self, session, fromeid, rtype, toeid): |
|
246 eschema = self.schema.eschema(session.describe(fromeid)[0]) |
|
247 rqls = [] |
|
248 for rel in self.subject_relations: |
|
249 if eschema.has_subject_relation(rel): |
|
250 rqls.append(('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, ' |
|
251 'X %s R' % (rtype, rel), |
|
252 {'x': fromeid, 'p': toeid}, 'x')) |
|
253 for rel in self.object_relations: |
|
254 if eschema.has_object_relation(rel): |
|
255 rqls.append(('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, ' |
|
256 'R %s X' % (rtype, rel), |
|
257 {'x': fromeid, 'p': toeid}, 'x')) |
|
258 if rqls: |
|
259 RQLPrecommitOperation(session, rqls=rqls) |
|
260 |
|
261 |
183 # abstract classes for operation ############################################### |
262 # abstract classes for operation ############################################### |
184 |
263 |
185 class Operation(object): |
264 class Operation(object): |
186 """an operation is triggered on connections pool events related to |
265 """an operation is triggered on connections pool events related to |
187 commit / rollback transations. Possible events are: |
266 commit / rollback transations. Possible events are: |
263 do nothing by default, the operation will just be removed from the pool |
342 do nothing by default, the operation will just be removed from the pool |
264 operation list |
343 operation list |
265 """ |
344 """ |
266 |
345 |
267 @property |
346 @property |
268 @deprecated('[3.5] use self.session.user') |
347 @deprecated('[3.6] use self.session.user') |
269 def user(self): |
348 def user(self): |
270 return self.session.user |
349 return self.session.user |
271 |
350 |
272 @property |
351 @property |
273 @deprecated('[3.5] use self.session.repo') |
352 @deprecated('[3.6] use self.session.repo') |
274 def repo(self): |
353 def repo(self): |
275 return self.session.repo |
354 return self.session.repo |
276 |
355 |
277 @property |
356 @property |
278 @deprecated('[3.5] use self.session.vreg.schema') |
357 @deprecated('[3.6] use self.session.vreg.schema') |
279 def schema(self): |
358 def schema(self): |
280 return self.session.repo.schema |
359 return self.session.repo.schema |
281 |
360 |
282 @property |
361 @property |
283 @deprecated('[3.5] use self.session.vreg.config') |
362 @deprecated('[3.6] use self.session.vreg.config') |
284 def config(self): |
363 def config(self): |
285 return self.session.repo.config |
364 return self.session.repo.config |
286 |
365 |
287 set_log_methods(Operation, getLogger('cubicweb.session')) |
366 set_log_methods(Operation, getLogger('cubicweb.session')) |
288 |
367 |