Rename AccessToken model to Session, same with controller.

This commit is contained in:
Ferdinand Thiessen 2020-10-19 01:41:54 +02:00
parent ec05cde746
commit c629f5abf3
18 changed files with 113 additions and 107 deletions

View File

@ -1,7 +1,6 @@
""" Server-package """ Server-package
Initialize app, CORS, database and add it to the application. Initialize app, CORS, database and add it to the application.
Initialize also a singleton for the AccessTokenController and start the Thread.
""" """
import yaml import yaml

View File

@ -56,11 +56,14 @@ def __load_plugins(app):
def install_all(): def install_all():
from flaschengeist.system.database import db from flaschengeist.system.database import db
from flaschengeist.system.models import user, event, accessToken from flaschengeist.system.models import user, event, session
db.create_all() db.create_all()
db.session.commit() db.session.commit()
for name, plugin in current_app.config["FG_PLUGINS"].items(): for name, plugin in current_app.config["FG_PLUGINS"].items():
if not plugin:
logger.debug("Skip disabled plugin {}".format(name))
continue
logger.info("Install plugin {}".format(name)) logger.info("Install plugin {}".format(name))
plugin.install() plugin.install()
if plugin.permissions: if plugin.permissions:

View File

@ -7,6 +7,7 @@ class Plugin:
def __init__(self, config=None, blueprint=None, permissions={}): def __init__(self, config=None, blueprint=None, permissions={}):
self.blueprint = blueprint self.blueprint = blueprint
self.permissions = permissions self.permissions = permissions
self.version = "dummy"
def install(self): def install(self):
"""Installation routine """Installation routine
@ -14,6 +15,11 @@ class Plugin:
""" """
pass pass
def serialize(self):
return {
"version": self.version,
}
class AuthPlugin(Plugin): class AuthPlugin(Plugin):
def login(self, user, pw): def login(self, user, pw):

View File

