diff --git a/geruecht/__init__.py b/geruecht/__init__.py index 671f980..5a7316f 100644 --- a/geruecht/__init__.py +++ b/geruecht/__init__.py @@ -1,3 +1,10 @@ +""" Server-package + + Initialize app, cors, database and bcrypt (for passwordhashing) and added it to the application. + Initialize also a singelton for the AccesTokenControler and start the Thread. + +""" + from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_bcrypt import Bcrypt diff --git a/geruecht/controller/accesTokenController.py b/geruecht/controller/accesTokenController.py index e7a5c77..7c77680 100644 --- a/geruecht/controller/accesTokenController.py +++ b/geruecht/controller/accesTokenController.py @@ -5,16 +5,38 @@ from threading import Thread import hashlib class AccesTokenController(Thread): + """ Control all createt AccesToken + + This Class create, delete, find and manage AccesToken. + + Attributes: + tokenList: List of currents AccessToken + lifetime: Variable for the Lifetime of one AccessToken in seconds. + """ tokenList = None - self.lifetime = 60 + lifetime = 60 def __init__(self): + """ Initialize AccessTokenController + + Initialize Thread and set tokenList empty. + """ print("init AccesTokenControlle") print("init threading") Thread.__init__(self) self.tokenList = [] def findAccesToken(self, token): + """ Find a Token in current AccessTokens + + Iterate throw all availables AccesTokens and retrieve one, if they are the same. + + Args: + token: Token to find + + Returns: + An AccessToken if found or None if not found. + """ print("search for AccesToken", token) for accToken in self.tokenList: if accToken == token: @@ -24,6 +46,16 @@ class AccesTokenController(Thread): return None def createAccesToken(self, user): + """ Create an AccessToken + + Create an AccessToken for an User and add it to the tokenList. + + Args: + user: For wich User is to create an AccessToken + + Returns: + A created Token for User + """ print("create AccesToken") now = datetime.ctime(datetime.now()) token = hashlib.md5((now + user.password).encode('utf-8')).hexdigest() @@ -33,15 +65,30 @@ class AccesTokenController(Thread): return token def isSameGroup(self, accToken, group): + """ Verify group in AccessToken + + Verify if the User in the AccesToken has the right group. + + Args: + accToken: AccessToken to verify. + group: Group to verify. + + Returns: + A Bool. If the same then True else False + """ print("controll if", accToken, "hase group", group) return True if accToken.user.group == group else False def run(self): + """ Starting Controll-Thread + + Verify that the AccesToken are not out of date. If one AccessToken out of date it will be deletet from tokenList. + """ while True: print("start allocate") for accToken in self.tokenList: print("controle", accToken) - if (datetime.now() - accToken.timestamp).seconds > self.lifetime: + if (datetime.now() - accToken.timestamp).seconds > 60: print("delete", accToken) self.tokenList.remove(accToken) else: diff --git a/geruecht/model/accessToken.py b/geruecht/model/accessToken.py index 078c1bb..916b4ab 100644 --- a/geruecht/model/accessToken.py +++ b/geruecht/model/accessToken.py @@ -1,17 +1,38 @@ from datetime import datetime class AccessToken(): + """ Model for an AccessToken + + Attributes: + timestamp: Is a Datetime from current Time. + user: Is an User. + token: String to verify access later. + """ timestamp = None user = None token = None def __init__(self, user, token, timestamp=datetime.now()): + """ Initialize Class AccessToken + + No more to say. + + Args: + User: Is an User to set. + token: Is a String to verify later + timestamp: Default current time, but can set to an other datetime-Object. + """ + self.user = user self.timestamp = timestamp self.token = token def updateTimestamp(self): + """ Update the Timestamp + + Update the Timestamp to the current Time. + """ self.timestamp = datetime.now() def __eq__(self, token): @@ -21,7 +42,8 @@ class AccessToken(): return other - self.timestamp def __str__(self): - return f"AccessToken({self.user}, {self.token}, {self.timestamp}" + return "AccessToken({}, {}, {}".format(self.user, self.token, self.timestamp) def __repr__(self): - return f"AccessToken({self.user}, {self.token}, {self.timestamp}" + return "AccessToken({}, {}, {}".format(self.user, self.token, self.timestamp) + diff --git a/geruecht/model/creditList.py b/geruecht/model/creditList.py index a8e97a2..a99b5cb 100644 --- a/geruecht/model/creditList.py +++ b/geruecht/model/creditList.py @@ -2,6 +2,18 @@ from geruecht import db from datetime import datetime class CreditList(db.Model): + """ DataBase Object Credit List: + + Attributes: + id: id in Database. Is the Primary Key + _guthaben: Credit of the Month. + _schulden: Debt of the Month. + + last_schulden: Debt or Credit of last Year. + year: Year of all Credits and Debts. + + TODO: link to user??? + """ id = db.Column(db.Integer, primary_key=True) jan_guthaben = db.Column(db.Integer, nullable=False, default=0) diff --git a/geruecht/model/priceList.py b/geruecht/model/priceList.py index 7616dda..fa1864e 100644 --- a/geruecht/model/priceList.py +++ b/geruecht/model/priceList.py @@ -1,6 +1,10 @@ from geruecht import db class PriceList(db.Model): + """ Database Model for PriceList + + PriceList has lots of Drinks and safe all Prices (normal, for club, for other clubs, which catagory, etc) + """ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False, unique=True) diff --git a/geruecht/model/user.py b/geruecht/model/user.py index 6c8c9de..591b0a3 100644 --- a/geruecht/model/user.py +++ b/geruecht/model/user.py @@ -2,6 +2,19 @@ from geruecht import db from geruecht import bcrypt class User(db.Model): + """ Database Object for User + + Table for all safed User + + Attributes: + id: Id in Database as Primary Key. + userID: ID for the User maybe to Link? + username: Username of the User to Login + firstname: Firstname of the User + Lastname: Lastname of the User + group: Which group is the User? moneymaster, gastro, user or bar? + password: salted hashed password for the User. + """ id = db.Column(db.Integer, primary_key=True) userID = db.Column(db.String, nullable=False, unique=True) username = db.Column(db.String, nullable=False, unique=True) @@ -11,6 +24,11 @@ class User(db.Model): password = db.Column(db.String, nullable=False) def toJSON(self): + """ Create Dic to dump in JSON + + Returns: + A Dic with static Attributes. + """ dic = { "userId": self.userID, "username": self.username, @@ -21,5 +39,12 @@ class User(db.Model): return dic def login(self, password): + """ Login for the User + + Only check the given Password: + + Returns: + A Bool. True if the password is correct and False if it isn't. + """ return True if bcrypt.check_password_hash(self.password, password) else False diff --git a/geruecht/routes.py b/geruecht/routes.py index 967be95..a413bbb 100644 --- a/geruecht/routes.py +++ b/geruecht/routes.py @@ -10,6 +10,17 @@ USER = "user" BAR = "bar" def verifyAccessToken(token, group): + """ Verify Accestoken + + Verify an Accestoken and Group so if the User has permission or not. + Retrieves the accestoken if valid else retrieves None + + Args: + token: Token to verify. + group: Group like 'moneymaster', 'gastro', 'user' or 'bar' + Returns: + An the AccesToken for this given Token or None. + """ accToken = accesTokenController.findAccesToken(token) print(accToken) if accToken is not None: @@ -20,6 +31,15 @@ def verifyAccessToken(token, group): @app.route("/getFinanzerMain", methods=['POST']) def _getFinanzer(): + """ Function for /getFinanzerMain + + Retrieves all User for the groupe 'moneymaster' + + Returns: + A JSON-File with Users or an Error. + example: + + """ data = request.get_json() token = data["token"] @@ -43,6 +63,14 @@ def _valid(): @app.route("/login", methods=['POST']) def _login(): + """ Login User + + Nothing to say. + Login in User and create an AccessToken for the User. + + Returns: + A JSON-File with createt Token or Errors + """ data = request.get_json() print(data) username = data['username'] diff --git a/run.py b/run.py index 0de5915..b6d40ab 100644 --- a/run.py +++ b/run.py @@ -1,5 +1,9 @@ from geruecht import app +""" Main + + Start the backend +""" if __name__ == '__main__': app.run(debug=True, host='0.0.0.0')