diff --git a/attributs.py b/attributs.py index 492b9bd..c5ca1c5 100644 --- a/attributs.py +++ b/attributs.py @@ -255,7 +255,7 @@ class Attr(object): optional = True conn = None unique = False - concurent = True + concurrent = True unique_exclue = [] #: Le nom de l'attribut dans le schéma LDAP ldap_name = None @@ -852,7 +852,7 @@ class droits(Attr): class solde(floatAttr): python_type = float singlevalue = True - concurent = False + concurrent = False optional = True legend = u"Solde d'impression" can_modify = [imprimeur, nounou, tresorier] @@ -1306,6 +1306,7 @@ class historique(Attr): """Un historique est usuellement de la forme JJ/MM/AAAA HH:mm:ss, action comm""" singlevalue = False + concurrent = False optional = True legend = u"Historique de l'objet" category = 'info' diff --git a/objets.py b/objets.py index 08628db..8b39bfb 100644 --- a/objets.py +++ b/objets.py @@ -594,14 +594,17 @@ class CransLdapObject(object): cranslib.deprecated.usage("Des locks ne devrait être ajoutés que dans un context manager", level=2) self.conn.lockholder.addlock(attr, str(attribut), self.lockId) locked.append((attr, str(attribut), self.lockId)) - # On lock si l'attribut ne supporte pas les modifications concurente (comme pour le solde) si : - # * on effectue réellement un modification sur l'attribut - # * on a pas déjà effectuer un modification qui nous a déjà fait acquérir le lock - if not attribut.concurent and self._modifs.get(attr, []) == self.attrs.get(attr, []) and attrs_before_verif != self.attrs.get(attr, []): - if not self.in_context: - cranslib.deprecated.usage("Des locks ne devrait être ajoutés que dans un context manager", level=2) - self.conn.lockholder.addlock("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId) - locked.append(("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId)) + # On lock si l'attribut ne supporte pas les modifications concurrente (comme pour le solde) si : + # * on effectue réellement un modification sur l'attribut + # * on a pas déjà effectuer un modification qui nous a déjà fait acquérir le lock + if not attributs.AttributeFactory.get(attr).concurrent and self._modifs.get(attr, []) == self.attrs.get(attr, []) and attrs_before_verif != self.attrs.get(attr, []): + if not self.in_context: + cranslib.deprecated.usage("Des locks ne devrait être ajoutés que dans un context manager", level=2) + self.conn.lockholder.addlock("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId) + locked.append(("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId)) + # une fois le lock acquit, on vérifie que l'attribut n'a pas été édité entre temps + if self.conn.search(dn=self.dn, scope=0)[0].get(attr, []) != self.attrs.get(attr, []): + raise ldap_locks.LockError("L'attribut %s a été modifié dans la base ldap avant l'acquisition du lock" % attr) except ldap_locks.LockError: # Si on ne parvient pas à prendre le lock pour l'une des valeurs # on libère les locks pris jusque là et on propage l'erreur @@ -614,9 +617,9 @@ class CransLdapObject(object): for attribut in self._modifs.get(attr, []): if attribut.unique and not attribut in attrs_before_verif and not attribut in attribut.unique_exclue: self.conn.lockholder.removelock(attr, str(attribut), self.lockId) - # Si on remet la valeur antérieure au lock, on le libère - if not attribut.concurent and self._modifs.get(attr, []) != self.attrs.get(attr, []) and attrs_before_verif == self.attrs.get(attr, []): - self.conn.lockholder.removelock("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId) + # Si on remet la valeur antérieure au lock, on le libère + if not attributs.AttributeFactory.get(attr).concurrent and self._modifs.get(attr, []) != self.attrs.get(attr, []) and attrs_before_verif == self.attrs.get(attr, []): + self.conn.lockholder.removelock("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId) # On met à jour self._modifs avec les nouvelles valeurs self._modifs[attr] = attrs_before_verif