@ -11,9 +11,9 @@ from werkzeug.local import LocalProxy
from flaschengeist import logger from flaschengeist import logger
from flaschengeist.modules import Plugin from flaschengeist.modules import Plugin
from flaschengeist.system.decorator import login_required from flaschengeist.system.decorator import login_required
from flaschengeist.system.controller import accessTokenController, userController, messageController from flaschengeist.system.controller import sessionController, userController, messageController
access_controller = LocalProxy(lambda: accessTokenController.AccessTokenController()) session_controller = LocalProxy(lambda: sessionController.SessionController())
auth_bp = Blueprint("auth", __name__) auth_bp = Blueprint("auth", __name__)
@ -33,10 +33,10 @@ class AuthRoutePlugin(Plugin):
@auth_bp.route("/auth", methods=["POST"]) @auth_bp.route("/auth", methods=["POST"])
def _create_token(): def _login():
"""Login User """Login User
Login in User and create an AccessToken for the User. Login in User and create a Session for the User.
Requires POST data {'userid': string, 'password': string} Requires POST data {'userid': string, 'password': string}
Returns: Returns:
A JSON-File with user information and created token or errors A JSON-File with user information and created token or errors
@ -54,55 +54,55 @@ def _create_token():
if not user: if not user:
raise Unauthorized raise Unauthorized
logger.debug("user is {{ {} }}".format(user)) logger.debug("user is {{ {} }}".format(user))
token = access_controller.create(user, user_agent=request.user_agent) session = session_controller.create(user, user_agent=request.user_agent)
logger.debug("access token is {{ {} }}".format(token)) logger.debug("token is {{ {} }}".format(session.token))
logger.info("User {{ {} }} success login.".format(userid)) logger.info("User {{ {} }} success login.".format(userid))
# Lets cleanup the DB # Lets cleanup the DB
access_controller.clear_expired() session_controller.clear_expired()
return jsonify({"user": user, "token": token, "permissions": user.get_permissions()}) return jsonify({"session": session, "permissions": user.get_permissions()})
@auth_bp.route("/auth", methods=["GET"]) @auth_bp.route("/auth", methods=["GET"])
@login_required() @login_required()
def _get_tokens(access_token, **kwargs): def _get_tokens(access_token, **kwargs):
tokens = access_controller.get_users_tokens(access_token.user) tokens = session_controller.get_users_sessions(access_token.user)
a = messageController.Message(access_token.user, "Go", "Bar") a = messageController.Message(access_token.user, "Go", "Bar")
messageController.send_message(a) messageController.send_message(a)
return jsonify(tokens) return jsonify(tokens)
@login_required()
@auth_bp.route("/auth/<token>", methods=["DELETE"]) @auth_bp.route("/auth/<token>", methods=["DELETE"])
def _delete_token(token, access_token, **kwargs): @login_required()
def _delete_token(access_token, token, **kwargs):
logger.debug("Try to delete access token {{ {} }}".format(token)) logger.debug("Try to delete access token {{ {} }}".format(token))
token = access_controller.get_token(token, access_token.user) token = session_controller.get_session(token, access_token.user)
if not token: if not token:
logger.debug("Token not found in database!") logger.debug("Token not found in database!")
# Return 403 error, so that users can not bruteforce tokens # Return 403 error, so that users can not bruteforce tokens
# Valid tokens from other users and invalid tokens now are looking the same # Valid tokens from other users and invalid tokens now are looking the same
raise Forbidden raise Forbidden
access_controller.delete_token(token) session_controller.delete_session(token)
access_controller.clear_expired() session_controller.clear_expired()
return jsonify({"ok": "ok"}) return jsonify({"ok": "ok"})
@login_required()
@auth_bp.route("/auth/<token>", methods=["GET"]) @auth_bp.route("/auth/<token>", methods=["GET"])
@login_required()
def _get_token(token, access_token, **kwargs): def _get_token(token, access_token, **kwargs):
logger.debug("get token {{ {} }}".format(token)) logger.debug("get token {{ {} }}".format(token))
token = access_controller.get_token(token, access_token.user) session = session_controller.get_session(token, access_token.user)
if not token: if not token:
# Return 403 error, so that users can not bruteforce tokens # Return 403 error, so that users can not bruteforce tokens
# Valid tokens from other users and invalid tokens now are looking the same # Valid tokens from other users and invalid tokens now are looking the same
raise Forbidden raise Forbidden
return jsonify(token) return jsonify({"session": session, "permissions": session.user.get_permissions()})
@login_required()
@auth_bp.route("/auth/<token>", methods=["PUT"]) @auth_bp.route("/auth/<token>", methods=["PUT"])
@login_required()
def _set_lifetime(token, access_token, **kwargs): def _set_lifetime(token, access_token, **kwargs):
token = access_controller.get_token(token, access_token.user) token = session_controller.get_token(token, access_token.user)
if not token: if not token:
# Return 403 error, so that users can not bruteforce tokens # Return 403 error, so that users can not bruteforce tokens
# Valid tokens from other users and invalid tokens now are looking the same # Valid tokens from other users and invalid tokens now are looking the same
@ -110,7 +110,7 @@ def _set_lifetime(token, access_token, **kwargs):
try: try:
lifetime = request.get_json()["value"] lifetime = request.get_json()["value"]
logger.debug("set lifetime {{ {} }} to access token {{ {} }}".format(lifetime, token)) logger.debug("set lifetime {{ {} }} to access token {{ {} }}".format(lifetime, token))
access_controller.set_lifetime(token, lifetime) session_controller.set_lifetime(token, lifetime)
return jsonify({"ok": "ok"}) return jsonify({"ok": "ok"})
except (KeyError, TypeError): except (KeyError, TypeError):
raise BadRequest raise BadRequest

View File

