Ajout de fichiers de debug (scripts + LDIF) et de commentaires
This commit is contained in:
parent
93b9f9eb04
commit
63aee89a41
|
@ -14,48 +14,56 @@ scope = ldap.SCOPE_SUBTREE
|
|||
|
||||
@csrf_exempt
|
||||
def index(request):
|
||||
#return HttpResponse(request.scheme+" "+request.method+"\n"+request.body)
|
||||
|
||||
# SAML assertions are XML files:
|
||||
identity = ParseSAML(request.body)
|
||||
|
||||
#return HttpResponse(str(identity))
|
||||
# Do no add an already-existing user
|
||||
if LDAPInDirectory(identity):
|
||||
return HttpResponse("Utilisateur deja present")
|
||||
else:
|
||||
# We need to format the entry before adding it
|
||||
# in the LDAP directory
|
||||
return HttpResponse(LDAPAddEntry(identity))
|
||||
#return HttpResponse("Demande prise en compte")
|
||||
# return HttpResponse(LDAPInDirectory(identity))
|
||||
|
||||
|
||||
def ParseSAML(saml_assert):
|
||||
#SAML namespaces
|
||||
# XML namespaces defined in the sample SAML assertion:
|
||||
ns = {'saml' : 'urn:oasis:names:tc:SAML:2.0:assertion',
|
||||
'xs' : 'http://www.w3.org/2001/XMLSchema',
|
||||
'xsi' : 'http://www.w3.org/2001/XMLSchema-instance'}
|
||||
|
||||
#Identity dictionary
|
||||
# Identity dictionary
|
||||
id = {'first_name' : '',
|
||||
'last_name' : '',
|
||||
'urn:oid:1.3.6.1.4.1.5923.1.1.1.6' : ''} #EPPN
|
||||
|
||||
tree = ET.fromstring(saml_assert)
|
||||
|
||||
# Get all saml:Attribute nodes
|
||||
# i.e. nodes under saml:AttributeStatement
|
||||
for node in tree.find('saml:AttributeStatement', ns):
|
||||
# We need to fill the dictionary
|
||||
if id.has_key(node.get('Name')):
|
||||
id[node.get('Name')] = node.find('saml:AttributeValue',
|
||||
ns).text.strip()
|
||||
|
||||
# The saml:NameID node is located under saml:Subject:
|
||||
subject = tree.find('saml:Subject', ns)
|
||||
id['NameID'] = subject.find('saml:NameID', ns).text.strip()
|
||||
|
||||
return id
|
||||
|
||||
def LDAPInit():
|
||||
# The server's hostname:
|
||||
server = "spare.entrouvert.lan"
|
||||
# Admin DN:
|
||||
who = "cn=admin,dc=entrouvert,dc=lan"
|
||||
# Credentials: XXX
|
||||
cred = "test"
|
||||
|
||||
l = ldap.open(server)
|
||||
#l.protocol_version = ldap.VERSION3
|
||||
#l.protocol_version = ldap.VERSION3 # Unnecessary here
|
||||
if l.simple_bind(who, cred):
|
||||
return l
|
||||
else:
|
||||
|
@ -65,29 +73,37 @@ def LDAPTerminate(l):
|
|||
l.unbind()
|
||||
|
||||
def LDAPInDirectory(id):
|
||||
#filter = "uid="+id['NameID']
|
||||
# The way we derive UIDs from the id dict
|
||||
# is defined in LDAPCraftUid:
|
||||
filter = "uid="+LDAPCraftUid(id)
|
||||
#filter = "uid=ahel"
|
||||
|
||||
l = LDAPInit()
|
||||
|
||||
# Look for a user possessing the same uid:
|
||||
res = l.search(base, scope, filter, None)
|
||||
rtype, rdata = l.result(res, 0)
|
||||
|
||||
LDAPTerminate(l)
|
||||
|
||||
# Does this user already is in the LDAP directory ?
|
||||
return 1 if rdata else 0
|
||||
|
||||
def LDAPGetMaxUIDNumber():
|
||||
l = LDAPInit()
|
||||
|
||||
ret = 0
|
||||
|
||||
# We need to iterate the whole user list in
|
||||
# the default base DN:
|
||||
res = l.search(base, scope, '(uid=*)', None)
|
||||
rtype, rdata = l.result(res, 0)
|
||||
|
||||
# Let's assume UIDs are strictly positive numbers:
|
||||
uidNumber = 0
|
||||
#ret = ret+"\n"+str(rdata)
|
||||
|
||||
# rdata is non-empty as long as there are still
|
||||
# some entries to iterate over:
|
||||
while rdata :
|
||||
un = int(rdata[0][1]['uidNumber'][0])
|
||||
# Let's get the highest UID:
|
||||
if un > uidNumber:
|
||||
uidNumber = un
|
||||
rtype, rdata = l.result(res, 0)
|
||||
|
@ -96,24 +112,29 @@ def LDAPGetMaxUIDNumber():
|
|||
return uidNumber
|
||||
|
||||
def LDAPCraftUid(id):
|
||||
## uid-crafting rule define here
|
||||
# uid-crafting rules defined here:
|
||||
# uid derived from login
|
||||
# ex : login ="john.doe", uid = "jdoe"
|
||||
login = id['urn:oid:1.3.6.1.4.1.5923.1.1.1.6'].split('@')[0]
|
||||
#uid derived from login
|
||||
#ex : login ="john.doe", uid = "jdoe"
|
||||
|
||||
parts = login.split(".")
|
||||
# In case some logins already are valid UIDs:
|
||||
if len(parts) == 1:
|
||||
return parts[0]
|
||||
# see above for the rule applied here:
|
||||
else:
|
||||
return parts[0][0]+parts[1]
|
||||
#uid = id['NameID']
|
||||
|
||||
|
||||
def LDAPAddEntry(id):
|
||||
# uid and uidNumber on-the-fly production:
|
||||
uidNumber = LDAPGetMaxUIDNumber()+1
|
||||
uid = LDAPCraftUid(id)
|
||||
|
||||
# The to-be-added entry DN.
|
||||
# the "dn: " prefix musn't appear here:
|
||||
dn = 'uid='+uid+","+base
|
||||
|
||||
# All the entry attributes can be defind in a dictionary as below:
|
||||
addmod = {}
|
||||
addmod['objectClass'] = ['inetOrgPerson', 'organizationalPerson', 'person', 'posixAccount', 'top']
|
||||
addmod['cn'] = id['first_name']+" "+id['last_name']
|
||||
|
@ -123,13 +144,14 @@ def LDAPAddEntry(id):
|
|||
addmod['sn'] = id['last_name']
|
||||
addmod['homeDirectory'] = "/home/"+uid
|
||||
|
||||
# From here we get an addModlist intelligible to python-ldap:
|
||||
ldif = modlist.addModlist(addmod)
|
||||
l = LDAPInit()
|
||||
s = " "
|
||||
#try:
|
||||
|
||||
# Do not forget the entry DN:
|
||||
ret = l.add_s(dn, ldif)
|
||||
#except ldap.LDAPError, e:
|
||||
# s = "error "+e
|
||||
|
||||
LDAPTerminate(l)
|
||||
|
||||
# Temporary debug output
|
||||
return str(dn)+"\n"+str(ldif)+"\n"+str(ret)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
dn: uid=jdoe,ou=People,dc=entrouvert,dc=lan
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: organizationalPerson
|
||||
objectClass: person
|
||||
objectClass: posixAccount
|
||||
objectClass: top
|
||||
cn: John Doe
|
||||
sn: Doe
|
||||
gidNumber: 1000
|
||||
uidNumber: 2000
|
||||
uid: jdoe
|
||||
homeDirectory: /home/jdoe
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
ldapsearch -D "cn=admin,dc=entrouvert,dc=lan" -w test -p 389 -h spare.entrouvert.lan -b "ou=People,dc=entrouvert,dc=lan" -s sub "(ObjectClass=*)" * +
|
||||
|
||||
ldapadd -x -D "cn=admin,dc=entrouvert,dc=lan" -w test -p 389 -h spare.entrouvert.lan -f ./manual_add.ldif
|
Reference in New Issue