From cd0def0c1b1ba3925f7758916dc87cf3fae0f6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Fri, 3 May 2019 01:40:13 +0200 Subject: [PATCH] Task #60 erledigt. Es wird jetzt per StreamHandler geloggt und per File gespeichert. Vielleicht wird auch ein bisschen zuviel geloggt. --- geruecht/__init__.py | 30 +++++++++- geruecht/baruser/routes.py | 2 +- geruecht/controller/__init__.py | 3 + geruecht/controller/accesTokenController.py | 63 +++++++++++++++----- geruecht/finanzer/__init__.py | 3 + geruecht/finanzer/routes.py | 54 ++++++++++++----- geruecht/model/accessToken.py | 6 +- geruecht/model/creditList.py | 18 +++++- geruecht/model/user.py | 22 +++++-- geruecht/routes.py | 17 +++++- geruecht/site.db | Bin 28672 -> 28672 bytes 11 files changed, 173 insertions(+), 45 deletions(-) diff --git a/geruecht/__init__.py b/geruecht/__init__.py index 535c04e..2e93a13 100644 --- a/geruecht/__init__.py +++ b/geruecht/__init__.py @@ -4,21 +4,46 @@ Initialize also a singelton for the AccesTokenControler and start the Thread. """ +import logging +from logging.handlers import WatchedFileHandler +import sys + +FORMATTER = logging.Formatter("%(asctime)s — %(name)s — %(levelname)s — %(message)s") + +logFileHandler = WatchedFileHandler("testlog.log") +logFileHandler.setFormatter(FORMATTER) + +logStreamHandler = logging.StreamHandler(stream=sys.stdout) +logStreamHandler.setFormatter(FORMATTER) + +def getLogger(logger_name): + logger = logging.getLogger(logger_name) + logger.setLevel(logging.DEBUG) + logger.addHandler(logFileHandler) + logger.addHandler(logStreamHandler) + + logger.propagate = False + + return logger + +LOGGER = getLogger(__name__) +LOGGER.info("Initialize App") from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_bcrypt import Bcrypt from flask_cors import CORS from .controller.accesTokenController import AccesTokenController -# from flask_login import LoginManager +# from flask_login import LoginManager +LOGGER.info("Build APP") app = Flask(__name__) CORS(app) # app.config['SECRET_KEY'] = '0a657b97ef546da90b2db91862ad4e29' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' db = SQLAlchemy(app) bcrypt = Bcrypt(app) -accesTokenController = AccesTokenController() +accesTokenController = AccesTokenController("GERUECHT") accesTokenController.start() # login_manager = LoginManager(app) # login_manager.login_view = 'login' @@ -34,5 +59,6 @@ from geruecht import routes from geruecht.baruser.routes import baruser from geruecht.finanzer.routes import finanzer +LOGGER.info("Registrate bluebrints") app.register_blueprint(baruser) app.register_blueprint(finanzer) diff --git a/geruecht/baruser/routes.py b/geruecht/baruser/routes.py index 7cea2d6..1852a36 100644 --- a/geruecht/baruser/routes.py +++ b/geruecht/baruser/routes.py @@ -9,7 +9,7 @@ baruser = Blueprint("baruser", __name__) @baruser.route("/bar") def _bar(): """ Main function for Baruser - + Returns JSON-file with all Users, who hast amounts in this month. Returns: diff --git a/geruecht/controller/__init__.py b/geruecht/controller/__init__.py index e69de29..6464ff6 100644 --- a/geruecht/controller/__init__.py +++ b/geruecht/controller/__init__.py @@ -0,0 +1,3 @@ +from geruecht import getLogger + +LOGGER = getLogger(__name__) diff --git a/geruecht/controller/accesTokenController.py b/geruecht/controller/accesTokenController.py index 1597ee1..93e7e32 100644 --- a/geruecht/controller/accesTokenController.py +++ b/geruecht/controller/accesTokenController.py @@ -1,8 +1,11 @@ from geruecht.model.accessToken import AccessToken +from geruecht.controller import LOGGER from datetime import datetime import time from threading import Thread import hashlib +import logging +from logging.handlers import WatchedFileHandler class AccesTokenController(Thread): """ Control all createt AccesToken @@ -13,16 +16,40 @@ class AccesTokenController(Thread): tokenList: List of currents AccessToken lifetime: Variable for the Lifetime of one AccessToken in seconds. """ + class __OnlyOne: + def __init__(self, arg): + self.val = arg + + def __str__(self): + return repr(self) + self.val + instance = None tokenList = None lifetime = 60 - def __init__(self): + def __init__(self, arg): """ Initialize AccessTokenController Initialize Thread and set tokenList empty. """ - print("init AccesTokenControlle") - print("init threading") + LOGGER.info("Initialize AccessTokenController") + if not AccesTokenController.instance: + AccesTokenController.instance = AccesTokenController.__OnlyOne(arg) + else: + AccesTokenController.instance.val = arg + + LOGGER.debug("Build Logger for VerificationThread") + + FORMATTER = logging.Formatter("%(asctime)s — %(name)s — %(levelname)s — %(message)s") + + logFileHandler = WatchedFileHandler("Verification.log") + logFileHandler.setFormatter(FORMATTER) + + self.LOGGER = logging.getLogger("VerificationThread") + self.LOGGER.setLevel(logging.DEBUG) + self.LOGGER.addHandler(logFileHandler) + self.LOGGER.propagate = False + + LOGGER.debug("Initialize Threading") Thread.__init__(self) self.tokenList = [] @@ -37,12 +64,14 @@ class AccesTokenController(Thread): Returns: An AccessToken if found or None if not found. """ - print("search for AccesToken", token) + LOGGER.info("Search for Token: {}".format(token)) + LOGGER.debug("Iterate through List of current Tokens") for accToken in self.tokenList: + LOGGER.debug("Check if AccessToken {} has Token {}".format(accToken, token)) if accToken == token: - print("find AccesToken", accToken, "with token", token) + LOGGER.info("Find AccessToken {} with Token {}".format(accToken, token)) return accToken - print("no AccesToken with", token) + LOGGER.info("no AccesToken found with Token {}".format(token)) return None def createAccesToken(self, user): @@ -56,12 +85,13 @@ class AccesTokenController(Thread): Returns: A created Token for User """ - print("create AccesToken") + LOGGER.info("Create AccessToken") now = datetime.ctime(datetime.now()) token = hashlib.md5((now + user.password).encode('utf-8')).hexdigest() - self.tokenList.append(AccessToken(user, token)) - print(self.tokenList) - print("finished create AccesToken", token) + accToken = AccessToken(user, token) + LOGGER.debug("Add AccessToken {} to current Tokens".format(accToken)) + self.tokenList.append(accToken) + LOGGER.info("Finished create AccessToken {} with Token {}".format(accToken, token)) return token def isSameGroup(self, accToken, group): @@ -77,6 +107,7 @@ class AccesTokenController(Thread): A Bool. If the same then True else False """ print("controll if", accToken, "hase group", group) + LOGGER.debug("Check if AccessToken {} has group {}".format(accToken, group)) return True if accToken.user.group == group else False def run(self): @@ -84,15 +115,17 @@ class AccesTokenController(Thread): Verify that the AccesToken are not out of date. If one AccessToken out of date it will be deletet from tokenList. """ + LOGGER.info("Start Thread for verification that the AccessToken are not out of date.") while True: - print("start allocate") + self.LOGGER.debug("Start to iterate through List of current Tokens") for accToken in self.tokenList: - print("controle", accToken) + self.LOGGER.debug("Check if AccessToken {} is out of date".format(accToken)) if (datetime.now() - accToken.timestamp).seconds > 7200: print("delete", accToken) + self.LOGGER.info("Delete AccessToken {} from List of current Tokens".format(accToken)) self.tokenList.remove(accToken) else: - print("time is only", (datetime.now() - accToken.timestamp).seconds) - print(self.tokenList) - print("wait") + self.LOGGER.debug("AccessToken {} is up to date. {} seconds left".format(accToken, 7200 - (datetime.now() - accToken.timestamp).seconds)) + self.LOGGER.debug("List of current Tokens: {}".format(self.tokenList)) + self.LOGGER.info("Wait 10 Seconds") time.sleep(10) diff --git a/geruecht/finanzer/__init__.py b/geruecht/finanzer/__init__.py index e69de29..6464ff6 100644 --- a/geruecht/finanzer/__init__.py +++ b/geruecht/finanzer/__init__.py @@ -0,0 +1,3 @@ +from geruecht import getLogger + +LOGGER = getLogger(__name__) diff --git a/geruecht/finanzer/routes.py b/geruecht/finanzer/routes.py index 5da9bfb..b134e1e 100644 --- a/geruecht/finanzer/routes.py +++ b/geruecht/finanzer/routes.py @@ -1,4 +1,5 @@ from flask import Blueprint, request, jsonify +from geruecht.finanzer import LOGGER from datetime import datetime from geruecht import MONEY from geruecht.routes import verifyAccessToken @@ -17,15 +18,21 @@ def _getFinanzer(): A JSON-File with Users or ERROR 401 Permission Denied. """ + LOGGER.info("Get main for Finanzer") token = request.headers.get("Token") - + LOGGER.debug("Verify AccessToken with Token {}".format(token)) accToken = verifyAccessToken(token, MONEY) if accToken is not None: + LOGGER.debug("Get all Useres") users = User.query.all() dic = {} for user in users: + LOGGER.debug("Add User {} to ReturnValue".format(user)) dic[user.userID] = user.toJSON() + LOGGER.debug("ReturnValue is {}".format(dic)) + LOGGER.info("Send main for Finanzer") return jsonify(dic) + LOGGER.info("Permission Denied") return jsonify({"error": "permission denied"}), 401 @finanzer.route("/getFinanzerYears", methods=['POST']) @@ -38,21 +45,28 @@ def _getFinanzerYear(): JSON-File with geruechte of special user or ERROR 401 Permission Denied """ - print(request.headers) + LOGGER.info("Get all Geruechte from User.") token = request.headers.get("Token") - print(token) + LOGGER.debug("Verify AccessToken with Token {}".format(token)) accToken = verifyAccessToken(token, MONEY) dic = {} if accToken is not None: data = request.get_json() + LOGGER.debug("Get data {}".format(data)) userID = data['userId'] - + LOGGER.debug("UserID is {}".format(userID)) user = User.query.filter_by(userID=userID).first() + LOGGER.debug("User is {}".format(user)) dic[user.userID] = {} + LOGGER.debug("Build ReturnValue") for geruecht in user.geruechte: + LOGGER.debug("Add Geruecht {} to ReturnValue".format(geruecht)) dic[user.userID][geruecht.year] = geruecht.toJSON() + LOGGER.debug("ReturnValue is {}".format(dic)) + LOGGER.info("Send Geruechte from User {}".format(user)) return jsonify(dic) + LOGGER.info("Permission Denied") return jsonify({"error": "permission denied"}), 401 @finanzer.route("/finanzerAddAmount", methods=['POST']) @@ -67,31 +81,36 @@ def _addAmount(): JSON-File with geruecht of year or ERROR 401 Permission Denied """ - print(request.headers) + LOGGER.info("Add Amount") token = request.headers.get("Token") - print(token) + LOGGER.debug("Verify AccessToken with Token {}".format(token)) accToken = verifyAccessToken(token, MONEY) if accToken is not None: data = request.get_json() + LOGGER.debug("Get data {}".format(data)) userID = data['userId'] amount = int(data['amount']) - + LOGGER.debug("UserID is {} and amount is {}".format(userID, amount)) try: year = int(data['year']) except KeyError as er: - print("Error: ", er) + LOGGER.error("KeyError in year. Year is set to default.") year = datetime.now().year try: month = int(data['month']) except KeyError as er: - print("Error: ", er) + LOGGER.error("KeyError in month. Month is set to default.") month = datetime.now().month - + LOGGER.debug("Year is {} and Month is {}".format(year, month)) user = User.query.filter_by(userID=userID).first() + LOGGER.debug("User is {}".format(user)) + LOGGER.debug("Add amount to User {} in year {} and month {}".format(user, year, month)) user.addAmount(amount, year=year, month=month) retVal = user.getGeruecht(year=year).toJSON() + LOGGER.info("Send updated Geruecht") return jsonify(retVal) + LOGGER.info("Permission Denied") return jsonify({"error": "permission denied"}), 401 @finanzer.route("/finanzerAddCredit", methods=['POST']) @@ -106,29 +125,36 @@ def _addCredit(): JSON-File with geruecht of year or ERROR 401 Permission Denied """ - print(request.headers) + LOGGER.info("Add Amount") token = request.headers.get("Token") - print(token) + LOGGER.debug("Verify AccessToken with Token {}".format(token)) accToken = verifyAccessToken(token, MONEY) if accToken is not None: data = request.get_json() + LOGGER.debug("Get data {}".format(data)) userID = data['userId'] credit = int(data['credit']) + LOGGER.debug("UserID is {} and credit is {}".format(userID, credit)) try: year = int(data['year']) except KeyError as er: - print("Error: ", er) + LOGGER.error("KeyError in year. Year is set to default.") year = datetime.now().year try: month = int(data['month']) except KeyError as er: - print("Error: ", er) + LOGGER.error("KeyError in month. Month is set to default.") month = datetime.now().month + LOGGER.debug("Year is {} and Month is {}".format(year, month)) user = User.query.filter_by(userID=userID).first() + LOGGER.debug("User is {}".format(user)) + LOGGER.debug("Add credit to User {} in year {} and month {}".format(user, year, month)) user.addCredit(credit, year=year, month=month) retVal = user.getGeruecht(year=year).toJSON() + LOGGER.info("Send updated Geruecht") return jsonify(retVal) + LOGGER.info("Permission Denied") return jsonify({"error": "permission denied"}), 401 diff --git a/geruecht/model/accessToken.py b/geruecht/model/accessToken.py index 24212d7..0718dc4 100644 --- a/geruecht/model/accessToken.py +++ b/geruecht/model/accessToken.py @@ -1,4 +1,7 @@ from datetime import datetime +from geruecht import getLogger + +LOGGER = getLogger(__name__) class AccessToken(): """ Model for an AccessToken @@ -23,7 +26,7 @@ class AccessToken(): token: Is a String to verify later timestamp: Default current time, but can set to an other datetime-Object. """ - + LOGGER.debug("Initialize AccessToken") self.user = user self.timestamp = timestamp self.token = token @@ -33,6 +36,7 @@ class AccessToken(): Update the Timestamp to the current Time. """ + LOGGER.debug("Update Timestamp") self.timestamp = datetime.now() def __eq__(self, token): diff --git a/geruecht/model/creditList.py b/geruecht/model/creditList.py index 0ce3499..ddcc877 100644 --- a/geruecht/model/creditList.py +++ b/geruecht/model/creditList.py @@ -1,5 +1,8 @@ from geruecht import db from datetime import datetime +from geruecht import getLogger + +LOGGER = getLogger(__name__) class CreditList(db.Model): """ DataBase Object Credit List: @@ -13,6 +16,7 @@ class CreditList(db.Model): year: Year of all Credits and Debts. user_id: id from the User. """ + LOGGER.debug("Initialize Geruecht") id = db.Column(db.Integer, primary_key=True) jan_guthaben = db.Column(db.Integer, nullable=False, default=0) @@ -70,6 +74,7 @@ class CreditList(db.Model): Returns: double of the calculated amount """ + LOGGER.debug("Calculate amount") jan = self.jan_guthaben - self.jan_schulden feb = self.feb_guthaben - self.feb_schulden maer = self.maer_guthaben - self.maer_schulden @@ -84,6 +89,7 @@ class CreditList(db.Model): dez = self.dez_guthaben - self.dez_schulden sum = jan + feb + maer + apr + mai + jun + jul + aug + sep + okt + nov + dez - self.last_schulden + LOGGER.debug("Calculated amount is {}".format(sum)) return sum def getMonth(self, month=datetime.now().month): @@ -98,6 +104,7 @@ class CreditList(db.Model): Returns: double (credit, amount) """ + LOGGER.debug("Get Credit and Amount from Month {}".format(month)) retValue = None if month == 1: @@ -124,7 +131,7 @@ class CreditList(db.Model): retValue = (self.nov_guthaben, self.nov_schulden) elif month == 12: retValue = (self.dez_guthaben, self.dez_schulden) - + LOGGER.debug("Credit and Amount is {}".format(retValue)) return retValue def addAmount(self, amount, month=datetime.now().month): @@ -140,6 +147,7 @@ class CreditList(db.Model): Returns: double (credit, amount) """ + LOGGER.debug("Add Amount in Month {}".format(month)) if month == 1: self.jan_schulden += amount retValue = (self.jan_guthaben, self.jan_schulden) @@ -178,7 +186,7 @@ class CreditList(db.Model): retValue = (self.dez_guthaben, self.dez_schulden) db.session.commit() - + LOGGER.debug("Credit and Amount is {}".format(retValue)) return retValue def addCredit(self, credit, month=datetime.now().month): @@ -194,6 +202,7 @@ class CreditList(db.Model): Returns: double (credit, amount) """ + LOGGER.debug("Add Credit in Month {}".format(month)) if month == 1: self.jan_guthaben += credit retValue = (self.jan_guthaben, self.jan_schulden) @@ -232,7 +241,7 @@ class CreditList(db.Model): retValue = (self.dez_guthaben, self.dez_schulden) db.session.commit() - + LOGGER.debug("Credit and Amount is {}".format(retValue)) return retValue def toJSON(self): @@ -280,3 +289,6 @@ class CreditList(db.Model): "depts": self.dez_schulden}, } return dic + + def __repr__(self): + return "CreditList(year: {}, userID: {}, amount: {})".format(self.year, self.user_id, self.toJSON()) diff --git a/geruecht/model/user.py b/geruecht/model/user.py index db2cd98..4ba9d7c 100644 --- a/geruecht/model/user.py +++ b/geruecht/model/user.py @@ -1,8 +1,9 @@ -from geruecht import db -from geruecht import bcrypt +from geruecht import db, bcrypt, getLogger from geruecht.model.creditList import CreditList from datetime import datetime +LOGGER = getLogger(__name__) + class User(db.Model): """ Database Object for User @@ -40,12 +41,12 @@ class User(db.Model): Returns: the created geruecht """ - print('create geruecht for user {} in year {}'.format(self.userID, year)) + LOGGER.debug("Create Geruecht for user {} in year {}".format(self, year)) credit = CreditList(user_id=self.id, last_schulden=amount, year=year) db.session.add(credit) db.session.commit() credit = CreditList.query.filter_by(year=year, user_id=self.id).first() - print('reated geruecht {}'.format(credit)) + LOGGER.debug("Created Geruecht {}".format(credit)) return credit def getGeruecht(self, year=datetime.now().year): @@ -60,11 +61,13 @@ class User(db.Model): Returns: the geruecht of the year """ + LOGGER.debug("Iterate through Geruechte of User {}".format(self)) for geruecht in self.geruechte: + LOGGER.debug("Check if Geruecht {} has year {}".format(geruecht, year)) if geruecht.year == year: - print("find geruecht {} for user {}".format(geruecht, self.id)) + LOGGER.debug("Find Geruecht {} for User {}".format(geruecht, self)) return geruecht - print("no geruecht found for user {}. Will create one".format(self.id)) + LOGGER.debug("No Geruecht found for User {}. Will create one".format(self)) geruecht = self.createGeruecht(year=year) self.updateGeruecht() @@ -85,6 +88,7 @@ class User(db.Model): Returns: double (credit, amount) """ + LOGGER.debug("Add amount to User {} in year {} and month {}".format(self, year, month)) geruecht = self.getGeruecht(year=year) retVal = geruecht.addAmount(amount, month=month) @@ -109,6 +113,7 @@ class User(db.Model): Returns: double (credit, amount) """ + LOGGER.debug("Add credit to User {} in year {} and month {}".format(self, year, month)) geruecht = self.getGeruecht(year=year) retVal = geruecht.addCredit(credit, month=month) @@ -124,6 +129,7 @@ class User(db.Model): This function iterate through the geruechte, which sorted by year and update the last_schulden of the geruecht. """ + LOGGER.debug("Update all Geruechte ") self.geruechte.sort(key=self.sortYear) for index, geruecht in enumerate(self.geruechte): @@ -171,4 +177,8 @@ class User(db.Model): Returns: A Bool. True if the password is correct and False if it isn't. """ + LOGGER.debug("Login User {}".format(self)) return True if bcrypt.check_password_hash(self.password, password) else False + + def __repr__(self): + return "User({}, {}, {})".format(self.userID, self.username, self.group) diff --git a/geruecht/routes.py b/geruecht/routes.py index 62506a8..cd192cb 100644 --- a/geruecht/routes.py +++ b/geruecht/routes.py @@ -1,4 +1,4 @@ -from geruecht import app, db, accesTokenController, MONEY, BAR, USER, GASTRO +from geruecht import app, db, accesTokenController, MONEY, BAR, USER, GASTRO, LOGGER from geruecht.model.user import User from geruecht.model.creditList import CreditList from geruecht.model.priceList import PriceList @@ -17,12 +17,16 @@ def verifyAccessToken(token, group): Returns: An the AccesToken for this given Token or None. """ + LOGGER.info("Verify AccessToken with token: {} and group: {}".format(token, group)) accToken = accesTokenController.findAccesToken(token) - print(accToken) + LOGGER.debug("AccessToken is {}".format(accToken)) if accToken is not None: + LOGGER.debug("Check if AccesToken {} has same group {}".format(accToken, group)) if accesTokenController.isSameGroup(accToken, group): accToken.updateTimestamp() + LOGGER.info("Found AccessToken {} with token: {} and group: {}".format(accToken, token, group)) return accToken + LOGGER.info("No AccessToken with token: {} and group: {} found".format(token, group)) return None @app.route("/valid") @@ -52,19 +56,26 @@ def _login(): Returns: A JSON-File with createt Token or Errors """ + LOGGER.info("Start log in.") data = request.get_json() - print(data) + LOGGER.debug("JSON from request: {}".format(data)) username = data['username'] password = data['password'] + LOGGER.info("{} try to log in".format(username)) user = User.query.filter_by(username=username).first() + LOGGER.debug("User is {}".format(user)) if user: + LOGGER.debug("Check login for User {}".format(user)) if user.login(password): token = accesTokenController.createAccesToken(user) dic = user.toJSON() dic["token"] = token + LOGGER.info("User {} success login.".format(username)) return jsonify(dic) else: + LOGGER.info("User {} failed login.".format(username)) return jsonify({"error": "wrong password"}), 401 + LOGGER.info("User {} does not exist.".format(username)) return jsonify({"error": "wrong username"}), 402 @app.route("/getFinanzer") diff --git a/geruecht/site.db b/geruecht/site.db index fe9f624634a1ba6063c3a071a79f8af094a6da47..041487dde91ac01863bb9d3719696c7612d32e86 100644 GIT binary patch delta 224 zcmZp8z}WDBae_2s>_i!7#@LMsi{d4G7&!S98TnrFU*H$zPvp1fE976vH=9p!v!DPw zpMeIaECUAz2NM_q8Bo9krkNNSCor5~IKeo9{Q(Of-(dz-j>!Re;zo=>i7z7Tk61L= zWEmhzK}NsJJ433QBqorU;etN Wf_PAXFa^Q_TgB7>v~2SEd_w?c0xC!V delta 226 zcmZp8z}WDBae_2s#6%fq#)ypxi{d2?GjQ^GGx5FTzrZibpU7{|=gr^7H=D0`v!DPw zpFUqPgBAw|2NM_q8OVT%iIH&v!wH5HUp&|!u&A-gGB8aJ%o8^TiZj1p{KBlj{*XnD zQ