+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""Outil de gestion d'annuaire LDAP pour l'AuF.
-
-Copyright ©2009-2010 Agence universitaire de la Francophonie
-Licence : GPL version 3
-Auteur : Progfou <jean-christophe.andre@auf.org>
-
-Dépendances Debian : python >= 2.5, python-simplejson, auf-refer
-
-Usage :
-
- auf-annuaire.py | ldapmodify -x -c -D "cn=admin,o=AUF" -y /etc/ldap.secret
-"""
-
-import os
-import aufrefer
-import simplejson as json
-
-LDAP_HOST = '127.0.0.1'
-LDAP_BASE = 'ou=People,o=AUF'
-LDAP_BINDDN = 'cn=admin,' + LDAP_BASE
-LDAP_PWFILE = ['~/.ldap.secret', '/etc/ldap.secret']
-
-LDAP_INIT_LDIF = u"""dn: ou=People,o=AuF
-changeType: add
-objectClass: top
-objectClass: organizationalUnit
-ou: People
-"""
-
-PERSONNELS = aufrefer.get('personnels.json')
-ISO_3166 = aufrefer.get('iso-3166-fr.json')
-NOMS_BUREAU = aufrefer.get('bureaux.json')
-PAYS_IMPLANT = {'IFMT': 'LA', 'DANANG.VN': 'VN'}
-
-def capitale_sur_les_mots(s):
- r = ''
- previous_isalpha = False
- for c in s:
- isalpha = c.isalpha()
- if isalpha and not previous_isalpha:
- c = c.upper()
- r += c
- previous_isalpha = isalpha
- return r
-
-def pays_implantation(implant):
- return PAYS_IMPLANT.get(implant.upper(), implant.upper())
-
-def nom_pays(country):
- return ISO_3166.get(country.upper(),
- u'### Pays absent de la norme ISO-3166 ###')
-
-def noms_bureau(cc):
- for code, data in NOMS_BUREAU.items():
- if cc.upper() in data[1]:
- return code, data[0]
- return u'### implantation inconnue ###', u'### implantation inconnue ###'
-
-def login_nom_personnel(adel):
- info = filter(lambda p: p['adel'] == adel, PERSONNELS)
- if not info:
- return None, None
- return info[0]['login'], info[0]['nom']
-
-class LdapEntry(object):
- _attributes_order = [
- 'objectClass', 'sn', 'givenName', 'cn', 'ou', 'l', 'mail', 'o',
- 'userPassword', 'telephoneNumber', 'uid',
- ]
-
- def __init__(self, dn, d=None, **kv):
- self.dn = dn
- if d:
- self.dict = d
- else:
- self.dict = { }
- self.dict.update(kv)
-
- def get(self, attribute):
- return self.dict.get(attribute, None)
-
- def set(self, attribute, value):
- old_value = self.dict.get(attribute, None)
- self.dict[attribute] = value
- return old_value
-
- def from_ldif(self, ldif):
- raise RuntimeError('Note implemented')
-
- def _to_ldif_line(self, attribute, value):
- to_encode = False
- for c in value:
- if c < ' ' or 'z' < c:
- to_encode = True
- break
- if to_encode:
- attribute = attribute + ':'
- if type(value) == unicode:
- value = value.encode('utf-8')
- value = value.encode('base64').rstrip('\n')
- return u'%s: %s' % (attribute, value)
-
- def to_ldif(self, changeType=None):
- ldif = [ ]
- ldif.append(self._to_ldif_line(u'dn', self.dn))
- if changeType:
- ldif.append(u'changeType: %s' % changeType)
- set_keys = set(self.dict.keys())
- set_attr_order = set(self._attributes_order)
- for k in set_keys & set_attr_order:
- for e in self.dict[k]:
- ldif.append(self._to_ldif_line(k, e))
- for k in set_keys - set_attr_order:
- for e in self.dict[k]:
- ldif.append(self._to_ldif_line(k, e))
- ldif.append(u'')
- return '\n'.join(ldif).encode('utf-8')
-
-
-class AnnuaireAuF(object):
- _attributes = [
- 'adel', 'redir', 'nom', 'mdp', 'implant', 'coda', 'tel_ext', 'tel_ip',
- ]
-
- def __init__(self, ldap_base):
- self.ldap_base = ldap_base
- self.data = None
-
- def json2ldap(self, json_dict):
- CC = pays_implantation(json_dict['implant'])
- nom_bureau_court, nom_bureau_long = noms_bureau(CC)
- adel = json_dict['adel']
- user, domain = adel.split('@')
- cn = capitale_sur_les_mots(user)
- cn = cn.replace('-De-', '-de-').replace('.', ' ')
- prenom, nom = cn.rsplit(' ', 1)
- login, nom_affichage = login_nom_personnel(user)
- if nom_affichage is None:
- nom_affichage = json_dict['nom'] and json_dict['nom'] or cn
-
- ldap_dict = { }
- ldap_dict['objectClass'] = [
- u'top', u'person', u'organizationalPerson', u'inetOrgPerson'
- ]
- ldap_dict['sn'] = [ nom ]
- ldap_dict['givenName'] = [ prenom ]
- ldap_dict['cn'] = [ nom_affichage ]
- ldap_dict['ou'] = [ u'People', nom_bureau_court, nom_bureau_long ]
- ldap_dict['l'] = [ nom_pays(CC) ]
- ldap_dict['mail'] = [ adel ]
- ldap_dict['o'] = [ u'AuF', u'Agence universitaire de la Francophonie' ]
- if json_dict.has_key('mdp') and json_dict['mdp']:
- ldap_dict['userPassword'] = [ '{CRYPT}' + json_dict['mdp'] ]
- if json_dict.has_key('tel_ip') and json_dict['tel_ip']:
- ldap_dict['telephoneNumber'] = [ json_dict['tel_ip'] ]
- if login is not None and login:
- ldap_dict['uid'] = [ login ]
- ldap_dn = u'mail=%s,%s' % (adel, self.ldap_base)
- return ldap_dn, ldap_dict
-
- def load(self):
- self.data = [ ]
- for json_dict in aufrefer.get('annuaire.json'):
- ldap_dn, ldap_dict = self.json2ldap(json_dict)
- self.data.append(LdapEntry(ldap_dn, ldap_dict))
-
- def to_ldif(self):
- ldif = [ LDAP_INIT_LDIF ]
- for d in self.data:
- ldif.append(d.to_ldif(changeType='add'))
- ldif.append('')
- return '\n'.join(ldif)
-
- def search(self, name):
- return filter(lambda x: x['adel'].find(name) >= 0, self.data)
-
- def update_ldap(self, base=LDAP_BASE,
- host=LDAP_HOST, binddn=LDAP_BINDDN, pwfile=LDAP_PWFILE):
- pass
-
-if __name__ == '__main__':
- annuaire = AnnuaireAuF(LDAP_BASE)
- annuaire.load()
- #print "search('andre'): %s" % \
- # map(lambda x: x['adel'], annuaire.search('andre'))
- print annuaire.to_ldif(),
-