Make it possible to configure plugins.
* Reworked configuration
This commit is contained in:
parent
a000ccfb1c
commit
32066b1005
|
@ -29,55 +29,31 @@ def create_app():
|
|||
CORS(app)
|
||||
|
||||
with app.app_context():
|
||||
from .system.controller import dbConfig, ldapConfig
|
||||
from .system.database import db
|
||||
app.config['SECRET_KEY'] = '0a657b97ef546da90b2db91862ad4e29'
|
||||
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://{user}:{passwd}@{host}/{database}'.format(
|
||||
user=dbConfig['user'],
|
||||
passwd=dbConfig['passwd'],
|
||||
host=dbConfig['URL'],
|
||||
database=dbConfig['database'])
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
|
||||
# app.config['MYSQL_CURSORCLASS'] = 'DictCursor'
|
||||
app.config['LDAP_SERVER'] = ldapConfig['URL']
|
||||
app.config['LDAP_PORT'] = ldapConfig['PORT']
|
||||
if ldapConfig['BIND_DN']:
|
||||
app.config['LDAP_BINDDN'] = ldapConfig['BIND_DN']
|
||||
else:
|
||||
app.config['LDAP_BINDDN'] = ldapConfig['DN']
|
||||
if ldapConfig['BIND_SECRET']:
|
||||
app.config['LDAP_SECRET'] = ldapConfig['BIND_SECRET']
|
||||
app.config['LDAP_USE_TLS'] = False
|
||||
app.config['LDAP_USE_SSL'] = ldapConfig['SSL']
|
||||
app.config['LDAP_TLS_VERSION'] = ssl.PROTOCOL_TLSv1_2
|
||||
app.config['LDAP_REQUIRE_CERT'] = ssl.CERT_NONE
|
||||
app.config['FORCE_ATTRIBUTE_VALUE_AS_LIST'] = True
|
||||
|
||||
app.config['FG_AUTH_BACKENDS'] = [
|
||||
entry_point.load() for entry_point in pkg_resources.iter_entry_points('flaschengeist.auth')
|
||||
]
|
||||
|
||||
ldap = LDAPConn(app)
|
||||
from .system.config import configure_app, config
|
||||
configure_app(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)
|
||||
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 None)
|
||||
logger.info('Loaded authentification 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.info('Search for plugins')
|
||||
discovered_plugins = {
|
||||
entry_point.name: entry_point.load()
|
||||
for entry_point in pkg_resources.iter_entry_points('flaschengeist.plugin')
|
||||
}
|
||||
|
||||
#from geruecht import routes
|
||||
#from geruecht.baruser.routes import baruser
|
||||
#from geruecht.finanzer.routes import finanzer
|
||||
#from geruecht.user.routes import user
|
||||
#from geruecht.vorstand.routes import vorstand
|
||||
#from geruecht.gastro.routes import gastrouser
|
||||
#from geruecht.registration_route import registration
|
||||
|
||||
app.logger.info("Registrate bluebrints")
|
||||
for name in discovered_plugins:
|
||||
app.logger.info("Register plugin: %s" % name)
|
||||
logger.debug("Found plugin: %s", name)
|
||||
if config.get(name, 'enabled', fallback=False):
|
||||
logger.info('Loaded plugin > %s <', name)
|
||||
app.register_blueprint(discovered_plugins[name]())
|
||||
|
||||
return app
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
AccessTokenLifeTime: 1800
|
||||
Database:
|
||||
URL:
|
||||
user:
|
||||
passwd:
|
||||
database:
|
||||
LDAP:
|
||||
URL:
|
||||
DN:
|
||||
BIND_DN:
|
||||
BIND_SECRET:
|
||||
SSL:
|
||||
USER_DN:
|
||||
ADMIN_DN:
|
||||
ADMIN_SECRET:
|
||||
Mail:
|
||||
URL:
|
||||
port:
|
||||
user:
|
||||
passwd:
|
||||
email:
|
||||
crypt: SSL/STARTLS
|
|
@ -0,0 +1,37 @@
|
|||
[FLASCHENGEIST]
|
||||
# Set lifetime of session (idle time until you get logged out)
|
||||
AccessTokenLifetime = 1800
|
||||
# Select authentification provider
|
||||
AUTH = auth_plain
|
||||
|
||||
[DATABASE]
|
||||
USER =
|
||||
HOST =
|
||||
PASSWD =
|
||||
DATABASE =
|
||||
|
||||
# [LDAP]
|
||||
# URL =
|
||||
# PORT =
|
||||
# BINDDN =
|
||||
# SECRET =
|
||||
# USE_SSL =
|
||||
## ADMIN_DN:
|
||||
## ADMIN_SECRET:
|
||||
|
||||
[MAIL]
|
||||
URL =
|
||||
PORT =
|
||||
USER =
|
||||
PASSWD =
|
||||
MAIL =
|
||||
CRYPT = SSL/STARTLS
|
||||
|
||||
############################
|
||||
# Configuration of plugins #
|
||||
############################
|
||||
[geruecht]
|
||||
enable = true
|
||||
|
||||
[schubu]
|
||||
enable = false
|
|
@ -1,4 +1,10 @@
|
|||
class Auth():
|
||||
def defaultConfig(self):
|
||||
return None
|
||||
|
||||
def configure(self, config):
|
||||
pass
|
||||
|
||||
def login(self, user, pw):
|
||||
"""
|
||||
user User class containing at least the uid
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import flaschengeist.modules as modules
|
||||
from flask import current_app as app
|
||||
|
||||
class AuthPlain(modules.Auth):
|
||||
def configure(self, config):
|
||||
app.config.update(
|
||||
'LDAP_SERVER' = config['URL'],
|
||||
'LDAP_PORT' = config['PORT'],
|
||||
'LDAP_BINDDN' = config['BINDDN'],
|
||||
'LDAP_SECRET' = config['SECRET']
|
||||
'LDAP_USE_SSL' = config['USE_SSL'],
|
||||
'LDAP_TLS_VERSION' = ssl.PROTOCOL_TLSv1_2,
|
||||
'LDAP_REQUIRE_CERT' = ssl.CERT_NONE,
|
||||
'FORCE_ATTRIBUTE_VALUE_AS_LIST' = True
|
||||
)
|
||||
|
||||
def login(self, user, password):
|
||||
if not user:
|
||||
return False
|
||||
return False
|
|
@ -0,0 +1,162 @@
|
|||
import configparser
|
||||
import os
|
||||
from pathlib import Path
|
||||
from .. import _modpath, logger
|
||||
|
||||
default = {
|
||||
'FLASCHENGEIST': {
|
||||
'AccessTokenLifeTime': 1800
|
||||
},
|
||||
'MAIL': {
|
||||
'CRYPT': 'SSL/STARTLS'
|
||||
}
|
||||
}
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read_dict(default)
|
||||
pathes = [_modpath, Path.home()/".config"]
|
||||
if 'FLASCHENGEIST_CONF' in os.environ:
|
||||
pathes.append(Path(os.environ.get("FLASCHENGEIST_CONF")))
|
||||
for loc in pathes:
|
||||
try:
|
||||
with (loc/"flaschengeist.cfg").open() as source:
|
||||
config.read_file(source)
|
||||
except IOError:
|
||||
pass
|
||||
# Always enable this buildin plugins!
|
||||
config.read_dict({
|
||||
'auth': {
|
||||
'enabled': True
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def configure_app(app):
|
||||
if not config.has_option('FLASCHENGEIST', 'SECRET_KEY'):
|
||||
logger.warn('No secret key was configured, please configure one for production systems!')
|
||||
app.config['SECRET_KEY'] = config.get('FLASCHENGEIST', 'SECRET_KEY', fallback='0a657b97ef546da90b2db91862ad4e29')
|
||||
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://{user}:{passwd}@{host}/{database}'.format(
|
||||
user=config['DATABASE']['user'],
|
||||
passwd=config['DATABASE']['passwd'],
|
||||
host=config['DATABASE']['host'],
|
||||
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()
|
|
@ -1,135 +0,0 @@
|
|||
import yaml
|
||||
import sys
|
||||
from flask import current_app
|
||||
from werkzeug.local import LocalProxy
|
||||
logger = LocalProxy(lambda: current_app.logger)
|
||||
|
||||
default = {
|
||||
'AccessTokenLifeTime': 1800,
|
||||
'Mail': {
|
||||
'URL': '',
|
||||
'port': 0,
|
||||
'user': '',
|
||||
'passwd': '',
|
||||
'email': '',
|
||||
'crypt': 'STARTTLS'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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()
|
|
@ -1,8 +1,3 @@
|
|||
from ..configparser import ConifgParser
|
||||
from flaschengeist import _modpath
|
||||
|
||||
config = ConifgParser(_modpath/'config.yml')
|
||||
|
||||
class Singleton(type):
|
||||
_instances = {}
|
||||
def __call__(cls, *args, **kwargs):
|
||||
|
@ -10,7 +5,3 @@ class Singleton(type):
|
|||
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
||||
return cls._instances[cls]
|
||||
|
||||
dbConfig = config.getDatabase()
|
||||
ldapConfig = config.getLDAP()
|
||||
accConfig = config.getAccessToken()
|
||||
mailConfig = config.getMail()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from .. import Singleton, mailConfig
|
||||
from .. import Singleton
|
||||
from ...models.user import User
|
||||
from datetime import datetime, timedelta
|
||||
from . import mainUserController
|
||||
|
|
|
@ -167,9 +167,7 @@ class Base:
|
|||
user = User.query.filter_by(uid=username).first()
|
||||
if user is None:
|
||||
user = User(uid=username)
|
||||
for backend in current_app.config['FG_AUTH_BACKENDS']:
|
||||
b = backend()
|
||||
if b.login(user, password):
|
||||
if current_app.config['FG_AUTH_BACKEND'].login(user, password):
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
return user
|
||||
|
|
Loading…
Reference in New Issue