Outil de recodage de données PHP sérialisées.
[progfou.git] / openldap / auf-annuaire
CommitLineData
435595b8
P
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3"""Outil de gestion d'annuaire LDAP pour l'AuF.
4
5Copyright ©2009-2010 Agence universitaire de la Francophonie
6Licence : GPL version 3
7Auteur : Progfou <jean-christophe.andre@auf.org>
8
9Dépendances Debian : python >= 2.5, python-simplejson, auf-refer
10
11Usage :
12
13 auf-annuaire.py | ldapmodify -x -c -D "cn=admin,o=AUF" -y /etc/ldap.secret
14"""
15
16import os
17import aufrefer
18import simplejson as json
19
20LDAP_HOST = '127.0.0.1'
21LDAP_BASE = 'ou=People,o=AUF'
22LDAP_BINDDN = 'cn=admin,' + LDAP_BASE
23LDAP_PWFILE = ['~/.ldap.secret', '/etc/ldap.secret']
24
25LDAP_INIT_LDIF = u"""dn: ou=People,o=AuF
26changeType: add
27objectClass: top
28objectClass: organizationalUnit
29ou: People
30"""
31
32PERSONNELS = aufrefer.get('personnels.json')
33ISO_3166 = aufrefer.get('iso-3166-fr.json')
34NOMS_BUREAU = aufrefer.get('bureaux.json')
35PAYS_IMPLANT = {'IFMT': 'LA', 'DANANG.VN': 'VN'}
36
37def capitale_sur_les_mots(s):
38 r = ''
39 previous_isalpha = False
40 for c in s:
41 isalpha = c.isalpha()
42 if isalpha and not previous_isalpha:
43 c = c.upper()
44 r += c
45 previous_isalpha = isalpha
46 return r
47
48def pays_implantation(implant):
49 return PAYS_IMPLANT.get(implant.upper(), implant.upper())
50
51def nom_pays(country):
52 return ISO_3166.get(country.upper(),
53 u'### Pays absent de la norme ISO-3166 ###')
54
55def noms_bureau(cc):
56 for code, data in NOMS_BUREAU.items():
57 if cc.upper() in data[1]:
58 return code, data[0]
59 return u'### implantation inconnue ###', u'### implantation inconnue ###'
60
61def login_nom_personnel(adel):
62 info = filter(lambda p: p['adel'] == adel, PERSONNELS)
63 if not info:
64 return None, None
65 return info[0]['login'], info[0]['nom']
66
67class LdapEntry(object):
68 _attributes_order = [
69 'objectClass', 'sn', 'givenName', 'cn', 'ou', 'l', 'mail', 'o',
70 'userPassword', 'telephoneNumber', 'uid',
71 ]
72
73 def __init__(self, dn, d=None, **kv):
74 self.dn = dn
75 if d:
76 self.dict = d
77 else:
78 self.dict = { }
79 self.dict.update(kv)
80
81 def get(self, attribute):
82 return self.dict.get(attribute, None)
83
84 def set(self, attribute, value):
85 old_value = self.dict.get(attribute, None)
86 self.dict[attribute] = value
87 return old_value
88
89 def from_ldif(self, ldif):
90 raise RuntimeError('Note implemented')
91
92 def _to_ldif_line(self, attribute, value):
93 to_encode = False
94 for c in value:
95 if c < ' ' or 'z' < c:
96 to_encode = True
97 break
98 if to_encode:
99 attribute = attribute + ':'
100 if type(value) == unicode:
101 value = value.encode('utf-8')
102 value = value.encode('base64').rstrip('\n')
103 return u'%s: %s' % (attribute, value)
104
105 def to_ldif(self, changeType=None):
106 ldif = [ ]
107 ldif.append(self._to_ldif_line(u'dn', self.dn))
108 if changeType:
109 ldif.append(u'changeType: %s' % changeType)
110 set_keys = set(self.dict.keys())
111 set_attr_order = set(self._attributes_order)
112 for k in set_keys & set_attr_order:
113 for e in self.dict[k]:
114 ldif.append(self._to_ldif_line(k, e))
115 for k in set_keys - set_attr_order:
116 for e in self.dict[k]:
117 ldif.append(self._to_ldif_line(k, e))
118 ldif.append(u'')
119 return '\n'.join(ldif).encode('utf-8')
120
121
122class AnnuaireAuF(object):
123 _attributes = [
124 'adel', 'redir', 'nom', 'mdp', 'implant', 'coda', 'tel_ext', 'tel_ip',
125 ]
126
127 def __init__(self, ldap_base):
128 self.ldap_base = ldap_base
129 self.data = None
130
131 def json2ldap(self, json_dict):
132 CC = pays_implantation(json_dict['implant'])
133 nom_bureau_court, nom_bureau_long = noms_bureau(CC)
134 adel = json_dict['adel']
135 user, domain = adel.split('@')
136 cn = capitale_sur_les_mots(user)
137 cn = cn.replace('-De-', '-de-').replace('.', ' ')
138 prenom, nom = cn.rsplit(' ', 1)
139 login, nom_affichage = login_nom_personnel(user)
140 if nom_affichage is None:
141 nom_affichage = json_dict['nom'] and json_dict['nom'] or cn
142
143 ldap_dict = { }
144 ldap_dict['objectClass'] = [
145 u'top', u'person', u'organizationalPerson', u'inetOrgPerson'
146 ]
147 ldap_dict['sn'] = [ nom ]
148 ldap_dict['givenName'] = [ prenom ]
149 ldap_dict['cn'] = [ nom_affichage ]
150 ldap_dict['ou'] = [ u'People', nom_bureau_court, nom_bureau_long ]
151 ldap_dict['l'] = [ nom_pays(CC) ]
152 ldap_dict['mail'] = [ adel ]
153 ldap_dict['o'] = [ u'AuF', u'Agence universitaire de la Francophonie' ]
154 if json_dict.has_key('mdp') and json_dict['mdp']:
155 ldap_dict['userPassword'] = [ '{CRYPT}' + json_dict['mdp'] ]
156 if json_dict.has_key('tel_ip') and json_dict['tel_ip']:
157 ldap_dict['telephoneNumber'] = [ json_dict['tel_ip'] ]
158 if login is not None and login:
159 ldap_dict['uid'] = [ login ]
160 ldap_dn = u'mail=%s,%s' % (adel, self.ldap_base)
161 return ldap_dn, ldap_dict
162
163 def load(self):
164 self.data = [ ]
165 for json_dict in aufrefer.get('annuaire.json'):
166 ldap_dn, ldap_dict = self.json2ldap(json_dict)
167 self.data.append(LdapEntry(ldap_dn, ldap_dict))
168
169 def to_ldif(self):
170 ldif = [ LDAP_INIT_LDIF ]
171 for d in self.data:
172 ldif.append(d.to_ldif(changeType='add'))
173 ldif.append('')
174 return '\n'.join(ldif)
175
176 def search(self, name):
177 return filter(lambda x: x['adel'].find(name) >= 0, self.data)
178
179 def update_ldap(self, base=LDAP_BASE,
180 host=LDAP_HOST, binddn=LDAP_BINDDN, pwfile=LDAP_PWFILE):
181 pass
182
183if __name__ == '__main__':
184 annuaire = AnnuaireAuF(LDAP_BASE)
185 annuaire.load()
186 #print "search('andre'): %s" % \
187 # map(lambda x: x['adel'], annuaire.search('andre'))
188 print annuaire.to_ldif(),
189