@ -37,17 +37,17 @@ class AuthLDAP(AuthPlugin):
def login(self, user, password): def login(self, user, password):
if not user: if not user:
return False return False
return self.ldap.authenticate(user.uid, password, "uid", self.dn) return self.ldap.authenticate(user.userid, password, "uid", self.dn)
def update_user(self, user): def update_user(self, user):
self.ldap.connection.search( self.ldap.connection.search(
"ou=user,{}".format(self.dn), "ou=user,{}".format(self.dn),
"(uid={})".format(user.uid), "(uid={})".format(user.userid),
SUBTREE, SUBTREE,
attributes=["uid", "givenName", "sn", "mail"], attributes=["uid", "givenName", "sn", "mail"],
) )
r = self.ldap.connection.response[0]["attributes"] r = self.ldap.connection.response[0]["attributes"]
if r["uid"][0] == user.uid: if r["uid"][0] == user.userid:
user.set_attribute("DN", self.ldap.connection.response[0]["dn"]) user.set_attribute("DN", self.ldap.connection.response[0]["dn"])
user.firstname = r["givenName"][0] user.firstname = r["givenName"][0]
user.lastname = r["sn"][0] user.lastname = r["sn"][0]
@ -55,7 +55,7 @@ class AuthLDAP(AuthPlugin):
user.mail = r["mail"][0] user.mail = r["mail"][0]
if "displayName" in r: if "displayName" in r:
user.display_name = r["displayName"][0] user.display_name = r["displayName"][0]
for group in self._get_groups(user.uid): for group in self._get_groups(user.userid):
user.add_role(group) user.add_role(group)
def _get_groups(self, uid): def _get_groups(self, uid):

View File

@ -2,7 +2,7 @@ import binascii
import hashlib import hashlib
import os import os
import flaschengeist.modules as modules from flaschengeist.modules import AuthPlugin
from flaschengeist.system.models.user import User from flaschengeist.system.models.user import User
@ -21,7 +21,7 @@ def _verify_password(stored_password, provided_password):
return pass_hash == stored_password return pass_hash == stored_password
class AuthPlain(modules.Auth): class AuthPlain(AuthPlugin):
def login(self, user: User, password: str): def login(self, user: User, password: str):
if user and "password" in user.attributes: if user and "password" in user.attributes:
return _verify_password(user.attributes["password"].value, password) return _verify_password(user.attributes["password"].value, password)

View File

@ -42,7 +42,7 @@ def _bar(**kwargs):
type = 'credit' type = 'credit'
else: else:
type = 'amount' type = 'amount'
dic[user.uid] = {"username": user.uid, dic[user.userid] = {"username": user.userid,
"firstname": user.firstname, "firstname": user.firstname,
"lastname": user.lastname, "lastname": user.lastname,
"amount": all, "amount": all,
@ -50,8 +50,8 @@ def _bar(**kwargs):
"type": type, "type": type,
"limit": user.limit, "limit": user.limit,
"autoLock": user.autoLock "autoLock": user.autoLock
} }
dic[user.uid]['last_seen'] = {"year": user.last_seen.year, "month": user.last_seen.month, "day": user.last_seen.day, "hour": user.last_seen.hour, "minute": user.last_seen.minute, "second": user.last_seen.second} if user.last_seen else None dic[user.userid]['last_seen'] = {"year": user.last_seen.year, "month": user.last_seen.month, "day": user.last_seen.day, "hour": user.last_seen.hour, "minute": user.last_seen.minute, "second": user.last_seen.second} if user.last_seen else None
debug.debug("return {{ {} }}".format(dic)) debug.debug("return {{ {} }}".format(dic))
return jsonify(dic) return jsonify(dic)
except Exception as err: except Exception as err:

View File

@ -10,7 +10,7 @@ class Base:
def getCreditListFromUser(self, user, **kwargs): def getCreditListFromUser(self, user, **kwargs):
try: try:
if type(user) is User: if type(user) is User:
if user.uid == 'extern': if user.userid == 'extern':
return [] return []
cursor = self.db.connection.cursor() cursor = self.db.connection.cursor()
if 'year' in kwargs: if 'year' in kwargs:

View File

