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': username, } if user['mail']: retVal['mail'] = user['mail'][0] debug.debug("user is {{ {} }}".format(retVal)) return retVal 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']) response = self.ldap.connection.response main_group_number = self.ldap.connection.response[0]['attributes']['gidNumber'] debug.debug("main group number is {{ {} }}".format(main_group_number)) if main_group_number: group_data = 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')