Fixed typos
This commit is contained in:
parent
e4b4db3405
commit
b4505de253
|
@ -1,7 +1,7 @@
|
||||||
#############################################
|
#############################################
|
||||||
# Plugin: Auth #
|
# Plugin: Auth #
|
||||||
# Functionality: Allow management of #
|
# Functionality: Allow management of #
|
||||||
# authentification, login, logout, etc #
|
# authentication, login, logout, etc #
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
from flask import Blueprint, current_app, request, jsonify
|
from flask import Blueprint, current_app, request, jsonify
|
||||||
|
@ -24,7 +24,7 @@ def register():
|
||||||
return auth_bp
|
return auth_bp
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
## Routes ##
|
# Routes #
|
||||||
############################################
|
############################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,10 +68,10 @@ def _login():
|
||||||
def _logout(**kwargs):
|
def _logout(**kwargs):
|
||||||
try:
|
try:
|
||||||
logger.debug("logout user")
|
logger.debug("logout user")
|
||||||
accToken = kwargs['accToken']
|
token = kwargs['accToken']
|
||||||
logger.debug("accesstoken is {{ {} }}".format(accToken))
|
logger.debug("access token is {{ {} }}".format(token))
|
||||||
logger.debug("delete accesstoken")
|
logger.debug("delete access token")
|
||||||
access_controller.deleteAccessToken(accToken)
|
access_controller.deleteAccessToken(token)
|
||||||
access_controller.clearExpired()
|
access_controller.clearExpired()
|
||||||
logger.info("return ok logout user")
|
logger.info("return ok logout user")
|
||||||
return jsonify({"ok": "ok"})
|
return jsonify({"ok": "ok"})
|
||||||
|
@ -81,7 +81,7 @@ def _logout(**kwargs):
|
||||||
|
|
||||||
|
|
||||||
@auth_bp.route("/user/getAccessTokens", methods=['GET', 'POST'])
|
@auth_bp.route("/user/getAccessTokens", methods=['GET', 'POST'])
|
||||||
#@auth_bp.route("/accessTokens", methods=['GET', 'POST'])
|
# @auth_bp.route("/accessTokens", methods=['GET', 'POST'])
|
||||||
@login_required()
|
@login_required()
|
||||||
def _getAccessTokens(**kwargs):
|
def _getAccessTokens(**kwargs):
|
||||||
try:
|
try:
|
||||||
|
@ -102,12 +102,12 @@ def _getAccessTokens(**kwargs):
|
||||||
@login_required()
|
@login_required()
|
||||||
def _getLifeTime(**kwargs):
|
def _getLifeTime(**kwargs):
|
||||||
try:
|
try:
|
||||||
logger.debug("get lifetime of accesstoken")
|
logger.debug("get lifetime of access token")
|
||||||
accToken = kwargs['accToken']
|
token = kwargs['accToken']
|
||||||
logger.debug("accessToken is {{ {} }}".format(accToken))
|
logger.debug("accessToken is {{ {} }}".format(token))
|
||||||
return jsonify({"value": accToken.lifetime})
|
return jsonify({"value": token.lifetime})
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.warning("exception in get lifetime of accesstoken.", exc_info=True)
|
logger.warning("exception in get lifetime of access token.", exc_info=True)
|
||||||
return jsonify({"error": str(err)}), 500
|
return jsonify({"error": str(err)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ def _saveLifeTime(**kwargs):
|
||||||
token.lifetime = lifetime
|
token.lifetime = lifetime
|
||||||
logger.info("update access token timestamp")
|
logger.info("update access token timestamp")
|
||||||
token = access_controller.update(token)
|
token = access_controller.update(token)
|
||||||
return jsonify({"value": token.lifetime })
|
return jsonify({"value": token.lifetime})
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"exception in save lifetime for access token.", exc_info=True)
|
"exception in save lifetime for access token.", exc_info=True)
|
||||||
|
|
|
@ -10,9 +10,9 @@ logger = logging.getLogger("flaschenpost")
|
||||||
|
|
||||||
|
|
||||||
class AccessTokenController(metaclass=Singleton):
|
class AccessTokenController(metaclass=Singleton):
|
||||||
""" Control all createt AccesToken
|
""" Control all created AccessToken
|
||||||
|
|
||||||
This Class create, delete, find and manage AccesToken.
|
This Class create, delete, find and manage AccessToken.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
lifetime: Variable for the Lifetime of one AccessToken in seconds.
|
lifetime: Variable for the Lifetime of one AccessToken in seconds.
|
||||||
|
@ -25,10 +25,10 @@ class AccessTokenController(metaclass=Singleton):
|
||||||
|
|
||||||
Initialize Thread and set tokenList empty.
|
Initialize Thread and set tokenList empty.
|
||||||
"""
|
"""
|
||||||
logger.debug("init accesstoken controller")
|
logger.debug("init access token controller")
|
||||||
self.lifetime = lifetime
|
self.lifetime = lifetime
|
||||||
|
|
||||||
def validate(self, token, roles):
|
def validate_token(self, token, roles):
|
||||||
""" Verify access token
|
""" Verify access token
|
||||||
|
|
||||||
Verify an AccessToken and Group so if the User has permission or not.
|
Verify an AccessToken and Group so if the User has permission or not.
|
||||||
|
@ -41,19 +41,19 @@ class AccessTokenController(metaclass=Singleton):
|
||||||
An the AccessToken for this given Token or False.
|
An the AccessToken for this given Token or False.
|
||||||
"""
|
"""
|
||||||
logger.debug("check token {{ {} }} is valid".format(token))
|
logger.debug("check token {{ {} }} is valid".format(token))
|
||||||
for accToken in AccessToken.query.filter_by(token=token):
|
for access_token in AccessToken.query.filter_by(token=token):
|
||||||
time_end = accToken.timestamp + timedelta(seconds=accToken.lifetime)
|
time_end = access_token.timestamp + timedelta(seconds=access_token.lifetime)
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
logger.debug("now is {{ {} }}, endtime is {{ {} }}".format(now, time_end))
|
logger.debug("now is {{ {} }}, endtime is {{ {} }}".format(now, time_end))
|
||||||
if now <= time_end:
|
if now <= time_end:
|
||||||
logger.debug("check if token {{ {} }} is same as {{ {} }}".format(token, accToken))
|
logger.debug("check if token {{ {} }} is same as {{ {} }}".format(token, access_token))
|
||||||
if not roles or (roles and self.userHasRole(accToken.user, roles)):
|
if not roles or (roles and self.userHasRole(access_token.user, roles)):
|
||||||
accToken.updateTimestamp()
|
access_token.updateTimestamp()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return accToken
|
return access_token
|
||||||
else:
|
else:
|
||||||
logger.debug("access token is {{ {} }} out of date".format(accToken))
|
logger.debug("access token is {{ {} }} out of date".format(access_token))
|
||||||
db.session.delete(accToken)
|
db.session.delete(access_token)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
logger.debug("no valid access token with token: {{ {} }} and group: {{ {} }}".format(token, roles))
|
logger.debug("no valid access token with token: {{ {} }} and group: {{ {} }}".format(token, roles))
|
||||||
return False
|
return False
|
||||||
|
@ -79,7 +79,8 @@ class AccessTokenController(metaclass=Singleton):
|
||||||
"""
|
"""
|
||||||
logger.debug("create access token")
|
logger.debug("create access token")
|
||||||
token_str = secrets.token_hex(16)
|
token_str = secrets.token_hex(16)
|
||||||
token = AccessToken(token=token_str, user=user, lifetime=self.lifetime, browser=user_agent.browser, platform=user_agent.platform)
|
token = AccessToken(token=token_str, user=user, lifetime=self.lifetime,
|
||||||
|
browser=user_agent.browser, platform=user_agent.platform)
|
||||||
db.session.add(token)
|
db.session.add(token)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
@ -89,22 +90,23 @@ class AccessTokenController(metaclass=Singleton):
|
||||||
def getAccessTokensFromUser(self, user):
|
def getAccessTokensFromUser(self, user):
|
||||||
return AccessToken.query.filter(AccessToken.user == user)
|
return AccessToken.query.filter(AccessToken.user == user)
|
||||||
|
|
||||||
def deleteAccessToken(self, accessToken):
|
@staticmethod
|
||||||
if accessToken is isinstance(accessToken, AccessToken):
|
def delete_token(token):
|
||||||
db.session.delete(accessToken)
|
if token is isinstance(token, AccessToken):
|
||||||
|
db.session.delete(token)
|
||||||
else:
|
else:
|
||||||
AccessToken.query.filter_by(token=accessToken).delete()
|
AccessToken.query.filter_by(token=token).delete()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def update_token(self, token):
|
def update_token(token):
|
||||||
token.updateTimestamp()
|
token.update_timestamp()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
def clear_expired(self):
|
def clear_expired(self):
|
||||||
logger.debug("Clear expired AccessToken")
|
logger.debug("Clear expired AccessToken")
|
||||||
mightExpired = datetime.utcnow() - timedelta(seconds=self.lifetime)
|
might_expired = datetime.utcnow() - timedelta(seconds=self.lifetime)
|
||||||
tokens = AccessToken.query.filter(AccessToken.timestamp < mightExpired)
|
tokens = AccessToken.query.filter(AccessToken.timestamp < might_expired)
|
||||||
logger.debug(tokens)
|
logger.debug(tokens)
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
if token.timestamp < datetime.utcnow() - timedelta(seconds=token.lifetime):
|
if token.timestamp < datetime.utcnow() - timedelta(seconds=token.lifetime):
|
||||||
|
|
|
@ -15,7 +15,7 @@ def login_required(**kwargs):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
token = request.headers.get('Token')
|
token = request.headers.get('Token')
|
||||||
logger.debug("token is {{ {} }}".format(token))
|
logger.debug("token is {{ {} }}".format(token))
|
||||||
access_token = ac_controller.validate(token, roles)
|
access_token = ac_controller.validate_token(token, roles)
|
||||||
logger.debug("accToken is {{ {} }}".format(access_token))
|
logger.debug("accToken is {{ {} }}".format(access_token))
|
||||||
kwargs['accToken'] = access_token
|
kwargs['accToken'] = access_token
|
||||||
if access_token:
|
if access_token:
|
||||||
|
|
|
@ -25,12 +25,12 @@ class AccessToken(db.Model):
|
||||||
browser = db.Column(db.String(30))
|
browser = db.Column(db.String(30))
|
||||||
platform = db.Column(db.String(30))
|
platform = db.Column(db.String(30))
|
||||||
|
|
||||||
def updateTimestamp(self):
|
def update_timestamp(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 accesstoken {{ {} }}".format(self))
|
logger.debug("update timestamp from access token {{ {} }}".format(self))
|
||||||
self.timestamp = datetime.utcnow()
|
self.timestamp = datetime.utcnow()
|
||||||
|
|
||||||
def toJSON(self):
|
def toJSON(self):
|
||||||
|
@ -61,7 +61,9 @@ class AccessToken(db.Model):
|
||||||
return other - self.timestamp
|
return other - self.timestamp
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "AccessToken(user={}, token={}, timestamp={}, lifetime={}".format(self.user, self.token, self.timestamp, self.lifetime)
|
return "AccessToken(user={}, token={}, timestamp={}, lifetime={}".format(
|
||||||
|
self.user, self.token, self.timestamp, self.lifetime)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "AccessToken(user={}, token={}, timestamp={}, lifetime={}".format(self.user, self.token, self.timestamp, self.lifetime)
|
return "AccessToken(user={}, token={}, timestamp={}, lifetime={}".format(
|
||||||
|
self.user, self.token, self.timestamp, self.lifetime)
|
||||||
|
|
|
@ -2,51 +2,53 @@ from ..database import db
|
||||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from werkzeug.local import LocalProxy
|
from werkzeug.local import LocalProxy
|
||||||
|
|
||||||
logger = LocalProxy(lambda: current_app.logger)
|
logger = LocalProxy(lambda: current_app.logger)
|
||||||
|
|
||||||
association_table = db.Table('user_group',
|
association_table = db.Table('user_group',
|
||||||
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
|
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
|
||||||
db.Column('group_id', db.Integer, db.ForeignKey('group.id'))
|
db.Column('group_id', db.Integer, db.ForeignKey('group.id'))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class User(db.Model):
|
class User(db.Model):
|
||||||
""" Database Object for User
|
""" Database Object for User
|
||||||
|
|
||||||
Table for all safed User
|
Table for all saved User
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
id: Id in Database as Primary Key.
|
id: Id in Database as Primary Key.
|
||||||
uid: User ID used by authentication provider
|
uid: User ID used by authentication provider
|
||||||
displayname: Name to show
|
display_name: Name to show
|
||||||
firstname: Firstname of the User
|
firstname: Firstname of the User
|
||||||
lastname: Lastname of the User
|
lastname: Lastname of the User
|
||||||
mail: mail address of the User
|
mail: mail address of the User
|
||||||
"""
|
"""
|
||||||
__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))
|
uid = db.Column(db.String(30))
|
||||||
displayname = 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))
|
||||||
groups = db.relationship("Group", secondary=association_table)
|
groups = db.relationship("Group", secondary=association_table)
|
||||||
sessions = db.relationship("AccessToken", back_populates="user")
|
sessions = db.relationship("AccessToken", back_populates="user")
|
||||||
attributes = db.relationship("UserAttribute", collection_class=attribute_mapped_collection('name'), cascade="all, delete")
|
attributes = db.relationship("UserAttribute", collection_class=attribute_mapped_collection('name'),
|
||||||
|
cascade="all, delete")
|
||||||
|
|
||||||
def setAttribute(self, name, value):
|
def set_attribute(self, name, value):
|
||||||
if name in self.attributes:
|
if name in self.attributes:
|
||||||
self.attributes[name].value = value
|
self.attributes[name].value = value
|
||||||
else:
|
else:
|
||||||
self.attributes[name] = UserAttribute(name=name, value=value)
|
self.attributes[name] = UserAttribute(name=name, value=value)
|
||||||
|
|
||||||
def addGroup(self, name):
|
def add_group(self, name):
|
||||||
r = Group.query.filter_by(name=name).first()
|
r = Group.query.filter_by(name=name).first()
|
||||||
if not r:
|
if not r:
|
||||||
r = Group(name=name)
|
r = Group(name=name)
|
||||||
self.groups.append(r)
|
self.groups.append(r)
|
||||||
|
|
||||||
def updateData(self, data):
|
def update_data(self, data):
|
||||||
logger.debug("update data of user")
|
logger.debug("update data of user")
|
||||||
if 'uid' in data:
|
if 'uid' in data:
|
||||||
self.uid = data['uid']
|
self.uid = data['uid']
|
||||||
|
@ -56,14 +58,14 @@ class User(db.Model):
|
||||||
self.lastname = data['lastname']
|
self.lastname = data['lastname']
|
||||||
if 'mail' in data:
|
if 'mail' in data:
|
||||||
self.mail = data['mail']
|
self.mail = data['mail']
|
||||||
if 'displayname' in data:
|
if 'display_name' in data:
|
||||||
self.displayname = data['displayname']
|
self.display_name = data['display_name']
|
||||||
|
|
||||||
def toJSON(self):
|
def toJSON(self):
|
||||||
return {
|
return {
|
||||||
# TODO: username should be UID?
|
# TODO: username should be UID?
|
||||||
"username": self.uid,
|
"username": self.uid,
|
||||||
"displayname": self.displayname,
|
"display_name": self.display_name,
|
||||||
"firstname": self.firstname,
|
"firstname": self.firstname,
|
||||||
"lastname": self.lastname,
|
"lastname": self.lastname,
|
||||||
"mail": self.mail,
|
"mail": self.mail,
|
||||||
|
@ -73,20 +75,21 @@ class User(db.Model):
|
||||||
|
|
||||||
class UserAttribute(db.Model):
|
class UserAttribute(db.Model):
|
||||||
__tablename__ = 'userAttribute'
|
__tablename__ = 'userAttribute'
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
user = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
user = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||||
name = db.Column(db.String(30))
|
name = db.Column(db.String(30))
|
||||||
value = db.Column(db.String(192))
|
value = db.Column(db.String(192))
|
||||||
|
|
||||||
|
|
||||||
group_permission_association_table = db.Table('group_permission',
|
group_permission_association_table = db.Table('group_permission',
|
||||||
db.Column('group_id', db.Integer, db.ForeignKey('group.id')),
|
db.Column('group_id', db.Integer, db.ForeignKey('group.id')),
|
||||||
db.Column('permission_id', db.Integer, db.ForeignKey('permission.id'))
|
db.Column('permission_id', db.Integer, db.ForeignKey('permission.id'))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Group(db.Model):
|
class Group(db.Model):
|
||||||
__tablename__ = 'group'
|
__tablename__ = 'group'
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.String(30))
|
name = db.Column(db.String(30))
|
||||||
permissions = db.relationship("Permission", secondary=group_permission_association_table)
|
permissions = db.relationship("Permission", secondary=group_permission_association_table)
|
||||||
|
|
||||||
|
|
3
setup.py
3
setup.py
|
@ -10,7 +10,8 @@ setup(
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
package_data={'': ['*.yml']},
|
package_data={'': ['*.yml']},
|
||||||
scripts=['run_flaschengeist'],
|
scripts=['run_flaschengeist'],
|
||||||
install_requires=['Flask >= 1.1', 'PyYAML>=5.3.1', 'sqlalchemy>=1.3', "flask_sqlalchemy", "flask_cors"],
|
install_requires=['Flask >= 1.1', 'PyYAML>=5.3.1', 'sqlalchemy>=1.3', "flask_sqlalchemy",
|
||||||
|
"flask_cors", "werkzeug"],
|
||||||
extras_require={
|
extras_require={
|
||||||
'ldap': [
|
'ldap': [
|
||||||
'flask_ldapconn',
|
'flask_ldapconn',
|
||||||
|
|
Loading…
Reference in New Issue