Merge branch 'master' of charybde.crans.org:/git/ldap

This commit is contained in:
Vincent Le Gallic 2013-03-07 19:12:05 +01:00
commit d3c6d699f5
3 changed files with 34 additions and 26 deletions

View file

@ -76,13 +76,13 @@ DROITS_SUPERVISEUR = { nounou : TOUS_DROITS,
def attrify(val, attr, ldif, conn, ctxt_check = True): def attrify(val, attr, ldif, conn, ctxt_check = True):
"""Transforme un n'importe quoi en Attr. """Transforme un n'importe quoi en :py:class:`Attr`.
Doit effectuer les normalisations et sanity check si un str ou un Doit effectuer les normalisations et sanity check si un str ou un
unicode est passé en argument. unicode est passé en argument.
Devrait insulter en cas de potentiel problème d'encodage. Devrait insulter en cas de potentiel problème d'encodage.
Doit effectuer les vérifications de contexte dans le *ldif* si Doit effectuer les vérifications de contexte dans le ``ldif`` si
ctxt_check est vrai""" ``ctxt_check`` est vrai"""
if isinstance(val, Attr): if isinstance(val, Attr):
return val return val
@ -90,7 +90,14 @@ def attrify(val, attr, ldif, conn, ctxt_check = True):
return CRANS_ATTRIBUTES.get(attr, Attr)(val, ldif, conn, ctxt_check) return CRANS_ATTRIBUTES.get(attr, Attr)(val, ldif, conn, ctxt_check)
class Attr(object): class Attr(object):
"""La liste des droits qui suffisent à avoir le droit de modifier la valeur""" """Objet représentant un attribut.
**Paramètres :**
* ``val`` : valeur de l'attribut
* ``ldif`` : objet contenant l'attribut (permet de faire les validations sur l'environnement)
* ``ctxt_check`` : effectue les validations
"""
legend = "Human-readable description of attribute" legend = "Human-readable description of attribute"
singlevalue = None singlevalue = None
optional = None optional = None
@ -98,6 +105,7 @@ class Attr(object):
unique = False unique = False
can_modify = [nounou] can_modify = [nounou]
"""La liste des droits qui suffisent à avoir le droit de modifier la valeur"""
can_view = [nounou, apprenti, soi, parent, respo] can_view = [nounou, apprenti, soi, parent, respo]
"""Qui peut voir l'attribut. Par défaut, les Nounous et les Apprentis """Qui peut voir l'attribut. Par défaut, les Nounous et les Apprentis
@ -108,12 +116,7 @@ class Attr(object):
"""Catégorie de l'attribut (pour affichage futur)""" """Catégorie de l'attribut (pour affichage futur)"""
def __init__(self, val, ldif, conn, ctxt_check): def __init__(self, val, ldif, conn, ctxt_check):
"""Crée un nouvel objet représentant un attribut. """Crée un nouvel objet représentant un attribut. """
val: valeur de l'attribut
ldif: objet contenant l'attribut (permet de faire les validations sur l'environnement)
ctxt_check: effectue les validations
"""
self.ctxt_check=ctxt_check self.ctxt_check=ctxt_check
#self.value = None #self.value = None
self.conn = conn self.conn = conn
@ -159,7 +162,7 @@ class Attr(object):
raise ValueError('%s doit avoir au moins une valeur' % self.__class__) raise ValueError('%s doit avoir au moins une valeur' % self.__class__)
def _check_uniqueness(self): def _check_uniqueness(self):
"""Vérifie l'unicité dans la base de la valeur (mailAlias, chbre, """Vérifie l'unicité dans la base de la valeur (``mailAlias``, ``chbre``,
etc...)""" etc...)"""
attr = self.__class__.__name__ attr = self.__class__.__name__
if self.unique: if self.unique:
@ -169,7 +172,7 @@ class Attr(object):
def _check_users_restrictions(self, values): def _check_users_restrictions(self, values):
"""Vérifie les restrictions supplémentaires imposées selon les """Vérifie les restrictions supplémentaires imposées selon les
niveaux de droits (<= 3 mailAlias, pas de mac identiques, niveaux de droits (<= 3 ``mailAlias``, pas de mac identiques,
etc...)""" etc...)"""
### On l'implémente dans les classes filles ! ### On l'implémente dans les classes filles !
pass pass

View file

@ -4,4 +4,7 @@ lc_ldap.attributs -- Conteneurs pour les attributs LDAP
.. automodule:: attributs .. automodule:: attributs
:members: :members:
:private-members:
:special-members:
:show-inheritance:

View file

@ -78,6 +78,7 @@ current_user = os.getenv("SUDO_USER") or os.getenv("USER")
# Quand on a besoin du fichier de secrets # Quand on a besoin du fichier de secrets
def import_secrets(): def import_secrets():
"""Importe le fichier de secrets"""
if not "/etc/crans/secrets/" in sys.path: if not "/etc/crans/secrets/" in sys.path:
sys.path.append("/etc/crans/secrets/") sys.path.append("/etc/crans/secrets/")
import secrets import secrets
@ -127,12 +128,12 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
""" """
def __init__(self, dn=None, user=None, cred=None, uri=uri, test=False): def __init__(self, dn=None, user=None, cred=None, uri=uri, test=False):
"""Initialise la connexion ldap, """Initialise la connexion ldap,
- En authentifiant avec dn et cred s'ils sont précisés - En authentifiant avec ``dn`` et ``cred`` s'ils sont précisés
- Si dn n'est pas précisé, mais que user est précisé, récupère - Si ``dn`` n'est pas précisé, mais que ``user`` est précisé, récupère
le dn associé à l'uid user, et effectue l'authentification le ``dn`` associé à l'uid ``user``, et effectue l'authentification
avec ce dn et cred avec ce ``dn`` et ``cred``
- Sinon effectue une authentification anonyme - Sinon effectue une authentification anonyme
Si test est à True, on se connecte à la base de test sur vo. Si ``test`` est à ``True``, on se connecte à la base de test sur ``vo``.
""" """
if test: if test:
uri = "ldapi:///" uri = "ldapi:///"
@ -177,8 +178,9 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
self.simple_bind_s(who=secrets.ldap_readonly_auth_dn, cred=secrets.ldap_readonly_password) self.simple_bind_s(who=secrets.ldap_readonly_auth_dn, cred=secrets.ldap_readonly_password)
def search(self, filterstr='(objectClass=*)', mode='ro', dn= base_dn, scope=ldap.SCOPE_SUBTREE, sizelimit=1000): def search(self, filterstr='(objectClass=*)', mode='ro', dn= base_dn, scope=ldap.SCOPE_SUBTREE, sizelimit=1000):
"""La fonction de recherche dans la base ldap qui renvoie un liste de """La fonction de recherche dans la base LDAP qui renvoie un liste de
CransLdapObjects. On utilise la feature de sizelimit de python ldap""" :py:class:`CransLdapObject`. On utilise la feature de ``sizelimit`` de
``python-ldap``"""
ldap_res = self.search_ext_s(dn, scope, filterstr, sizelimit=sizelimit) ldap_res = self.search_ext_s(dn, scope, filterstr, sizelimit=sizelimit)
ret = [] ret = []
for dn, ldif in ldap_res: for dn, ldif in ldap_res:
@ -228,7 +230,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
return adherents 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
--Partiellement implémenté""" --Partiellement implémenté"""
#adm, serveurs, bornes, wifi, adherents, gratuit ou personnel-ens""" #adm, serveurs, bornes, wifi, adherents, gratuit ou personnel-ens"""
@ -299,7 +301,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
raise NotImplementedError() raise NotImplementedError()
def _create_entity(self, dn, uldif): def _create_entity(self, dn, uldif):
'''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'''
# Conversion en cldif pour vérification des valeurs # Conversion en cldif pour vérification des valeurs
cldif = ldif_to_cldif(uldif, self) cldif = ldif_to_cldif(uldif, self)
@ -410,8 +412,8 @@ class lc_ldap_local(lc_ldap):
def new_cransldapobject(conn, dn, mode='ro', ldif = None): def new_cransldapobject(conn, dn, mode='ro', ldif = None):
"""Crée un objet CransLdap en utilisant la classe correspondant à """Crée un objet :py:class:`CransLdap` en utilisant la classe correspondant à
l'objectClass du ldif l'``objectClass`` du ``ldif``
--pour usage interne à la libraire uniquement !""" --pour usage interne à la libraire uniquement !"""
classe = None classe = None
@ -430,7 +432,7 @@ def new_cransldapobject(conn, dn, mode='ro', ldif = None):
return classe(conn, dn, mode, ldif) return classe(conn, dn, mode, ldif)
class CransLdapObject(object): class CransLdapObject(object):
"""Classe de base des objets CransLdap. """Classe de base des objets :py:class:`CransLdap`.
Cette classe ne devrait pas être utilisée directement.""" Cette classe ne devrait pas être utilisée directement."""
""" Qui peut faire quoi ? """ """ Qui peut faire quoi ? """
@ -444,7 +446,7 @@ class CransLdapObject(object):
def __init__(self, conn, dn, mode='ro', ldif = None): def __init__(self, conn, dn, mode='ro', ldif = None):
''' '''
Créée une instance d'un objet Crans (machine, adhérent, Créée une instance d'un objet Crans (machine, adhérent,
etc...) à ce dn, si ldif est précisé, n'effectue pas de etc...) à ce ``dn``, si ``ldif`` est précisé, n'effectue pas de
recherche dans la base ldap. recherche dans la base ldap.
''' '''
@ -532,7 +534,7 @@ class CransLdapObject(object):
def save(self): def save(self):
"""Sauvegarde dans la base les modifications apportées à l'objet. """Sauvegarde dans la base les modifications apportées à l'objet.
Interne: Vérifie que self._modifs contient des valeurs correctes et Interne: Vérifie que ``self._modifs`` contient des valeurs correctes et
enregistre les modifications.""" enregistre les modifications."""
if self.mode not in ['w', 'rw']: if self.mode not in ['w', 'rw']:
raise EnvironmentError("Objet en lecture seule, réessayer en lecture/écriture") raise EnvironmentError("Objet en lecture seule, réessayer en lecture/écriture")