@ -83,7 +83,7 @@ class Base:
cursor = self.db.connection.cursor() cursor = self.db.connection.cursor()
groups = self._convertGroupToString(user.group) groups = self._convertGroupToString(user.group)
cursor.execute("insert into user (uid, dn, firstname, lastname, gruppe, lockLimit, locked, autoLock, mail) 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.mail)) user.userid, user.dn, user.firstname, user.lastname, groups, user.limit, user.locked, user.autoLock, user.mail))
self.db.connection.commit() self.db.connection.commit()
except Exception as err: except Exception as err:
traceback.print_exc() traceback.print_exc()
@ -96,7 +96,7 @@ class Base:
cursor = self.db.connection.cursor() cursor = self.db.connection.cursor()
groups = self._convertGroupToString(user.group) groups = self._convertGroupToString(user.group)
sql = "update user set dn='{}', firstname='{}', lastname='{}', gruppe='{}', lockLimit={}, locked={}, autoLock={}, mail='{}' 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.mail, user.uid) user.dn, user.firstname, user.lastname, groups, user.limit, user.locked, user.autoLock, user.mail, user.userid)
print(sql) print(sql)
cursor.execute(sql) cursor.execute(sql)
self.db.connection.commit() self.db.connection.commit()
@ -109,7 +109,7 @@ class Base:
try: try:
cursor = self.db.connection.cursor() cursor = self.db.connection.cursor()
sql = "update user set last_seen='{}' where uid='{}'".format( sql = "update user set last_seen='{}' where uid='{}'".format(
time, user.uid) time, user.userid)
print(sql) print(sql)
cursor.execute(sql) cursor.execute(sql)
self.db.connection.commit() self.db.connection.commit()

View File

@ -29,8 +29,8 @@ def _getFinanzer(**kwargs):
users = mainController.getAllUsersfromDB() users = mainController.getAllUsersfromDB()
dic = {} dic = {}
for user in users: for user in users:
dic[user.uid] = user.toJSON() dic[user.userid] = user.toJSON()
dic[user.uid]['creditList'] = { dic[user.userid]['creditList'] = {
credit.year: credit.toJSON() for credit in user.geruechte} credit.year: credit.toJSON() for credit in user.geruechte}
debug.debug("return {{ {} }}".format(dic)) debug.debug("return {{ {} }}".format(dic))
return jsonify(dic) return jsonify(dic)
@ -168,8 +168,8 @@ def _finanzerAddUser(**kwargs):
users = mainController.getAllUsersfromDB() users = mainController.getAllUsersfromDB()
dic = {} dic = {}
for user in users: for user in users:
dic[user.uid] = user.toJSON() dic[user.userid] = user.toJSON()
dic[user.uid]['creditList'] = { dic[user.userid]['creditList'] = {
credit.year: credit.toJSON() for credit in user.geruechte} credit.year: credit.toJSON() for credit in user.geruechte}
debug.debug("return {{ {} }}".format(dic)) debug.debug("return {{ {} }}".format(dic))
return jsonify(dic), 200 return jsonify(dic), 200

View File

@ -94,9 +94,9 @@ class MainController(#mainJobKindController.Base,
def __updateDataFromLDAP(self, user): def __updateDataFromLDAP(self, user):
logger.info("update data from ldap for user {{ {} }}".format(user)) logger.info("update data from ldap for user {{ {} }}".format(user))
groups = ldap.getGroup(user.uid) groups = ldap.getGroup(user.userid)
logger.debug("ldap gorups are {{ {} }}".format(groups)) logger.debug("ldap gorups are {{ {} }}".format(groups))
user_data = ldap.getUserData(user.uid) user_data = ldap.getUserData(user.userid)
logger.debug("ldap data is {{ {} }}".format(user_data)) logger.debug("ldap data is {{ {} }}".format(user_data))
user_data['gruppe'] = groups user_data['gruppe'] = groups
user_data['group'] = groups user_data['group'] = groups

View File

@ -34,7 +34,7 @@ class Base:
amount, username, month, year)) amount, username, month, year))
user = self.getUser(username) user = self.getUser(username)
debug.debug("user is {{ {} }}".format(user)) debug.debug("user is {{ {} }}".format(user))
if user.uid == 'extern': if user.userid == 'extern':
debug.debug("user is extern user, so exit add amount") debug.debug("user is extern user, so exit add amount")
return return
if not user.locked or finanzer: if not user.locked or finanzer:
@ -60,7 +60,7 @@ class Base:
credit, username, month, year)) credit, username, month, year))
user = self.getUser(username) user = self.getUser(username)
debug.debug("user is {{ {} }}".format(user)) debug.debug("user is {{ {} }}".format(user))
if user.uid == 'extern': if user.userid == 'extern':
debug.debug("user is extern user, so exit add credit") debug.debug("user is extern user, so exit add credit")
return return
user.addCredit(credit, year=year, month=month) user.addCredit(credit, year=year, month=month)

View File

@ -57,7 +57,7 @@ def __edit_user(uid, **kwargs):
if not user: if not user:
raise NotFound raise NotFound
if uid != kwargs["access_token"].user.uid and user.has_permissions(permissions["EDIT_USER"]): if uid != kwargs["access_token"].user.userid and user.has_permissions(permissions["EDIT_USER"]):
return Forbidden return Forbidden
data = request.get_json() data = request.get_json()

View File

@ -1,5 +1,5 @@
import secrets import secrets
from ..models.accessToken import AccessToken from ..models.session import Session
from flaschengeist.system.database import db from flaschengeist.system.database import db
from flaschengeist import logger from flaschengeist import logger
from werkzeug.exceptions import Forbidden from werkzeug.exceptions import Forbidden
@ -7,22 +7,22 @@ from datetime import datetime, timezone
from . import Singleton from . import Singleton
class AccessTokenController(metaclass=Singleton): class SessionController(metaclass=Singleton):
"""Control all created AccessToken """Control all created Sessions
This Class create, delete, find and manage AccessToken. This Class create, delete, find and manage Sessions.
Attributes: Attributes:
lifetime: Variable for the Lifetime of one AccessToken in seconds. lifetime: Variable for the Lifetime of a Session in seconds.
""" """
def __init__(self, lifetime=1800): def __init__(self, lifetime=1800):
self.lifetime = lifetime self.lifetime = lifetime
def validate_token(self, token, user_agent, permissions): def validate_token(self, token, user_agent, permissions):
"""Verify access token """Verify session
Verify an AccessToken and Roles so if the User has permission or not. Verify a Session and Roles so if the User has permission or not.
Retrieves the access token if valid else retrieves False Retrieves the access token if valid else retrieves False
Args: Args:
@ -30,10 +30,10 @@ class AccessTokenController(metaclass=Singleton):
user_agent: User agent of browser to check user_agent: User agent of browser to check
permissions: Permissions needed to access restricted routes permissions: Permissions needed to access restricted routes
Returns: Returns:
An the AccessToken for this given Token or False. A Session for this given Token or False.
""" """
logger.debug("check token {{ {} }} is valid".format(token)) logger.debug("check token {{ {} }} is valid".format(token))
access_token = AccessToken.query.filter_by(token=token).one_or_none() access_token = Session.query.filter_by(token=token).one_or_none()
if access_token: if access_token:
logger.debug("token found, check if expired or invalid user agent differs") logger.debug("token found, check if expired or invalid user agent differs")
if access_token.expires >= datetime.utcnow() and ( if access_token.expires >= datetime.utcnow() and (
@ -45,34 +45,34 @@ class AccessTokenController(metaclass=Singleton):
return access_token return access_token
else: else:
logger.debug("access token is out of date or invalid client used") logger.debug("access token is out of date or invalid client used")
self.delete_token(access_token) self.delete_session(access_token)
logger.debug("no valid access token with token: {{ {} }} and permissions: {{ {} }}".format(token, permissions)) logger.debug("no valid access token with token: {{ {} }} and permissions: {{ {} }}".format(token, permissions))
return False return False
def create(self, user, user_agent=None) -> AccessToken: def create(self, user, user_agent=None) -> Session:
"""Create an AccessToken """Create a Session
Args: Args:
user: For which User is to create an AccessToken user: For which User is to create a Session
user_agent: User agent to identify session user_agent: User agent to identify session
Returns: Returns:
AccessToken: A created Token for User Session: A created Token for User
""" """
logger.debug("create access token") logger.debug("create access token")
token_str = secrets.token_hex(16) token_str = secrets.token_hex(16)
token = AccessToken( session = Session(
token=token_str, user=user, lifetime=self.lifetime, browser=user_agent.browser, platform=user_agent.platform token=token_str, user=user, lifetime=self.lifetime, browser=user_agent.browser, platform=user_agent.platform
) )
token.refresh() session.refresh()
db.session.add(token) db.session.add(session)
db.session.commit() db.session.commit()
logger.debug("access token is {{ {} }}".format(token)) logger.debug("access token is {{ {} }}".format(session.token))
return token return session
def get_token(self, token, owner=None): def get_session(self, token, owner=None):
"""Retrieves AccessToken from token string """Retrieves Session from token string
Args: Args:
token (str): Token string token (str): Token string
@ -81,38 +81,38 @@ class AccessTokenController(metaclass=Singleton):
Raises: Raises:
Forbidden: Raised if owner is set but does not match Forbidden: Raised if owner is set but does not match
Returns: Returns:
AccessToken: Token object identified by given token string Session: Token object identified by given token string
""" """
access_token = AccessToken.query.filter(AccessToken.token == token).one_or_none() session = Session.query.filter(Session.token == token).one_or_none()
if access_token and (owner and owner != access_token.user): if session and (owner and owner != session.user):
raise Forbidden raise Forbidden
return access_token return session
def get_users_tokens(self, user): def get_users_sessions(self, user):
return AccessToken.query.filter(AccessToken.user == user) return Session.query.filter(Session.user == user)
@staticmethod @staticmethod
def delete_token(token: AccessToken): def delete_session(token: Session):
"""Deletes given AccessToken """Deletes given Session
Args: Args:
token (AccessToken): Token to delete token (Session): Token to delete
""" """
db.session.delete(token) db.session.delete(token)
db.session.commit() db.session.commit()
@staticmethod @staticmethod
def update_token(token): def update_session(session):
token.refresh() session.refresh()
db.session.commit() db.session.commit()
def set_lifetime(self, token, lifetime): def set_lifetime(self, session, lifetime):
token.lifetime = lifetime session.lifetime = lifetime
self.update_token(token) self.update_session(session)
def clear_expired(self): def clear_expired(self):
"""Remove expired tokens from database""" """Remove expired tokens from database"""
logger.debug("Clear expired AccessToken") logger.debug("Clear expired Sessions")
deleted = AccessToken.query.filter(AccessToken.expires < datetime.utcnow()).delete() deleted = Session.query.filter(Session.expires < datetime.utcnow()).delete()
logger.debug("{} tokens have been removed".format(deleted)) logger.debug("{} sessions have been removed".format(deleted))
db.session.commit() db.session.commit()

View File

@ -7,9 +7,9 @@ from flaschengeist import logger
def login_user(username, password): def login_user(username, password):
logger.info("login user {{ {} }}".format(username)) logger.info("login user {{ {} }}".format(username))
user = User.query.filter_by(uid=username).one_or_none() user = User.query.filter(User.userid == username).one_or_none()
if user is None: if user is None:
user = User(uid=username) user = User(userid=username)
db.session.add(user) db.session.add(user)
if current_app.config["FG_AUTH_BACKEND"].login(user, password): if current_app.config["FG_AUTH_BACKEND"].login(user, password):
update_user(user) update_user(user)
@ -49,4 +49,4 @@ def get_user_by_role(role: Role):
def get_user(uid): def get_user(uid):
return User.query.filter(User.uid == uid).one_or_none() return User.query.filter(User.userid == uid).one_or_none()

View File

@ -6,9 +6,9 @@ from flaschengeist import logger
def login_required(**kwargs): def login_required(**kwargs):
from .controller.accessTokenController import AccessTokenController from .controller.sessionController import SessionController
ac_controller = AccessTokenController() ac_controller = SessionController()
permissions = None permissions = None
if "permissions" in kwargs: if "permissions" in kwargs:
permissions = kwargs["roles"] permissions = kwargs["roles"]
@ -16,7 +16,7 @@ def login_required(**kwargs):
def real_decorator(func): def real_decorator(func):
@wraps(func) @wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
token = request.headers.get("Token") token = request.headers.get("Authorization").split(" ")[-1]
access_token = ac_controller.validate_token(token, request.user_agent, permissions) access_token = ac_controller.validate_token(token, request.user_agent, permissions)
if access_token: if access_token:
kwargs["access_token"] = access_token kwargs["access_token"] = access_token

View File

@ -1,11 +1,13 @@
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from .user import User
from ..database import db from ..database import db
from secrets import compare_digest from secrets import compare_digest
from flaschengeist import logger from flaschengeist import logger
class AccessToken(db.Model): class Session(db.Model):
"""Model for an AccessToken """Model for a Session
Args: Args:
expires: Is a Datetime from current Time. expires: Is a Datetime from current Time.
@ -16,20 +18,20 @@ class AccessToken(db.Model):
__tablename__ = "session" __tablename__ = "session"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id")) user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
user = db.relationship("User", back_populates="sessions") user: User = db.relationship("User", back_populates="sessions")
expires = db.Column(db.DateTime) expires: datetime = db.Column(db.DateTime)
token = db.Column(db.String(32), unique=True) token: str = db.Column(db.String(32), unique=True)
lifetime = db.Column(db.Integer) lifetime: int = db.Column(db.Integer)
browser = db.Column(db.String(30)) browser: str = db.Column(db.String(30))
platform = db.Column(db.String(30)) platform: str = db.Column(db.String(30))
def refresh(self): def refresh(self):
"""Update the Timestamp """Update the Timestamp
Update the Timestamp to the current Time. Update the Timestamp to the current Time.
""" """
logger.debug("update timestamp from access token {{ {} }}".format(self)) logger.debug("update timestamp from session with token {{ {} }}".format(self))
self.expires = datetime.utcnow() + timedelta(seconds=self.lifetime) self.expires = datetime.utcnow() + timedelta(seconds=self.lifetime)
def serialize(self): def serialize(self):
@ -42,14 +44,10 @@ class AccessToken(db.Model):
"token": self.token, "token": self.token,
"expires": self.expires.replace(tzinfo=timezone.utc), "expires": self.expires.replace(tzinfo=timezone.utc),
"lifetime": self.lifetime, "lifetime": self.lifetime,
"user": self.user,
"browser": self.browser, "browser": self.browser,
"platform": self.platform, "platform": self.platform,
} }
def __eq__(self, token): def __eq__(self, token):
return compare_digest(self.token, token) return compare_digest(self.token, token)
def __str__(self):
return "AccessToken(user={}, token={}, expires={}, lifetime={})".format(
self.user, self.token, self.expires, self.lifetime
)

