Merge branch 'master' of sila:/git/ldap
This commit is contained in:
commit
6d4aad6b00
2 changed files with 87 additions and 41 deletions
42
attributs.py
42
attributs.py
|
@ -69,6 +69,7 @@ class Attr(object):
|
||||||
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
|
ctxt_check: effectue les validations
|
||||||
"""
|
"""
|
||||||
|
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)
|
||||||
|
@ -133,12 +134,14 @@ class objectClass(Attr):
|
||||||
singlevalue = False
|
singlevalue = False
|
||||||
optional = False
|
optional = False
|
||||||
legend = "entité"
|
legend = "entité"
|
||||||
|
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, val, ldif):
|
||||||
if val not in [ 'top', 'posixAccount', 'shadowAccount', 'proprio',
|
if val not in [ 'top', 'posixAccount', 'shadowAccount', 'proprio',
|
||||||
'adherent', 'club', 'machine', 'machineCrans',
|
'adherent', 'club', 'machine', 'machineCrans',
|
||||||
'borneWifi', 'machineWifi', 'machineFixe',
|
'borneWifi', 'machineWifi', 'machineFixe',
|
||||||
'cransAccount', 'service', 'facture', 'freeMid' ]:
|
'cransAccount', 'service', 'facture', 'freeMid' ]:
|
||||||
|
print(val)
|
||||||
raise ValueError("Pourquoi insérer un objectClass=%s ?" % val)
|
raise ValueError("Pourquoi insérer un objectClass=%s ?" % val)
|
||||||
else:
|
else:
|
||||||
self.value = unicode(val)
|
self.value = unicode(val)
|
||||||
|
@ -254,22 +257,23 @@ class chbre(Attr):
|
||||||
can_modify = ["self", "Cableur", "Nounou"]
|
can_modify = ["self", "Cableur", "Nounou"]
|
||||||
|
|
||||||
def parse_value(self, val, ldif):
|
def parse_value(self, val, ldif):
|
||||||
if u'club' in ldif['objectClass']:
|
if self.ctxt_check: # Si ce n'est pas la peine de vérifier, on ne vérifie pas
|
||||||
if val in annuaires_pg.locaux_clubs():
|
if u'club' in ldif['objectClass']:
|
||||||
|
if val in annuaires_pg.locaux_clubs():
|
||||||
|
self.value = val
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
raise ValueError("Club devrait etre en XclN, pas en %s" % val)
|
||||||
|
|
||||||
|
if val in (u"EXT", u"????"):
|
||||||
self.value = val
|
self.value = val
|
||||||
return
|
return
|
||||||
else:
|
|
||||||
raise ValueError("Club devrait etre en XclN, pas en %s" % val)
|
|
||||||
|
|
||||||
if val in (u"EXT", u"????"):
|
try:
|
||||||
self.value = val
|
annuaires_pg.chbre_prises(val[0], val[1:])
|
||||||
return
|
except NameError:
|
||||||
|
import annuaires_pg_test
|
||||||
try:
|
annuaires_pg_test.chbre_prises(val[0], val[1:])
|
||||||
annuaires_pg.chbre_prises(val[0], val[1:])
|
|
||||||
except NameError:
|
|
||||||
import annuaires_pg_test
|
|
||||||
annuaires_pg_test.chbre_prises(val[0], val[1:])
|
|
||||||
|
|
||||||
self.value = val
|
self.value = val
|
||||||
|
|
||||||
|
@ -295,8 +299,8 @@ class solde(Attr):
|
||||||
can_modify = ["imprimeur", "Nounou", "Tresorier"]
|
can_modify = ["imprimeur", "Nounou", "Tresorier"]
|
||||||
|
|
||||||
def parse_value(self, solde, ldif):
|
def parse_value(self, solde, ldif):
|
||||||
# on évite les dépassements
|
# 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 self.ctxt_check and not (float(solde) >= config.impression.decouvert and float(solde) <= 1024.):
|
||||||
raise ValueError("Solde invalide: %s" % solde)
|
raise ValueError("Solde invalide: %s" % solde)
|
||||||
self.value = solde
|
self.value = solde
|
||||||
|
|
||||||
|
@ -304,7 +308,7 @@ class dnsAttr(Attr):
|
||||||
def parse_value(self, dns, ldif):
|
def parse_value(self, dns, ldif):
|
||||||
dns = dns.lower()
|
dns = dns.lower()
|
||||||
name, net = dns.split('.', 1)
|
name, net = dns.split('.', 1)
|
||||||
if (net not in ['crans.org', 'wifi.crans.org'] or
|
if self.ctxt_check and (net not in ['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 '%s'" % dns)
|
raise ValueError("Nom d'hote invalide '%s'" % dns)
|
||||||
self.value = dns
|
self.value = dns
|
||||||
|
@ -544,8 +548,12 @@ class loginShell(Attr):
|
||||||
'/usr/bin/rssh',
|
'/usr/bin/rssh',
|
||||||
'/usr/local/bin/disconnect_shell',
|
'/usr/local/bin/disconnect_shell',
|
||||||
'/usr/scripts/surveillance/disconnect_shell',
|
'/usr/scripts/surveillance/disconnect_shell',
|
||||||
|
'/usr/local/bin/badPassSh',
|
||||||
|
'/usr/bin/passwd',
|
||||||
|
'/bin/false',
|
||||||
|
'/bin//zsh'
|
||||||
'']
|
'']
|
||||||
if (shell not in shells):
|
if self.ctxt_check and (shell not in shells):
|
||||||
raise ValueError("Shell %s invalide" % shell)
|
raise ValueError("Shell %s invalide" % shell)
|
||||||
self.value = shell
|
self.value = shell
|
||||||
|
|
||||||
|
|
86
lc_ldap.py
86
lc_ldap.py
|
@ -121,32 +121,53 @@ class lc_ldap(ldap.ldapobject.LDAPObject):
|
||||||
res = self.search_ext_s(dn, scope, filterstr, sizelimit=sizelimit)
|
res = self.search_ext_s(dn, scope, filterstr, sizelimit=sizelimit)
|
||||||
return [ new_cransldapobject(self, r[0], mode=mode) for r in res ]
|
return [ new_cransldapobject(self, r[0], mode=mode) for r in res ]
|
||||||
|
|
||||||
|
def allMachinesAdherents(self):
|
||||||
|
"""Renvoie la liste de toutes les machines et de tous les adherents
|
||||||
|
(club et Association Crans compris). Conçue pour s'éxécuter le plus
|
||||||
|
rapidement possible. On dumpe malgré tout toute la base."""
|
||||||
|
res = {}
|
||||||
|
parent = {}
|
||||||
|
machines = {}
|
||||||
|
# (proxying de la base ldap)
|
||||||
|
for dn, attrs in self.search_s(base_dn, scope=2):
|
||||||
|
# On crée les listes des machines et propriétaires
|
||||||
|
if dn.startswith('mid='): # les machines
|
||||||
|
m = new_cransldapobject(self, dn, ldif = attrs)
|
||||||
|
parent_dn = dn.split(',', 1)[1]
|
||||||
|
if not machines.has_key(parent_dn):
|
||||||
|
machines[parent_dn]=[]
|
||||||
|
machines[parent_dn].append(m)
|
||||||
|
elif (dn.startswith('aid=') or dn.startswith('cid=') or dn==base_dn) and not parent.has_key(dn):
|
||||||
|
# Hélas on refait une recherche ldap dans attributs.py pour trouver les responsables des club
|
||||||
|
# ce qui prends un temps non négligeable mais est toujours mieux que de le faire pour tous les adherents
|
||||||
|
parent[dn]=new_cransldapobject(self, dn, ldif = attrs)
|
||||||
|
allmachines=[]
|
||||||
|
for dn,mlist in machines.items(): # on associe propriétaires et machines
|
||||||
|
parent[dn]._machines=mlist
|
||||||
|
for m in mlist:
|
||||||
|
m._proprio=parent[dn]
|
||||||
|
allmachines.append(m)
|
||||||
|
return allmachines,parent.values() # on renvoie la liste des machines et des adherents (dont club et crans)
|
||||||
|
|
||||||
def allMachines(self):
|
def allMachines(self):
|
||||||
"""Renvoie la liste de toutes les machines, Conçue pour
|
"""Renvoie la liste de toutes les machines, Conçue pour
|
||||||
s'éxécuter le plus rapidement possible. On dumpe malgré tout
|
s'éxécuter le plus rapidement possible. On dumpe malgré tout
|
||||||
toute la base, c'est pour pouvoir aussi rajouter à moindre coût
|
toute la base, c'est pour pouvoir aussi rajouter à moindre coût
|
||||||
les propriétaires."""
|
les propriétaires."""
|
||||||
res = {}
|
machines,_=self.allMachinesAdherents()
|
||||||
parent = {}
|
|
||||||
machines = []
|
|
||||||
# On récupère tous les objets ldap et on les met dans un dico
|
|
||||||
# (proxying de la base ldap)
|
|
||||||
for dn, attrs in self.search_s(base_dn, scope=2): #on fait tout dans une seule boucle
|
|
||||||
#~ res[dn] = attrs
|
|
||||||
# On crée la liste des machines
|
|
||||||
#~ for dn, attrs in res.items():
|
|
||||||
if dn.startswith('mid='):
|
|
||||||
m = new_cransldapobject(self, dn, ldif = attrs)
|
|
||||||
parent_dn = dn.split(',', 1)[1]
|
|
||||||
if not parent.has_key(parent_dn):
|
|
||||||
parent[parent_dn]=adherent(self, dn,machines= [ new_cransldapobject(self, dn,ldif=attrs)]) # on utilise pas new_cransldapobject pour optimiser les appel ldap (on passe la liste des machines)
|
|
||||||
else:
|
|
||||||
parent[parent_dn]._machines.append(new_cransldapobject(self, dn,ldif=attrs))
|
|
||||||
#~ m._proprio = new_cransldapobject(self, parent_dn, res[parent_dn],opt=machine_proprio[parent_dn])
|
|
||||||
m._proprio = parent[parent_dn]
|
|
||||||
machines.append(m)
|
|
||||||
return machines
|
return machines
|
||||||
|
|
||||||
|
def allAdherents(self):
|
||||||
|
"""Renvoie la liste de toutes les adherents, Conçue pour
|
||||||
|
s'éxécuter le plus rapidement possible. On dumpe malgré tout
|
||||||
|
toute la base, c'est pour pouvoir aussi rajouter à moindre coût
|
||||||
|
les machines."""
|
||||||
|
_,adherents=self.allMachinesAdherents()
|
||||||
|
return adherents
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def newMachine(self, parent, realm, uldif):
|
def newMachine(self, parent, realm, uldif):
|
||||||
"""Crée une nouvelle machine: realm peut être:
|
"""Crée une nouvelle machine: realm peut être:
|
||||||
fil, fil-v6, wifi, wifi-v6, adm, gratuit, personnel-ens, special"""
|
fil, fil-v6, wifi, wifi-v6, adm, gratuit, personnel-ens, special"""
|
||||||
|
@ -241,10 +262,10 @@ def new_cransldapobject(conn, dn, mode='ro', ldif = None):
|
||||||
|
|
||||||
classe = None
|
classe = None
|
||||||
|
|
||||||
if ldif:
|
if dn == base_dn:
|
||||||
classe = globals()[ldif['objectClass'][0]]
|
|
||||||
elif dn == base_dn:
|
|
||||||
classe = AssociationCrans
|
classe = AssociationCrans
|
||||||
|
elif ldif:
|
||||||
|
classe = globals()[ldif['objectClass'][0]]
|
||||||
else:
|
else:
|
||||||
res = conn.search_s(dn, 0)
|
res = conn.search_s(dn, 0)
|
||||||
if not res:
|
if not res:
|
||||||
|
@ -265,7 +286,7 @@ class CransLdapObject(object):
|
||||||
|
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
|
|
||||||
self.attrs = None # Contient un dico uldif qui doit représenter ce qui
|
self.attrs = {} # Contient un dico uldif qui doit représenter ce qui
|
||||||
# est dans la base
|
# est dans la base
|
||||||
|
|
||||||
self._modifs = None # C'est là qu'on met les modifications
|
self._modifs = None # C'est là qu'on met les modifications
|
||||||
|
@ -279,6 +300,9 @@ class CransLdapObject(object):
|
||||||
# Vous précisez un ldif, l'objet est 'ro'
|
# Vous précisez un ldif, l'objet est 'ro'
|
||||||
self.mode = 'ro'
|
self.mode = 'ro'
|
||||||
self.attrs = ldif
|
self.attrs = ldif
|
||||||
|
if dn != base_dn: # new_cransldapobject ne donne pas de ldif formaté et utilise un ldif non formaté, donc on formate
|
||||||
|
self.attrs = ldif_to_uldif(self.attrs)
|
||||||
|
self.attrs = ldif_to_cldif(self.attrs, conn, check_ctxt = False) # on est en read only, donc pas la peine de vérifier la validité
|
||||||
elif dn != base_dn:
|
elif dn != base_dn:
|
||||||
res = conn.search_s(dn, 0)
|
res = conn.search_s(dn, 0)
|
||||||
if not res:
|
if not res:
|
||||||
|
@ -395,7 +419,7 @@ class CransLdapObject(object):
|
||||||
# XXX - Proposer de filtrer les blacklistes avec un arg supplémentaire ?
|
# XXX - Proposer de filtrer les blacklistes avec un arg supplémentaire ?
|
||||||
# XXX - Vérifier les blacklistes des machines pour les adhérents ?
|
# XXX - Vérifier les blacklistes des machines pour les adhérents ?
|
||||||
attrs = (self.attrs if self.mode not in ["w", "rw"] else self._modifs)
|
attrs = (self.attrs if self.mode not in ["w", "rw"] else self._modifs)
|
||||||
return filter((lambda bl: bl.is_actif()), attrs.get("blacklist"))
|
return filter((lambda bl: bl.is_actif()), attrs.get("blacklist",[]))
|
||||||
|
|
||||||
def blacklist(self, sanction, commentaire, debut="now", fin = '-'):
|
def blacklist(self, sanction, commentaire, debut="now", fin = '-'):
|
||||||
u"""
|
u"""
|
||||||
|
@ -424,6 +448,20 @@ class proprio(CransLdapObject):
|
||||||
def __init__(self, conn, dn, mode='ro', ldif = None, machines=[]):
|
def __init__(self, conn, dn, mode='ro', ldif = None, machines=[]):
|
||||||
super(proprio, self).__init__(conn, dn, mode, ldif)
|
super(proprio, self).__init__(conn, dn, mode, ldif)
|
||||||
self._machines = machines
|
self._machines = machines
|
||||||
|
|
||||||
|
def paiement_ok(self):
|
||||||
|
"""Renvoie si le propriétaire à payé pour l'année en cours"""
|
||||||
|
if self.dn == base_dn:
|
||||||
|
return True
|
||||||
|
try:
|
||||||
|
for paiement in self['paiement']:
|
||||||
|
if paiement.value == config.ann_scol:
|
||||||
|
return True
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def machines(self):
|
def machines(self):
|
||||||
if not self._machines:
|
if not self._machines:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue