[global] On jette ctxt_check, et les ldifs qui traînent partout, qu'on remplace.
* Les ldifs sont remplacés par un pointeur vers l'objet propriétaire des attributs * Le test de cardinalité est fait lors du setitem dans AttrsDict * Le test d'unicité dans le setitem d'un CransLdapObject. Le setitem vérifie également qu'on affecte pas des attributs non désirés à un objet
This commit is contained in:
parent
60ea18d180
commit
180c17baed
2 changed files with 172 additions and 170 deletions
304
attributs.py
304
attributs.py
|
@ -75,28 +75,34 @@ DROITS_SUPERVISEUR = { nounou : TOUS_DROITS,
|
||||||
bureau : DROITS_FAIBLES + [bureau, tresorier],
|
bureau : DROITS_FAIBLES + [bureau, tresorier],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SingleValueError(ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
def attrify(val, attr, ldif, conn, ctxt_check = True):
|
class UniquenessError(EnvironmentError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class OptionalError(EnvironmentError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def attrify(val, attr, conn, Parent=None):
|
||||||
"""Transforme un n'importe quoi en :py:class:`Attr`.
|
"""Transforme un n'importe quoi en :py:class:`Attr`.
|
||||||
|
|
||||||
Doit effectuer les normalisations et sanity check si un str ou un
|
Doit effectuer les normalisations et sanity check si un str ou un
|
||||||
unicode est passé en argument.
|
unicode est passé en argument.
|
||||||
Devrait insulter en cas de potentiel problème d'encodage.
|
Devrait insulter en cas de potentiel problème d'encodage.
|
||||||
Doit effectuer les vérifications de contexte dans le ``ldif`` si
|
"""
|
||||||
``ctxt_check`` est vrai"""
|
|
||||||
|
|
||||||
if isinstance(val, Attr):
|
if isinstance(val, Attr):
|
||||||
return val
|
return val
|
||||||
else:
|
else:
|
||||||
return CRANS_ATTRIBUTES.get(attr, Attr)(val, ldif, conn, ctxt_check)
|
return CRANS_ATTRIBUTES.get(attr, Attr)(val, conn, Parent)
|
||||||
|
|
||||||
|
|
||||||
class AttrsDict(dict) :
|
class AttrsDict(dict) :
|
||||||
def __init__(self, conn, ldif = {}, check_ctxt = True):
|
def __init__(self, conn, ldif={}, Parent=None):
|
||||||
super(AttrsDict, self).__init__(ldif)
|
super(AttrsDict, self).__init__(ldif)
|
||||||
self._conn = conn
|
self._conn = conn
|
||||||
self._ldif = ldif
|
self._parent = Parent
|
||||||
self._check_ctxt = check_ctxt
|
|
||||||
|
|
||||||
def __getitem__(self, attr):
|
def __getitem__(self, attr):
|
||||||
values = super(AttrsDict, self).__getitem__(attr)
|
values = super(AttrsDict, self).__getitem__(attr)
|
||||||
|
@ -105,12 +111,23 @@ class AttrsDict(dict) :
|
||||||
output = []
|
output = []
|
||||||
for val in values:
|
for val in values:
|
||||||
if not isinstance(val, Attr):
|
if not isinstance(val, Attr):
|
||||||
output.append(attrify(unicode(val, 'utf-8'), attr, self._ldif, self._conn, self._check_ctxt))
|
output.append(attrify(unicode(val, 'utf-8'), attr, self._conn, self._parent))
|
||||||
else:
|
else:
|
||||||
output.append(val)
|
output.append(val)
|
||||||
self[attr] = output
|
self[attr] = output
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def __setitem__(self, attr, values):
|
||||||
|
# ne devrait par arriver
|
||||||
|
if not isinstance(values, list):
|
||||||
|
values = [ values ]
|
||||||
|
if self._parent.mode in ['w', 'rw']:
|
||||||
|
if CRANS_ATTRIBUTES.get(attr, Attr).singlevalue and len(values) > 1:
|
||||||
|
raise SingleValueError("L'attribut %s doit être monovalué.")
|
||||||
|
super(AttrsDict, self).__setitem__(attr, values)
|
||||||
|
else:
|
||||||
|
super(AttrsDict, self).__setitem__(attr, values)
|
||||||
|
|
||||||
def get(self, value, default_value):
|
def get(self, value, default_value):
|
||||||
try:
|
try:
|
||||||
return self[value]
|
return self[value]
|
||||||
|
@ -124,36 +141,33 @@ class Attr(object):
|
||||||
|
|
||||||
* ``val`` : valeur de l'attribut
|
* ``val`` : valeur de l'attribut
|
||||||
* ``ldif`` : objet contenant l'attribut (permet de faire les validations sur l'environnement)
|
* ``ldif`` : objet contenant l'attribut (permet de faire les validations sur l'environnement)
|
||||||
* ``ctxt_check`` : effectue les validations
|
|
||||||
"""
|
"""
|
||||||
legend = "Human-readable description of attribute"
|
legend = "Human-readable description of attribute"
|
||||||
singlevalue = None
|
singlevalue = False
|
||||||
optional = None
|
optional = True
|
||||||
conn = None
|
conn = None
|
||||||
unique = False
|
unique = False
|
||||||
|
|
||||||
can_modify = [nounou]
|
|
||||||
"""La liste des droits qui suffisent à avoir le droit de modifier la valeur"""
|
"""La liste des droits qui suffisent à avoir le droit de modifier la valeur"""
|
||||||
|
can_modify = [nounou]
|
||||||
|
|
||||||
can_view = [nounou, apprenti, soi, parent, respo]
|
|
||||||
"""Qui peut voir l'attribut. Par défaut, les Nounous et les Apprentis
|
"""Qui peut voir l'attribut. Par défaut, les Nounous et les Apprentis
|
||||||
peuvent tout voir. Par transparence, et par utilité, on autorise par
|
peuvent tout voir. Par transparence, et par utilité, on autorise par
|
||||||
défaut l'adhérent à voir les données le concernant."""
|
défaut l'adhérent à voir les données le concernant."""
|
||||||
|
can_view = [nounou, apprenti, soi, parent, respo]
|
||||||
|
|
||||||
category = 'other'
|
|
||||||
"""Catégorie de l'attribut (pour affichage futur)"""
|
"""Catégorie de l'attribut (pour affichage futur)"""
|
||||||
|
category = 'other'
|
||||||
|
|
||||||
def __init__(self, val, ldif, conn, ctxt_check):
|
def __init__(self, val, conn, Parent):
|
||||||
"""Crée un nouvel objet représentant un attribut. """
|
"""Crée un nouvel objet représentant un attribut. """
|
||||||
self.ctxt_check=ctxt_check
|
self.value = None
|
||||||
#self.value = None
|
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
assert isinstance(val, unicode)
|
assert isinstance(val, unicode)
|
||||||
self.parse_value(val, ldif)
|
self.parent = Parent
|
||||||
if ctxt_check:
|
self.parse_value(val)
|
||||||
self.validate(ldif)
|
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, val):
|
||||||
"""Transforme l'attribut pour travailler avec notre validateur
|
"""Transforme l'attribut pour travailler avec notre validateur
|
||||||
Le ldif est en dépendance car à certains endroits, il peut servir
|
Le ldif est en dépendance car à certains endroits, il peut servir
|
||||||
(par exemple, pour l'ipv6, ou l'ipv4..."""
|
(par exemple, pour l'ipv6, ou l'ipv4..."""
|
||||||
|
@ -167,37 +181,16 @@ class Attr(object):
|
||||||
assert isinstance(self.value, unicode)
|
assert isinstance(self.value, unicode)
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
def validate(self, ldif):
|
def check_uniqueness(self, liste_exclue):
|
||||||
"""validates:
|
|
||||||
vérifie déjà que ce qu'on a rentré est parsable"""
|
|
||||||
if not self.__class__.__name__ in CRANS_ATTRIBUTES:
|
|
||||||
raise ValueError('Attribut %s inconnu' % self.__class__.__name__)
|
|
||||||
|
|
||||||
# On utilise un ldif parce qu'il faut avoir un contexte
|
|
||||||
# pour savoir si l'attribut qu'on est en train de créer
|
|
||||||
# est légitime.
|
|
||||||
own_values = ldif.get(self.__class__.__name__, [])
|
|
||||||
self._check_cardinality(own_values)
|
|
||||||
self._check_uniqueness()
|
|
||||||
|
|
||||||
def _check_cardinality(self, values):
|
|
||||||
"""Vérifie qu'il y a un nombre correct de valeur =1, <=1, {0,1},
|
|
||||||
etc..."""
|
|
||||||
if self.singlevalue and len(values) > 1:
|
|
||||||
raise ValueError('%s doit avoir au maximum une valeur (affecte %s)' % (self.__class__, values))
|
|
||||||
# A priori, ça sert à rien, on fait du for val in values, si la liste
|
|
||||||
# est vide, le type d'attribut généré n'est pas pris en compte.
|
|
||||||
if not self.optional and len(values) == 0:
|
|
||||||
raise ValueError('%s doit avoir au moins une valeur' % self.__class__)
|
|
||||||
|
|
||||||
def _check_uniqueness(self):
|
|
||||||
"""Vérifie l'unicité dans la base de la valeur (``mailAlias``, ``chbre``,
|
"""Vérifie l'unicité dans la base de la valeur (``mailAlias``, ``chbre``,
|
||||||
etc...)"""
|
etc...)"""
|
||||||
attr = self.__class__.__name__
|
attr = self.__class__.__name__
|
||||||
|
if str(self) in liste_exclue:
|
||||||
|
return
|
||||||
if self.unique:
|
if self.unique:
|
||||||
res = self.conn.search('%s=%s' % (attr, str(self)))
|
res = self.conn.search('%s=%s' % (attr, str(self)))
|
||||||
if res:
|
if res:
|
||||||
raise ValueError("%s déjà existant" % attr, [r.dn for r in res])
|
raise UniquenessError("%s déjà existant" % attr, [r.dn for r in res])
|
||||||
|
|
||||||
def is_modifiable(self, liste_droits):
|
def is_modifiable(self, liste_droits):
|
||||||
"""
|
"""
|
||||||
|
@ -210,13 +203,13 @@ class objectClass(Attr):
|
||||||
optional = False
|
optional = False
|
||||||
legend = "entité"
|
legend = "entité"
|
||||||
|
|
||||||
can_modify = []
|
|
||||||
""" Personne ne doit modifier de classe """
|
""" Personne ne doit modifier de classe """
|
||||||
|
can_modify = []
|
||||||
|
|
||||||
can_view = [nounou, apprenti]
|
|
||||||
""" Internal purpose (et à fin pédagogique) """
|
""" Internal purpose (et à fin pédagogique) """
|
||||||
|
can_view = [nounou, apprenti]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, val):
|
||||||
if val not in [ 'top', 'organizationalUnit', 'posixAccount', 'shadowAccount',
|
if val not in [ 'top', 'organizationalUnit', 'posixAccount', 'shadowAccount',
|
||||||
'proprio', 'adherent', 'club', 'machine', 'machineCrans',
|
'proprio', 'adherent', 'club', 'machine', 'machineCrans',
|
||||||
'borneWifi', 'machineWifi', 'machineFixe',
|
'borneWifi', 'machineWifi', 'machineFixe',
|
||||||
|
@ -227,7 +220,7 @@ class objectClass(Attr):
|
||||||
|
|
||||||
|
|
||||||
class intAttr(Attr):
|
class intAttr(Attr):
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, val):
|
||||||
if int(val) <= 0:
|
if int(val) <= 0:
|
||||||
raise ValueError("Valeur entière invalide : %r" % val)
|
raise ValueError("Valeur entière invalide : %r" % val)
|
||||||
self.value = int(val)
|
self.value = int(val)
|
||||||
|
@ -236,7 +229,7 @@ class intAttr(Attr):
|
||||||
return unicode(self.value)
|
return unicode(self.value)
|
||||||
|
|
||||||
class boolAttr(Attr):
|
class boolAttr(Attr):
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, val):
|
||||||
if val.lower() in [u'true', u'ok']:
|
if val.lower() in [u'true', u'ok']:
|
||||||
self.value = True
|
self.value = True
|
||||||
elif val.lower() == u'false':
|
elif val.lower() == u'false':
|
||||||
|
@ -256,13 +249,13 @@ class aid(intAttr):
|
||||||
category = 'id'
|
category = 'id'
|
||||||
unique = True
|
unique = True
|
||||||
|
|
||||||
can_modify = []
|
|
||||||
""" Personne ne devrait modifier un attribut d'identification """
|
""" Personne ne devrait modifier un attribut d'identification """
|
||||||
|
can_modify = []
|
||||||
|
|
||||||
can_view = [nounou, apprenti, 'Cableurs']
|
can_view = [nounou, apprenti, cableur]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, aid):
|
||||||
self.value = int(val)
|
self.value = int(aid)
|
||||||
|
|
||||||
class uid(Attr):
|
class uid(Attr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
|
@ -278,11 +271,14 @@ class nom(Attr):
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
can_modify = [nounou, cableur]
|
can_modify = [nounou, cableur]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, nom):
|
||||||
if u'club' in ldif['objectClass']:
|
if self.parent != None:
|
||||||
self.value = validate_name(val,"0123456789\[\]")
|
if u'club' in self.parent['objectClass']:
|
||||||
|
self.value = validate_name(nom,"0123456789\[\]")
|
||||||
|
else:
|
||||||
|
self.value = validate_name(nom)
|
||||||
else:
|
else:
|
||||||
self.value = validate_name(val)
|
self.value = validate_name(nom)
|
||||||
|
|
||||||
class prenom(Attr):
|
class prenom(Attr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
|
@ -291,8 +287,8 @@ class prenom(Attr):
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
can_modify = [nounou, cableur]
|
can_modify = [nounou, cableur]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, prenom):
|
||||||
self.value = validate_name(val)
|
self.value = validate_name(prenom)
|
||||||
|
|
||||||
class compteWiki(Attr):
|
class compteWiki(Attr):
|
||||||
singlevalue = False
|
singlevalue = False
|
||||||
|
@ -301,8 +297,8 @@ class compteWiki(Attr):
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
can_modify = [nounou, cableur, soi]
|
can_modify = [nounou, cableur, soi]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, compte):
|
||||||
self.value = validate_name(val)
|
self.value = validate_name(compte)
|
||||||
# TODO: validate with mdp for user definition here ?
|
# TODO: validate with mdp for user definition here ?
|
||||||
|
|
||||||
class tel(Attr):
|
class tel(Attr):
|
||||||
|
@ -312,19 +308,20 @@ class tel(Attr):
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
can_modify = [soi, nounou, cableur]
|
can_modify = [soi, nounou, cableur]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, tel):
|
||||||
self.value = format_tel(val)
|
self.value = format_tel(tel)
|
||||||
if len(self.value) == 0:
|
if len(self.value) == 0:
|
||||||
raise ValueError("Numéro de téléphone invalide (%r)" % val)
|
raise ValueError("Numéro de téléphone invalide (%r)" % tel)
|
||||||
|
|
||||||
class yearAttr(intAttr):
|
class yearAttr(intAttr):
|
||||||
singlevalue = False
|
singlevalue = False
|
||||||
optional= True
|
optional = True
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, annee):
|
||||||
if int(val) < 1998:
|
annee = int(annee)
|
||||||
raise ValueError("Année invalide (%r)" % val)
|
if annee < 1998:
|
||||||
self.value = int(val)
|
raise ValueError("Année invalide (%r)" % annee)
|
||||||
|
self.value = annee
|
||||||
|
|
||||||
class paiement(yearAttr):
|
class paiement(yearAttr):
|
||||||
legend = u"Paiement"
|
legend = u"Paiement"
|
||||||
|
@ -348,8 +345,10 @@ class mail(Attr):
|
||||||
can_modify = [soi, nounou, cableur]
|
can_modify = [soi, nounou, cableur]
|
||||||
category = 'mail'
|
category = 'mail'
|
||||||
|
|
||||||
def _check_uniqueness(self):
|
def check_uniqueness(self, liste_exclue):
|
||||||
attr = self.__class__.__name__
|
attr = self.__class__.__name__
|
||||||
|
if str(self) in liste_exclue:
|
||||||
|
return
|
||||||
if attr in ["mailAlias", "canonicalAlias", 'mail']:
|
if attr in ["mailAlias", "canonicalAlias", 'mail']:
|
||||||
mail = str(self).split('@', 1)[0]
|
mail = str(self).split('@', 1)[0]
|
||||||
|
|
||||||
|
@ -364,7 +363,7 @@ class mail(Attr):
|
||||||
if res:
|
if res:
|
||||||
raise ValueError("Le mail %s est déjà pris." % (str(self)))
|
raise ValueError("Le mail %s est déjà pris." % (str(self)))
|
||||||
|
|
||||||
def parse_value(self, mail, ldif):
|
def parse_value(self, mail):
|
||||||
if not re.match('^[-_.0-9A-Za-z]+@([A-Za-z0-9]{1}[A-Za-z0-9-_]+[.])+[a-z]{2,6}$', mail):
|
if not re.match('^[-_.0-9A-Za-z]+@([A-Za-z0-9]{1}[A-Za-z0-9-_]+[.])+[a-z]{2,6}$', mail):
|
||||||
raise ValueError("Adresse mail invalide (%s)" % mail)
|
raise ValueError("Adresse mail invalide (%s)" % mail)
|
||||||
self.value = mail
|
self.value = mail
|
||||||
|
@ -377,11 +376,11 @@ class canonicalAlias(mail):
|
||||||
legend = u"Alias mail canonique"
|
legend = u"Alias mail canonique"
|
||||||
category = 'mail'
|
category = 'mail'
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, mail):
|
||||||
val = u".".join([ a.capitalize() for a in val.split(u'.', 1) ])
|
mail = u".".join([ a.capitalize() for a in mail.split(u'.', 1) ])
|
||||||
if not re.match('^[-_.0-9A-Za-z]+@([A-Za-z0-9]{1}[A-Za-z0-9-_]+[.])+[a-z]{2,6}$', val):
|
if not re.match('^[-_.0-9A-Za-z]+@([A-Za-z0-9]{1}[A-Za-z0-9-_]+[.])+[a-z]{2,6}$', mail):
|
||||||
raise ValueError("Alias mail invalide (%s)" % val)
|
raise ValueError("Alias mail invalide (%s)" % mail)
|
||||||
self.value = val
|
self.value = mail
|
||||||
|
|
||||||
class mailAlias(mail):
|
class mailAlias(mail):
|
||||||
singlevalue = False
|
singlevalue = False
|
||||||
|
@ -391,11 +390,11 @@ class mailAlias(mail):
|
||||||
can_modify = [soi, cableur, nounou]
|
can_modify = [soi, cableur, nounou]
|
||||||
category = 'mail'
|
category = 'mail'
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, mail):
|
||||||
val = val.lower()
|
mail = mail.lower()
|
||||||
if not re.match('^[-_.0-9A-Za-z]+@([A-Za-z0-9]{2}[A-Za-z0-9-_]+[.])+[a-z]{2,6}$', val):
|
if not re.match('^[-_.0-9A-Za-z]+@([A-Za-z0-9]{2}[A-Za-z0-9-_]+[.])+[a-z]{2,6}$', mail):
|
||||||
raise ValueError("Alias mail invalide (%r)" % val)
|
raise ValueError("Alias mail invalide (%r)" % mail)
|
||||||
self.value = val
|
self.value = mail
|
||||||
|
|
||||||
class mailInvalide(boolAttr):
|
class mailInvalide(boolAttr):
|
||||||
optional = True
|
optional = True
|
||||||
|
@ -418,10 +417,9 @@ class etudes(Attr):
|
||||||
can_modify = [soi, cableur, nounou]
|
can_modify = [soi, cableur, nounou]
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, etudes):
|
||||||
# who cares
|
# who cares
|
||||||
self.value = val
|
self.value = etudes
|
||||||
|
|
||||||
|
|
||||||
class chbre(Attr):
|
class chbre(Attr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
|
@ -431,26 +429,26 @@ class chbre(Attr):
|
||||||
can_modify = [soi, cableur, nounou]
|
can_modify = [soi, cableur, nounou]
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, chambre):
|
||||||
if self.ctxt_check: # Si ce n'est pas la peine de vérifier, on ne vérifie pas
|
if self.parent != None:
|
||||||
if u'club' in ldif['objectClass']:
|
if u'club' in self.parent['objectClass']:
|
||||||
if val in annuaires_pg.locaux_clubs():
|
if chambre in annuaires_pg.locaux_clubs():
|
||||||
self.value = val
|
self.value = chambre
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise ValueError("Club devrait etre en XclN, pas en %r" % val)
|
raise ValueError("Club devrait etre en XclN, pas en %r" % chambre)
|
||||||
|
|
||||||
if val in (u"EXT", u"????"):
|
if chambre in (u"EXT", u"????"):
|
||||||
self.value = val
|
self.value = chambre
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
annuaires_pg.chbre_prises(val[0], val[1:])
|
annuaires_pg.chbre_prises(chambre[0], chambre[1:])
|
||||||
except NameError:
|
except NameError:
|
||||||
import annuaires_pg_test
|
import annuaires_pg_test
|
||||||
annuaires_pg_test.chbre_prises(val[0], val[1:])
|
annuaires_pg_test.chbre_prises(chambre[0], chambre[1:])
|
||||||
|
|
||||||
self.value = val
|
self.value = chambre
|
||||||
|
|
||||||
class droits(Attr):
|
class droits(Attr):
|
||||||
singlevalue = False
|
singlevalue = False
|
||||||
|
@ -459,10 +457,10 @@ class droits(Attr):
|
||||||
can_modify = [nounou, bureau] #ne sert à rien ici, mais c'est tout à fait exceptionnel
|
can_modify = [nounou, bureau] #ne sert à rien ici, mais c'est tout à fait exceptionnel
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, droits):
|
||||||
# if val.lower() not in [i.lower() for i in TOUS_DROITS]:
|
# if val.lower() not in [i.lower() for i in TOUS_DROITS]:
|
||||||
# raise ValueError("Ces droits n'existent pas (%r)" % val)
|
# raise ValueError("Ces droits n'existent pas (%r)" % val)
|
||||||
self.value = val.capitalize()
|
self.value = droits.capitalize()
|
||||||
|
|
||||||
def is_modifiable(self, liste_droits):
|
def is_modifiable(self, liste_droits):
|
||||||
"""
|
"""
|
||||||
|
@ -481,21 +479,21 @@ class solde(Attr):
|
||||||
legend = u"Solde d'impression"
|
legend = u"Solde d'impression"
|
||||||
can_modify = [imprimeur, nounou, tresorier]
|
can_modify = [imprimeur, nounou, tresorier]
|
||||||
|
|
||||||
def parse_value(self, solde, ldif):
|
def parse_value(self, solde):
|
||||||
# on évite les dépassements, sauf si on nous dit de ne pas vérifier
|
# on évite les dépassements, sauf si on nous dit de ne pas vérifier
|
||||||
if self.ctxt_check and not (float(solde) >= config.impression.decouvert and float(solde) <= 1024.):
|
if not (float(solde) >= config.impression.decouvert and float(solde) <= 1024.):
|
||||||
raise ValueError("Solde invalide: %r" % solde)
|
raise ValueError("Solde invalide: %r" % solde)
|
||||||
self.value = solde
|
self.value = solde
|
||||||
|
|
||||||
class dnsAttr(Attr):
|
class dnsAttr(Attr):
|
||||||
category = 'dns'
|
category = 'dns'
|
||||||
def parse_value(self, dns, ldif):
|
def parse_value(self, val):
|
||||||
dns = dns.lower()
|
val = val.lower()
|
||||||
name, net = dns.split('.', 1)
|
name, net = val.split('.', 1)
|
||||||
if self.ctxt_check and (net not in ['adm.crans.org', 'crans.org', 'wifi.crans.org'] or
|
if (net not in ['adm.crans.org', 'crans.org', 'wifi.crans.org'] or
|
||||||
not re.match('[a-z][-_a-z0-9]+', name)):
|
not re.match('[a-z][-_a-z0-9]+', name)):
|
||||||
raise ValueError("Nom d'hote invalide %r" % dns)
|
raise ValueError("Nom d'hote invalide %r" % val)
|
||||||
self.value = dns
|
self.value = val
|
||||||
|
|
||||||
class host(dnsAttr):
|
class host(dnsAttr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
|
@ -504,8 +502,10 @@ class host(dnsAttr):
|
||||||
can_modify = [parent, nounou, cableur]
|
can_modify = [parent, nounou, cableur]
|
||||||
category = 'base_tech'
|
category = 'base_tech'
|
||||||
|
|
||||||
def _check_uniqueness(self):
|
def check_uniqueness(self, liste_exclue):
|
||||||
attr = self.__class__.__name__
|
attr = self.__class__.__name__
|
||||||
|
if str(self) in liste_exclue:
|
||||||
|
return
|
||||||
if attr in ["host", "hostAlias"]:
|
if attr in ["host", "hostAlias"]:
|
||||||
res = self.conn.search('(|(host=%s)(hostAlias=%s))' % ((str(self),)*2))
|
res = self.conn.search('(|(host=%s)(hostAlias=%s))' % ((str(self),)*2))
|
||||||
if res:
|
if res:
|
||||||
|
@ -527,13 +527,13 @@ class macAddress(Attr):
|
||||||
category = 'base_tech'
|
category = 'base_tech'
|
||||||
can_modify = [parent, nounou, cableur]
|
can_modify = [parent, nounou, cableur]
|
||||||
|
|
||||||
def parse_value(self, mac, ldif):
|
def parse_value(self, mac):
|
||||||
self.value = format_mac(mac)
|
self.value = format_mac(mac)
|
||||||
|
# XXX self.parent['ip6HostNumber'] = cequ'ilfaut
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.value).lower()
|
return unicode(self.value).lower()
|
||||||
|
|
||||||
|
|
||||||
class ipHostNumber(Attr):
|
class ipHostNumber(Attr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
|
@ -543,9 +543,9 @@ class ipHostNumber(Attr):
|
||||||
category = 'base_tech'
|
category = 'base_tech'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
|
|
||||||
def parse_value(self, ip, ldif):
|
def parse_value(self, ip):
|
||||||
if ip == '<automatique>':
|
if ip == '<automatique>':
|
||||||
ip = ip4_of_rid(ldif['rid'][0])
|
ip = ip4_of_rid(self.parent['rid'][0])
|
||||||
self.value = netaddr.ip.IPAddress(ip)
|
self.value = netaddr.ip.IPAddress(ip)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -560,8 +560,8 @@ class ip6HostNumber(Attr):
|
||||||
category = 'base_tech'
|
category = 'base_tech'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, ip6):
|
||||||
ip = ip6_of_mac(ldif['macAddress'][0], int(ldif['rid'][0]))
|
ip = ip6_of_mac(self.parent['macAddress'][0], int(self.parent['rid'][0]))
|
||||||
self.value = netaddr.ip.IPAddress(ip)
|
self.value = netaddr.ip.IPAddress(ip)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -574,7 +574,7 @@ class mid(Attr):
|
||||||
legend = u"Identifiant de machine"
|
legend = u"Identifiant de machine"
|
||||||
category = 'id'
|
category = 'id'
|
||||||
|
|
||||||
def parse_value(self, mid, ldif):
|
def parse_value(self, mid):
|
||||||
self.value = int(mid)
|
self.value = int(mid)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -588,7 +588,7 @@ class rid(Attr):
|
||||||
category = 'id'
|
category = 'id'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
|
|
||||||
def parse_value(self, rid, ldif):
|
def parse_value(self, rid):
|
||||||
rid = int(rid)
|
rid = int(rid)
|
||||||
|
|
||||||
# On veut éviter les rid qui recoupent les ipv4 finissant par
|
# On veut éviter les rid qui recoupent les ipv4 finissant par
|
||||||
|
@ -644,11 +644,11 @@ class positionBorne(Attr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, pos):
|
||||||
if val == u'N/A N/A':
|
if pos == u'N/A N/A':
|
||||||
self.value = u"N/A°N N/A°E"
|
self.value = u"N/A°N N/A°E"
|
||||||
else:
|
else:
|
||||||
lat, lon = val.split(" ")
|
lat, lon = pos.split(" ")
|
||||||
self.value = u"%f°N %f°E" % (float(lat), float(lon))
|
self.value = u"%f°N %f°E" % (float(lat), float(lon))
|
||||||
|
|
||||||
class nvram(Attr):
|
class nvram(Attr):
|
||||||
|
@ -656,8 +656,9 @@ class nvram(Attr):
|
||||||
optional = True
|
optional = True
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, nvr):
|
||||||
pass
|
# XXX - on fait quoi ici ?
|
||||||
|
self.value = nvr
|
||||||
|
|
||||||
class portAttr(Attr):
|
class portAttr(Attr):
|
||||||
singlevalue = False
|
singlevalue = False
|
||||||
|
@ -666,7 +667,7 @@ class portAttr(Attr):
|
||||||
category = 'firewall'
|
category = 'firewall'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
|
|
||||||
def parse_value(self, port, ldif):
|
def parse_value(self, port):
|
||||||
if ":" in port:
|
if ":" in port:
|
||||||
a,b = port.split(":", 1)
|
a,b = port.split(":", 1)
|
||||||
if a:
|
if a:
|
||||||
|
@ -694,7 +695,6 @@ class portAttr(Attr):
|
||||||
else:
|
else:
|
||||||
return unicode(self.value[0])
|
return unicode(self.value[0])
|
||||||
|
|
||||||
|
|
||||||
class portTCPout(portAttr):
|
class portTCPout(portAttr):
|
||||||
legend = u'Port TCP ouvert vers l\'extérieur'
|
legend = u'Port TCP ouvert vers l\'extérieur'
|
||||||
|
|
||||||
|
@ -724,8 +724,8 @@ class prise(Attr):
|
||||||
category = 'base_tech'
|
category = 'base_tech'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
|
|
||||||
def parse_value(self, prise, ldif):
|
def parse_value(self, prise):
|
||||||
### Tu es une Nounou, je te fais confiance
|
### Tu es Beau, je te fais confiance
|
||||||
self.value = prise
|
self.value = prise
|
||||||
|
|
||||||
class cid(intAttr):
|
class cid(intAttr):
|
||||||
|
@ -735,7 +735,7 @@ class cid(intAttr):
|
||||||
legend = u"Identifiant du club"
|
legend = u"Identifiant du club"
|
||||||
category = 'id'
|
category = 'id'
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, val):
|
||||||
self.value = int(val)
|
self.value = int(val)
|
||||||
|
|
||||||
class responsable(Attr):
|
class responsable(Attr):
|
||||||
|
@ -745,7 +745,7 @@ class responsable(Attr):
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
can_modify = [cableur, nounou]
|
can_modify = [cableur, nounou]
|
||||||
|
|
||||||
def nonefunction(self, val):
|
def nonefunction(self, resp):
|
||||||
"""
|
"""
|
||||||
Just... do... nothing.
|
Just... do... nothing.
|
||||||
L'idée est qu'on initialise self.value à None
|
L'idée est qu'on initialise self.value à None
|
||||||
|
@ -755,6 +755,9 @@ class responsable(Attr):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_respo(self):
|
def get_respo(self):
|
||||||
|
"""Méthode spéciale, pour aller avec
|
||||||
|
property. On génère le respo quand
|
||||||
|
c'est nécessaire, pas avant."""
|
||||||
if hasattr(self, "_value"):
|
if hasattr(self, "_value"):
|
||||||
return self._value
|
return self._value
|
||||||
else:
|
else:
|
||||||
|
@ -765,7 +768,7 @@ class responsable(Attr):
|
||||||
self._value = res
|
self._value = res
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def parse_value(self, resp, ldif):
|
def parse_value(self, resp):
|
||||||
self.__value = resp
|
self.__value = resp
|
||||||
|
|
||||||
value = property(get_respo, nonefunction)
|
value = property(get_respo, nonefunction)
|
||||||
|
@ -779,7 +782,7 @@ class imprimeurClub(Attr):
|
||||||
category = "perso"
|
category = "perso"
|
||||||
can_modify = [cableur, nounou]
|
can_modify = [cableur, nounou]
|
||||||
|
|
||||||
def nonefunction(self, val):
|
def nonefunction(self, imprimeur):
|
||||||
"""
|
"""
|
||||||
Just... do... nothing.
|
Just... do... nothing.
|
||||||
L'idée est qu'on initialise self.value à None
|
L'idée est qu'on initialise self.value à None
|
||||||
|
@ -799,8 +802,8 @@ class imprimeurClub(Attr):
|
||||||
self._value = res
|
self._value = res
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, imprimeur):
|
||||||
self.__value = val
|
self.__value = imprimeur
|
||||||
|
|
||||||
value = property(get_imprimeur, nonefunction)
|
value = property(get_imprimeur, nonefunction)
|
||||||
|
|
||||||
|
@ -814,8 +817,8 @@ class blacklist(Attr):
|
||||||
category = 'info'
|
category = 'info'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
|
|
||||||
def parse_value(self, bl, ldif):
|
def parse_value(self, blacklist):
|
||||||
bl_debut, bl_fin, bl_type, bl_comm = bl.split('$')
|
bl_debut, bl_fin, bl_type, bl_comm = blacklist.split('$')
|
||||||
now = time.time()
|
now = time.time()
|
||||||
self.value = { 'debut' : bl_debut if bl_debut == '-' else int (bl_debut),
|
self.value = { 'debut' : bl_debut if bl_debut == '-' else int (bl_debut),
|
||||||
'fin' : bl_fin if bl_fin == '-' else int(bl_fin),
|
'fin' : bl_fin if bl_fin == '-' else int(bl_fin),
|
||||||
|
@ -860,10 +863,10 @@ class charteMA(Attr):
|
||||||
can_modify = [nounou, bureau]
|
can_modify = [nounou, bureau]
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
|
|
||||||
def parse_value(self, signed, ldif):
|
def parse_value(self, charteSignee):
|
||||||
if signed.upper() not in ["TRUE", "FALSE"]:
|
if charteSignee.upper() not in ["TRUE", "FALSE"]:
|
||||||
raise ValueError("La charte MA est soit TRUE ou FALSE, pas %r" % signed)
|
raise ValueError("La charte MA est soit TRUE ou FALSE, pas %r" % charteSignee)
|
||||||
self.value = signed.upper()
|
self.value = charteSignee.upper()
|
||||||
|
|
||||||
class homeDirectory(Attr):
|
class homeDirectory(Attr):
|
||||||
singlevalue=True
|
singlevalue=True
|
||||||
|
@ -871,13 +874,12 @@ class homeDirectory(Attr):
|
||||||
unique = True
|
unique = True
|
||||||
legend="Le chemin du home de l'adhérent"
|
legend="Le chemin du home de l'adhérent"
|
||||||
|
|
||||||
def parse_value(self, home, ldif):
|
def parse_value(self, home):
|
||||||
uid = ldif['uid'][0]
|
uid = str(self.parent['uid'][0])
|
||||||
if uid.startswith('club-'):
|
if uid.startswith('club-'):
|
||||||
uid = uid.split('-',1)[1]
|
uid = uid.split('-',1)[1]
|
||||||
if home != u'/home/%s' % uid and home != u'/home/club/%s' % uid:
|
if home != u'/home/%s' % uid and home != u'/home/club/%s' % uid:
|
||||||
raise ValueError("Le répertoire personnel n'est pas bon: %r (devrait être %r ou %r)" %
|
raise ValueError("Le répertoire personnel n'est pas bon: %r (devrait être %r ou %r)" % (home, '/home/%s' % self.parent['uid'][0], '/home/club/%s' % self.parent['uid'][0]))
|
||||||
(home, '/home/%s' % ldif['uid'][0], '/home/club/%s' % ldif['uid'][0]))
|
|
||||||
self.value = home
|
self.value = home
|
||||||
|
|
||||||
class loginShell(Attr):
|
class loginShell(Attr):
|
||||||
|
@ -886,10 +888,10 @@ class loginShell(Attr):
|
||||||
legend = "Le shell de l'adherent"
|
legend = "Le shell de l'adherent"
|
||||||
can_modify = [soi, nounou, cableur]
|
can_modify = [soi, nounou, cableur]
|
||||||
|
|
||||||
def parse_value(self, shell, ldif):
|
def parse_value(self, shell):
|
||||||
#with open('/etc/shells') as f:
|
#with open('/etc/shells') as f:
|
||||||
# shells = [ l.strip() for l in f.readlines() if not l.startswith('#') ]
|
# shells = [ l.strip() for l in f.readlines() if not l.startswith('#') ]
|
||||||
shells=['/bin/csh',
|
shells = ['/bin/csh',
|
||||||
'/bin/sh',
|
'/bin/sh',
|
||||||
'/usr/bin/es',
|
'/usr/bin/es',
|
||||||
'/usr/bin/ksh',
|
'/usr/bin/ksh',
|
||||||
|
@ -912,7 +914,7 @@ class loginShell(Attr):
|
||||||
'/bin/false',
|
'/bin/false',
|
||||||
'/bin//zsh'
|
'/bin//zsh'
|
||||||
'']
|
'']
|
||||||
if self.ctxt_check and (shell not in shells):
|
if shell not in shells:
|
||||||
raise ValueError("Shell %r invalide" % shell)
|
raise ValueError("Shell %r invalide" % shell)
|
||||||
self.value = shell
|
self.value = shell
|
||||||
|
|
||||||
|
@ -935,7 +937,7 @@ class gecos(Attr):
|
||||||
legend = "Le gecos"
|
legend = "Le gecos"
|
||||||
category = 'id'
|
category = 'id'
|
||||||
|
|
||||||
def parse_value(self, gecos, ldif):
|
def parse_value(self, gecos):
|
||||||
self.value = gecos
|
self.value = gecos
|
||||||
|
|
||||||
class sshFingerprint(Attr):
|
class sshFingerprint(Attr):
|
||||||
|
@ -976,7 +978,7 @@ class controle(Attr):
|
||||||
can_modify = [tresorier, nounou]
|
can_modify = [tresorier, nounou]
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
|
|
||||||
def parse_value(self, ctrl, ldif):
|
def parse_value(self, ctrl):
|
||||||
if ctrl not in [u"", u"c", u"p", u"cp", u"pc"]:
|
if ctrl not in [u"", u"c", u"p", u"cp", u"pc"]:
|
||||||
raise ValueError("control peut prendre les valeurs [c][p]")
|
raise ValueError("control peut prendre les valeurs [c][p]")
|
||||||
if ctrl == u'cp':
|
if ctrl == u'cp':
|
||||||
|
@ -1008,7 +1010,7 @@ MACHINE_ATTRS = [ host, macAddress, hostAlias, ipHostNumber, portTCPout,
|
||||||
portTCPin, portUDPout, portUDPin ]
|
portTCPin, portUDPout, portUDPin ]
|
||||||
|
|
||||||
|
|
||||||
CRANS_ATTRIBUTES= {
|
CRANS_ATTRIBUTES = {
|
||||||
'objectClass' : objectClass,
|
'objectClass' : objectClass,
|
||||||
'cn' : cn,
|
'cn' : cn,
|
||||||
'dn' : dn,
|
'dn' : dn,
|
||||||
|
|
38
lc_ldap.py
38
lc_ldap.py
|
@ -104,7 +104,7 @@ def ldif_to_uldif(ldif):
|
||||||
uldif[attr] = [ unicode(val, 'utf-8') for val in vals ]
|
uldif[attr] = [ unicode(val, 'utf-8') for val in vals ]
|
||||||
return uldif
|
return uldif
|
||||||
|
|
||||||
def ldif_to_cldif(ldif, conn, check_ctxt = True):
|
def ldif_to_cldif(ldif, conn):
|
||||||
"""Transforme un dictionnaire renvoyé par python-ldap, en
|
"""Transforme un dictionnaire renvoyé par python-ldap, en
|
||||||
un dictionnaire dont les valeurs sont des instances de Attr
|
un dictionnaire dont les valeurs sont des instances de Attr
|
||||||
Lorsqu'on récupère le ldif de la base ldap, on n'a pas besoin
|
Lorsqu'on récupère le ldif de la base ldap, on n'a pas besoin
|
||||||
|
@ -112,7 +112,7 @@ def ldif_to_cldif(ldif, conn, check_ctxt = True):
|
||||||
"""
|
"""
|
||||||
cldif = {}
|
cldif = {}
|
||||||
for attr, vals in ldif.items():
|
for attr, vals in ldif.items():
|
||||||
cldif[attr] = [ attributs.attrify(val, attr, ldif, conn, check_ctxt) for val in vals]
|
cldif[attr] = [ attributs.attrify(val, attr, ldif, conn) for val in vals]
|
||||||
return cldif
|
return cldif
|
||||||
|
|
||||||
def cldif_to_ldif(cldif):
|
def cldif_to_ldif(cldif):
|
||||||
|
@ -325,7 +325,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
# On crée l'attribut associé, pour parser sa valeur.
|
# On crée l'attribut associé, pour parser sa valeur.
|
||||||
my_id = attributs.attrify(unicode(i), attr, {}, self, False)
|
my_id = attributs.attrify(unicode(i), attr, self, False, None)
|
||||||
if my_id.value != i:
|
if my_id.value != i:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
@ -456,20 +456,20 @@ class CransLdapObject(object):
|
||||||
raise TypeError("conn doit être une instance de lc_ldap")
|
raise TypeError("conn doit être une instance de lc_ldap")
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
|
|
||||||
self.attrs = attributs.AttrsDict(conn) # Contient un dico uldif qui doit représenter ce qui
|
self.attrs = attributs.AttrsDict(conn, Parent=self) # Contient un dico uldif qui doit représenter ce qui
|
||||||
# est dans la base. On attrify paresseusement au moment où on utilise un attribut
|
# est dans la base. On attrify paresseusement au moment où on utilise un attribut
|
||||||
|
|
||||||
self._modifs = None # C'est là qu'on met les modifications
|
self._modifs = None # C'est là qu'on met les modifications
|
||||||
|
self._modifs_unchecked = []
|
||||||
self.dn = dn
|
self.dn = dn
|
||||||
|
|
||||||
orig = {}
|
orig = {}
|
||||||
if ldif:
|
if ldif:
|
||||||
if dn != base_dn: # new_cransldapobject ne donne pas de ldif formaté et utilise un ldif non formaté, donc on formate
|
if dn != base_dn: # new_cransldapobject ne donne pas de ldif formaté et utilise un ldif non formaté, donc on formate
|
||||||
self.attrs = attributs.AttrsDict(self.conn, ldif, check_ctxt = False)
|
self.attrs = attributs.AttrsDict(self.conn, ldif, Parent=self)
|
||||||
else:
|
else:
|
||||||
self.attrs = ldif
|
self.attrs = ldif
|
||||||
self._modifs = attributs.AttrsDict(self.conn, ldif, check_ctxt = False)
|
self._modifs = attributs.AttrsDict(self.conn, ldif, Parent=self)
|
||||||
orig = ldif
|
orig = ldif
|
||||||
|
|
||||||
elif dn != base_dn:
|
elif dn != base_dn:
|
||||||
|
@ -480,12 +480,12 @@ class CransLdapObject(object):
|
||||||
|
|
||||||
# L'objet sortant de la base ldap, on ne fait pas de vérifications sur
|
# L'objet sortant de la base ldap, on ne fait pas de vérifications sur
|
||||||
# l'état des données.
|
# l'état des données.
|
||||||
self.attrs = attributs.AttrsDict(self.conn, res_attrs, check_ctxt = False)
|
self.attrs = attributs.AttrsDict(self.conn, res_attrs, Parent=self)
|
||||||
|
|
||||||
# Pour test en cas de mode w ou rw
|
# Pour test en cas de mode w ou rw
|
||||||
orig = res[0][1]
|
orig = res[0][1]
|
||||||
|
|
||||||
self._modifs = attributs.AttrsDict(self.conn, res[0][1], check_ctxt = False)
|
self._modifs = attributs.AttrsDict(self.conn, res[0][1], Parent=self)
|
||||||
|
|
||||||
if mode in ['w', 'rw']:
|
if mode in ['w', 'rw']:
|
||||||
if not self.may_be(modified, self.conn.droits + self.conn._check_parent(dn) + self.conn._check_self(dn)):
|
if not self.may_be(modified, self.conn.droits + self.conn._check_parent(dn) + self.conn._check_self(dn)):
|
||||||
|
@ -550,7 +550,7 @@ class CransLdapObject(object):
|
||||||
raise EnvironmentError("Impossible de modifier l'objet, peut-être n'existe-t-il pas ?")
|
raise EnvironmentError("Impossible de modifier l'objet, peut-être n'existe-t-il pas ?")
|
||||||
|
|
||||||
# Vérification des modifications
|
# Vérification des modifications
|
||||||
self.attrs = attributs.AttrsDict(self.conn, self.conn.search_s(self.dn, 0)[0][1], check_ctxt=False)
|
self.attrs = attributs.AttrsDict(self.conn, self.conn.search_s(self.dn, 0)[0][1], Parent=self)
|
||||||
differences = []
|
differences = []
|
||||||
# On fait les différences entre les deux dicos
|
# On fait les différences entre les deux dicos
|
||||||
for attr in set(self.attrs.keys()).union(set(self._modifs.keys())):
|
for attr in set(self.attrs.keys()).union(set(self._modifs.keys())):
|
||||||
|
@ -607,6 +607,8 @@ class CransLdapObject(object):
|
||||||
# Quand on est pas en mode d'écriture, ça plante.
|
# Quand on est pas en mode d'écriture, ça plante.
|
||||||
if self.mode not in ['w', 'rw']:
|
if self.mode not in ['w', 'rw']:
|
||||||
raise ValueError("Objet en lecture seule")
|
raise ValueError("Objet en lecture seule")
|
||||||
|
if not self.has_key(attr):
|
||||||
|
raise ValueError("L'objet que vous modifiez n'a pas d'attribut %s" % (attr))
|
||||||
# Les valeurs sont nécessairement stockées en liste
|
# Les valeurs sont nécessairement stockées en liste
|
||||||
if not isinstance(values, list):
|
if not isinstance(values, list):
|
||||||
values = [ values ]
|
values = [ values ]
|
||||||
|
@ -616,12 +618,9 @@ class CransLdapObject(object):
|
||||||
# (on peut pas utiliser self._modifs, car il ne faut
|
# (on peut pas utiliser self._modifs, car il ne faut
|
||||||
# faire le changement que si on peut)
|
# faire le changement que si on peut)
|
||||||
|
|
||||||
# Sans le dict(), les deux pointent vers le même truc.
|
attrs_before_verif = [ attributs.attrify(val, attr, self.conn, Parent=self) for val in values ]
|
||||||
ldif = dict(self._modifs)
|
for attribut in attrs_before_verif:
|
||||||
# On doit encoder, car _modifs est un ensemble de données brutes
|
attribut.check_uniqueness([str(content) for content in self.attrs[attr]])
|
||||||
# comme tout ldif
|
|
||||||
ldif[attr] = [ value.encode('utf-8') for value in values ]
|
|
||||||
attrs_before_verif = [ attributs.attrify(val, attr, ldif, self.conn) for val in values ]
|
|
||||||
|
|
||||||
# On groupe les attributs précédents, et les nouveaux
|
# On groupe les attributs précédents, et les nouveaux
|
||||||
mixed_attrs = attrs_before_verif + self.attrs[attr]
|
mixed_attrs = attrs_before_verif + self.attrs[attr]
|
||||||
|
@ -950,7 +949,8 @@ class facture(CransLdapObject):
|
||||||
}
|
}
|
||||||
attribs = [attributs.fid, attributs.modePaiement, attributs.recuPaiement]
|
attribs = [attributs.fid, attributs.modePaiement, attributs.recuPaiement]
|
||||||
|
|
||||||
class service(CransLdapObject): pass
|
class service(CransLdapObject):
|
||||||
|
pass
|
||||||
class lock(CransLdapObject): pass
|
|
||||||
|
|
||||||
|
class lock(CransLdapObject):
|
||||||
|
pass
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue