40 |
40 |
41 class _GroupOperation(hook.Operation): |
41 class _GroupOperation(hook.Operation): |
42 """base class for group operation""" |
42 """base class for group operation""" |
43 cnxuser = None # make pylint happy |
43 cnxuser = None # make pylint happy |
44 |
44 |
45 def __init__(self, session, *args, **kwargs): |
45 def __init__(self, cnx, *args, **kwargs): |
46 """override to get the group name before actual groups manipulation: |
46 """override to get the group name before actual groups manipulation: |
47 |
47 |
48 we may temporarily loose right access during a commit event, so |
48 we may temporarily loose right access during a commit event, so |
49 no query should be emitted while comitting |
49 no query should be emitted while comitting |
50 """ |
50 """ |
51 rql = 'Any N WHERE G eid %(x)s, G name N' |
51 rql = 'Any N WHERE G eid %(x)s, G name N' |
52 result = session.execute(rql, {'x': kwargs['geid']}, build_descr=False) |
52 result = cnx.execute(rql, {'x': kwargs['geid']}, build_descr=False) |
53 hook.Operation.__init__(self, session, *args, **kwargs) |
53 hook.Operation.__init__(self, cnx, *args, **kwargs) |
54 self.group = result[0][0] |
54 self.group = result[0][0] |
55 |
55 |
56 |
56 |
57 class _DeleteGroupOp(_GroupOperation): |
57 class _DeleteGroupOp(_GroupOperation): |
58 """synchronize user when a in_group relation has been deleted""" |
58 """synchronize user when a in_group relation has been deleted""" |
92 opcls(self._cw, cnxuser=session.user, geid=self.eidto) |
92 opcls(self._cw, cnxuser=session.user, geid=self.eidto) |
93 |
93 |
94 |
94 |
95 class _DelUserOp(hook.Operation): |
95 class _DelUserOp(hook.Operation): |
96 """close associated user's session when it is deleted""" |
96 """close associated user's session when it is deleted""" |
97 def __init__(self, session, cnxid): |
97 def __init__(self, cnx, sessionid): |
98 self.cnxid = cnxid |
98 self.sessionid = sessionid |
99 hook.Operation.__init__(self, session) |
99 hook.Operation.__init__(self, cnx) |
100 |
100 |
101 def postcommit_event(self): |
101 def postcommit_event(self): |
102 """the observed connections set has been commited""" |
102 """the observed connections set has been commited""" |
103 try: |
103 try: |
104 self.session.repo.close(self.cnxid) |
104 self.cnx.repo.close(self.sessionid) |
105 except BadConnectionId: |
105 except BadConnectionId: |
106 pass # already closed |
106 pass # already closed |
107 |
107 |
108 |
108 |
109 class CloseDeletedUserSessionsHook(SyncSessionHook): |
109 class CloseDeletedUserSessionsHook(SyncSessionHook): |
159 |
159 |
160 def __call__(self): |
160 def __call__(self): |
161 key, value = self.entity.pkey, self.entity.value |
161 key, value = self.entity.pkey, self.entity.value |
162 if key.startswith('sources.'): |
162 if key.startswith('sources.'): |
163 return |
163 return |
164 session = self._cw |
164 cnx = self._cw |
165 try: |
165 try: |
166 value = session.vreg.typed_value(key, value) |
166 value = cnx.vreg.typed_value(key, value) |
167 except UnknownProperty: |
167 except UnknownProperty: |
168 msg = _('unknown property key %s') |
168 msg = _('unknown property key %s') |
169 raise validation_error(self.entity, {('pkey', 'subject'): msg}, (key,)) |
169 raise validation_error(self.entity, {('pkey', 'subject'): msg}, (key,)) |
170 except ValueError as ex: |
170 except ValueError as ex: |
171 raise validation_error(self.entity, |
171 raise validation_error(self.entity, |
172 {('value', 'subject'): str(ex)}) |
172 {('value', 'subject'): str(ex)}) |
173 if not session.user.matching_groups('managers'): |
173 if not cnx.user.matching_groups('managers'): |
174 session.add_relation(self.entity.eid, 'for_user', session.user.eid) |
174 cnx.add_relation(self.entity.eid, 'for_user', cnx.user.eid) |
175 else: |
175 else: |
176 _AddCWPropertyOp(session, cwprop=self.entity) |
176 _AddCWPropertyOp(cnx, cwprop=self.entity) |
177 |
177 |
178 |
178 |
179 class UpdateCWPropertyHook(AddCWPropertyHook): |
179 class UpdateCWPropertyHook(AddCWPropertyHook): |
180 __regid__ = 'updatecwprop' |
180 __regid__ = 'updatecwprop' |
181 events = ('after_update_entity',) |
181 events = ('after_update_entity',) |
186 'value' in entity.cw_edited): |
186 'value' in entity.cw_edited): |
187 return |
187 return |
188 key, value = entity.pkey, entity.value |
188 key, value = entity.pkey, entity.value |
189 if key.startswith('sources.'): |
189 if key.startswith('sources.'): |
190 return |
190 return |
191 session = self._cw |
191 cnx = self._cw |
192 try: |
192 try: |
193 value = session.vreg.typed_value(key, value) |
193 value = cnx.vreg.typed_value(key, value) |
194 except UnknownProperty: |
194 except UnknownProperty: |
195 return |
195 return |
196 except ValueError as ex: |
196 except ValueError as ex: |
197 raise validation_error(entity, {('value', 'subject'): str(ex)}) |
197 raise validation_error(entity, {('value', 'subject'): str(ex)}) |
198 if entity.for_user: |
198 if entity.for_user: |
199 for session_ in get_user_sessions(session.repo, entity.for_user[0].eid): |
199 for session in get_user_sessions(cnx.repo, entity.for_user[0].eid): |
200 _ChangeCWPropertyOp(session, cwpropdict=session_.user.properties, |
200 _ChangeCWPropertyOp(cnx, cwpropdict=session.user.properties, |
201 key=key, value=value) |
201 key=key, value=value) |
202 else: |
202 else: |
203 # site wide properties |
203 # site wide properties |
204 _ChangeCWPropertyOp(session, cwpropdict=session.vreg['propertyvalues'], |
204 _ChangeCWPropertyOp(cnx, cwpropdict=cnx.vreg['propertyvalues'], |
205 key=key, value=value) |
205 key=key, value=value) |
206 |
206 |
207 |
207 |
208 class DeleteCWPropertyHook(AddCWPropertyHook): |
208 class DeleteCWPropertyHook(AddCWPropertyHook): |
209 __regid__ = 'delcwprop' |
209 __regid__ = 'delcwprop' |
210 events = ('before_delete_entity',) |
210 events = ('before_delete_entity',) |
211 |
211 |
212 def __call__(self): |
212 def __call__(self): |
213 eid = self.entity.eid |
213 eid = self.entity.eid |
214 session = self._cw |
214 cnx = self._cw |
215 for eidfrom, rtype, eidto in session.transaction_data.get('pendingrelations', ()): |
215 for eidfrom, rtype, eidto in cnx.transaction_data.get('pendingrelations', ()): |
216 if rtype == 'for_user' and eidfrom == self.entity.eid: |
216 if rtype == 'for_user' and eidfrom == self.entity.eid: |
217 # if for_user was set, delete has already been handled |
217 # if for_user was set, delete has already been handled |
218 break |
218 break |
219 else: |
219 else: |
220 _DelCWPropertyOp(session, cwpropdict=session.vreg['propertyvalues'], |
220 _DelCWPropertyOp(cnx, cwpropdict=cnx.vreg['propertyvalues'], |
221 key=self.entity.pkey) |
221 key=self.entity.pkey) |
222 |
222 |
223 |
223 |
224 class AddForUserRelationHook(SyncSessionHook): |
224 class AddForUserRelationHook(SyncSessionHook): |
225 __regid__ = 'addcwpropforuser' |
225 __regid__ = 'addcwpropforuser' |
226 __select__ = SyncSessionHook.__select__ & hook.match_rtype('for_user') |
226 __select__ = SyncSessionHook.__select__ & hook.match_rtype('for_user') |
227 events = ('after_add_relation',) |
227 events = ('after_add_relation',) |
228 |
228 |
229 def __call__(self): |
229 def __call__(self): |
230 session = self._cw |
230 cnx = self._cw |
231 eidfrom = self.eidfrom |
231 eidfrom = self.eidfrom |
232 if not session.entity_metas(eidfrom)['type'] == 'CWProperty': |
232 if not cnx.entity_metas(eidfrom)['type'] == 'CWProperty': |
233 return |
233 return |
234 key, value = session.execute('Any K,V WHERE P eid %(x)s,P pkey K,P value V', |
234 key, value = cnx.execute('Any K,V WHERE P eid %(x)s,P pkey K,P value V', |
235 {'x': eidfrom})[0] |
235 {'x': eidfrom})[0] |
236 if session.vreg.property_info(key)['sitewide']: |
236 if cnx.vreg.property_info(key)['sitewide']: |
237 msg = _("site-wide property can't be set for user") |
237 msg = _("site-wide property can't be set for user") |
238 raise validation_error(eidfrom, {('for_user', 'subject'): msg}) |
238 raise validation_error(eidfrom, {('for_user', 'subject'): msg}) |
239 for session_ in get_user_sessions(session.repo, self.eidto): |
239 for session in get_user_sessions(cnx.repo, self.eidto): |
240 _ChangeCWPropertyOp(session, cwpropdict=session_.user.properties, |
240 _ChangeCWPropertyOp(cnx, cwpropdict=session.user.properties, |
241 key=key, value=value) |
241 key=key, value=value) |
242 |
242 |
243 |
243 |
244 class DelForUserRelationHook(AddForUserRelationHook): |
244 class DelForUserRelationHook(AddForUserRelationHook): |
245 __regid__ = 'delcwpropforuser' |
245 __regid__ = 'delcwpropforuser' |
246 events = ('after_delete_relation',) |
246 events = ('after_delete_relation',) |
247 |
247 |
248 def __call__(self): |
248 def __call__(self): |
249 session = self._cw |
249 cnx = self._cw |
250 key = session.execute('Any K WHERE P eid %(x)s, P pkey K', |
250 key = cnx.execute('Any K WHERE P eid %(x)s, P pkey K', |
251 {'x': self.eidfrom})[0][0] |
251 {'x': self.eidfrom})[0][0] |
252 session.transaction_data.setdefault('pendingrelations', []).append( |
252 cnx.transaction_data.setdefault('pendingrelations', []).append( |
253 (self.eidfrom, self.rtype, self.eidto)) |
253 (self.eidfrom, self.rtype, self.eidto)) |
254 for session_ in get_user_sessions(session.repo, self.eidto): |
254 for session in get_user_sessions(cnx.repo, self.eidto): |
255 _DelCWPropertyOp(session, cwpropdict=session_.user.properties, key=key) |
255 _DelCWPropertyOp(cnx, cwpropdict=session.user.properties, key=key) |