added EmailController

with the emailController you can send automaticly emails, if a user is over the limit or if the finanzer send the emails
the configparser is updated. So you have to set database and ldapconfig. if accestokenlifetime and mailconfig is not set, the parser set default values.
This commit is contained in:
Tim Gröger 2020-01-05 14:15:02 +01:00
parent 9f40d2c93b
commit d0a9345d68
10 changed files with 193 additions and 18 deletions

View File

@ -30,7 +30,7 @@ def _bar():
month = geruecht.getMonth(datetime.now().month) month = geruecht.getMonth(datetime.now().month)
amount = month[0] - month[1] amount = month[0] - month[1]
all = geruecht.getSchulden() all = geruecht.getSchulden()
if amount != 0: if all != 0:
if all >= 0: if all >= 0:
type = 'credit' type = 'credit'
else: else:
@ -106,7 +106,16 @@ def _getUser():
if accToken: if accToken:
data = request.get_json() data = request.get_json()
username = data['userId'] 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(retVal)
return jsonify("error", "permission denied"), 401 return jsonify("error", "permission denied"), 401

View File

@ -1,9 +1,9 @@
AccessTokenLifeTime: 1800 AccessTokenLifeTime: 1800
Database: Database:
URL: 192.168.5.108 URL: 192.168.5.128
user: wu5 user: wu5
passwd: E1n$tein passwd: E1n$tein
database: geruecht database: geruecht
LDAP: LDAP:
URL: ldap://192.168.5.108 URL: ldap://192.168.5.128
dn: dc=ldap,dc=example,dc=local dn: dc=ldap,dc=example,dc=local

View File

@ -1,15 +1,68 @@
import yaml import yaml
import sys
from . import LOGGER
default = {
'AccessTokenLifeTime': 1800,
'Mail': {
'URL': '',
'port': 0,
'user': '',
'passwd': '',
'email': ''
}
}
class ConifgParser(): class ConifgParser():
def __init__(self, file='config.yml'): def __init__(self, file='config.yml'):
self.file = file self.file = file
with open(file, 'r') as f: 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'] 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.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): def getLDAP(self):
return self.ldap return self.ldap
@ -20,5 +73,12 @@ class ConifgParser():
def getAccessToken(self): def getAccessToken(self):
return self.accessTokenLifeTime return self.accessTokenLifeTime
def getMail(self):
return self.mail
def __error__(self, msg):
LOGGER.error(msg)
sys.exit(-1)
if __name__ == '__main__': if __name__ == '__main__':
ConifgParser() ConifgParser()

View File

@ -32,9 +32,12 @@ from .accesTokenController import AccesTokenController
dbConfig = config.getDatabase() dbConfig = config.getDatabase()
ldapConfig = config.getLDAP() ldapConfig = config.getLDAP()
accConfig = config.getAccessToken() accConfig = config.getAccessToken()
mailConfig = config.getMail()
db = DatabaseController(dbConfig['URL'], dbConfig['user'], dbConfig['passwd'], dbConfig['database']) db = DatabaseController(dbConfig['URL'], dbConfig['user'], dbConfig['passwd'], dbConfig['database'])
ldapController = LDAPController(ldapConfig['URL'], ldapConfig['dn']) ldapController = LDAPController(ldapConfig['URL'], ldapConfig['dn'])
accesTokenController = AccesTokenController(accConfig) accesTokenController = AccesTokenController(accConfig)
from . emailController import EmailController
emailController = EmailController(mailConfig['URL'], mailConfig['user'], mailConfig['passwd'], mailConfig['port'], mailConfig['email'])
from . userController import UserController from . userController import UserController
userController = UserController() userController = UserController()

View File

@ -74,8 +74,8 @@ class DatabaseController(metaclass=Singleton):
cursor = self.db.cursor() cursor = self.db.cursor()
groups = self._convertGroupToString(user.group) groups = self._convertGroupToString(user.group)
try: try:
cursor.execute("insert into user (uid, dn, firstname, lastname, gruppe, lockLimit, locked, autoLock) VALUES ('{}','{}','{}','{}','{}',{},{},{})".format( 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.uid, user.dn, user.firstname, user.lastname, groups, user.limit, user.locked, user.autoLock, user.mail))
self.db.commit() self.db.commit()
except Exception as err: except Exception as err:
self.db.rollback() self.db.rollback()
@ -88,8 +88,8 @@ class DatabaseController(metaclass=Singleton):
cursor = self.db.cursor() cursor = self.db.cursor()
groups = self._convertGroupToString(user.group) groups = self._convertGroupToString(user.group)
try: try:
sql = "update user set dn='{}', firstname='{}', lastname='{}', gruppe='{}', lockLimit={}, locked={}, autoLock={} where uid='{}'".format( 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.uid) user.dn, user.firstname, user.lastname, groups, user.limit, user.locked, user.autoLock, user.mail, user.uid)
print(sql) print(sql)
cursor.execute(sql) cursor.execute(sql)
self.db.commit() self.db.commit()

