From ff9d21bcd5eac4b1557d056dd07dc06fedaa22da Mon Sep 17 00:00:00 2001 From: Simon Pirkelmann Date: Thu, 27 Jan 2022 23:45:17 +0100 Subject: [PATCH] moved creation of initial admin user to separate function --- imaginaerraum_door_admin/__init__.py | 109 ++++++++++++++------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/imaginaerraum_door_admin/__init__.py b/imaginaerraum_door_admin/__init__.py index 8d9d10a..d381e71 100644 --- a/imaginaerraum_door_admin/__init__.py +++ b/imaginaerraum_door_admin/__init__.py @@ -2,7 +2,8 @@ import logging from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_security.models import fsqla_v2 as fsqla -from flask_security import Security, SQLAlchemyUserDatastore +from flask_security import Security, SQLAlchemyUserDatastore, hash_password +from email_validator import validate_email import ldap3 @@ -15,6 +16,57 @@ from .auth import ExtendedLoginForm security = Security() +# create admin users (only if they don't exists already) +def create_super_admins(app, db, user_datastore, logger): + # setup user database when starting the app + with app.app_context(): + new_admin_data = [] + if app.config['ADMIN_FILE'] is not None: + if not Path(app.config['ADMIN_FILE']).exists(): + logger.warning( + f"Admin user creation file not found at {app.config['ADMIN_FILE']}") + else: + # store data for new admins in memory s.t. the file can be deleted afterwards + with open(app.config['ADMIN_FILE']) as f: + for i, line in enumerate(f.readlines()): + if not line.strip().startswith('#'): + try: + user, email, pw = line.split() + validate_email(email) + new_admin_data.append( + {'username': user, 'email': email, + 'password': pw}) + except Exception as e: + print( + f"Error while parsing line {i} in admin config file. Config file should contain lines of " + f"' \\n'\n Exception: {e}\nAdmin account could not be created.") + + db.create_all() + super_admin_role = user_datastore.find_or_create_role( + 'super_admin') # root admin = can create other admins + admin_role = user_datastore.find_or_create_role( + 'admin') # 'normal' admin + local_role = user_datastore.find_or_create_role( + 'local') # LDAP user or local user + + for d in new_admin_data: + if user_datastore.find_user(email=d['email'], + username=d['username']) is None: + roles = [super_admin_role, admin_role] + if not d['password'] == 'LDAP': + roles.append(local_role) + logger.info( + f"New super admin user created with username '{d['username']}' and email '{d['email']}', roles = {[r.name for r in roles]}") + + # create new admin (only if admin does not already exist) + new_admin = user_datastore.create_user(email=d['email'], + username=d[ + 'username'], + password=hash_password( + d['password']), + roles=roles) + db.session.commit() + def setup_logging(app): # set up logging for the web app logger = logging.getLogger('webapp') @@ -108,63 +160,12 @@ def create_app(): app.register_blueprint(door_app) - # setup user database when starting the app - # with app.app_context(): - # new_admin_data = [] - # if config.admin_file is not None: - # if not Path(config.admin_file).exists(): - # logger.warning( - # f"Admin user creation file not found at {config.admin_file}") - # else: - # # store data for new admins in memory s.t. the file can be deleted afterwards - # with open(config.admin_file) as f: - # for i, line in enumerate(f.readlines()): - # if not line.strip().startswith('#'): - # try: - # user, email, pw = line.split() - # validate_email(email) - # new_admin_data.append( - # {'username': user, 'email': email, - # 'password': pw}) - # except Exception as e: - # print( - # f"Error while parsing line {i} in admin config file. Config file should contain lines of " - # f"' \\n'\n Exception: {e}\nAdmin account could not be created.") - # - # # create admin users (only if they don't exists already) - # def create_super_admins(new_admin_data): - # db.create_all() - # super_admin_role = user_datastore.find_or_create_role( - # 'super_admin') # root admin = can create other admins - # admin_role = user_datastore.find_or_create_role( - # 'admin') # 'normal' admin - # local_role = user_datastore.find_or_create_role( - # 'local') # LDAP user or local user - # - # for d in new_admin_data: - # if user_datastore.find_user(email=d['email'], - # username=d['username']) is None: - # roles = [super_admin_role, admin_role] - # if not d['password'] == 'LDAP': - # roles.append(local_role) - # logger.info( - # f"New super admin user created with username '{d['username']}' and email '{d['email']}', roles = {[r.name for r in roles]}") - # - # # create new admin (only if admin does not already exist) - # new_admin = user_datastore.create_user(email=d['email'], - # username=d[ - # 'username'], - # password=hash_password( - # d['password']), - # roles=roles) - # db.session.commit() - # - # create_super_admins(new_admin_data) - ldap_server = ldap3.Server(app.config['LDAP_URL']) # Setup Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) security.init_app(app, user_datastore, login_form=ExtendedLoginForm) + create_super_admins(app, db, user_datastore, logger) + return app \ No newline at end of file