flaschengeist/geruecht/controller/ldapController.py

203 lines
9.2 KiB
Python

from geruecht import ldap
from ldap3 import SUBTREE, MODIFY_REPLACE, HASHED_SALTED_MD5
from ldap3.utils.hashed import hashed
from geruecht.model import MONEY, USER, GASTRO, BAR, VORSTAND, EXTERN
from geruecht.exceptions import PermissionDenied
from . import Singleton
from geruecht.exceptions import UsernameExistLDAP, LDAPExcetpion
from geruecht import ldapConfig
from geruecht.logger import getDebugLogger
debug = getDebugLogger()
class LDAPController(metaclass=Singleton):
'''
Authentification over LDAP. Create Account on-the-fly
'''
def __init__(self):
debug.info("init ldap controller")
self.dn = ldapConfig['dn']
self.ldap = ldap
debug.debug("base dn is {{ {} }}".format(self.dn))
debug.debug("ldap is {{ {} }}".format(self.ldap))
def login(self, username, password):
debug.info("login user {{ {} }} in ldap")
try:
retVal = self.ldap.authenticate(username, password, 'uid', self.dn)
debug.debug("authentification to ldap is {{ {} }}".format(retVal))
if not retVal:
debug.debug("authenification is incorrect")
raise PermissionDenied("Invalid Password or Username")
except Exception as err:
debug.warning("exception while login into ldap", exc_info=True)
raise PermissionDenied("Invalid Password or Username. {}".format(err))
def bind(self, user, password):
debug.info("bind user {{ {} }} to ldap")
ldap_conn = self.ldap.connect(user.dn, password)
debug.debug("ldap_conn is {{ {} }}".format(ldap_conn))
return ldap_conn
def getUserData(self, username):
debug.info("get user data from ldap of user {{ {} }}".format(username))
try:
debug.debug("search user in ldap")
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(uid={})'.format(username), SUBTREE, attributes=['uid', 'givenName', 'sn', 'mail'])
user = self.ldap.connection.response[0]['attributes']
debug.debug("user is {{ {} }}".format(user))
retVal = {
'dn': self.ldap.connection.response[0]['dn'],
'firstname': user['givenName'][0],
'lastname': user['sn'][0],
'uid': user['uid'][0],
}
if user['mail']:
retVal['mail'] = user['mail'][0]
debug.debug("user is {{ {} }}".format(retVal))
if retVal['uid'] == username:
return retVal
else:
raise Exception()
except:
debug.warning("exception in get user data from ldap", exc_info=True)
raise PermissionDenied("No User exists with this uid.")
def getGroup(self, username):
debug.info("get group from user {{ {} }}".format(username))
try:
retVal = []
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(uid={})'.format(username), SUBTREE, attributes=['gidNumber'])
main_group_number = self.ldap.connection.response[0]['attributes']['gidNumber']
debug.debug("main group number is {{ {} }}".format(main_group_number))
if main_group_number:
if type(main_group_number) is list:
main_group_number = main_group_number[0]
self.ldap.connection.search('ou=group,{}'.format(self.dn), '(gidNumber={})'.format(main_group_number), attributes=['cn'])
group_name = self.ldap.connection.response[0]['attributes']['cn'][0]
debug.debug("group name is {{ {} }}".format(group_name))
if group_name == 'ldap-user':
retVal.append(USER)
if group_name == 'extern':
retVal.append(EXTERN)
self.ldap.connection.search('ou=group,{}'.format(self.dn), '(memberUID={})'.format(username), SUBTREE, attributes=['cn'])
groups_data = self.ldap.connection.response
debug.debug("groups number is {{ {} }}".format(groups_data))
for data in groups_data:
group_name = data['attributes']['cn'][0]
debug.debug("group name is {{ {} }}".format(group_name))
if group_name == 'finanzer':
retVal.append(MONEY)
elif group_name == 'gastro':
retVal.append(GASTRO)
elif group_name == 'bar':
retVal.append(BAR)
elif group_name == 'vorstand':
retVal.append(VORSTAND)
debug.debug("groups are {{ {} }}".format(retVal))
return retVal
except Exception as err:
debug.warning("exception in get groups from ldap", exc_info=True)
raise LDAPExcetpion(str(err))
def __isUserInList(self, list, username):
help_list = []
for user in list:
help_list.append(user['username'])
if username in help_list:
return True
return False
def getAllUser(self):
debug.info("get all users from ldap")
retVal = []
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(uid=*)', SUBTREE, attributes=['uid', 'givenName', 'sn', 'mail'])
data = self.ldap.connection.response
debug.debug("data is {{ {} }}".format(data))
for user in data:
if 'uid' in user['attributes']:
username = user['attributes']['uid'][0]
firstname = user['attributes']['givenName'][0]
lastname = user['attributes']['sn'][0]
retVal.append({'username': username, 'firstname': firstname, 'lastname': lastname})
debug.debug("users are {{ {} }}".format(retVal))
return retVal
def searchUser(self, searchString):
name = searchString.split(" ")
for i in range(len(name)):
name[i] = "*"+name[i]+"*"
print(name)
name_result = []
if len(name) == 1:
if name[0] == "**":
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(uid=*)', SUBTREE,
attributes=['uid', 'givenName', 'sn'])
name_result.append(self.ldap.connection.response)
else:
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(givenName={})'.format(name[0]), SUBTREE, attributes=['uid', 'givenName', 'sn', 'mail'])
name_result.append(self.ldap.connection.response)
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(sn={})'.format(name[0]), SUBTREE, attributes=['uid', 'givenName', 'sn', 'mail'])
name_result.append(self.ldap.connection.response)
else:
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(givenName={})'.format(name[1]), SUBTREE, attributes=['uid', 'givenName', 'sn'])
name_result.append(self.ldap.connection.response)
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(sn={})'.format(name[1]), SUBTREE, attributes=['uid', 'givenName', 'sn', 'mail'])
name_result.append(self.ldap.connection.response)
retVal = []
for names in name_result:
for user in names:
if 'uid' in user['attributes']:
username = user['attributes']['uid'][0]
if not self.__isUserInList(retVal, username):
firstname = user['attributes']['givenName'][0]
lastname = user['attributes']['sn'][0]
retVal.append({'username': username, 'firstname': firstname, 'lastname': lastname})
return retVal
def modifyUser(self, user, conn, attributes):
debug.info("modify ldap data from user {{ {} }} with attributes {{ {} }}".format(user, attributes))
try:
if 'username' in attributes:
debug.debug("change username")
conn.search('ou=user,{}'.format(self.dn), '(uid={})'.format(attributes['username']))
if conn.entries:
debug.warning("username already exists", exc_info=True)
raise UsernameExistLDAP("Username already exists in LDAP")
#create modifyer
mody = {}
if 'username' in attributes:
mody['uid'] = [(MODIFY_REPLACE, [attributes['username']])]
if 'firstname' in attributes:
mody['givenName'] = [(MODIFY_REPLACE, [attributes['firstname']])]
if 'lastname' in attributes:
mody['sn'] = [(MODIFY_REPLACE, [attributes['lastname']])]
if 'mail' in attributes:
mody['mail'] = [(MODIFY_REPLACE, [attributes['mail']])]
if 'password' in attributes:
salted_password = hashed(HASHED_SALTED_MD5, attributes['password'])
mody['userPassword'] = [(MODIFY_REPLACE, [salted_password])]
debug.debug("modyfier are {{ {} }}".format(mody))
conn.modify(user.dn, mody)
except Exception as err:
debug.warning("exception in modify user data from ldap", exc_info=True)
raise LDAPExcetpion("Something went wrong in LDAP: {}".format(err))
if __name__ == '__main__':
a = LDAPController()
a.getUserData('jhille')