diff --git a/geruecht/baruser/routes.py b/geruecht/baruser/routes.py index 2ecfaff..f809622 100644 --- a/geruecht/baruser/routes.py +++ b/geruecht/baruser/routes.py @@ -30,7 +30,7 @@ def _bar(): month = geruecht.getMonth(datetime.now().month) amount = month[0] - month[1] all = geruecht.getSchulden() - if amount != 0: + if all != 0: if all >= 0: type = 'credit' else: @@ -106,7 +106,16 @@ def _getUser(): if accToken: data = request.get_json() username = data['userId'] - retVal = userController.getUser(username).toJSON() + user = userController.getUser(username) + amount = user.getGeruecht(datetime.now().year).getSchulden() + if amount >= 0: + type = 'credit' + else: + type = 'amount' + + retVal = user.toJSON() + retVal['amount'] = amount + retVal['type'] = type return jsonify(retVal) return jsonify("error", "permission denied"), 401 diff --git a/geruecht/config.yml b/geruecht/config.yml index 2b3e45b..3df779a 100644 --- a/geruecht/config.yml +++ b/geruecht/config.yml @@ -1,9 +1,9 @@ AccessTokenLifeTime: 1800 Database: - URL: 192.168.5.108 + URL: 192.168.5.128 user: wu5 passwd: E1n$tein database: geruecht LDAP: - URL: ldap://192.168.5.108 + URL: ldap://192.168.5.128 dn: dc=ldap,dc=example,dc=local \ No newline at end of file diff --git a/geruecht/configparser.py b/geruecht/configparser.py index ee945e0..247f23c 100644 --- a/geruecht/configparser.py +++ b/geruecht/configparser.py @@ -1,15 +1,68 @@ import yaml +import sys +from . import LOGGER + +default = { + 'AccessTokenLifeTime': 1800, + 'Mail': { + 'URL': '', + 'port': 0, + 'user': '', + 'passwd': '', + 'email': '' + } +} class ConifgParser(): def __init__(self, file='config.yml'): self.file = file with open(file, 'r') as f: - self.config = yaml.load(f) + self.config = yaml.safe_load(f) + + if 'Database' not in self.config: + self.__error__('Wrong Configuration for Database. You should configure databaseconfig with "URL", "user", "passwd", "database"') + if 'URL' not in self.config['Database'] or 'user' not in self.config['Database'] or 'passwd' not in self.config['Database'] or 'database' not in self.config['Database']: + self.__error__('Wrong Configuration for Database. You should configure databaseconfig with "URL", "user", "passwd", "database"') - print(self.config) self.db = self.config['Database'] + LOGGER.debug("Set Databaseconfig: {}".format(self.db)) + + if 'LDAP' not in self.config: + self.__error__('Wrong Configuration for LDAP. You should configure ldapconfig with "URL" and "dn"') + if 'URL' not in self.config['LDAP'] or 'dn' not in self.config['LDAP']: + self.__error__('Wrong Configuration for LDAP. You should configure ldapconfig with "URL" and "dn"') self.ldap = self.config['LDAP'] - self.accessTokenLifeTime = self.config['AccessTokenLifeTime'] + LOGGER.info("Set LDAPconfig: {}".format(self.ldap)) + if 'AccessTokenLifeTime' in self.config: + self.accessTokenLifeTime = self.config['AccessTokenLifeTime'] + LOGGER.info("Set AccessTokenLifeTime: {}".format(self.accessTokenLifeTime)) + else: + self.accessTokenLifeTime = default['AccessTokenLifeTime'] + LOGGER.info("No Config for AccessTokenLifetime found. Set it to default: {}".format(self.accessTokenLifeTime)) + + if 'Mail' not in self.config: + self.config['Mail'] = default['Mail'] + LOGGER.info('No Conifg for Mail found. Set it to defaul: {}'.format(self.config['Mail'])) + if 'URL' not in self.config['Mail']: + self.config['Mail']['URL'] = default['Mail']['URL'] + LOGGER.info("No Config for URL in Mail found. Set it to default") + if 'port' not in self.config['Mail']: + self.config['Mail']['port'] = default['Mail']['port'] + LOGGER.info("No Config for port in Mail found. Set it to default") + else: + self.config['Mail']['port'] = int(self.config['Mail']['port']) + if 'user' not in self.config['Mail']: + self.config['Mail']['user'] = default['Mail']['user'] + LOGGER.info("No Config for user in Mail found. Set it to default") + if 'passwd' not in self.config['Mail']: + self.config['Mail']['passwd'] = default['Mail']['passwd'] + LOGGER.info("No Config for passwd in Mail found. Set it to default") + if 'email' not in self.config['Mail']: + self.config['Mail']['email'] = default['Mail']['email'] + LOGGER.info("No Config for email in Mail found. Set it to default") + self.mail = self.config['Mail'] + LOGGER.info('Set Mailconfig: {}'.format(self.mail)) + def getLDAP(self): return self.ldap @@ -20,5 +73,12 @@ class ConifgParser(): def getAccessToken(self): return self.accessTokenLifeTime + def getMail(self): + return self.mail + + def __error__(self, msg): + LOGGER.error(msg) + sys.exit(-1) + if __name__ == '__main__': ConifgParser() \ No newline at end of file diff --git a/geruecht/controller/__init__.py b/geruecht/controller/__init__.py index efcc892..ed03c81 100644 --- a/geruecht/controller/__init__.py +++ b/geruecht/controller/__init__.py @@ -32,9 +32,12 @@ from .accesTokenController import AccesTokenController dbConfig = config.getDatabase() ldapConfig = config.getLDAP() accConfig = config.getAccessToken() +mailConfig = config.getMail() db = DatabaseController(dbConfig['URL'], dbConfig['user'], dbConfig['passwd'], dbConfig['database']) ldapController = LDAPController(ldapConfig['URL'], ldapConfig['dn']) accesTokenController = AccesTokenController(accConfig) +from . emailController import EmailController +emailController = EmailController(mailConfig['URL'], mailConfig['user'], mailConfig['passwd'], mailConfig['port'], mailConfig['email']) from . userController import UserController userController = UserController() \ No newline at end of file diff --git a/geruecht/controller/databaseController.py b/geruecht/controller/databaseController.py index 9d7fb68..f58cd6c 100644 --- a/geruecht/controller/databaseController.py +++ b/geruecht/controller/databaseController.py @@ -74,8 +74,8 @@ class DatabaseController(metaclass=Singleton): cursor = self.db.cursor() groups = self._convertGroupToString(user.group) try: - cursor.execute("insert into user (uid, dn, firstname, lastname, gruppe, lockLimit, locked, autoLock) VALUES ('{}','{}','{}','{}','{}',{},{},{})".format( - user.uid, user.dn, user.firstname, user.lastname, groups, user.limit, user.locked, user.autoLock)) + cursor.execute("insert into user (uid, dn, firstname, lastname, gruppe, lockLimit, locked, autoLock, mail) VALUES ('{}','{}','{}','{}','{}',{},{},{},'{}')".format( + user.uid, user.dn, user.firstname, user.lastname, groups, user.limit, user.locked, user.autoLock, user.mail)) self.db.commit() except Exception as err: self.db.rollback() @@ -88,8 +88,8 @@ class DatabaseController(metaclass=Singleton): cursor = self.db.cursor() groups = self._convertGroupToString(user.group) try: - sql = "update user set dn='{}', firstname='{}', lastname='{}', gruppe='{}', lockLimit={}, locked={}, autoLock={} where uid='{}'".format( - user.dn, user.firstname, user.lastname, groups, user.limit, user.locked, user.autoLock, user.uid) + sql = "update user set dn='{}', firstname='{}', lastname='{}', gruppe='{}', lockLimit={}, locked={}, autoLock={}, mail='{}' where uid='{}'".format( + user.dn, user.firstname, user.lastname, groups, user.limit, user.locked, user.autoLock, user.mail, user.uid) print(sql) cursor.execute(sql) self.db.commit() diff --git a/geruecht/controller/emailController.py b/geruecht/controller/emailController.py new file mode 100644 index 0000000..23882d8 --- /dev/null +++ b/geruecht/controller/emailController.py @@ -0,0 +1,49 @@ +import smtplib +from datetime import datetime +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +from email.header import Header +from . import LOGGER + +class EmailController(): + + def __init__(self, smtpServer, user, passwd, port = 587, email = ""): + self.smtpServer = smtpServer + self.port = port + self.user = user + self.passwd = passwd + if email: + self.email = email + else: + self.email = user + + def __connect__(self): + self.smtp = smtplib.SMTP(self.smtpServer, self.port) + self.smtp.starttls() + self.smtp.login(self.user, self.passwd) + + def sendMail(self, user): + try: + if user.mail == 'None' or not user.mail: + LOGGER.debug("cant send email to {}. Has no email-address. {}".format(user.uid, {'error': True, 'user': {'userId': user.uid, 'firstname': user.firstname, 'lastname': user.lastname}})) + raise Exception("no valid Email") + msg = MIMEMultipart() + msg['From'] = self.email + msg['To'] = user.mail + msg['Subject'] = Header('Gerücht, bezahle deine ￿Schulden!', 'utf-8') + sum = user.getGeruecht(datetime.now().year).getSchulden() + if sum < 0: + type = '￿Schulden' + add = 'Bezahle diese umgehend an den Finanzer.' + else: + type = 'Guthaben' + add = '' + text = MIMEText("Hallo {} {},\nDu hast {} im Wert von {:.2f} €. {}\n\nDiese Nachricht wurde automatisch erstellt.".format(user.firstname, user.lastname, type, abs(sum)/100, add), 'plain', 'utf-8') + msg.attach(text) + LOGGER.debug("Send email to {}: '{}'".format(user.uid, msg.as_string())) + self.__connect__() + self.smtp.sendmail(self.email, user.mail, msg.as_string()) + LOGGER.debug("Sended email to {}. {}".format(user.uid, {'error': False, 'user': {'userId': user.uid, 'firstname': user.firstname, 'lastname': user.lastname}})) + return {'error': False, 'user': {'userId': user.uid, 'firstname': user.firstname, 'lastname': user.lastname}} + except Exception: + return {'error': True, 'user': {'userId': user.uid, 'firstname': user.firstname, 'lastname': user.lastname}} \ No newline at end of file diff --git a/geruecht/controller/ldapController.py b/geruecht/controller/ldapController.py index 67ba4c0..7002f44 100644 --- a/geruecht/controller/ldapController.py +++ b/geruecht/controller/ldapController.py @@ -32,7 +32,7 @@ class LDAPController(metaclass=Singleton): 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']) + 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') @@ -79,7 +79,7 @@ class LDAPController(metaclass=Singleton): def getAllUser(self): self.connect() retVal = [] - data = self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, attrlist=['uid', 'givenName', 'sn']) + data = self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, attrlist=['uid', 'givenName', 'sn', 'mail']) for user in data: if 'uid' in user[1]: username = user[1]['uid'][0].decode('utf-8') @@ -106,13 +106,13 @@ class LDAPController(metaclass=Singleton): name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, attrlist=['uid', 'givenName', 'sn'])) else: - name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'givenName={}'.format(name[0]), ['uid', 'givenName', 'sn'])) - name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'sn={}'.format(name[0]),['uid', 'givenName', 'sn'])) + 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')) 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'])) + ['uid', 'givenName', 'sn', 'mail'])) retVal = [] for names in name_result: diff --git a/geruecht/controller/userController.py b/geruecht/controller/userController.py index fcf3d7e..f027816 100644 --- a/geruecht/controller/userController.py +++ b/geruecht/controller/userController.py @@ -1,4 +1,4 @@ -from . import LOGGER, Singleton, db, ldapController as ldap +from . import LOGGER, Singleton, db, ldapController as ldap, emailController from geruecht.model.user import User from geruecht.exceptions import PermissionDenied from datetime import datetime @@ -24,6 +24,7 @@ class UserController(metaclass=Singleton): if user.autoLock: if user.getGeruecht(year=datetime.now().year).getSchulden() <= (-1*user.limit): user.updateData({'locked': True}) + emailController.sendMail(user) else: user.updateData({'locked': False}) db.updateUser(user) @@ -48,6 +49,9 @@ class UserController(metaclass=Singleton): return user.getGeruecht(year) def getAllUsersfromDB(self): + users = db.getAllUser() + for user in users: + self.__updateGeruechte(user) return db.getAllUser() def getUser(self, username): @@ -63,8 +67,30 @@ class UserController(metaclass=Singleton): user.updateData(user_data) db.updateUser(user) user = db.getUser(username) + self.__updateGeruechte(user) return user + def __updateGeruechte(self, user): + user.getGeruecht(datetime.now().year) + creditLists = user.updateGeruecht() + if user.getGeruecht(datetime.now().year).getSchulden() != 0: + for creditList in creditLists: + db.updateCreditList(creditList) + + def sendMail(self, username): + if type(username) == User: + user = username + if type(username) == str: + user = db.getUser(username) + return emailController.sendMail(user) + + def sendAllMail(self): + retVal = [] + users = db.getAllUser() + for user in users: + retVal.append(self.sendMail(user)) + return retVal + def loginUser(self, username, password): try: user = self.getUser(username) diff --git a/geruecht/finanzer/routes.py b/geruecht/finanzer/routes.py index d72e2fc..4f1894d 100644 --- a/geruecht/finanzer/routes.py +++ b/geruecht/finanzer/routes.py @@ -170,4 +170,26 @@ def _finanzerAddUser(): dic[user.uid]['creditList'] = {credit.year: credit.toJSON() for credit in user.geruechte} LOGGER.debug("ReturnValue is {}".format(dic)) return jsonify(dic), 200 - return jsonify("error:" "permission denied"), 401 \ No newline at end of file + return jsonify({"error": "permission denied"}), 401 + +@finanzer.route("/finanzerSendOneMail", methods=['POST']) +def _finanzerSendOneMail(): + token = request.headers.get("Token") + accToken = accesTokenController.validateAccessToken(token, MONEY) + + if accToken: + data = request.get_json() + username = data['userId'] + retVal = userController.sendMail(username) + return jsonify(retVal) + return jsonify({"error:", "permission denied"}), 401 + +@finanzer.route("/finanzerSendAllMail", methods=['GET']) +def _finanzerSendAllMail(): + token = request.headers.get("Token") + accToken = accesTokenController.validateAccessToken(token, MONEY) + + if accToken: + retVal = userController.sendAllMail() + return jsonify(retVal) + return jsonify({"error": "permission denied"}), 401 \ No newline at end of file diff --git a/geruecht/model/user.py b/geruecht/model/user.py index 85c6b7a..925ca37 100644 --- a/geruecht/model/user.py +++ b/geruecht/model/user.py @@ -27,6 +27,10 @@ class User(): self.firstname = data['firstname'] self.lastname = data['lastname'] self.group = data['gruppe'] + if 'mail' in data: + self.mail = data['mail'] + else: + self.mail = '' if 'lockLimit' in data: self.limit = int(data['lockLimit']) else: @@ -61,6 +65,8 @@ class User(): self.locked = bool(data['locked']) if 'autoLock' in data: self.autoLock = bool(data['autoLock']) + if 'mail' in data: + self.mail = data['mail'] def initGeruechte(self, creditLists): if type(creditLists) == list: