Ajout de methodes pour tester l'égalité d'objets ou d'attributs,
possibilité de fournir une valeur du bon type python à un attribut test booléen sur s'attribut propagée à sa valeur. Le teste d'égalité sur un attribut peut se faire avec la sérialisation de l'attribut ou le type python qui le représente. Le teste d'égalité sur les cransLdapObjet se fait sur le dn et ses attributs. De plus, on peut aussi le testé avec un chaine de caractère : "host=freebox.crans.org" == MachineCrans(...) renvoie True ssi MachineCrans(...) a l'attribut host, qu'il est globalement unique et vaut freebox.crans.org vala vala
This commit is contained in:
parent
e9d092698a
commit
ca170c19f4
2 changed files with 79 additions and 28 deletions
68
attributs.py
68
attributs.py
|
@ -125,10 +125,11 @@ def attrify(val, attr, conn, Parent=None):
|
||||||
if isinstance(val, Attr):
|
if isinstance(val, Attr):
|
||||||
return val
|
return val
|
||||||
else:
|
else:
|
||||||
if not isinstance(val, unicode):
|
attr_classe = AttributeFactory.get(attr, fallback=Attr)
|
||||||
|
if not isinstance(val, unicode) and (attr_classe.python_type and not isinstance(val, attr_classe.python_type)):
|
||||||
cranslib.deprecated.usage("attrify ne devrait être appelé qu'avec des unicode (%r)" % val, level=3)
|
cranslib.deprecated.usage("attrify ne devrait être appelé qu'avec des unicode (%r)" % val, level=3)
|
||||||
val = val.decode('utf-8')
|
val = val.decode('utf-8')
|
||||||
return AttributeFactory.get(attr, fallback=Attr)(val, conn, Parent)
|
return attr_classe(val, conn, Parent)
|
||||||
|
|
||||||
|
|
||||||
class AttrsDict(dict):
|
class AttrsDict(dict):
|
||||||
|
@ -193,6 +194,7 @@ class Attr(object):
|
||||||
unique = False
|
unique = False
|
||||||
#: Le nom de l'attribut dans le schéma LDAP
|
#: Le nom de l'attribut dans le schéma LDAP
|
||||||
ldap_name = None
|
ldap_name = None
|
||||||
|
python_type = None
|
||||||
|
|
||||||
"""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_modify = [nounou]
|
||||||
|
@ -213,6 +215,21 @@ class Attr(object):
|
||||||
self.parent = Parent
|
self.parent = Parent
|
||||||
self.parse_value(val)
|
self.parse_value(val)
|
||||||
|
|
||||||
|
def __eq__(self, item):
|
||||||
|
if isinstance(item, self.__class__):
|
||||||
|
return str(self) == str(item)
|
||||||
|
elif self.python_type and isinstance(item, self.python_type):
|
||||||
|
return self.value == item
|
||||||
|
elif isinstance(item, str):
|
||||||
|
return str(self) == item
|
||||||
|
elif isinstance(item, unicode):
|
||||||
|
return unicode(self) == item
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __nonzero__(self):
|
||||||
|
return self.value.__nonzero__()
|
||||||
|
|
||||||
def parse_value(self, val):
|
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
|
||||||
|
@ -304,22 +321,28 @@ class objectClass(Attr):
|
||||||
|
|
||||||
|
|
||||||
class intAttr(Attr):
|
class intAttr(Attr):
|
||||||
|
|
||||||
|
python_type = int
|
||||||
|
|
||||||
def parse_value(self, val):
|
def parse_value(self, val):
|
||||||
if int(val) <= 0:
|
if self.python_type(val) <= 0:
|
||||||
raise ValueError("Valeur entière invalide : %r" % val)
|
raise ValueError("Valeur entière invalide : %r" % val)
|
||||||
self.value = int(val)
|
self.value = self.python_type(val)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.value)
|
return unicode(self.value)
|
||||||
|
|
||||||
class boolAttr(Attr):
|
class boolAttr(Attr):
|
||||||
|
|
||||||
|
python_type = bool
|
||||||
|
|
||||||
def parse_value(self, val):
|
def parse_value(self, val):
|
||||||
if val.lower() in [u'true', u'ok']:
|
if isinstance(val, self.python_type):
|
||||||
|
self.value = val
|
||||||
|
elif val.lower() in [u'true', u'ok']:
|
||||||
self.value = True
|
self.value = True
|
||||||
elif val.lower() == u'false':
|
elif val.lower() == u'false':
|
||||||
self.value = False
|
self.value = False
|
||||||
elif isinstance(val, bool):
|
|
||||||
self.value = val
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("%r doit être un booléen !" % val)
|
raise ValueError("%r doit être un booléen !" % val)
|
||||||
|
|
||||||
|
@ -414,7 +437,7 @@ class yearAttr(intAttr):
|
||||||
optional = True
|
optional = True
|
||||||
|
|
||||||
def parse_value(self, annee):
|
def parse_value(self, annee):
|
||||||
annee = int(annee)
|
annee = self.python_type(annee)
|
||||||
if annee < 1998:
|
if annee < 1998:
|
||||||
raise ValueError("Année invalide (%r)" % annee)
|
raise ValueError("Année invalide (%r)" % annee)
|
||||||
self.value = annee
|
self.value = annee
|
||||||
|
@ -598,6 +621,7 @@ class droits(Attr):
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class solde(Attr):
|
class solde(Attr):
|
||||||
|
python_type = float
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
legend = u"Solde d'impression"
|
legend = u"Solde d'impression"
|
||||||
|
@ -608,7 +632,7 @@ class solde(Attr):
|
||||||
# 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 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 = float(solde)
|
self.value = self.python_type(solde)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%.2f" % self.value
|
return u"%.2f" % self.value
|
||||||
|
@ -679,12 +703,13 @@ class ipHostNumber(Attr):
|
||||||
category = 'base_tech'
|
category = 'base_tech'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
ldap_name = "ipHostNumber"
|
ldap_name = "ipHostNumber"
|
||||||
|
python_type = netaddr.IPAddress
|
||||||
default = u'<automatique>'
|
default = u'<automatique>'
|
||||||
|
|
||||||
def parse_value(self, ip):
|
def parse_value(self, ip):
|
||||||
if ip == '<automatique>':
|
if ip == '<automatique>':
|
||||||
ip = ip4_of_rid(str(self.parent['rid'][0]))
|
ip = ip4_of_rid(str(self.parent['rid'][0]))
|
||||||
self.value = netaddr.IPAddress(ip)
|
self.value = self.python_type(ip)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.value)
|
return unicode(self.value)
|
||||||
|
@ -699,18 +724,19 @@ class ip6HostNumber(Attr):
|
||||||
category = 'base_tech'
|
category = 'base_tech'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
ldap_name = "ip6HostNumber"
|
ldap_name = "ip6HostNumber"
|
||||||
|
python_type = netaddr.IPAddress
|
||||||
default = u'<automatique>'
|
default = u'<automatique>'
|
||||||
|
|
||||||
def parse_value(self, ip6):
|
def parse_value(self, ip6):
|
||||||
if ip6 == '<automatique>':
|
if ip6 == '<automatique>':
|
||||||
ip6 = ip6_of_mac(str(self.parent['macAddress'][0]), int(str(self.parent['rid'][0])))
|
ip6 = ip6_of_mac(str(self.parent['macAddress'][0]), int(str(self.parent['rid'][0])))
|
||||||
self.value = netaddr.IPAddress(ip6)
|
self.value = self.python_type(ip6)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.value)
|
return unicode(self.value)
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class mid(Attr):
|
class mid(intAttr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = False
|
optional = False
|
||||||
unique = True
|
unique = True
|
||||||
|
@ -718,14 +744,8 @@ class mid(Attr):
|
||||||
category = 'id'
|
category = 'id'
|
||||||
ldap_name = "mid"
|
ldap_name = "mid"
|
||||||
|
|
||||||
def parse_value(self, mid):
|
|
||||||
self.value = int(mid)
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return unicode(self.value)
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class rid(Attr):
|
class rid(intAttr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
unique = True
|
unique = True
|
||||||
|
@ -735,7 +755,7 @@ class rid(Attr):
|
||||||
ldap_name = "rid"
|
ldap_name = "rid"
|
||||||
|
|
||||||
def parse_value(self, rid):
|
def parse_value(self, rid):
|
||||||
rid = int(rid)
|
rid = self.python_type(rid)
|
||||||
|
|
||||||
# On veut éviter les rid qui recoupent les ipv4 finissant par
|
# On veut éviter les rid qui recoupent les ipv4 finissant par
|
||||||
# .0 ou .255
|
# .0 ou .255
|
||||||
|
@ -989,6 +1009,7 @@ class blacklist(Attr):
|
||||||
category = 'info'
|
category = 'info'
|
||||||
can_modify = [nounou]
|
can_modify = [nounou]
|
||||||
ldap_name = "blacklist"
|
ldap_name = "blacklist"
|
||||||
|
python_type = dict
|
||||||
|
|
||||||
def parse_value(self, blacklist):
|
def parse_value(self, blacklist):
|
||||||
bl_debut, bl_fin, bl_type, bl_comm = blacklist.split('$')
|
bl_debut, bl_fin, bl_type, bl_comm = blacklist.split('$')
|
||||||
|
@ -1061,7 +1082,7 @@ class homepageAlias(Attr):
|
||||||
ldap_name = "homepageAlias"
|
ldap_name = "homepageAlias"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class charteMA(Attr):
|
class charteMA(boolAttr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
legend= "Signale si l'adhérent a signé la charte de membres actifs"
|
legend= "Signale si l'adhérent a signé la charte de membres actifs"
|
||||||
|
@ -1069,11 +1090,6 @@ class charteMA(Attr):
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
ldap_name = "charteMA"
|
ldap_name = "charteMA"
|
||||||
|
|
||||||
def parse_value(self, charteSignee):
|
|
||||||
if charteSignee.upper() not in [u"TRUE", u"FALSE"]:
|
|
||||||
raise ValueError("La charte MA est soit TRUE ou FALSE, pas %r" % charteSignee)
|
|
||||||
self.value = charteSignee.upper()
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class homeDirectory(Attr):
|
class homeDirectory(Attr):
|
||||||
singlevalue=True
|
singlevalue=True
|
||||||
|
|
39
objets.py
39
objets.py
|
@ -162,6 +162,41 @@ class CransLdapObject(object):
|
||||||
nvals = [nldif[attr][vals.index(v)] for v in vals ]
|
nvals = [nldif[attr][vals.index(v)] for v in vals ]
|
||||||
raise EnvironmentError("λv. str(Attr(v)) n'est peut-être pas une projection (ie non idempotente):", attr, nvals, vals)
|
raise EnvironmentError("λv. str(Attr(v)) n'est peut-être pas une projection (ie non idempotente):", attr, nvals, vals)
|
||||||
|
|
||||||
|
def __eq__(self, obj):
|
||||||
|
if isinstance(obj, self.__class__):
|
||||||
|
if self.mode in ['w', 'rw']:
|
||||||
|
return self.dn == obj.dn and self._modifs == obj._modifs and self.attrs == obj.attrs
|
||||||
|
else:
|
||||||
|
return self.dn == obj.dn and self.attrs == obj.attrs
|
||||||
|
elif (isinstance(obj, str) or isinstance(obj, unicode)) and '=' in obj:
|
||||||
|
attr, val = obj.split('=', 1)
|
||||||
|
return attr in self.attrs.keys() and val in self[attr]
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
|
return self._modifs.__iter__()
|
||||||
|
else:
|
||||||
|
return self.attrs.__iter__()
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
|
return self._modifs.keys()
|
||||||
|
else:
|
||||||
|
return self.attrs.keys()
|
||||||
|
|
||||||
|
def values(self):
|
||||||
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
|
return self._modifs.values()
|
||||||
|
else:
|
||||||
|
return self.attrs.values()
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
|
return self._modifs.items()
|
||||||
|
else:
|
||||||
|
return self.attrs.items()
|
||||||
|
|
||||||
def display(self):
|
def display(self):
|
||||||
print printing.sprint(self)
|
print printing.sprint(self)
|
||||||
|
@ -543,7 +578,7 @@ class proprio(CransLdapObject):
|
||||||
super(proprio, self).__init__(conn, dn, mode, ldif)
|
super(proprio, self).__init__(conn, dn, mode, ldif)
|
||||||
self._machines = None
|
self._machines = None
|
||||||
self._factures = None
|
self._factures = None
|
||||||
if u'cransAccount' in [ unicode(o) for o in self['objectClass']]:
|
if u'cransAccount' in self['objectClass']:
|
||||||
self.attribs = self.attribs + crans_account_attribs
|
self.attribs = self.attribs + crans_account_attribs
|
||||||
self.full = True
|
self.full = True
|
||||||
|
|
||||||
|
@ -837,7 +872,7 @@ class adherent(proprio):
|
||||||
u"""Renvoie le nom du compte crans. S'il n'existe pas, et que uid
|
u"""Renvoie le nom du compte crans. S'il n'existe pas, et que uid
|
||||||
est précisé, le crée."""
|
est précisé, le crée."""
|
||||||
|
|
||||||
if u'posixAccount' in [str(o) for o in self.attrs['objectClass']]:
|
if u'posixAccount' in self['objectClass']:
|
||||||
return self.attrs['uid'][0]
|
return self.attrs['uid'][0]
|
||||||
|
|
||||||
elif login:
|
elif login:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue