From 16521a60c20c075c7bb91df8718de869b09d1dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Sun, 26 Jan 2020 23:31:22 +0100 Subject: [PATCH] added ldap modifying for users --- geruecht/controller/accesTokenController.py | 4 +-- geruecht/controller/databaseController.py | 15 +++++++++ geruecht/controller/ldapController.py | 34 ++++++++++++++++++++- geruecht/controller/userController.py | 24 ++++++++++++++- geruecht/exceptions/__init__.py | 8 +++++ geruecht/finanzer/routes.py | 1 + geruecht/model/accessToken.py | 4 ++- geruecht/model/user.py | 4 ++- geruecht/routes.py | 4 +-- geruecht/user/routes.py | 14 ++++++++- 10 files changed, 103 insertions(+), 9 deletions(-) diff --git a/geruecht/controller/accesTokenController.py b/geruecht/controller/accesTokenController.py index 160459e..b23e2d1 100644 --- a/geruecht/controller/accesTokenController.py +++ b/geruecht/controller/accesTokenController.py @@ -70,7 +70,7 @@ class AccesTokenController(metaclass=Singleton): LOGGER.info("Found no valid AccessToken with token: {} and group: {}".format(token, group)) return False - def createAccesToken(self, user): + def createAccesToken(self, user, ldap_conn): """ Create an AccessToken Create an AccessToken for an User and add it to the tokenList. @@ -85,7 +85,7 @@ class AccesTokenController(metaclass=Singleton): now = datetime.ctime(datetime.now()) token = hashlib.md5((now + user.dn).encode('utf-8')).hexdigest() self.checkBar(user) - accToken = AccessToken(user, token, datetime.now()) + accToken = AccessToken(user, token, ldap_conn, datetime.now()) LOGGER.debug("Add AccessToken {} to current Tokens".format(accToken)) self.tokenList.append(accToken) LOGGER.info("Finished create AccessToken {} with Token {}".format(accToken, token)) diff --git a/geruecht/controller/databaseController.py b/geruecht/controller/databaseController.py index 321610b..ae62453 100644 --- a/geruecht/controller/databaseController.py +++ b/geruecht/controller/databaseController.py @@ -4,6 +4,7 @@ from geruecht import db from geruecht.model.user import User from geruecht.model.creditList import CreditList from datetime import datetime, timedelta +from geruecht.exceptions import UsernameExistDB, DatabaseExecption import traceback class DatabaseController(metaclass=Singleton): @@ -152,6 +153,20 @@ class DatabaseController(metaclass=Singleton): except Exception as err: traceback.print_exc() + def changeUsername(self, user, newUsername): + try: + cursor= self.db.connection.cursor() + cursor.execute("select * from user where uid='{}'".format(newUsername)) + data = cursor.fetchall() + if data: + raise UsernameExistDB("Username already exists") + else: + cursor.execute("update user set uid='{}' where id={}".format(newUsername, user.id)) + self.db.connection() + except Exception as err: + traceback.print_exc() + raise DatabaseExecption("Something went worng with Datatabase: {}".format(err)) + if __name__ == '__main__': db = DatabaseController() user = db.getUser('jhille') diff --git a/geruecht/controller/ldapController.py b/geruecht/controller/ldapController.py index 517cdfd..40c95b3 100644 --- a/geruecht/controller/ldapController.py +++ b/geruecht/controller/ldapController.py @@ -1,8 +1,10 @@ from geruecht import ldap -from ldap3 import SUBTREE, Connection +from ldap3 import SUBTREE, MODIFY_REPLACE, HASHED_SALTED_MD5 +from ldap3.utils.hashed import hashed from geruecht.model import MONEY, USER, GASTRO, BAR from geruecht.exceptions import PermissionDenied from . import Singleton +from geruecht.exceptions import UsernameExistLDAP, LDAPExcetpion import traceback class LDAPController(metaclass=Singleton): @@ -24,6 +26,10 @@ class LDAPController(metaclass=Singleton): traceback.print_exception(err) raise PermissionDenied("Wrong username or password.") + def bind(self, user, password): + ldap_conn = self.ldap.connect(user.dn, password) + return ldap_conn + def getUserData(self, username): try: self.ldap.connection.search('ou=user,{}'.format(self.dn), '(uid={})'.format(username), SUBTREE, attributes=['uid', 'givenName', 'sn', 'mail']) @@ -43,6 +49,7 @@ class LDAPController(metaclass=Singleton): 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'] if main_group_number: group_data = self.ldap.connection.search('ou=group,{}'.format(self.dn), '(gidNumber={})'.format(main_group_number), attributes=['cn']) @@ -125,6 +132,31 @@ class LDAPController(metaclass=Singleton): return retVal + def modifyUser(self, user, conn, attributes): + try: + if 'username' in attributes: + conn.search('ou=user,{}'.format(self.dn), '(uid={})'.format(attributes['username'])) + if conn.entries: + 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])] + conn.modify(user.dn, mody) + except Exception as err: + traceback.print_exc() + raise LDAPExcetpion("Something went wrong in LDAP: {}".format(err)) + + if __name__ == '__main__': a = LDAPController() diff --git a/geruecht/controller/userController.py b/geruecht/controller/userController.py index 97a94cb..6d551c8 100644 --- a/geruecht/controller/userController.py +++ b/geruecht/controller/userController.py @@ -5,6 +5,7 @@ import geruecht.controller.emailController as ec from geruecht.model.user import User from geruecht.exceptions import PermissionDenied from datetime import datetime, timedelta +from geruecht.exceptions import UsernameExistLDAP, UsernameExistDB, DatabaseExecption, LDAPExcetpion db = dc.DatabaseController() ldap = lc.LDAPController(ldapConfig['dn']) @@ -128,10 +129,31 @@ class UserController(metaclass=Singleton): retVal.append(self.sendMail(user)) return retVal + def modifyUser(self, user, ldap_conn, attributes): + try: + if 'username' in attributes: + db.changeUsername(user, attributes['username']) + ldap.modifyUser(user, ldap_conn, attributes) + if 'username' in attributes: + return self.getUser(attributes['username']) + else: + return self.getUser(user.uid) + except UsernameExistLDAP as err: + db.changeUsername(user, user.uid) + raise Exception(err) + except LDAPExcetpion as err: + if 'username' in attributes: + db.changeUsername(user, user.uid) + raise Exception(err) + except Exception as err: + raise Exception(err) + def loginUser(self, username, password): try: user = self.getUser(username) + user.password = password ldap.login(username, password) - return user + ldap_conn = ldap.bind(user, password) + return user, ldap_conn except PermissionDenied as err: raise err diff --git a/geruecht/exceptions/__init__.py b/geruecht/exceptions/__init__.py index 30bba52..6aeaf8e 100644 --- a/geruecht/exceptions/__init__.py +++ b/geruecht/exceptions/__init__.py @@ -1,2 +1,10 @@ class PermissionDenied(Exception): + pass +class UsernameExistDB(Exception): + pass +class UsernameExistLDAP(Exception): + pass +class DatabaseExecption(Exception): + pass +class LDAPExcetpion(Exception): pass \ No newline at end of file diff --git a/geruecht/finanzer/routes.py b/geruecht/finanzer/routes.py index 92d7be1..d6f1a57 100644 --- a/geruecht/finanzer/routes.py +++ b/geruecht/finanzer/routes.py @@ -4,6 +4,7 @@ from datetime import datetime import geruecht.controller.userController as uc from geruecht.model import MONEY from geruecht.decorator import login_required +import time finanzer = Blueprint("finanzer", __name__) diff --git a/geruecht/model/accessToken.py b/geruecht/model/accessToken.py index 0718dc4..f63db6c 100644 --- a/geruecht/model/accessToken.py +++ b/geruecht/model/accessToken.py @@ -15,8 +15,9 @@ class AccessToken(): timestamp = None user = None token = None + ldap_conn = None - def __init__(self, user, token, timestamp=datetime.now()): + def __init__(self, user, token, ldap_conn, timestamp=datetime.now()): """ Initialize Class AccessToken No more to say. @@ -30,6 +31,7 @@ class AccessToken(): self.user = user self.timestamp = timestamp self.token = token + self.ldap_conn = ldap_conn def updateTimestamp(self): """ Update the Timestamp diff --git a/geruecht/model/user.py b/geruecht/model/user.py index 925ca37..23460fb 100644 --- a/geruecht/model/user.py +++ b/geruecht/model/user.py @@ -49,6 +49,7 @@ class User(): self.group = data['gruppe'].split(',') if 'creditLists' in data: self.geruechte = data['creditLists'] + self.password = '' def updateData(self, data): if 'dn' in data: @@ -204,7 +205,8 @@ class User(): "username": self.uid, "locked": self.locked, "autoLock": self.autoLock, - "limit": self.limit + "limit": self.limit, + "mail": self.mail } return dic diff --git a/geruecht/routes.py b/geruecht/routes.py index 9b7fa6b..bd71ea5 100644 --- a/geruecht/routes.py +++ b/geruecht/routes.py @@ -48,9 +48,9 @@ def _login(): password = data['password'] LOGGER.info("search {} in database".format(username)) try: - user = userController.loginUser(username, password) + user, ldap_conn = userController.loginUser(username, password) user.password = password - token = accesTokenController.createAccesToken(user) + token = accesTokenController.createAccesToken(user, ldap_conn) dic = accesTokenController.validateAccessToken(token, [USER]).user.toJSON() dic["token"] = token dic["accessToken"] = token diff --git a/geruecht/user/routes.py b/geruecht/user/routes.py index 5b30297..1ef4846 100644 --- a/geruecht/user/routes.py +++ b/geruecht/user/routes.py @@ -33,4 +33,16 @@ def _addAmount(**kwargs): retVal = accToken.user.toJSON() retVal['creditList'] = {credit.year: credit.toJSON() for credit in accToken.user.geruechte} return jsonify(retVal) - return jsonify({"error": "something went wrong"}), 500 \ No newline at end of file + return jsonify({"error": "something went wrong"}), 500 + +@user.route("/user/saveConfig", methods=['POST']) +@login_required(groups=[USER]) +def _saveConfig(**kwargs): + try: + if 'accToken' in kwargs: + accToken = kwargs['accToken'] + data = request.get_json() + accToken.user = userController.modifyUser(accToken.user, accToken.ldap_conn, data) + return jsonify(data) + except Exception as err: + return jsonify("error", err), 409 \ No newline at end of file