cleanup
This commit is contained in:
parent
5bfa305c41
commit
ea107a28dd
|
@ -1,26 +1,25 @@
|
|||
""" 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.
|
||||
Initialize app, CORS, database and add it to the application.
|
||||
Initialize also a singleton for the AccessTokenController and start the Thread.
|
||||
|
||||
"""
|
||||
from pathlib import Path
|
||||
_modpath = Path(__file__).parent
|
||||
|
||||
from flask import Flask
|
||||
from flask_cors import CORS
|
||||
import pkg_resources, yaml
|
||||
|
||||
from logging.config import dictConfig
|
||||
|
||||
with (_modpath/'logging.yml').open(mode='rb') as file:
|
||||
config = yaml.safe_load(file.read())
|
||||
dictConfig(config)
|
||||
|
||||
import yaml
|
||||
import logging
|
||||
import pkg_resources
|
||||
from flask import Flask
|
||||
from pathlib import Path
|
||||
from flask_cors import CORS
|
||||
from logging.config import dictConfig
|
||||
from werkzeug.local import LocalProxy
|
||||
|
||||
_module_path = Path(__file__).parent
|
||||
logger = LocalProxy(lambda: logging.getLogger(__name__))
|
||||
|
||||
with (_module_path / 'logging.yml').open(mode='rb') as file:
|
||||
config = yaml.safe_load(file.read())
|
||||
logging.config.dictConfig(config)
|
||||
|
||||
|
||||
def create_app():
|
||||
app = Flask(__name__)
|
||||
|
@ -33,14 +32,15 @@ def create_app():
|
|||
db.init_app(app)
|
||||
|
||||
for entry_point in pkg_resources.iter_entry_points('flaschengeist.auth'):
|
||||
logger.debug('Found authentification plugin: %s', entry_point.name)
|
||||
logger.debug('Found authentication plugin: %s', entry_point.name)
|
||||
if entry_point.name == config['FLASCHENGEIST']['AUTH']:
|
||||
app.config['FG_AUTH_BACKEND'] = entry_point.load()()
|
||||
app.config['FG_AUTH_BACKEND'].configure(config[entry_point.name] if config.has_section(entry_point.name) else {})
|
||||
logger.info('Loaded authentification plugin > %s <', entry_point.name)
|
||||
app.config['FG_AUTH_BACKEND'].configure(
|
||||
config[entry_point.name] if config.has_section(entry_point.name) else {})
|
||||
logger.info('Loaded authentication plugin > %s <', entry_point.name)
|
||||
break
|
||||
if not app.config['FG_AUTH_BACKEND']:
|
||||
logger.error('No authentification plugin configured or authentification plugin not found')
|
||||
logger.error('No authentication plugin configured or authentication plugin not found')
|
||||
|
||||
logger.info('Search for plugins')
|
||||
for entry_point in pkg_resources.iter_entry_points('flaschengeist.plugin'):
|
||||
|
@ -50,9 +50,3 @@ def create_app():
|
|||
app.register_blueprint(entry_point.load()())
|
||||
|
||||
return app
|
||||
#app.register_blueprint(baruser)
|
||||
#app.register_blueprint(finanzer)
|
||||
#app.register_blueprint(user)
|
||||
#app.register_blueprint(vorstand)
|
||||
#app.register_blueprint(gastrouser)
|
||||
#app.register_blueprint(registration)
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
[FLASCHENGEIST]
|
||||
# Set lifetime of session (idle time until you get logged out)
|
||||
AccessTokenLifetime = 1800
|
||||
# Select authentification provider
|
||||
# Select authentication provider (builtin: auth_plain, auth_ldap)
|
||||
AUTH = auth_plain
|
||||
# Enable if you run flaschengeist behind a proxy, e.g. nginx + gunicorn
|
||||
# PROXY = false
|
||||
# Set root path, prefixes all routes
|
||||
# ROOT = /
|
||||
|
||||
[DATABASE]
|
||||
USER =
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class Auth():
|
||||
class Auth:
|
||||
def configure(self, config):
|
||||
pass
|
||||
|
||||
|
@ -7,14 +7,14 @@ class Auth():
|
|||
user User class containing at least the uid
|
||||
pw given password
|
||||
|
||||
HAS TO BE IMPLEMENTED!
|
||||
MUST BE IMPLEMENTED!
|
||||
|
||||
should return False if not found or invalid credentials
|
||||
should return True if success
|
||||
"""
|
||||
return False
|
||||
raise NotImplementedError
|
||||
|
||||
def updateUser(self, user):
|
||||
def update_user(self, user):
|
||||
"""
|
||||
user User class
|
||||
|
||||
|
@ -22,11 +22,10 @@ class Auth():
|
|||
"""
|
||||
pass
|
||||
|
||||
def modifyUser(self, user):
|
||||
def modify_user(self, user):
|
||||
"""
|
||||
user User class
|
||||
|
||||
If backend is using (writeable) external data, then update the external database with the user provided.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ def _login():
|
|||
try:
|
||||
logger.debug("search {{ {} }} in database".format(username))
|
||||
main_controller = mc.MainController()
|
||||
user = main_controller.loginUser(username, password)
|
||||
user = main_controller.login_user(username, password)
|
||||
logger.debug("user is {{ {} }}".format(user))
|
||||
token = access_controller.create(user, user_agent=request.user_agent)
|
||||
logger.debug("access token is {{ {} }}".format(token))
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from ldap3.core.exceptions import LDAPException
|
||||
|
||||
import flaschengeist.modules as modules
|
||||
from flaschengeist import logger
|
||||
from flask import current_app as app
|
||||
|
@ -39,11 +41,11 @@ class AuthLDAP(modules.Auth):
|
|||
try:
|
||||
r = self.ldap.authenticate(user.uid, password, 'uid', self.dn)
|
||||
return r == True
|
||||
except Exception as err:
|
||||
except LDAPException as err:
|
||||
logger.warning("Exception while login into ldap", exc_info=True)
|
||||
return False
|
||||
|
||||
def modifyUser(self, user):
|
||||
def modify_user(self, user):
|
||||
try:
|
||||
ldap_conn = self.ldap.bind(user.uid, password)
|
||||
if attributes:
|
||||
|
@ -66,7 +68,7 @@ class AuthLDAP(modules.Auth):
|
|||
"username exists on ldap, rechange username on database", exc_info=True)
|
||||
db.changeUsername(user, user.uid)
|
||||
raise Exception(err)
|
||||
except LDAPExcetpion as err:
|
||||
except LDAPException as err:
|
||||
if 'username' in attributes:
|
||||
db.changeUsername(user, user.uid)
|
||||
raise Exception(err)
|
||||
|
@ -105,7 +107,7 @@ class AuthLDAP(modules.Auth):
|
|||
debug.warning("exception in modify user data from ldap", exc_info=True)
|
||||
raise LDAPExcetpion("Something went wrong in LDAP: {}".format(err))
|
||||
|
||||
def updateUser(self, user):
|
||||
def update_user(self, user):
|
||||
self.ldap.connection.search('ou=user,{}'.format(self.dn), '(uid={})'.format(user.uid), SUBTREE,
|
||||
attributes=['uid', 'givenName', 'sn', 'mail'])
|
||||
r = self.ldap.connection.response[0]['attributes']
|
||||
|
|
|
@ -5,23 +5,25 @@ import os
|
|||
import flaschengeist.modules as modules
|
||||
|
||||
|
||||
def _hash_password(password):
|
||||
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
|
||||
pass_hash = hashlib.pbkdf2_hmac('sha3-512', password.encode('utf-8'), salt, 100000)
|
||||
pass_hash = binascii.hexlify(pass_hash)
|
||||
return (salt + pass_hash).decode('ascii')
|
||||
|
||||
|
||||
def _verify_password(stored_password, provided_password):
|
||||
salt = stored_password[:64]
|
||||
stored_password = stored_password[64:]
|
||||
pass_hash = hashlib.pbkdf2_hmac('sha3-512', provided_password.encode('utf-8'), salt.encode('ascii'), 100000)
|
||||
pass_hash = binascii.hexlify(pass_hash).decode('ascii')
|
||||
return pass_hash == stored_password
|
||||
|
||||
|
||||
class AuthPlain(modules.Auth):
|
||||
def login(self, user, password):
|
||||
if not user:
|
||||
return False
|
||||
if 'password' in user.attributes:
|
||||
return self._verify_password(user.attributes['password'].value, password)
|
||||
return _verify_password(user.attributes['password'].value, password)
|
||||
return False
|
||||
|
||||
def _hash_password(self, password):
|
||||
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
|
||||
pass_hash = hashlib.pbkdf2_hmac('sha3-512', password.encode('utf-8'), salt, 100000)
|
||||
pass_hash = binascii.hexlify(pass_hash)
|
||||
return (salt + pass_hash).decode('ascii')
|
||||
|
||||
def _verify_password(self, stored_password, provided_password):
|
||||
salt = stored_password[:64]
|
||||
stored_password = stored_password[64:]
|
||||
pass_hash = hashlib.pbkdf2_hmac('sha3-512', provided_password.encode('utf-8'), salt.encode('ascii'), 100000)
|
||||
pass_hash = binascii.hexlify(pass_hash).decode('ascii')
|
||||
return pass_hash == stored_password
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import configparser
|
||||
import os
|
||||
import configparser
|
||||
from pathlib import Path
|
||||
from .. import _modpath, logger
|
||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
from .. import _module_path, logger
|
||||
|
||||
default = {
|
||||
'FLASCHENGEIST': {
|
||||
'AccessTokenLifeTime': 1800
|
||||
},
|
||||
'MAIL': {
|
||||
'CRYPT': 'SSL/STARTLS'
|
||||
}
|
||||
|
@ -14,7 +12,7 @@ default = {
|
|||
|
||||
config = configparser.ConfigParser()
|
||||
config.read_dict(default)
|
||||
paths = [_modpath, Path.home()/".config"]
|
||||
paths = [_module_path, Path.home()/".config"]
|
||||
if 'FLASCHENGEIST_CONF' in os.environ:
|
||||
paths.append(Path(os.environ.get("FLASCHENGEIST_CONF")))
|
||||
for loc in paths:
|
||||
|
@ -23,7 +21,8 @@ for loc in paths:
|
|||
config.read_file(source)
|
||||
except IOError:
|
||||
pass
|
||||
# Always enable this buildin plugins!
|
||||
|
||||
# Always enable this builtin plugins!
|
||||
config.read_dict({
|
||||
'auth': {
|
||||
'enabled': True
|
||||
|
@ -43,120 +42,8 @@ def configure_app(app):
|
|||
database=config['DATABASE']['database']
|
||||
)
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
|
||||
#class ConifgParser():
|
||||
# def __init__(self, file='config.yml'):
|
||||
# self.file = file
|
||||
# with open(file, 'r') as 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"')
|
||||
#
|
||||
# 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 "BIND_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 "BIND_DN"')
|
||||
# if 'PORT' not in self.config['LDAP']:
|
||||
# logger.info(
|
||||
# 'No Config for port in LDAP found. Set it to default: {}'.format(389))
|
||||
# self.config['LDAP']['PORT'] = 389
|
||||
# if 'ADMIN_DN' not in self.config['LDAP']:
|
||||
# logger.info(
|
||||
# 'No Config for ADMIN_DN in LDAP found. Set it to default {}. (Maybe Password reset not working)'.format(None)
|
||||
# )
|
||||
# self.config['LDAP']['ADMIN_DN'] = None
|
||||
# if 'ADMIN_SECRET' not in self.config['LDAP']:
|
||||
# logger.info(
|
||||
# 'No Config for ADMIN_SECRET in LDAP found. Set it to default {}. (Maybe Password reset not working)'.format(None)
|
||||
# )
|
||||
# self.config['LDAP']['ADMIN_SECRET'] = None
|
||||
# if 'USER_DN' not in self.config['LDAP']:
|
||||
# logger.info(
|
||||
# 'No Config for USER_DN in LDAP found. Set it to default {}. (Maybe Password reset not working)'.format(None)
|
||||
# )
|
||||
# self.config['LDAP']['USER_DN'] = None
|
||||
# if 'BIND_DN' not in self.config['LDAP']:
|
||||
# logger.info(
|
||||
# 'No Config for BIND_DN in LDAP found. Set it to default {}. (Maybe Password reset not working)'.format(None)
|
||||
# )
|
||||
# self.config['LDAP']['BIND_DN'] = None
|
||||
# if 'BIND_SECRET' not in self.config['LDAP']:
|
||||
# logger.info(
|
||||
# 'No Config for BIND_SECRET in LDAP found. Set it to default {}. (Maybe Password reset not working)'.format(None)
|
||||
# )
|
||||
# self.config['LDAP']['BIND_SECRET'] = None
|
||||
# if 'SSL' not in self.config['LDAP']:
|
||||
# logger.info(
|
||||
# 'No Config for SSL in LDAP found. Set it to default {}. (Maybe Password reset not working)'.format(False)
|
||||
# )
|
||||
# self.config['LDAP']['SSL'] = False
|
||||
# else:
|
||||
# self.config['LDAP']['SSL'] = bool(self.config['LDAP']['SSL'])
|
||||
# self.ldap = self.config['LDAP']
|
||||
# logger.debug("Set LDAPconfig: {}".format(self.ldap))
|
||||
# if 'AccessTokenLifeTime' in self.config:
|
||||
# self.accessTokenLifeTime = int(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'])
|
||||
# logger.info("No Conifg for port in Mail found. Set it to default")
|
||||
# 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")
|
||||
# if 'crypt' not in self.config['Mail']:
|
||||
# self.config['Mail']['crypt'] = default['Mail']['crypt']
|
||||
# logger.info("No Config for crypt in Mail found. Set it to default")
|
||||
# self.mail = self.config['Mail']
|
||||
# logger.debug('Set Mailconfig: {}'.format(self.mail))
|
||||
#
|
||||
# def getLDAP(self):
|
||||
# return self.ldap
|
||||
#
|
||||
# def getDatabase(self):
|
||||
# return self.db
|
||||
#
|
||||
# def getAccessToken(self):
|
||||
# return self.accessTokenLifeTime
|
||||
#
|
||||
# def getMail(self):
|
||||
# return self.mail
|
||||
#
|
||||
# def __error__(self, msg):
|
||||
# logger.error(msg, exc_info=True)
|
||||
# sys.exit(-1)
|
||||
#
|
||||
#
|
||||
#if __name__ == '__main__':
|
||||
# ConifgParser()
|
||||
|
||||
if config.has_option("FLASCHENGEIST", "ROOT"):
|
||||
app.config["APPLICATION_ROOT"] = config["FLASCHENGEIST"]["ROOT"]
|
||||
if config.getboolean("FLASCHENGEIST", "PROXY", fallback=False):
|
||||
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
|
||||
|
|
|
@ -7,14 +7,14 @@ from flaschengeist import logger
|
|||
|
||||
|
||||
class Base:
|
||||
def loginUser(self, username, password):
|
||||
def login_user(self, username, password):
|
||||
logger.info("login user {{ {} }}".format(username))
|
||||
user = User.query.filter_by(uid=username).first()
|
||||
if user is None:
|
||||
user = User(uid=username)
|
||||
if current_app.config['FG_AUTH_BACKEND'].login(user, password):
|
||||
db.session.add(user)
|
||||
current_app.config['FG_AUTH_BACKEND'].updateUser(user)
|
||||
current_app.config['FG_AUTH_BACKEND'].update_user(user)
|
||||
db.session.commit()
|
||||
return user
|
||||
raise PermissionDenied()
|
||||
|
|
Loading…
Reference in New Issue