View File

@ -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}}

View File

@ -32,7 +32,7 @@ class LDAPController(metaclass=Singleton):
def getUserData(self, username): def getUserData(self, username):
try: try:
self.connect() 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] retVal = search_data[0][1]
for k,v in retVal.items(): for k,v in retVal.items():
retVal[k] = v[0].decode('utf-8') retVal[k] = v[0].decode('utf-8')
@ -79,7 +79,7 @@ class LDAPController(metaclass=Singleton):
def getAllUser(self): def getAllUser(self):
self.connect() self.connect()
retVal = [] 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: for user in data:
if 'uid' in user[1]: if 'uid' in user[1]:
username = user[1]['uid'][0].decode('utf-8') 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, name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE,
attrlist=['uid', 'givenName', 'sn'])) attrlist=['uid', 'givenName', 'sn']))
else: 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, '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'])) name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, 'sn={}'.format(name[0]),['uid', 'givenName', 'sn'], 'mail'))
else: else:
name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE, name_result.append(self.client.search_s('ou=user,{}'.format(self.dn), ldap.SCOPE_SUBTREE,
'givenName={}'.format(name[1]), ['uid', 'givenName', 'sn'])) '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]), 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 = [] retVal = []
for names in name_result: for names in name_result:

View File

@ -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.model.user import User
from geruecht.exceptions import PermissionDenied from geruecht.exceptions import PermissionDenied
from datetime import datetime from datetime import datetime
@ -24,6 +24,7 @@ class UserController(metaclass=Singleton):
if user.autoLock: if user.autoLock:
if user.getGeruecht(year=datetime.now().year).getSchulden() <= (-1*user.limit): if user.getGeruecht(year=datetime.now().year).getSchulden() <= (-1*user.limit):
user.updateData({'locked': True}) user.updateData({'locked': True})
emailController.sendMail(user)
else: else:
user.updateData({'locked': False}) user.updateData({'locked': False})
db.updateUser(user) db.updateUser(user)
@ -48,6 +49,9 @@ class UserController(metaclass=Singleton):
return user.getGeruecht(year) return user.getGeruecht(year)
def getAllUsersfromDB(self): def getAllUsersfromDB(self):
users = db.getAllUser()
for user in users:
self.__updateGeruechte(user)
return db.getAllUser() return db.getAllUser()
def getUser(self, username): def getUser(self, username):
@ -63,8 +67,30 @@ class UserController(metaclass=Singleton):
user.updateData(user_data) user.updateData(user_data)
db.updateUser(user) db.updateUser(user)
user = db.getUser(username) user = db.getUser(username)
self.__updateGeruechte(user)
return 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): def loginUser(self, username, password):
try: try:
user = self.getUser(username) user = self.getUser(username)

View File

@ -170,4 +170,26 @@ def _finanzerAddUser():
dic[user.uid]['creditList'] = {credit.year: credit.toJSON() for credit in user.geruechte} dic[user.uid]['creditList'] = {credit.year: credit.toJSON() for credit in user.geruechte}
LOGGER.debug("ReturnValue is {}".format(dic)) LOGGER.debug("ReturnValue is {}".format(dic))
return jsonify(dic), 200 return jsonify(dic), 200
return jsonify("error:" "permission denied"), 401 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

View File

@ -27,6 +27,10 @@ class User():
self.firstname = data['firstname'] self.firstname = data['firstname']
self.lastname = data['lastname'] self.lastname = data['lastname']
self.group = data['gruppe'] self.group = data['gruppe']
if 'mail' in data:
self.mail = data['mail']
else:
self.mail = ''
if 'lockLimit' in data: if 'lockLimit' in data:
self.limit = int(data['lockLimit']) self.limit = int(data['lockLimit'])
else: else:
@ -61,6 +65,8 @@ class User():
self.locked = bool(data['locked']) self.locked = bool(data['locked'])
if 'autoLock' in data: if 'autoLock' in data:
self.autoLock = bool(data['autoLock']) self.autoLock = bool(data['autoLock'])
if 'mail' in data:
self.mail = data['mail']
def initGeruechte(self, creditLists): def initGeruechte(self, creditLists):
if type(creditLists) == list: if type(creditLists) == list: