Skip to content

Commit 793350f

Browse files
committed
Update backend_ldap_utils.py
1 parent 188825c commit 793350f

File tree

1 file changed

+119
-40
lines changed

1 file changed

+119
-40
lines changed

src/lib/backend_ldap_utils.py

Lines changed: 119 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import configparser
22
import json
3+
4+
import jinja2
35
import ldap
46
import ldap.modlist as modlist
57
from sys import stdin
@@ -16,7 +18,12 @@ def config(key,default=''):
1618
c=__CONFIG__['config']
1719
return c.get(key,default)
1820

19-
21+
def get_config():
22+
items=__CONFIG__.items('config')
23+
data = {}
24+
for k, v in items:
25+
data[k] = v
26+
return data
2027
def connect_ldap(url,dn,password):
2128
try:
2229
l=ldap.initialize(url)
@@ -77,33 +84,60 @@ def make_entry_array(entity):
7784
additionalFields = entity['payload']['additionalFields']['attributes']
7885
#inetOrgPerson
7986
for k,v in inetOrgPerson.items():
80-
data[k]=str(v)
87+
if type(v) is int:
88+
v=str(v)
89+
data[k.lower()]=v
8190

8291
for obj in objectclasses:
8392
#recherche si l objectclass est exclu
8493
exclusions=config('excludedObjectclasses').lower()
8594
if exclusions.find(obj.lower()) == -1:
86-
for k,v in additionalFields[obj].items():
87-
data[k]=str(v)
95+
if obj in additionalFields.keys():
96+
for k,v in additionalFields[obj].items():
97+
if type(v) is int:
98+
v = str(v)
99+
data[k.lower()]=v
88100
return data
89101

90102

91-
def make_objectclass(entity):
103+
def make_objectclass(entity,entry):
92104
data = {}
105+
objectclasses=[]
106+
if entry:
107+
current=entry[0][1]['objectClass']
108+
for k in current:
109+
x=k.decode('UTF-8').lower()
110+
objectclasses.append(x)
111+
else:
112+
objectclasses.append('top')
113+
objectclasses.append('inetOrgPerson')
93114
if "identity" in entity['payload']:
94-
objectclasses = entity['payload']['identity']['identity']['additionalFields']['objectClasses']
115+
new_objectclasses = entity['payload']['identity']['identity']['additionalFields']['objectClasses']
95116
else:
96-
objectclasses = entity['payload']['additionalFields']['objectClasses']
117+
new_objectclasses = entity['payload']['additionalFields']['objectClasses']
118+
119+
for k in new_objectclasses:
120+
if k.lower() not in objectclasses:
121+
objectclasses.append(k)
97122

98-
return ['top', 'inetOrgPerson'] + objectclasses
123+
return objectclasses
99124

100125

101126
def make_entry_array_without_empty(entity):
102127
data={}
103128
data1=make_entry_array(entity)
104129
for k,v in data1.items():
105-
if str(v) != "":
106-
data[k]=v
130+
if type(v) is list and len(k) > 0:
131+
l=[]
132+
for i in v:
133+
if i != '':
134+
l.append(i)
135+
if len(l)>0:
136+
data[k.lower()] = l
137+
if type(v) is int:
138+
v=str(v)
139+
if type(v) is str and str(v) != "":
140+
data[k.lower()]=v
107141
return data
108142

109143
def convert_to_utf8(entry):
@@ -121,27 +155,35 @@ def compose_rdn(entity):
121155
rdn = config('rdnAttribute', 'uid')
122156
rdnValue = find_key(entity, rdn)
123157
return rdn +'=' + rdnValue
124-
125158
def compose_dn(entity):
126-
rdn=config('rdnAttribute','uid')
159+
"""Compose the DN of a identity"""
160+
rdn = config('rdnAttribute', 'uid')
127161
rdnValue=find_key(entity,rdn)
162+
data = {
163+
'e': make_entry_array(entity),
164+
'config': get_config(),
165+
'rdnValue': rdnValue
166+
}
167+
168+
x=type(rdnValue)
169+
if rdnValue is None:
170+
rdnValue='test'
128171
branchAttr=config('branchAttr','')
129-
branch = ''
172+
data['rdnValue']=rdnValue
130173
if branchAttr != '':
131174
branchValue=find_key(entity,branchAttr)
132-
133-
match branchValue:
134-
case 'etd':
135-
branch=config('branchForEtd','')
136-
case 'esn':
137-
branch = config('branchForEsn', '')
138-
case 'adm':
139-
branch = config('branchForAdm', '')
140-
if branch != '':
141-
return rdn+ '=' + rdnValue+ ',' + branch + "," + config('userbase')
175+
key_branch='branchFor' + branchValue
176+
branch=config(key_branch,'')
177+
data['branch']=branch
178+
template_string = '{{ config.rdnattribute}}={{rdnValue}},{{ branch }},{{ config.userbase }}'
142179
else:
143-
return rdn+ '=' + rdnValue+ "," + config('userbase')
144-
180+
if config('userbase','') != '':
181+
template_string ='{{config.rdnattribute}}={{ rdnValue}},{{ config.userbase }}'
182+
else:
183+
template_string = '{{config.rdnattribute}}={{ rdnValue}},{{ config.base }}'
184+
template = jinja2.Environment(loader=jinja2.BaseLoader()).from_string(config('dnTemplate',template_string))
185+
content = template.render(data)
186+
return content
145187
def dn_superior(dn):
146188
tab=dn.split(',')
147189
tab.pop(0)
@@ -153,13 +195,22 @@ def search_entity(l,entity):
153195
employeeNumber=find_key(entity,'employeeNumber')
154196
employeeType=find_key(entity,'employeeType')
155197
base=config('base')
156-
filter='(&(employeeNumber=' + employeeNumber + ')(employeeType=' + employeeType + '))'
198+
if config('searchFilter',''):
199+
data = {
200+
'e': make_entry_array(entity),
201+
}
202+
template = jinja2.Environment(loader=jinja2.BaseLoader()).from_string(config('searchFilter'))
203+
filter = template.render(data)
204+
205+
206+
else:
207+
filter='(&(employeeNumber=' + employeeNumber + ')(employeeType=' + employeeType + '))'
157208
try:
158209
r=l.search_s(base,ldap.SCOPE_SUBTREE,filter)
159210
return r
160211
except ldap.LDAPError as e:
161212
e_dict = e.args[0]
162-
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc")))
213+
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc") + " " + e_dict.get("info")))
163214
exit(1)
164215

165216
def upsert_entry(l,entity):
@@ -170,44 +221,50 @@ def upsert_entry(l,entity):
170221
#creation de la liste
171222
entry=make_entry_array_without_empty(entity)
172223
## Ajout objectclass
173-
entry['objectclass']=make_objectclass(entity)
224+
entry['objectclass']=make_objectclass(entity,r)
174225
dn=compose_dn(entity)
175226
ldif = modlist.addModlist(convert_to_utf8(entry))
176227
try:
177228
action="add"
178229
l.add_s(dn, ldif)
179230
except ldap.LDAPError as e:
180231
e_dict = e.args[0]
181-
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc")))
232+
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc") + " "+ e_dict.get("info")))
182233
exit(1)
183234
else:
184235
if len(r) > 1:
185236
print(returncode(1,"many identities found"))
186237
exit(1)
187238
entry=make_entry_array_without_empty(entity);
188-
entry['objectclass'] = make_objectclass(entity)
239+
entry=complete_entry(entry,r);
240+
241+
entry['objectclass'] = make_objectclass(entity,r)
189242
entry = convert_to_utf8(entry)
190-
ldif = modlist.modifyModlist(r[0][1],entry)
243+
old_entry=normalize_entry(r[0][1])
244+
ldif = modlist.modifyModlist(old_entry,entry)
191245
dn = compose_dn(entity)
192-
if dn == r[0][0]:
246+
#dn= r[0][0]
247+
if dn_superior(dn) == dn_superior(r[0][0]):
193248
try:
194249
action="mod"
195-
l.modify_s(dn,ldif)
250+
l.modify_s(r[0][0],ldif)
196251
except ldap.LDAPError as e:
197252
e_dict = e.args[0]
198-
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc")))
253+
print(returncode(1, 'mod ' + str(e_dict.get("result")) + ' ' + e_dict.get("desc") + " "+ e_dict.get("info")))
199254
exit(1)
200255
else:
201256
## changement du DN
202257
oldDn=r[0][0]
203-
rdn=compose_rdn(entity)
258+
rdn=get_rdn_attribure(oldDn)
259+
rdnValue=entry[rdn][0].decode('UTF-8')
260+
new_rdn=rdn +"="+rdnValue
204261
newSuperior=dn_superior(compose_dn(entity))
205262
try:
206263
action="rename"
207-
l.rename_s(oldDn,rdn,newSuperior)
264+
l.rename_s(oldDn,new_rdn,newSuperior)
208265
except ldap.LDAPError as e:
209266
e_dict = e.args[0]
210-
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc")))
267+
print(returncode(1, 'rename ' + str(e_dict.get("result")) + ' ' + e_dict.get("desc") + " "+ e_dict.get("info")))
211268
exit(1)
212269
return returncode(0,"Entree " + dn + " " + action)
213270

@@ -226,15 +283,15 @@ def change_password(l,uid,old,new):
226283
l.passwd_s(r[0][0],old,new)
227284
except ldap.LDAPError as e:
228285
e_dict = e.args[0]
229-
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc")))
286+
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc") + " "+ e_dict.get("info")))
230287
exit(1)
231288
else:
232289
ldif=[(ldap.MOD_REPLACE, 'userPassword', [new.encode('utf-8')])]
233290
try:
234291
l.modify_s(r[0][0], ldif)
235292
except ldap.LDAPError as e:
236293
e_dict = e.args[0]
237-
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc")))
294+
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc") + " "+ e_dict.get("info")))
238295
exit(1)
239296

240297
def change_entity_password(l,entity):
@@ -271,9 +328,31 @@ def delete_entity(l,entity):
271328
return returncode(0, "user : " + r[0][0] + " deleted")
272329
except ldap.LDAPError as e:
273330
e_dict = e.args[0]
274-
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc")))
331+
print(returncode(1, str(e_dict.get("result")) + ' ' + e_dict.get("desc") + " "+ e_dict.get("info")))
275332
exit(1)
276333
else:
277334
print(returncode(1, "User not found"))
278335
exit(1)
336+
def complete_entry(entry,r):
337+
for cle,valeur in r[0][1].items():
338+
if cle.lower() != 'objectclass':
339+
if cle not in entry:
340+
if type(valeur) is list:
341+
for i in valeur:
342+
x=i.decode('UTF-8')
343+
if len(x) == 1:
344+
v=x[0]
345+
else:
346+
v=x
347+
entry[cle.lower()]=v
348+
return entry
279349

350+
def normalize_entry(entry):
351+
e={}
352+
for cle, valeur in entry.items():
353+
e[cle.lower()]=valeur
354+
return e
355+
def get_rdn_attribure(dn):
356+
dnTab=dn.split(',')
357+
attr=dnTab[0].split('=')
358+
return attr[0]

0 commit comments

Comments
 (0)