2013-10-24 21:27:15 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
import ldap
|
|
|
|
|
import copy
|
|
|
|
|
|
|
|
|
|
from django.conf import settings
|
2013-10-27 21:13:41 +01:00
|
|
|
from password_encryption import get_ldap_password
|
2013-10-24 21:27:15 +02:00
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
Example configuration:
|
|
|
|
|
|
|
|
|
|
CBASE_LDAP_URL = 'ldap://lea.cbrp3.c-base.org:389/'
|
|
|
|
|
CBASE_BASE_DN = 'ou=crew,dc=c-base,dc=org'
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def retrieve_member(request):
|
2013-10-27 21:13:41 +01:00
|
|
|
ldap_password = get_ldap_password(request)
|
|
|
|
|
session = dict(request.session)
|
|
|
|
|
print "session:", session
|
|
|
|
|
print "cookies:", request.COOKIES
|
|
|
|
|
return MemberValues(request.user.username, ldap_password)
|
2013-10-24 21:27:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class MemberValues(object):
|
|
|
|
|
"""
|
|
|
|
|
Dictionary-like abstraction of the c-base member attributes.
|
|
|
|
|
"""
|
|
|
|
|
def __init__(self, username, password):
|
|
|
|
|
self._username = username
|
|
|
|
|
self._password = password
|
|
|
|
|
self._old = self._get_user_values()
|
|
|
|
|
|
|
|
|
|
# Make a complete copy of the old values so we can later check
|
|
|
|
|
# which
|
|
|
|
|
self._new = copy.deepcopy(self._old)
|
|
|
|
|
|
|
|
|
|
def get(self, key, default=None):
|
2013-10-25 01:03:16 +02:00
|
|
|
value_list = self._new.get(key, default)
|
|
|
|
|
if value_list:
|
|
|
|
|
value = value_list[0]
|
|
|
|
|
else:
|
|
|
|
|
value = default
|
|
|
|
|
|
|
|
|
|
# Decode
|
2013-10-24 21:27:15 +02:00
|
|
|
if value == 'TRUE':
|
|
|
|
|
return True
|
|
|
|
|
elif value == 'FALSE':
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
def set(self, key, value):
|
2015-12-01 00:32:51 +01:00
|
|
|
if value == None:
|
|
|
|
|
self._new[key] = [None]
|
|
|
|
|
return
|
|
|
|
|
|
2013-10-24 21:27:15 +02:00
|
|
|
converted_value = value
|
|
|
|
|
if isinstance(value, bool):
|
|
|
|
|
if value == True:
|
|
|
|
|
converted_value = 'TRUE'
|
|
|
|
|
else:
|
|
|
|
|
converted_value = 'FALSE'
|
2015-12-01 00:32:51 +01:00
|
|
|
|
2013-10-24 21:27:15 +02:00
|
|
|
self._new[key] = [converted_value.encode('latin-1')]
|
|
|
|
|
|
|
|
|
|
def save(self):
|
|
|
|
|
"""
|
|
|
|
|
Save the values back to the LDAP server.
|
|
|
|
|
"""
|
|
|
|
|
dn = "uid=%s,ou=crew,dc=c-base,dc=org" % self._username
|
|
|
|
|
|
2013-10-26 20:06:42 +02:00
|
|
|
l = ldap.initialize(settings.CBASE_LDAP_URL)
|
2013-10-24 21:27:15 +02:00
|
|
|
l.simple_bind_s(dn, self._password)
|
|
|
|
|
|
|
|
|
|
mod_attrs = []
|
|
|
|
|
for new_key, new_value in self._new.items():
|
|
|
|
|
# Replace is the default.
|
|
|
|
|
action = ldap.MOD_REPLACE
|
|
|
|
|
if new_key not in self._old.keys():
|
|
|
|
|
action = ldap.MOD_ADD
|
|
|
|
|
mod_attrs.append((action, '%s' % new_key, new_value ))
|
|
|
|
|
continue
|
2015-12-01 00:32:51 +01:00
|
|
|
if self._old[new_key][0] != None and new_value == [None]:
|
|
|
|
|
action = ldap.MOD_DELETE
|
|
|
|
|
mod_attrs.append((action, '%s' % new_key, []))
|
|
|
|
|
continue
|
2013-10-24 21:27:15 +02:00
|
|
|
# Set the attribute and wait for the LDAP server to complete.
|
|
|
|
|
if self._old[new_key][0] != new_value[0]:
|
|
|
|
|
action = ldap.MOD_REPLACE
|
|
|
|
|
mod_attrs.append((action, '%s' % new_key, new_value ))
|
|
|
|
|
continue
|
|
|
|
|
|
2015-12-01 00:32:51 +01:00
|
|
|
|
2013-10-24 21:27:15 +02:00
|
|
|
print "modattrs: ",mod_attrs
|
|
|
|
|
result = l.modify_s(dn, mod_attrs)
|
2013-10-27 21:13:41 +01:00
|
|
|
#
|
|
|
|
|
# print "result is: ", result
|
2013-10-26 20:06:42 +02:00
|
|
|
l.unbind_s()
|
|
|
|
|
|
|
|
|
|
def change_password(self, new_password):
|
|
|
|
|
"""
|
|
|
|
|
Change the password of the member.
|
|
|
|
|
You do not need to call save() after calling change_password().
|
|
|
|
|
"""
|
|
|
|
|
l = ldap.initialize(settings.CBASE_LDAP_URL)
|
|
|
|
|
user_dn = self._get_bind_dn()
|
|
|
|
|
l.simple_bind_s(user_dn, self._password)
|
|
|
|
|
l.passwd_s(user_dn, self._password, new_password)
|
|
|
|
|
l.unbind_s()
|
2013-10-24 21:27:15 +02:00
|
|
|
|
2013-10-25 01:03:16 +02:00
|
|
|
def to_dict(self):
|
|
|
|
|
result = {}
|
|
|
|
|
for key, value in self._new.items():
|
|
|
|
|
result[key] = self.get(key)
|
|
|
|
|
return result
|
|
|
|
|
|
2013-10-26 22:40:47 +02:00
|
|
|
def _get_bind_dn(self, username=None):
|
2013-10-24 21:27:15 +02:00
|
|
|
"""
|
|
|
|
|
Adds the uid=userid, to the base dn and returns that.
|
|
|
|
|
"""
|
2013-10-26 22:40:47 +02:00
|
|
|
if not username:
|
|
|
|
|
bind_dn = 'uid=%s,' % self._username
|
|
|
|
|
else:
|
|
|
|
|
bind_dn = 'uid=%s,' % username
|
2013-10-24 21:27:15 +02:00
|
|
|
bind_dn += settings.CBASE_BASE_DN
|
|
|
|
|
return bind_dn
|
|
|
|
|
|
|
|
|
|
def _get_user_values(self):
|
|
|
|
|
"""
|
|
|
|
|
Get an attribute from the ldap storage.
|
|
|
|
|
"""
|
|
|
|
|
# Create a new LDAP bind (aka connection or session)
|
|
|
|
|
session = ldap.initialize(settings.CBASE_LDAP_URL)
|
|
|
|
|
session.simple_bind_s(self._get_bind_dn(), self._password)
|
|
|
|
|
|
|
|
|
|
# Set the attribute and wait for the LDAP server to complete.
|
|
|
|
|
searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
|
|
|
|
|
# retrieve all attributes
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
searchFilter = "uid=%s" % self._username
|
|
|
|
|
|
|
|
|
|
dn = settings.CBASE_BASE_DN
|
|
|
|
|
result = session.search_s(dn, searchScope, searchFilter, retrieveAttributes)
|
|
|
|
|
# TODO: latin1
|
|
|
|
|
print "result is: ", result
|
|
|
|
|
# TODO: if len(result)==0
|
2013-10-26 20:06:42 +02:00
|
|
|
session.unbind_s()
|
2013-10-26 22:40:47 +02:00
|
|
|
return result[0][1]
|
|
|
|
|
|
|
|
|
|
def admin_change_password(self, username, new_password):
|
|
|
|
|
"""
|
|
|
|
|
Change the password of the member.
|
|
|
|
|
You do not need to call save() after calling change_password().
|
|
|
|
|
"""
|
|
|
|
|
l = ldap.initialize(settings.CBASE_LDAP_URL)
|
|
|
|
|
user_dn = self._get_bind_dn()
|
|
|
|
|
l.simple_bind_s(user_dn, self._password)
|
|
|
|
|
l.passwd_s(self._get_bind_dn(username), None, new_password)
|
|
|
|
|
l.unbind_s()
|
|
|
|
|
|
2013-10-29 04:20:52 +01:00
|
|
|
def get_number_of_members(self):
|
|
|
|
|
"""
|
|
|
|
|
Returns the total number of c-base members with active user accounts.
|
|
|
|
|
"""
|
|
|
|
|
return len(self.list_users())
|
|
|
|
|
|
2013-10-26 22:40:47 +02:00
|
|
|
def list_users(self):
|
2013-10-29 04:20:52 +01:00
|
|
|
"""
|
|
|
|
|
Returns a list of strings with all usernames in the group 'crew'.
|
|
|
|
|
The list is sorted alphabetically.
|
|
|
|
|
"""
|
2013-10-26 22:40:47 +02:00
|
|
|
l = ldap.initialize(settings.CBASE_LDAP_URL)
|
|
|
|
|
user_dn = self._get_bind_dn()
|
|
|
|
|
l.simple_bind_s(user_dn, self._password)
|
|
|
|
|
try:
|
2013-10-29 04:20:52 +01:00
|
|
|
result_id = l.search(settings.CBASE_BASE_DN, ldap.SCOPE_SUBTREE,
|
|
|
|
|
"memberOf=cn=crew,ou=groups,dc=c-base,dc=org", None)
|
2013-10-26 22:40:47 +02:00
|
|
|
result_set = []
|
2013-10-29 04:20:52 +01:00
|
|
|
while True:
|
|
|
|
|
result_type, result_data = l.result(result_id, 0)
|
2013-10-26 22:40:47 +02:00
|
|
|
if (result_data == []):
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
if result_type == ldap.RES_SEARCH_ENTRY:
|
|
|
|
|
result_set.append(result_data)
|
|
|
|
|
|
2013-11-12 21:28:00 +01:00
|
|
|
# list comprehension to get a list of user tupels in the format ("nickname", "nickname (real name)")
|
2015-09-26 17:54:04 +02:00
|
|
|
userlist = [(x[0][1]['uid'][0], '%s (%s, %s)' % (x[0][1]['uid'][0], x[0][1]['cn'][0], x[0][1]['uidNumber'][0])) for x in result_set]
|
2013-10-26 22:40:47 +02:00
|
|
|
return sorted(userlist)
|
|
|
|
|
except:
|
2015-09-26 17:54:04 +02:00
|
|
|
return []
|