View File

@ -28,13 +28,13 @@ class User(db.Model):
__tablename__ = "user" __tablename__ = "user"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
uid = db.Column(db.String(30)) userid = db.Column(db.String(30))
display_name = db.Column(db.String(30)) display_name = db.Column(db.String(30))
firstname = db.Column(db.String(30)) firstname = db.Column(db.String(30))
lastname = db.Column(db.String(30)) lastname = db.Column(db.String(30))
mail = db.Column(db.String(30)) mail = db.Column(db.String(30))
roles = db.relationship("Role", secondary=association_table) roles = db.relationship("Role", secondary=association_table)
sessions = db.relationship("AccessToken", back_populates="user") sessions = db.relationship("Session", back_populates="user")
attributes = db.relationship( attributes = db.relationship(
"UserAttribute", collection_class=attribute_mapped_collection("name"), cascade="all, delete" "UserAttribute", collection_class=attribute_mapped_collection("name"), cascade="all, delete"
) )
@ -53,8 +53,8 @@ class User(db.Model):
def update_data(self, data): def update_data(self, data):
logger.debug("update data of user") logger.debug("update data of user")
if "uid" in data: if "userid" in data:
self.uid = data["uid"] self.userid = data["userid"]
if "firstname" in data: if "firstname" in data:
self.firstname = data["firstname"] self.firstname = data["firstname"]
if "lastname" in data: if "lastname" in data:
@ -76,7 +76,7 @@ class User(db.Model):
def serialize(self): def serialize(self):
return { return {
"userid": self.uid, "userid": self.userid,
"display_name": self.display_name, "display_name": self.display_name,
"firstname": self.firstname, "firstname": self.firstname,
"lastname": self.lastname, "lastname": self.lastname,