[lc_ldap,attributs] nettoyage bl & set_ldapattr
This commit is contained in:
parent
222a2a9a4d
commit
adfa070db5
2 changed files with 29 additions and 201 deletions
|
@ -431,6 +431,13 @@ class blacklist(Attr):
|
||||||
'comm' : bl_comm,
|
'comm' : bl_comm,
|
||||||
'actif' : int(bl_debut) < now and (bl_fin == '-' or int(bl_fin) > now) }
|
'actif' : int(bl_debut) < now and (bl_fin == '-' or int(bl_fin) > now) }
|
||||||
|
|
||||||
|
def is_actif(self):
|
||||||
|
return self.value['actif']
|
||||||
|
|
||||||
|
def terminer(self):
|
||||||
|
self.value.fin = max(self.value.debut, time.time() - 60)
|
||||||
|
self.actif = False
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'%(debut)s$%(fin)s$%(type)s$%(comm)s' % self.value
|
return u'%(debut)s$%(fin)s$%(type)s$%(comm)s' % self.value
|
||||||
|
|
||||||
|
|
223
lc_ldap.py
223
lc_ldap.py
|
@ -47,20 +47,6 @@ log_dn = "cn=log"
|
||||||
# Champs à ignorer dans l'historique
|
# Champs à ignorer dans l'historique
|
||||||
HIST_IGNORE_FIELDS = ["modifiersName", "entryCSN", "modifyTimestamp"]
|
HIST_IGNORE_FIELDS = ["modifiersName", "entryCSN", "modifyTimestamp"]
|
||||||
|
|
||||||
def is_actif(sanction):
|
|
||||||
"""Retourne True ou False suivant si la sanction fournie (chaîne
|
|
||||||
venant de blacklist) est active ou non.
|
|
||||||
La blacklist est de la forme "debut$fin$..."
|
|
||||||
"""
|
|
||||||
bl_debut, bl_fin, _ = sanction.split('$', 3)
|
|
||||||
now = time.time()
|
|
||||||
debut = int(bl_debut)
|
|
||||||
if bl_fin == '-':
|
|
||||||
fin = now + 1
|
|
||||||
else:
|
|
||||||
fin = int(bl_fin)
|
|
||||||
return debut < now and fin > now
|
|
||||||
|
|
||||||
def ldif_to_uldif(ldif):
|
def ldif_to_uldif(ldif):
|
||||||
uldif = {}
|
uldif = {}
|
||||||
for attr, vals in ldif.items():
|
for attr, vals in ldif.items():
|
||||||
|
@ -325,100 +311,23 @@ class CransLdapObject(object):
|
||||||
|
|
||||||
return modifyModlist(orig_ldif, ldif)
|
return modifyModlist(orig_ldif, ldif)
|
||||||
|
|
||||||
def get_values(self, attr):
|
def get(self, attr, default):
|
||||||
"""Renvoie les valeurs d'un attribut ldap de l'objet self"""
|
try:
|
||||||
attrs = self.attrs.get(attr, [])
|
return self[attr]
|
||||||
return attrs
|
except KeyError:
|
||||||
|
return default
|
||||||
|
|
||||||
def get_value(self, attr):
|
def __getitem__(self, attr):
|
||||||
"""Renvoie la première valeur d'un attribut ldap de l'objet self"""
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
return self.get_values(attr)[0]
|
return [ unicode(v) for v in self._modifs[attr] ]
|
||||||
|
|
||||||
def set_ldapattr(self, attr, new_vals):
|
|
||||||
"""Définit les nouvelles valeurs d'un attribut"""
|
|
||||||
|
|
||||||
if self.mode not in ['w', 'rw']:
|
|
||||||
raise EnvironmentError("Objet en lecture seule, réessayer en lecture/écriture")
|
|
||||||
|
|
||||||
if not isinstance(new_vals, list):
|
|
||||||
new_vals = [new_vals]
|
|
||||||
|
|
||||||
# On attrify
|
|
||||||
cldif = self.attrs.copy()
|
|
||||||
cldif[attr] = new_vals
|
|
||||||
new_vals = [ attrify(val, attr, cldif, self.conn) for val in new_vals ]
|
|
||||||
|
|
||||||
# Si ça passe, on effectue les modifications
|
|
||||||
old_vals = [ str(val) for val in self.attrs.get(attr, []) ]
|
|
||||||
new_vals = [ str(val) for val in new_vals ]
|
|
||||||
modlist = modifyModlist({attr : old_vals}, {attr : new_vals})
|
|
||||||
self.conn.modify_s(self.dn, modlist)
|
|
||||||
|
|
||||||
def mod_ldapattr(self, attr, new_val, old_val = None):
|
|
||||||
"""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
|
|
||||||
de préciser oldVal."""
|
|
||||||
new_vals = self.attrs.get(attr, [])[:]
|
|
||||||
if old_val: # and oldVal in attrs:
|
|
||||||
new_vals = [ val for val in new_vals if str(val) != str(old_val) ]
|
|
||||||
new_vals.append(new_val)
|
|
||||||
elif len(new_vals) == 1:
|
|
||||||
new_vals = [ new_val ]
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("%s has multiple values, must specify old_val")
|
return [ unicode(v) for v in self.attrs[attr] ]
|
||||||
return self.set_ldapattr(attr, new_vals)
|
|
||||||
|
|
||||||
def del_ldapattr(self, attr, val):
|
def __setitem__(self, attr, values):
|
||||||
"""Supprime la valeur val de l'attribut attr"""
|
if not isinstance(values, list):
|
||||||
new_vals = self.attrs.get(attr, [])[:]
|
values = [ values ]
|
||||||
new_vals = [ v for v in new_vals if str(v) != str(val) ]
|
self._modifs[attr] = values
|
||||||
return self.set_ldapattr(attr, new_vals)
|
self._modifs[attr] = [ attrify(val, attr, self._modifs, self.conn) for val in values ]
|
||||||
|
|
||||||
def add_ldapattr(self, attr, new_val):
|
|
||||||
"""Rajoute la valeur val à l'attribut attr"""
|
|
||||||
new_vals = self.attrs.get(attr, [])[:]
|
|
||||||
new_vals.append(new_val)
|
|
||||||
return self.set_ldapattr(attr, new_vals)
|
|
||||||
|
|
||||||
def _gen_hist(self, modifs):
|
|
||||||
# XXX - Kill it! l'historique devrait être généré par ldap
|
|
||||||
"""Genère l'historique des modifications apportées. Cette
|
|
||||||
fonction n'est là que pour de la rétro-compatibilité,
|
|
||||||
normalement les modifications sont automatiquement loggées."""
|
|
||||||
histo = []
|
|
||||||
for field in self.ofields:
|
|
||||||
if modifs.get(field, []) != self.attrs.get(field, []):
|
|
||||||
if modifs.get(field, []) == []:
|
|
||||||
msg = u"[%s] %s -> RESET" % (field, self.attrs[field][0])
|
|
||||||
elif self.attrs.get(field, []) == []:
|
|
||||||
msg = u"[%s] := %s" % (field, modifs[field][0])
|
|
||||||
else:
|
|
||||||
msg = u"[%s] %s -> %s" % (field, self.attrs[field][0], modifs[field][0])
|
|
||||||
histo.append(self.conn._hist(msg))
|
|
||||||
|
|
||||||
for field in self.xfields + self.ufields:
|
|
||||||
if modifs.get(field, []) != self.attrs.get(field, []):
|
|
||||||
msg = u"[%s] %s -> %s" % (field, u'; '.join(self.attrs[field]), u'; '.join(modifs[field]))
|
|
||||||
histo.append(self.conn._hist(msg))
|
|
||||||
|
|
||||||
for field in self.mfields:
|
|
||||||
oldvals = self.attrs.get(field, [])
|
|
||||||
newvals = modifs.get(field, [])
|
|
||||||
olds = set(oldvals)
|
|
||||||
news = set(newvals)
|
|
||||||
if oldvals == newvals:
|
|
||||||
continue
|
|
||||||
elif olds != news:
|
|
||||||
adds = ''.join([ '+' + val for val in news - olds])
|
|
||||||
diff = ''.join([ '-' + val for val in olds - news])
|
|
||||||
msg = u'[%s]%s%s' % ( field, adds, diff)
|
|
||||||
elif olds == news and len(oldvals) == len(newvals) == len(olds):
|
|
||||||
msg = u"[%s].shuffle()" % field
|
|
||||||
else:
|
|
||||||
raise ValueError("Les valeurs pour %s : %s -> %s ne semblent pas différentes" % (field, oldvals, newvals))
|
|
||||||
histo.append(self.conn._hist(msg))
|
|
||||||
|
|
||||||
return histo
|
|
||||||
|
|
||||||
def search_historique(self, ign_fields=HIST_IGNORE_FIELDS):
|
def search_historique(self, ign_fields=HIST_IGNORE_FIELDS):
|
||||||
u"""Récupère l'historique
|
u"""Récupère l'historique
|
||||||
|
@ -445,114 +354,26 @@ class CransLdapObject(object):
|
||||||
for field in fields:
|
for field in fields:
|
||||||
mods = fields[field]
|
mods = fields[field]
|
||||||
mod_list.append("%s %s" %(field, ", ".join(mods)))
|
mod_list.append("%s %s" %(field, ", ".join(mods)))
|
||||||
|
|
||||||
if mod_list != []:
|
if mod_list != []:
|
||||||
out.append("%s : [%s] %s" % (date, attrs['reqAuthzID'][0], " ; ".join(mod_list)))
|
out.append("%s : [%s] %s" % (date, attrs['reqAuthzID'][0], " ; ".join(mod_list)))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def blacklist_actif(self):
|
def blacklist(self, sanction, commentaire, debut=time.time(), fin = '-')
|
||||||
u"""Vérifie si l'instance courante est blacklistée.
|
|
||||||
Retourne les sanctions en cours (liste).
|
|
||||||
Retourne une liste vide si aucune sanction en cours.
|
|
||||||
"""
|
|
||||||
return self.blacklist_all()[0].keys()
|
|
||||||
|
|
||||||
def blacklist_all(self):
|
|
||||||
u"""Vérifie si l'instance courante est blacklistée ou a été
|
|
||||||
blacklistée. Retourne les sanctions en cours sous la forme
|
|
||||||
d'un couple de deux dictionnaires (l'un pour les sanctions
|
|
||||||
actives, l'autre pour les inactive), chacun ayant comme
|
|
||||||
clef la sanction et comme valeur une liste de couple de
|
|
||||||
dates (en secondes depuis epoch) correspondant aux
|
|
||||||
différentes périodes de sanctions.
|
|
||||||
|
|
||||||
ex: {'upload': [(1143336210, 1143509010), ...]}
|
|
||||||
"""
|
|
||||||
bl_liste = self.attrs.get('blacklist', [])
|
|
||||||
if isinstance(self, machine): # Blist du propriétaire
|
|
||||||
bl_liste += proprio().blacklist()
|
|
||||||
|
|
||||||
actifs = {}; inactifs = {}
|
|
||||||
for sanction in bl_liste:
|
|
||||||
f = sanction.split('$')
|
|
||||||
if is_actif(sanction):
|
|
||||||
actifs.setdefault(f[2], []).append((f[0], f[1]))
|
|
||||||
else:
|
|
||||||
inactifs.setdefault(f[2], []).append((f[0], f[1]))
|
|
||||||
return (actifs, inactifs)
|
|
||||||
|
|
||||||
def blacklist(self, new=None):
|
|
||||||
u"""
|
u"""
|
||||||
Blacklistage de la ou de toutes la machines du propriétaire
|
Blacklistage de la ou de toutes la machines du propriétaire
|
||||||
* new est une liste de 4 termes :
|
* debut et fin sont le nombre de secondes depuis epoch
|
||||||
[debut_sanction, fin_sanction, sanction, commentaire]
|
|
||||||
* début et fin sont le nombre de secondes depuis epoch
|
|
||||||
* pour un début ou fin immédiate mettre now
|
* pour un début ou fin immédiate mettre now
|
||||||
* pour une fin indéterminée mettre '-'
|
* pour une fin indéterminée mettre '-'
|
||||||
Les données sont stockées dans la base sous la forme :
|
Les données sont stockées dans la base sous la forme :
|
||||||
debut$fin$sanction$commentaire
|
debut$fin$sanction$commentaire
|
||||||
Pour modifier une entrée donner un tuple de deux termes :
|
|
||||||
(index dans blacklist à modifier, nouvelle liste),
|
|
||||||
l'index étant celui dans la liste retournée par blacklist().
|
|
||||||
"""
|
"""
|
||||||
Blist = self.attrs.setdefault('blacklist', [])[:]
|
if debut == 'now':
|
||||||
if new == None:
|
debut = time.time()
|
||||||
return Blist
|
if fin == 'now':
|
||||||
|
fin = time.time()
|
||||||
|
bl = balcklist(u'%s$s$s$s' % (sanction, commentaire, debut, fin), {}, self.conn, False)
|
||||||
|
|
||||||
if type(new) == tuple:
|
self._modifs.setdefault('blacklist', []).append(bl)
|
||||||
# Modification
|
|
||||||
index = new[0]
|
|
||||||
new = new[1]
|
|
||||||
if new == '':
|
|
||||||
Blist.pop(index)
|
|
||||||
return Blist
|
|
||||||
else:
|
|
||||||
index = -1
|
|
||||||
|
|
||||||
if type(new) != list or len(new) != 4:
|
|
||||||
raise TypeError
|
|
||||||
|
|
||||||
# Verification que les dates sont OK
|
|
||||||
if new[0] == 'now':
|
|
||||||
debut = new[0] = int(time.time())
|
|
||||||
else:
|
|
||||||
try: debut = new[0] = int(new[0])
|
|
||||||
except: raise ValueError('Date de début blacklist invalide')
|
|
||||||
|
|
||||||
if new[1] == 'now':
|
|
||||||
fin = new[1] = int(time.time())
|
|
||||||
elif new[1] == '-':
|
|
||||||
fin = -1
|
|
||||||
else:
|
|
||||||
try: fin = new[1] = int(new[1])
|
|
||||||
except: raise ValueError('Date de fin blacklist invalide')
|
|
||||||
|
|
||||||
if debut == fin:
|
|
||||||
raise ValueError('Dates de début et de fin identiques')
|
|
||||||
elif fin != -1 and debut > fin:
|
|
||||||
raise ValueError('Date de fin avant date de début')
|
|
||||||
|
|
||||||
# On dépasse la fin de sanction d'1min pour être sûr qu'elle est périmée.
|
|
||||||
fin = fin + 60
|
|
||||||
|
|
||||||
new_c = u'$'.join(map(str, new))
|
|
||||||
|
|
||||||
if index != -1:
|
|
||||||
Blist[index] = new_c
|
|
||||||
else:
|
|
||||||
Blist.append(new_c)
|
|
||||||
|
|
||||||
if Blist != self.attrs.get('blacklist'):
|
|
||||||
self.set_ldapattr('blacklist', Blist)
|
|
||||||
if not hasattr(self, "_blacklist_restart"):
|
|
||||||
self._blacklist_restart = {}
|
|
||||||
restart = self._blacklist_restart.setdefault(new[2], [])
|
|
||||||
if debut not in restart:
|
|
||||||
restart.append(debut)
|
|
||||||
if fin != -1 and fin not in restart:
|
|
||||||
restart.append(fin)
|
|
||||||
|
|
||||||
return Blist
|
|
||||||
|
|
||||||
|
|
||||||
class proprio(CransLdapObject):
|
class proprio(CransLdapObject):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue