[ldap_locks] Mise en place des locks. Cf commentaires pour les détails.
* Malheureusement lc_ldap._create_entity et objet.create sont un peu sales, mais j'ai pas trouvé mieux. * L'historique contient désormais les secondes.
This commit is contained in:
parent
17efae121c
commit
d6efff30de
7 changed files with 123 additions and 58 deletions
10
attributs.py
10
attributs.py
|
@ -548,7 +548,7 @@ class etudes(Attr):
|
||||||
class chbre(Attr):
|
class chbre(Attr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = False
|
optional = False
|
||||||
unique = True
|
unique = False
|
||||||
legend = u"Chambre sur le campus"
|
legend = u"Chambre sur le campus"
|
||||||
can_modify = [soi, cableur, nounou]
|
can_modify = [soi, cableur, nounou]
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
|
@ -1125,6 +1125,14 @@ class gecos(Attr):
|
||||||
category = 'id'
|
category = 'id'
|
||||||
ldap_name = "gecos"
|
ldap_name = "gecos"
|
||||||
|
|
||||||
|
@crans_attribute
|
||||||
|
class userPassword(Attr):
|
||||||
|
singlevalue = True
|
||||||
|
optional = True
|
||||||
|
legend = "Le mot de passe"
|
||||||
|
category = ''
|
||||||
|
ldap_name = "userPassword"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class sshFingerprint(Attr):
|
class sshFingerprint(Attr):
|
||||||
singlevalue = False
|
singlevalue = False
|
||||||
|
|
|
@ -41,6 +41,7 @@ import ldap.filter
|
||||||
sys.path.append('/usr/scripts/gestion')
|
sys.path.append('/usr/scripts/gestion')
|
||||||
import config
|
import config
|
||||||
from unicodedata import normalize
|
from unicodedata import normalize
|
||||||
|
import subprocess
|
||||||
|
|
||||||
DEVNULL = open(os.devnull, 'w')
|
DEVNULL = open(os.devnull, 'w')
|
||||||
|
|
||||||
|
@ -208,7 +209,7 @@ def process_status(pid):
|
||||||
"""
|
"""
|
||||||
Vérifie l'état du processus pid
|
Vérifie l'état du processus pid
|
||||||
"""
|
"""
|
||||||
cmd = subprocess.check(['ps', '%s' % pid], stdout=DEVNULL, stderr=subprocess.STDOUT)
|
cmd = subprocess.call(['ps', '%s' % pid], stdout=DEVNULL, stderr=subprocess.STDOUT)
|
||||||
if cmd != 0:
|
if cmd != 0:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
|
20
lc_ldap.py
20
lc_ldap.py
|
@ -85,6 +85,8 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
"""
|
"""
|
||||||
ldap.ldapobject.LDAPObject.__init__(self, uri)
|
ldap.ldapobject.LDAPObject.__init__(self, uri)
|
||||||
|
|
||||||
|
self.lockholder = ldap_locks.LdapLockHolder(self)
|
||||||
|
|
||||||
if user and not re.match('[a-z_][a-z0-9_-]*', user):
|
if user and not re.match('[a-z_][a-z0-9_-]*', user):
|
||||||
raise ValueError('Invalid user name: %r' % user)
|
raise ValueError('Invalid user name: %r' % user)
|
||||||
|
|
||||||
|
@ -205,7 +207,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
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."""
|
||||||
machines,_ = self.allMachinesAdherents(mode)
|
machines, _ = self.allMachinesAdherents(mode)
|
||||||
return machines
|
return machines
|
||||||
|
|
||||||
def allAdherents(self, mode='ro'):
|
def allAdherents(self, mode='ro'):
|
||||||
|
@ -213,7 +215,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
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 machines."""
|
les machines."""
|
||||||
_,adherents = self.allMachinesAdherents(mode)
|
_, adherents = self.allMachinesAdherents(mode)
|
||||||
return adherents
|
return adherents
|
||||||
|
|
||||||
def newMachine(self, parent, realm, uldif, login=None):
|
def newMachine(self, parent, realm, uldif, login=None):
|
||||||
|
@ -295,6 +297,13 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
'''Crée une nouvelle entité ldap avec le dn ``dn`` et les
|
'''Crée une nouvelle entité ldap avec le dn ``dn`` et les
|
||||||
attributs de ``ldif``. Attention, ldif doit contenir des
|
attributs de ``ldif``. Attention, ldif doit contenir des
|
||||||
données encodées.'''
|
données encodées.'''
|
||||||
|
for key, values in uldif.iteritems():
|
||||||
|
if key.endswith('id'):
|
||||||
|
continue
|
||||||
|
attribs = [attributs.attrify(val, key, self) for val in values]
|
||||||
|
for attribut in attribs:
|
||||||
|
if attribut.unique:
|
||||||
|
self.lockholder.addlock(key, str(attribut))
|
||||||
return objets.new_cransldapobject(self, dn, 'rw', uldif)
|
return objets.new_cransldapobject(self, dn, 'rw', uldif)
|
||||||
|
|
||||||
def _find_id(self, attr, plage=None):
|
def _find_id(self, attr, plage=None):
|
||||||
|
@ -314,12 +323,17 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
if my_id.value != i:
|
if my_id.value != i:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
break
|
try:
|
||||||
|
self.lockholder.addlock(attr, str(i))
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
raise EnvironmentError('Aucun %s libre dans la plage [%d, %d]' %
|
raise EnvironmentError('Aucun %s libre dans la plage [%d, %d]' %
|
||||||
(attr, plage[0], i))
|
(attr, plage[0], i))
|
||||||
else:
|
else:
|
||||||
i = nonfree[-1]+1
|
i = nonfree[-1]+1
|
||||||
|
self.lockholder.addlock(attr, str(i))
|
||||||
return i
|
return i
|
||||||
|
|
||||||
def _check_parent(self, objdn):
|
def _check_parent(self, objdn):
|
||||||
|
|
|
@ -38,6 +38,8 @@ import os
|
||||||
import exceptions
|
import exceptions
|
||||||
import socket
|
import socket
|
||||||
import crans_utils
|
import crans_utils
|
||||||
|
import collections
|
||||||
|
import subprocess
|
||||||
|
|
||||||
class LdapLockedByYou(exceptions.StandardError):
|
class LdapLockedByYou(exceptions.StandardError):
|
||||||
"""
|
"""
|
||||||
|
@ -67,24 +69,37 @@ class LdapLockHolder:
|
||||||
"""
|
"""
|
||||||
On crée la connexion, et on crée un dico vide.
|
On crée la connexion, et on crée un dico vide.
|
||||||
"""
|
"""
|
||||||
self.locks = {}
|
self.locks = collections.defaultdict(dict, {})
|
||||||
self.host = socket.gethostbyname()
|
self.host = socket.gethostname()
|
||||||
self.pid = os.getpid()
|
self.pid = os.getpid()
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
|
|
||||||
def __del__(self):
|
def purge(self, Id=None):
|
||||||
"""
|
"""
|
||||||
On essaye de détruire tous les verrous hébergés par
|
On essaye de détruire tous les verrous hébergés par
|
||||||
l'objet mourant.
|
l'objet.
|
||||||
"""
|
"""
|
||||||
for item, value in self.locks:
|
if Id == None:
|
||||||
try:
|
for key, subdict in self.locks['default'].keys():
|
||||||
self.removelock(item, value)
|
for item, value in subdict:
|
||||||
except:
|
try:
|
||||||
pass
|
self.removelock(item, value, key)
|
||||||
del self.conn
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
for item, value in self.locks[Id].items():
|
||||||
|
try:
|
||||||
|
self.removelock(item, value, Id)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def addlock(self, item, value):
|
def __del__(self):
|
||||||
|
"""
|
||||||
|
En cas de destruction du lockholder
|
||||||
|
"""
|
||||||
|
self.purge()
|
||||||
|
|
||||||
|
def addlock(self, item, value, Id='default'):
|
||||||
"""
|
"""
|
||||||
Applique un verrou sur "$item=$value,$LOCKS_DN",
|
Applique un verrou sur "$item=$value,$LOCKS_DN",
|
||||||
si le précédent verrou était géré par la session
|
si le précédent verrou était géré par la session
|
||||||
|
@ -97,21 +112,21 @@ class LdapLockHolder:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
host, pid = self.getlock(item, value)
|
host, pid = self.getlock(item, value, Id)
|
||||||
if host == self.host and pid == self.pid():
|
if host == self.host and pid == self.pid:
|
||||||
raise LdapLockedByYou("La donnée %r=%r est lockée par vous-même." % (item, value))
|
raise LdapLockedByYou("La donnée %r=%r est lockée par vous-même." % (item, value))
|
||||||
elif host == self.host:
|
elif host == self.host:
|
||||||
status = crans_utils.process_status(pid)
|
status = crans_utils.process_status(pid)
|
||||||
if status:
|
if status:
|
||||||
raise LdapLockedByOther("La donnée %r=%r est lockée par quelqu'un d'autre ou un processus." % (item, value))
|
raise LdapLockedByOther("La donnée %r=%r est lockée par quelqu'un d'autre ou un processus." % (item, value))
|
||||||
else:
|
else:
|
||||||
self.removelock(item, value)
|
self.removelock(item, value, Id, True)
|
||||||
else:
|
else:
|
||||||
raise LdapLockedByOther("La donnée %r=%r est lockée par quelqu'un d'autre ou un processus." % (item, value))
|
raise LdapLockedByOther("La donnée %r=%r est lockée par quelqu'un d'autre ou un processus." % (item, value))
|
||||||
except ldap.NO_SUCH_OBJECT:
|
except ldap.NO_SUCH_OBJECT:
|
||||||
pass
|
pass
|
||||||
except LockFormatError:
|
except LockFormatError:
|
||||||
self.removelock(item, value)
|
self.removelock(item, value, Id)
|
||||||
|
|
||||||
dn = "%s=%s,%s" % (item, value, LOCKS_DN)
|
dn = "%s=%s,%s" % (item, value, LOCKS_DN)
|
||||||
lockid = "%s-%s" % (self.host, self.pid)
|
lockid = "%s-%s" % (self.host, self.pid)
|
||||||
|
@ -121,38 +136,49 @@ class LdapLockHolder:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.conn.add_s(dn, modlist)
|
self.conn.add_s(dn, modlist)
|
||||||
self.locks[item] = value
|
self.locks[Id][item] = value
|
||||||
except ldap.ALREADY_EXISTS:
|
except ldap.ALREADY_EXISTS:
|
||||||
status = crans_utils.process_status(pid)
|
status = crans_utils.process_status(pid)
|
||||||
if status:
|
if status:
|
||||||
raise LdapLockedByOther("La donnée %r=%r est lockée par quelqu'un d'autre ou un processus." % (item, value))
|
raise LdapLockedByOther("La donnée %r=%r est lockée par quelqu'un d'autre ou un processus." % (item, value))
|
||||||
else:
|
else:
|
||||||
self.removelock(item, value)
|
self.removelock(item, value, Id)
|
||||||
try:
|
try:
|
||||||
self.conn.add_s(dn, modlist)
|
self.conn.add_s(dn, modlist)
|
||||||
self.locks[item] = value
|
|
||||||
|
# Si on a un pointeur vers l'id de l'objet, on en tient compte
|
||||||
|
self.locks[Id][item] = value
|
||||||
except:
|
except:
|
||||||
raise StandardError("Quelque chose a planté durant la pose du lock %s=%s" % (item, value))
|
raise StandardError("Quelque chose a planté durant la pose du lock %s=%s" % (item, value))
|
||||||
|
|
||||||
def removelock(self, item, value):
|
def removelock(self, item, value, Id='default', force=False):
|
||||||
"""
|
"""
|
||||||
Libère le lock "$item=$value,$LOCKS_DN".
|
Libère le lock "$item=$value,$LOCKS_DN".
|
||||||
"""
|
"""
|
||||||
print "Deleting %s=%s,%s\n" % (item, value, LOCKS_DN)
|
if not force:
|
||||||
if self.locks.get(item, "") == value:
|
if self.locks[Id].get(item, "") == str(value):
|
||||||
self.locks.pop(item)
|
_ = self.locks[Id].pop(item)
|
||||||
self.conn.delete_s("%s=%s,%s" % (item, value, LOCKS_DN))
|
self.conn.delete_s("%s=%s,%s" % (item, value, LOCKS_DN))
|
||||||
|
else:
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
print "Lock %s=%s,%s does not exist on this session" % (item, value, LOCKS_DN)
|
try:
|
||||||
|
self.conn.delete_s("%s=%s,%s" % (item, value, LOCKS_DN))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def getlock(self, item, value):
|
def getlock(self, item, value, Id):
|
||||||
"""
|
"""
|
||||||
Trouve le lock item=value, et renvoie le contenu de lockinfo
|
Trouve le lock item=value, et renvoie le contenu de lockinfo
|
||||||
via un couple host, pid
|
via un couple host, pid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
result = self.conn.search_s('%s=%s,%s' % (item, value, LOCKS_DN), 0)
|
result = self.conn.search_s('%s=%s,%s' % (item, value, LOCKS_DN), 0)
|
||||||
|
if not result:
|
||||||
|
_ = self.locks[Id].pop(item)
|
||||||
|
return None, 0
|
||||||
try:
|
try:
|
||||||
return result[0][1]['lockid'][0].split('-')
|
host, pid = result[0][1]['lockid'][0].split('-')
|
||||||
|
return host, int(pid)
|
||||||
except:
|
except:
|
||||||
raise LockFormatError
|
raise LockFormatError
|
||||||
|
|
64
objets.py
64
objets.py
|
@ -63,6 +63,12 @@ from gestion.gen_confs.dhcpd_new import dydhcp
|
||||||
|
|
||||||
#: Champs à ignorer dans l'historique
|
#: Champs à ignorer dans l'historique
|
||||||
HIST_IGNORE_FIELDS = ["modifiersName", "entryCSN", "modifyTimestamp", "historique"]
|
HIST_IGNORE_FIELDS = ["modifiersName", "entryCSN", "modifyTimestamp", "historique"]
|
||||||
|
crans_account_attribs = [attributs.uid, attributs.canonicalAlias, attributs.solde,
|
||||||
|
attributs.contourneGreylist, attributs.derniereConnexion,
|
||||||
|
attributs.homepageAlias, attributs.loginShell, attributs.gecos,
|
||||||
|
attributs.uidNumber, attributs.homeDirectory,
|
||||||
|
attributs.gidNumber, attributs.userPassword,
|
||||||
|
attributs.mailAlias, attributs.cn]
|
||||||
|
|
||||||
def new_cransldapobject(conn, dn, mode='ro', uldif=None):
|
def new_cransldapobject(conn, dn, mode='ro', uldif=None):
|
||||||
"""Crée un objet :py:class:`CransLdapObject` en utilisant la classe correspondant à
|
"""Crée un objet :py:class:`CransLdapObject` en utilisant la classe correspondant à
|
||||||
|
@ -159,7 +165,7 @@ class CransLdapObject(object):
|
||||||
assert isinstance(login, unicode)
|
assert isinstance(login, unicode)
|
||||||
assert isinstance(chain, unicode)
|
assert isinstance(chain, unicode)
|
||||||
|
|
||||||
new_line = u"%s, %s : %s" % (time.strftime("%d/%m/%Y %H:%M"), login, chain)
|
new_line = u"%s, %s : %s" % (time.strftime("%d/%m/%Y %H:%M:%S"), login, chain)
|
||||||
# Attention, le __setitem__ est surchargé, mais pas .append sur l'historique
|
# Attention, le __setitem__ est surchargé, mais pas .append sur l'historique
|
||||||
self["historique"] = self.get("historique", []) + [new_line]
|
self["historique"] = self.get("historique", []) + [new_line]
|
||||||
|
|
||||||
|
@ -193,6 +199,12 @@ class CransLdapObject(object):
|
||||||
modlist = addModlist(self._modifs.to_ldif())
|
modlist = addModlist(self._modifs.to_ldif())
|
||||||
# Requête LDAP de création de l'objet
|
# Requête LDAP de création de l'objet
|
||||||
self.conn.add_s(self.dn, modlist)
|
self.conn.add_s(self.dn, modlist)
|
||||||
|
# On nettoie les locks
|
||||||
|
for key, values in self._modifs.to_ldif().iteritems():
|
||||||
|
for value in values:
|
||||||
|
self.conn.lockholder.removelock(key, value)
|
||||||
|
self.conn.lockholder.purge(id(self))
|
||||||
|
# Services à relancer
|
||||||
services.services_to_restart(self.conn, {}, self._modifs)
|
services.services_to_restart(self.conn, {}, self._modifs)
|
||||||
self._post_creation()
|
self._post_creation()
|
||||||
|
|
||||||
|
@ -221,6 +233,7 @@ class CransLdapObject(object):
|
||||||
raise EnvironmentError("Vous n'avez pas le droit de supprimer %s." % self.dn)
|
raise EnvironmentError("Vous n'avez pas le droit de supprimer %s." % self.dn)
|
||||||
self.bury(comm, login)
|
self.bury(comm, login)
|
||||||
self.conn.delete_s(self.dn)
|
self.conn.delete_s(self.dn)
|
||||||
|
self.conn.lockholder.purge(id(self))
|
||||||
self._post_deletion()
|
self._post_deletion()
|
||||||
services.services_to_restart(self.conn, self.attrs, {})
|
services.services_to_restart(self.conn, self.attrs, {})
|
||||||
|
|
||||||
|
@ -243,6 +256,9 @@ class CransLdapObject(object):
|
||||||
# On programme le redémarrage des services
|
# On programme le redémarrage des services
|
||||||
services.services_to_restart(self.conn, self.attrs, self._modifs)
|
services.services_to_restart(self.conn, self.attrs, self._modifs)
|
||||||
|
|
||||||
|
# On nettoie les locks
|
||||||
|
self.conn.lockholder.purge(id(self))
|
||||||
|
|
||||||
# Vérification des modifications
|
# Vérification des modifications
|
||||||
old_ldif = self.conn.search_s(self.dn, ldap.SCOPE_BASE)[0][1]
|
old_ldif = self.conn.search_s(self.dn, ldap.SCOPE_BASE)[0][1]
|
||||||
old_uldif = lc_ldap.ldif_to_uldif(old_ldif)
|
old_uldif = lc_ldap.ldif_to_uldif(old_ldif)
|
||||||
|
@ -330,6 +346,9 @@ class CransLdapObject(object):
|
||||||
if not mixed_attrs[0].is_modifiable(self.conn.droits + self.conn._check_parent(self.dn) + self.conn._check_self(self.dn)):
|
if not mixed_attrs[0].is_modifiable(self.conn.droits + self.conn._check_parent(self.dn) + self.conn._check_self(self.dn)):
|
||||||
raise EnvironmentError("Vous ne pouvez pas toucher aux attributs de type %r." % (attr))
|
raise EnvironmentError("Vous ne pouvez pas toucher aux attributs de type %r." % (attr))
|
||||||
self._modifs[attr] = attrs_before_verif
|
self._modifs[attr] = attrs_before_verif
|
||||||
|
for attribut in attrs_before_verif:
|
||||||
|
if attribut.unique:
|
||||||
|
self.conn.lockholder.addlock(attr, str(attribut), id(self))
|
||||||
|
|
||||||
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
|
||||||
|
@ -617,15 +636,16 @@ class adherent(proprio):
|
||||||
attributs.mail, attributs.mailInvalide, attributs.charteMA,
|
attributs.mail, attributs.mailInvalide, attributs.charteMA,
|
||||||
attributs.derniereConnexion, attributs.gpgFingerprint,
|
attributs.derniereConnexion, attributs.gpgFingerprint,
|
||||||
attributs.carteEtudiant, attributs.droits, attributs.etudes,
|
attributs.carteEtudiant, attributs.droits, attributs.etudes,
|
||||||
attributs.postalAddress, attributs.mailExt, attributs.compteWiki]
|
attributs.postalAddress, attributs.mailExt, attributs.compteWiki,
|
||||||
|
]
|
||||||
ldap_name = "adherent"
|
ldap_name = "adherent"
|
||||||
|
|
||||||
def __init__(self, conn, dn, mode='ro', ldif = None):
|
def __init__(self, conn, dn, mode='ro', ldif = None):
|
||||||
super(adherent, self).__init__(conn, dn, mode, ldif)
|
super(adherent, self).__init__(conn, dn, mode, ldif)
|
||||||
|
self.full = False
|
||||||
if u'cransAccount' in [ unicode(o) for o in self['objectClass']]:
|
if u'cransAccount' in [ unicode(o) for o in self['objectClass']]:
|
||||||
self.attribs = self.attribs + [attributs.uid, attributs.canonicalAlias, attributs.solde,
|
self.attribs = self.attribs + crans_account_attribs
|
||||||
attributs.contourneGreylist, attributs.derniereConnexion,
|
self.full = True
|
||||||
attributs.homepageAlias, attributs.mailAlias, attributs.loginShell ]
|
|
||||||
|
|
||||||
def compte(self, login = None, uidNumber=0, hash_pass = '', shell=config.login_shell):
|
def compte(self, login = None, uidNumber=0, hash_pass = '', shell=config.login_shell):
|
||||||
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
|
||||||
|
@ -650,17 +670,20 @@ class adherent(proprio):
|
||||||
if os.path.exists("/var/mail/" + login):
|
if os.path.exists("/var/mail/" + login):
|
||||||
raise ValueError('Création du compte impossible : /var/mail/%s existant' % login)
|
raise ValueError('Création du compte impossible : /var/mail/%s existant' % login)
|
||||||
|
|
||||||
self._modifs['homeDirectory'] = [home]
|
if not self.full:
|
||||||
self._modifs['mail'] = [login]
|
self.attribs = self.attribs + crans_account_attribs
|
||||||
self._modifs['uid' ] = [login]
|
self.full = True
|
||||||
|
self['homeDirectory'] = [home]
|
||||||
|
self['mail'] = [login + u"@crans.org"]
|
||||||
|
self['uid' ] = [login]
|
||||||
calias = crans_utils.strip_spaces(fn) + u'.' + crans_utils.strip_spaces(ln)
|
calias = crans_utils.strip_spaces(fn) + u'.' + crans_utils.strip_spaces(ln)
|
||||||
if crans_utils.mailexist(calias):
|
if crans_utils.mailexist(calias):
|
||||||
calias = login
|
calias = login
|
||||||
self._modifs['canonicalAlias'] = [calias]
|
self['canonicalAlias'] = [calias]
|
||||||
self._modifs['objectClass'] = [u'adherent', u'cransAccount', u'posixAccount', u'shadowAccount']
|
self['objectClass'] = [u'adherent', u'cransAccount', u'posixAccount', u'shadowAccount']
|
||||||
self._modifs['cn'] = [ fn + u' ' + ln ]
|
self['cn'] = [ fn + u' ' + ln ]
|
||||||
self._modifs['loginShell'] = [unicode(shell)]
|
self['loginShell'] = [unicode(shell)]
|
||||||
self._modifs['userPassword'] = [unicode(hash_pass)]
|
self['userPassword'] = [unicode(hash_pass)]
|
||||||
|
|
||||||
if uidNumber:
|
if uidNumber:
|
||||||
if self.conn.search('(uidNumber=%s)' % uidNumber):
|
if self.conn.search('(uidNumber=%s)' % uidNumber):
|
||||||
|
@ -675,18 +698,11 @@ class adherent(proprio):
|
||||||
if not len(pool_uid):
|
if not len(pool_uid):
|
||||||
raise ValueError("Plus d'uid disponibles !")
|
raise ValueError("Plus d'uid disponibles !")
|
||||||
|
|
||||||
## try:
|
self['uidNumber'] = [unicode(uidNumber)]
|
||||||
## self.lock('uidNumber', str(uidNumber))
|
self['gidNumber'] = [unicode(config.gid)]
|
||||||
## except:
|
self['gecos'] = [self._modifs['cn'][0] + u',,,']
|
||||||
## # Quelqu'un nous a piqué l'uid que l'on venait de choisir !
|
|
||||||
## return self.compte(login, uidNumber, hash_pass, shell)
|
|
||||||
|
|
||||||
self._modifs['uidNumber'] = [unicode(uidNumber)]
|
|
||||||
self._modifs['gidNumber'] = [unicode(config.gid)]
|
|
||||||
self._modifs['gecos'] = [self._modifs['cn'][0] + u',,,']
|
|
||||||
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
|
#self.save()
|
||||||
else:
|
else:
|
||||||
raise EnvironmentError("L'adhérent n'a pas de compte crans")
|
raise EnvironmentError("L'adhérent n'a pas de compte crans")
|
||||||
|
|
||||||
|
|
3
test.py
3
test.py
|
@ -53,7 +53,7 @@ borne_ldif = {
|
||||||
'macAddress' : [randomMAC()],
|
'macAddress' : [randomMAC()],
|
||||||
'host' : ["autotest-%s.crans.org" % randomStr() ],
|
'host' : ["autotest-%s.crans.org" % randomStr() ],
|
||||||
'canal' : ["11"],
|
'canal' : ["11"],
|
||||||
'puissance' : ["52 khz"],
|
'puissance' : [u"52"],
|
||||||
}
|
}
|
||||||
|
|
||||||
club_ldif = {
|
club_ldif = {
|
||||||
|
@ -97,7 +97,6 @@ def test_list_of_dict(keys, list):
|
||||||
anim("\tTest de l'attribut %s" % key)
|
anim("\tTest de l'attribut %s" % key)
|
||||||
ok = True
|
ok = True
|
||||||
for item in list:
|
for item in list:
|
||||||
if key == "chbre":
|
|
||||||
print item['aid'][0]
|
print item['aid'][0]
|
||||||
try: item.get(key, [])
|
try: item.get(key, [])
|
||||||
except psycopg2.OperationalError as error:
|
except psycopg2.OperationalError as error:
|
||||||
|
|
|
@ -33,3 +33,4 @@ deleted = 'deleted'
|
||||||
|
|
||||||
#: Mot de passe de la base de tests
|
#: Mot de passe de la base de tests
|
||||||
ldap_test_password = '75bdb64f32'
|
ldap_test_password = '75bdb64f32'
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue