hooks/syncsession.py
changeset 9913 a74e9e43806a
parent 9469 032825bbacab
child 10663 54b8a1f249fb
child 11097 900c27ea30e9
equal deleted inserted replaced
9896:4900a937838b 9913:a74e9e43806a
    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):
   146 
   146 
   147     def postcommit_event(self):
   147     def postcommit_event(self):
   148         """the observed connections set has been commited"""
   148         """the observed connections set has been commited"""
   149         cwprop = self.cwprop
   149         cwprop = self.cwprop
   150         if not cwprop.for_user:
   150         if not cwprop.for_user:
   151             self.session.vreg['propertyvalues'][cwprop.pkey] = cwprop.value
   151             self.cnx.vreg['propertyvalues'][cwprop.pkey] = cwprop.value
   152         # if for_user is set, update is handled by a ChangeCWPropertyOp operation
   152         # if for_user is set, update is handled by a ChangeCWPropertyOp operation
   153 
   153 
   154 
   154 
   155 class AddCWPropertyHook(SyncSessionHook):
   155 class AddCWPropertyHook(SyncSessionHook):
   156     __regid__ = 'addcwprop'
   156     __regid__ = 'addcwprop'
   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)