From 59a6440c31ac084cc4552a78a46120c39c7f3622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Tue, 21 Jan 2020 06:54:35 +0100 Subject: [PATCH] added flask ldapconn, fixed bug in login --- geruecht/__init__.py | 8 ++ geruecht/controller/ldapController.py | 123 +++++++++++++------------- geruecht/controller/userController.py | 2 +- geruecht/routes.py | 2 + 4 files changed, 72 insertions(+), 63 deletions(-) diff --git a/geruecht/__init__.py b/geruecht/__init__.py index af71892..0963dd8 100644 --- a/geruecht/__init__.py +++ b/geruecht/__init__.py @@ -7,6 +7,7 @@ from .logger import getLogger from geruecht.controller import dbConfig from flask_mysqldb import MySQL +from flask_ldapconn import LDAPConn LOGGER = getLogger(__name__) LOGGER.info("Initialize App") @@ -23,6 +24,13 @@ app.config['MYSQL_USER'] = dbConfig['user'] app.config['MYSQL_PASSWORD'] = dbConfig['passwd'] app.config['MYSQL_DB'] = dbConfig['database'] app.config['MYSQL_CURSORCLASS'] = 'DictCursor' +app.config['LDAP_SERVER'] = '192.168.5.128' +app.config['LDAP_PORT'] = 389 +app.config['LDAP_BINDDN'] = 'dc=ldap,dc=example,dc=local' +app.config['LDAP_USE_TLS'] = False +app.config['FORCE_ATTRIBUTE_VALUE_AS_LIST'] = True + +ldap = LDAPConn(app) db = MySQL(app) from geruecht import routes diff --git a/geruecht/controller/ldapController.py b/geruecht/controller/ldapController.py index 7002f44..517cdfd 100644 --- a/geruecht/controller/ldapController.py +++ b/geruecht/controller/ldapController.py @@ -1,72 +1,68 @@ -import ldap +from geruecht import ldap +from ldap3 import SUBTREE, Connection from geruecht.model import MONEY, USER, GASTRO, BAR from geruecht.exceptions import PermissionDenied from . import Singleton +import traceback class LDAPController(metaclass=Singleton): ''' Authentification over LDAP. Create Account on-the-fly ''' - def __init__(self, url="ldap://192.168.5.108", dn='dc=ldap,dc=example,dc=local'): - self.url = url + def __init__(self, dn='dc=ldap,dc=example,dc=local'): self.dn = dn - self.connect() + self.ldap = ldap - def connect(self): - try: - self.client = ldap.initialize(self.url, bytes_mode=False) - except Exception as err: - raise err def login(self, username, password): - self.connect() try: - cn = self.client.search_s("ou=user,{}".format(self.dn), ldap.SCOPE_SUBTREE, 'uid={}'.format(username),['cn'])[0][1]['cn'][0].decode('utf-8') - self.client.bind_s("cn={},ou=user,{}".format(cn, self.dn), password) - self.client.unbind_s() - except: - self.client.unbind_s() - raise PermissionDenied("Invalid Password or Username") + retVal = self.ldap.authenticate(username, password, 'uid', self.dn) + if not retVal: + raise PermissionDenied("Invalid Password or Username") + except Exception as err: + traceback.print_exception(err) + raise PermissionDenied("Wrong username or password.") def getUserData(self, username): try: - self.connect() - search_data = self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'uid={}'.format(username), ['uid', 'givenName', 'sn', 'mail']) - retVal = search_data[0][1] - for k,v in retVal.items(): - retVal[k] = v[0].decode('utf-8') - retVal['dn'] = self.dn - retVal['firstname'] = retVal['givenName'] - retVal['lastname'] = retVal['sn'] + 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'] + retVal = { + 'dn': self.ldap.connection.response[0]['dn'], + 'firstname': user['givenName'][0], + 'lastname': user['sn'][0], + 'uid': username + } return retVal except: raise PermissionDenied("No User exists with this uid.") def getGroup(self, username): - retVal = [] - self.connect() - main_group_data = self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'uid={}'.format(username), ['gidNumber']) - if main_group_data: - main_group_number = main_group_data[0][1]['gidNumber'][0].decode('utf-8') - group_data = self.client.search_s('ou=group,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'gidNumber={}'.format(main_group_number), ['cn']) - if group_data: - group_name = group_data[0][1]['cn'][0].decode('utf-8') + 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'] + 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] if group_name == 'ldap-user': retVal.append(USER) - groups_data = self.client.search_s('ou=group,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'memberUID={}'.format(username), ['cn']) - for data in groups_data: - print(data[1]['cn'][0].decode('utf-8')) - group_name = data[1]['cn'][0].decode('utf-8') - if group_name == 'finanzer': - retVal.append(MONEY) - elif group_name == 'gastro': - retVal.append(GASTRO) - elif group_name == 'bar': - retVal.append(BAR) - return retVal + self.ldap.connection.search('ou=group,{}'.format(self.dn), '(memberUID={})'.format(username), SUBTREE, attributes=['cn']) + groups_data = self.ldap.connection.response + for data in groups_data: + group_name = data['attributes']['cn'][0] + if group_name == 'finanzer': + retVal.append(MONEY) + elif group_name == 'gastro': + retVal.append(GASTRO) + elif group_name == 'bar': + retVal.append(BAR) + return retVal + except Exception as err: + traceback.print_exception(err) def __isUserInList(self, list, username): help_list = [] @@ -77,19 +73,19 @@ class LDAPController(metaclass=Singleton): return False def getAllUser(self): - self.connect() retVal = [] - data = self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, attrlist=['uid', 'givenName', 'sn', 'mail']) + self.ldap.connection.search() + self.ldap.connection.search('ou=user,{}'.format(self.dn), '(uid=*)', SUBTREE, attributes=['uid', 'givenName', 'sn', 'mail']) + data = self.ldap.connection.response for user in data: - if 'uid' in user[1]: - username = user[1]['uid'][0].decode('utf-8') - firstname = user[1]['givenName'][0].decode('utf-8') - lastname = user[1]['sn'][0].decode('utf-8') + 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}) return retVal def searchUser(self, searchString): - self.connect() name = searchString.split(" ") @@ -103,25 +99,28 @@ class LDAPController(metaclass=Singleton): if len(name) == 1: if name[0] == "**": - name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, - attrlist=['uid', 'givenName', 'sn'])) + self.ldap.connection.search('ou=user,{}'.format(self.dn), '(uid=*)', SUBTREE, + attributes=['uid', 'givenName', 'sn']) + name_result.append(self.ldap.connection.response) else: - name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'givenName={}'.format(name[0]), ['uid', 'givenName', 'sn', 'mail'])) - name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'sn={}'.format(name[0]),['uid', 'givenName', 'sn'], 'mail')) + 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: - name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, - 'givenName={}'.format(name[1]), ['uid', 'givenName', 'sn'])) - name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'sn={}'.format(name[1]), - ['uid', 'givenName', 'sn', 'mail'])) + 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[1]: - username = user[1]['uid'][0].decode('utf-8') + if 'uid' in user['attributes']: + username = user['attributes']['uid'][0] if not self.__isUserInList(retVal, username): - firstname = user[1]['givenName'][0].decode('utf-8') - lastname = user[1]['sn'][0].decode('utf-8') + firstname = user['attributes']['givenName'][0] + lastname = user['attributes']['sn'][0] retVal.append({'username': username, 'firstname': firstname, 'lastname': lastname}) return retVal diff --git a/geruecht/controller/userController.py b/geruecht/controller/userController.py index 1590749..97a94cb 100644 --- a/geruecht/controller/userController.py +++ b/geruecht/controller/userController.py @@ -7,7 +7,7 @@ from geruecht.exceptions import PermissionDenied from datetime import datetime, timedelta db = dc.DatabaseController() -ldap = lc.LDAPController(ldapConfig['URL'], ldapConfig['dn']) +ldap = lc.LDAPController(ldapConfig['dn']) emailController = ec.EmailController(mailConfig['URL'], mailConfig['user'], mailConfig['passwd'], mailConfig['port'], mailConfig['email']) class UserController(metaclass=Singleton): diff --git a/geruecht/routes.py b/geruecht/routes.py index daf8d78..9b7fa6b 100644 --- a/geruecht/routes.py +++ b/geruecht/routes.py @@ -58,5 +58,7 @@ def _login(): return jsonify(dic) except PermissionDenied as err: return jsonify({"error": str(err)}), 401 + except Exception: + return jsonify({"error": "permission denied"}), 401 LOGGER.info("User {} does not exist.".format(username)) return jsonify({"error": "wrong username"}), 401