[lc_ldap, attributs] les Attr contiennent aussi les valeurs
This commit is contained in:
parent
5f3c3d56fb
commit
85c513a1aa
2 changed files with 95 additions and 58 deletions
90
attributs.py
90
attributs.py
|
@ -50,21 +50,39 @@ def validate_mac(value):
|
||||||
"""Vérifie qu'une adresse mac est valide"""
|
"""Vérifie qu'une adresse mac est valide"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class Attr:
|
def attrify(val, attr, ldif, ctxt_check = True):
|
||||||
|
"""Transforme un n'importe quoi en Attr.
|
||||||
|
|
||||||
|
Doit effectuer les normalisations et sanity check si un str ou un
|
||||||
|
unicode est passé en argument.
|
||||||
|
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"""
|
||||||
|
|
||||||
|
return val if isinstance(val, Attr) else CRANS_ATTRIBUTES[attr](val, ldif)
|
||||||
|
|
||||||
|
class Attr(object):
|
||||||
legend = "Human-readable description of attribute"
|
legend = "Human-readable description of attribute"
|
||||||
singlevalue = None
|
singlevalue = None
|
||||||
optional = None
|
optional = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, val, ldif):
|
||||||
pass
|
assert isinstance(val, unicode)
|
||||||
|
self.parse_value(val)
|
||||||
|
self.validate(ldif)
|
||||||
|
|
||||||
def validate(self, values, uldif):
|
def parse_value(self, val):
|
||||||
"validates"
|
self.value = val
|
||||||
self._check_cardinality(values)
|
|
||||||
self._check_type(values)
|
def __str__(self):
|
||||||
self._check_uniqueness(values)
|
unicode.encode(unicode(self), 'utf-8')
|
||||||
self._check_values(values)
|
|
||||||
self._check_users_restrictions(values)
|
def validate(self, ldif):
|
||||||
|
"""validates:
|
||||||
|
vérifie déjà que ce qu'on a rentré est parsable"""
|
||||||
|
self._check_cardinality(ldif)
|
||||||
|
self._check_uniqueness(ldif)
|
||||||
|
self._check_users_restrictions(ldif)
|
||||||
|
|
||||||
def normalize(self, values, uldif):
|
def normalize(self, values, uldif):
|
||||||
"normalizes"
|
"normalizes"
|
||||||
|
@ -271,31 +289,31 @@ class historique(Attr):
|
||||||
|
|
||||||
|
|
||||||
CRANS_ATTRIBUTES= {
|
CRANS_ATTRIBUTES= {
|
||||||
'objectClass' : objectClass(),
|
'objectClass' : objectClass,
|
||||||
'nom' : nom(),
|
'nom' : nom,
|
||||||
'prenom' : prenom(),
|
'prenom' : prenom,
|
||||||
'tel' : tel(),
|
'tel' : tel,
|
||||||
'paiement' : paiement(),
|
'paiement' : paiement,
|
||||||
'carteEtudiant' : carteEtudiant(),
|
'carteEtudiant' : carteEtudiant,
|
||||||
'mailAlias' : mailAlias(),
|
'mailAlias' : mailAlias,
|
||||||
'canonicalAlias' : canonicalAlias(),
|
'canonicalAlias' : canonicalAlias,
|
||||||
'etudes' : etudes(),
|
'etudes' : etudes,
|
||||||
'chbre' : chbre(),
|
'chbre' : chbre,
|
||||||
'droits' : droits(),
|
'droits' : droits,
|
||||||
'solde' : solde(),
|
'solde' : solde,
|
||||||
'mid' : mid(),
|
'mid' : mid,
|
||||||
'hostAlias' : hostAlias(),
|
'hostAlias' : hostAlias,
|
||||||
'ipsec' : ipsec(),
|
'ipsec' : ipsec,
|
||||||
'puissance' : puissance(),
|
'puissance' : puissance,
|
||||||
'canal' : canal(),
|
'canal' : canal,
|
||||||
'portTCPout' : portTCPout(),
|
'portTCPout' : portTCPout,
|
||||||
'portTCPin' : portTCPin(),
|
'portTCPin' : portTCPin,
|
||||||
'portUDPout' : portUDPout(),
|
'portUDPout' : portUDPout,
|
||||||
'portUDPin' : portUDPin(),
|
'portUDPin' : portUDPin,
|
||||||
'prise' : prise(),
|
'prise' : prise,
|
||||||
'cid' : cid(),
|
'cid' : cid,
|
||||||
'responsable' : responsable(),
|
'responsable' : responsable,
|
||||||
'blacklist' : blacklist(),
|
'blacklist' : blacklist,
|
||||||
'historique' : historique()
|
'historique' : historique
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
63
lc_ldap.py
63
lc_ldap.py
|
@ -35,7 +35,8 @@ import os, sys, ldap, re, netaddr, datetime, copy, time
|
||||||
from ldap.modlist import addModlist, modifyModlist
|
from ldap.modlist import addModlist, modifyModlist
|
||||||
sys.path.append('/usr/scripts/gestion')
|
sys.path.append('/usr/scripts/gestion')
|
||||||
|
|
||||||
import config, crans_utils, attributs
|
import config, crans_utils
|
||||||
|
from attributs import attrify
|
||||||
from ldap_locks import CransLock
|
from ldap_locks import CransLock
|
||||||
|
|
||||||
uri = 'ldapi:///' #'ldap://ldap.adm.crans.org/'
|
uri = 'ldapi:///' #'ldap://ldap.adm.crans.org/'
|
||||||
|
@ -55,6 +56,7 @@ def is_actif(sanction):
|
||||||
return debut < now and fin > now
|
return debut < now and fin > now
|
||||||
|
|
||||||
def uldif_to_ldif(uldif):
|
def uldif_to_ldif(uldif):
|
||||||
|
## XXX - Kill
|
||||||
"""Prend en argument un dico ldif, et vérifie que toutes les
|
"""Prend en argument un dico ldif, et vérifie que toutes les
|
||||||
valeurs sont bien des unicodes, les converti alors en chaînes
|
valeurs sont bien des unicodes, les converti alors en chaînes
|
||||||
utf-8, renvoie un ldif"""
|
utf-8, renvoie un ldif"""
|
||||||
|
@ -64,12 +66,26 @@ def uldif_to_ldif(uldif):
|
||||||
return ldif
|
return ldif
|
||||||
|
|
||||||
def ldif_to_uldif(ldif):
|
def ldif_to_uldif(ldif):
|
||||||
|
## XXX - Kill
|
||||||
'Prend en argument un dico ldif, et décode toutes les chaînes en utf-8'
|
'Prend en argument un dico ldif, et décode toutes les chaînes en utf-8'
|
||||||
uldif = {}
|
uldif = {}
|
||||||
for attr, vals in ldif.items():
|
for attr, vals in ldif.items():
|
||||||
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):
|
||||||
|
cldif = {}
|
||||||
|
for attr, vals in ldif.items():
|
||||||
|
cldif[attr] = [ attrify(val, attr, ldif) for val in vals]
|
||||||
|
return cldif
|
||||||
|
|
||||||
|
def cldif_to_ldif(cldif):
|
||||||
|
ldif = {}
|
||||||
|
for attr, vals in cldif.items():
|
||||||
|
ldif[attr] = [ str(attr) for attr in vals ]
|
||||||
|
return ldif
|
||||||
|
|
||||||
|
|
||||||
def lc_ldap_test():
|
def lc_ldap_test():
|
||||||
return lc_ldap(dn='cn=admin,dc=crans,dc=org', cred='75bdb64f32')
|
return lc_ldap(dn='cn=admin,dc=crans,dc=org', cred='75bdb64f32')
|
||||||
|
|
||||||
|
@ -168,19 +184,17 @@ class lc_ldap(ldap.ldapobject.LDAPObject):
|
||||||
"""Crée une nouvelle facture"""
|
"""Crée une nouvelle facture"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def _create_entity(self, dn, uldif):
|
def _create_entity(self, dn, ldif):
|
||||||
'''Crée une nouvelle entité ldap en dn, avec attributs ldif:
|
'''Crée une nouvelle entité ldap en dn, avec attributs ldif:
|
||||||
uniquement en unicode'''
|
uniquement en unicode'''
|
||||||
nuldif = {}
|
cldif = ldif_to_cldif(ldif)
|
||||||
for attr, vals in uldif.items() :
|
|
||||||
nuldif[attr] = attributs.normalize_and_validate(attr, vals, uldif)
|
|
||||||
#lock = CransLock(self)
|
#lock = CransLock(self)
|
||||||
for item in ['aid', 'uid', 'chbre', 'mailAlias', 'canonicalAlias',
|
for item in ['aid', 'uid', 'chbre', 'mailAlias', 'canonicalAlias',
|
||||||
'fid', 'cid', 'mid', 'macAddress', 'host', 'hostAlias' ]:
|
'fid', 'cid', 'mid', 'macAddress', 'host', 'hostAlias' ]:
|
||||||
for val in nuldif.get(item, []):
|
for val in cldif.get(item, []):
|
||||||
pass #lock.add(item, val)
|
pass #lock.add(item, val)
|
||||||
#uldif['historique'] = [ self._hist('Création')]
|
#uldif['historique'] = [ self._hist('Création')]
|
||||||
ldif = uldif_to_ldif(nuldif)
|
ldif = cldif_to_ldif(cldif)
|
||||||
modlist = addModlist(ldif)
|
modlist = addModlist(ldif)
|
||||||
#with lock:
|
#with lock:
|
||||||
# print dn, modlist
|
# print dn, modlist
|
||||||
|
@ -243,20 +257,21 @@ class CransLdapObject:
|
||||||
if not res:
|
if not res:
|
||||||
raise ValueError ('objet inexistant: %s' % dn)
|
raise ValueError ('objet inexistant: %s' % dn)
|
||||||
self.dn, self.attrs = res[0]
|
self.dn, self.attrs = res[0]
|
||||||
self.attrs = ldif_to_uldif(self.attrs)
|
if mode in ['w', 'rw']:
|
||||||
|
self.attrs = ldif_to_cldif(self.attrs)
|
||||||
|
else:
|
||||||
|
self.attrs = ldif_to_uldif(self.attrs)
|
||||||
self.__class__ = eval(self.attrs['objectClass'][0])
|
self.__class__ = eval(self.attrs['objectClass'][0])
|
||||||
# self._modifs = copy.deepcopy(self.attrs)
|
# self._modifs = copy.deepcopy(self.attrs)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"Vérifie que self._modifs contient des valeurs correctes et enregistre les modifications"
|
"Vérifie que self._modifs contient des valeurs correctes et enregistre les modifications"
|
||||||
if self.mode != 'w':
|
if self.mode not in ['w', 'rw']:
|
||||||
raise EnvironmentError(u"Objet en lecture seule, réessayer en lecture/écriture")
|
raise EnvironmentError(u"Objet en lecture seule, réessayer en lecture/écriture")
|
||||||
|
|
||||||
# Vérifications et Historique
|
# Vérifications et Historique
|
||||||
#histo = self._gen_hist(self._modifs)
|
#histo = self._gen_hist(self._modifs)
|
||||||
#self._modifs['historique'] += histo
|
#self._modifs['historique'] += histo
|
||||||
for attr, vals in self._modifs.items:
|
|
||||||
self._modifs[attr] = attributs.normalize_and_validate(attr, vals, self._modifs)
|
|
||||||
|
|
||||||
# On récupère la liste des modifications
|
# On récupère la liste des modifications
|
||||||
modlist = self.get_modlist()
|
modlist = self.get_modlist()
|
||||||
|
@ -270,8 +285,8 @@ class CransLdapObject:
|
||||||
def get_modlist(self):
|
def get_modlist(self):
|
||||||
"""Renvoie le dico des modifs"""
|
"""Renvoie le dico des modifs"""
|
||||||
# unicode -> utf-8
|
# unicode -> utf-8
|
||||||
ldif = uldif_to_ldif(self._modifs)
|
ldif = cldif_to_ldif(self._modifs)
|
||||||
orig_ldif = uldif_to_ldif(self.attrs)
|
orig_ldif = cldif_to_ldif(self.attrs)
|
||||||
|
|
||||||
return modifyModlist(orig_ldif, ldif)
|
return modifyModlist(orig_ldif, ldif)
|
||||||
|
|
||||||
|
@ -286,16 +301,21 @@ class CransLdapObject:
|
||||||
|
|
||||||
def set_ldapattr(self, attr, new_vals):
|
def set_ldapattr(self, attr, new_vals):
|
||||||
"""Définit les nouvelles valeurs d'un attribut"""
|
"""Définit les nouvelles valeurs d'un attribut"""
|
||||||
|
|
||||||
|
if self.mode not in ['w', 'rw']:
|
||||||
|
raise EnvironmentError(u"Objet en lecture seule, réessayer en lecture/écriture")
|
||||||
|
|
||||||
if not isinstance(new_vals, list):
|
if not isinstance(new_vals, list):
|
||||||
new_vals = [new_vals]
|
new_vals = [new_vals]
|
||||||
for val in new_vals: assert isinstance(val, unicode)
|
|
||||||
|
|
||||||
# On vérifie les nouvelles valeurs données à l'attribut
|
# On attrify
|
||||||
new_vals = attributs.normalize_and_validate(attr, new_vals, self._modifs)
|
new_vals = [ attrify(val, attr, self._modifs) for val in new_vals ]
|
||||||
|
|
||||||
|
# XXX - Manque un sanity check
|
||||||
|
|
||||||
# Si ça passe, on effectue les modifications
|
# Si ça passe, on effectue les modifications
|
||||||
old_vals = [ unicode.encode(val, 'utf-8') for val in self.attrs.get(attr, []) ]
|
old_vals = [ str(val) for val in self.attrs.get(attr, []) ]
|
||||||
new_vals = [ unicode.encode(val, 'utf-8') for val in new_vals ]
|
new_vals = [ str(val) for val in new_vals ]
|
||||||
modlist = modifyModlist({attr : old_vals}, {attr : new_vals})
|
modlist = modifyModlist({attr : old_vals}, {attr : new_vals})
|
||||||
self.conn.modify_s(self.dn, modlist)
|
self.conn.modify_s(self.dn, modlist)
|
||||||
|
|
||||||
|
@ -303,10 +323,10 @@ class CransLdapObject:
|
||||||
"""Modifie l'attribut attr ayant la valeur oldVal en newVal. Si
|
"""Modifie l'attribut attr ayant la valeur oldVal en newVal. Si
|
||||||
l'attribut attr n'a qu'une seule valeur, il n'est pas nécessaire
|
l'attribut attr n'a qu'une seule valeur, il n'est pas nécessaire
|
||||||
de préciser oldVal."""
|
de préciser oldVal."""
|
||||||
assert isinstance(new_val, unicode)
|
new_val = attrify(new_val, attr, self._modifs)
|
||||||
new_vals = self.attrs.get(attr, [])[:]
|
new_vals = self.attrs.get(attr, [])[:]
|
||||||
if old_val: # and oldVal in attrs:
|
if old_val: # and oldVal in attrs:
|
||||||
new_vals.remove(old_val)
|
new_vals = [ val for val in new_vals if str(val) != str(old_val) ]
|
||||||
new_vals.append(new_val)
|
new_vals.append(new_val)
|
||||||
elif len(new_vals) == 1:
|
elif len(new_vals) == 1:
|
||||||
new_vals = [ new_val ]
|
new_vals = [ new_val ]
|
||||||
|
@ -317,12 +337,11 @@ class CransLdapObject:
|
||||||
def del_ldapattr(self, attr, val):
|
def del_ldapattr(self, attr, val):
|
||||||
"""Supprime la valeur val de l'attribut attr"""
|
"""Supprime la valeur val de l'attribut attr"""
|
||||||
new_vals = self.attrs.get(attr, [])[:]
|
new_vals = self.attrs.get(attr, [])[:]
|
||||||
new_vals.remove(val)
|
new_vals = [ v for v in new_vals if str(v) != str(val) ]
|
||||||
return self.set_ldapattr(attr, new_vals)
|
return self.set_ldapattr(attr, new_vals)
|
||||||
|
|
||||||
def add_ldapattr(self, attr, new_val):
|
def add_ldapattr(self, attr, new_val):
|
||||||
"""Rajoute la valeur val à l'attribut attr"""
|
"""Rajoute la valeur val à l'attribut attr"""
|
||||||
assert isinstance(new_val, unicode)
|
|
||||||
new_vals = self.attrs.get(attr, [])[:]
|
new_vals = self.attrs.get(attr, [])[:]
|
||||||
new_vals.append(new_val)
|
new_vals.append(new_val)
|
||||||
return self.set_ldapattr(attr, new_vals)
|
return self.set_ldapattr(attr, new_vals)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue