From 5b58872b156672e1bfd02ff48cd3b66f0a1f06d6 Mon Sep 17 00:00:00 2001 From: Terrtia Date: Tue, 11 Jun 2019 17:37:20 +0200 Subject: [PATCH] chg: [user_management UI] add admin section: edit + create users --- var/www/modules/Flask_config.py | 4 + var/www/modules/Role_Manager.py | 107 ++++++++++++++++ var/www/modules/settings/Flask_settings.py | 113 +++++++++++++++- .../settings/templates/create_user.html | 121 ++++++++++++++++++ .../settings/templates/edit_profile.html | 4 +- .../settings/templates/users_list.html | 108 ++++++++++++++++ var/www/templates/settings/menu_sidebar.html | 6 +- 7 files changed, 456 insertions(+), 7 deletions(-) create mode 100644 var/www/modules/settings/templates/create_user.html create mode 100644 var/www/modules/settings/templates/users_list.html diff --git a/var/www/modules/Flask_config.py b/var/www/modules/Flask_config.py index 899a26b5..2219824a 100644 --- a/var/www/modules/Flask_config.py +++ b/var/www/modules/Flask_config.py @@ -7,6 +7,7 @@ import configparser import redis import os +import re import sys # FLASK # @@ -175,6 +176,9 @@ max_dashboard_logs = int(cfg.get("Flask", "max_dashboard_logs")) crawler_enabled = cfg.getboolean("Crawler", "activate_crawler") +regex_password = r'^(?=(.*\d){2})(?=.*[a-z])(?=.*[A-Z]).{10,}$' +regex_password = re.compile(regex_password) + # VT try: from virusTotalKEYS import vt_key diff --git a/var/www/modules/Role_Manager.py b/var/www/modules/Role_Manager.py index 19314003..85440d57 100644 --- a/var/www/modules/Role_Manager.py +++ b/var/www/modules/Role_Manager.py @@ -1,6 +1,12 @@ #!/usr/bin/env python3 # -*-coding:UTF-8 -* +import os +import redis +import bcrypt +import secrets +import configparser + from functools import wraps from flask_login import LoginManager, current_user, login_user, logout_user, login_required @@ -9,6 +15,22 @@ from flask import request, current_app login_manager = LoginManager() login_manager.login_view = 'role' +# CONFIG # +configfile = os.path.join(os.environ['AIL_BIN'], 'packages/config.cfg') +if not os.path.exists(configfile): + raise Exception('Unable to find the configuration file. \ + Did you set environment variables? \ + Or activate the virtualenv.') + +cfg = configparser.ConfigParser() +cfg.read(configfile) + +r_serv_db = redis.StrictRedis( + host=cfg.get("ARDB_DB", "host"), + port=cfg.getint("ARDB_DB", "port"), + db=cfg.getint("ARDB_DB", "db"), + decode_responses=True) + def login_admin(func): @wraps(func) def decorated_view(*args, **kwargs): @@ -28,3 +50,88 @@ def login_analyst(func): return login_manager.unauthorized() return func(*args, **kwargs) return decorated_view + + + +############################################################### +############################################################### +############################################################### + + + +def create_user_db(username_id , password, default=False, role=None, update=False): + password = password.encode() + password_hash = hashing_password(password) + + # create user token + token = secrets.token_urlsafe(41) + r_serv_db.hset('user:tokens', token, username_id) + r_serv_db.hset('user_metadata:{}'.format(username_id), 'token', token) + + if update: + r_serv_db.hdel('user_metadata:{}'.format(username_id), 'change_passwd') + else: + if default: + r_serv_db.hset('user_metadata:{}'.format(username_id), 'change_passwd', True) + if role: + if role in get_all_role(): + for role_to_add in get_all_user_role(role): + r_serv_db.sadd('user_role:{}'.format(role_to_add), username_id) + r_serv_db.hset('user_metadata:{}'.format(username_id), 'role', role) + + r_serv_db.hset('user:all', username_id, password_hash) + +def edit_user_db(user_id, role, password=None): + if password: + password_hash = hashing_password(password.encode()) + r_serv_db.hset('user:all', user_id, password_hash) + + current_role = r_serv_db.hget('user_metadata:{}'.format(user_id), 'role') + if role != current_role: + request_level = get_role_level(role) + current_role = get_role_level(current_role) + + if current_role < request_level: + role_to_remove = get_user_role_by_range(current_role -1, request_level - 2) + print('to remove') + print(role_to_remove) + for role_id in role_to_remove: + r_serv_db.srem('user_role:{}'.format(role_id), user_id) + r_serv_db.hset('user_metadata:{}'.format(user_id), 'role', role) + else: + role_to_add = get_user_role_by_range(request_level -1, current_role) + print('to add') + print(role_to_add) + for role_id in role_to_add: + r_serv_db.sadd('user_role:{}'.format(role_id), user_id) + r_serv_db.hset('user_metadata:{}'.format(user_id), 'role', role) + +def delete_user_db(user_id): + if r_serv_db.exists('user_metadata:{}'.format(user_id)): + print('r') + role_to_remove =get_all_role() + for role_id in role_to_remove: + r_serv_db.srem('user_role:{}'.format(role_id), user_id) + user_token = r_serv_db.hget('user_metadata:{}'.format(user_id), 'token') + r_serv_db.hdel('user:tokens', user_token) + r_serv_db.delete('user_metadata:{}'.format(user_id)) + r_serv_db.hdel('user:all', user_id) + +def hashing_password(bytes_password): + hashed = bcrypt.hashpw(bytes_password, bcrypt.gensalt()) + return hashed + +def get_all_role(): + return r_serv_db.zrange('ail:all_role', 0, -1) + +def get_role_level(role): + return int(r_serv_db.zscore('ail:all_role', role)) + +def get_all_user_role(user_role): + current_role_val = get_role_level(user_role) + return r_serv_db.zrange('ail:all_role', current_role_val -1, -1) + +def get_user_role_by_range(inf, sup): + print(inf) + print(sup) + return r_serv_db.zrange('ail:all_role', inf, sup) diff --git a/var/www/modules/settings/Flask_settings.py b/var/www/modules/settings/Flask_settings.py index b6254d98..683d5b01 100644 --- a/var/www/modules/settings/Flask_settings.py +++ b/var/www/modules/settings/Flask_settings.py @@ -7,6 +7,8 @@ from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for from flask_login import login_required, current_user +from Role_Manager import login_admin, login_analyst, create_user_db, edit_user_db, delete_user_db + import json import secrets import datetime @@ -24,6 +26,7 @@ max_preview_char = Flask_config.max_preview_char max_preview_modal = Flask_config.max_preview_modal REPO_ORIGIN = Flask_config.REPO_ORIGIN dict_update_description = Flask_config.dict_update_description +regex_password = Flask_config.regex_password settings = Blueprint('settings', __name__, template_folder='templates') @@ -33,8 +36,12 @@ settings = Blueprint('settings', __name__, template_folder='templates') def one(): return 1 -#def get_v1.5_update_tags_backgroud_status(): -# return '38%' +def check_password_strength(password): + result = regex_password.match(password) + if result: + return True + else: + return False def generate_new_token(user_id): # create user token @@ -89,6 +96,18 @@ def get_user_metadata(user_id): user_metadata['api_key'] = r_serv_db.hget('user_metadata:{}'.format(user_id), 'token') return user_metadata +def get_users_metadata(list_users): + users = [] + for user in list_users: + users.append(get_user_metadata(user)) + return users + +def get_all_users(): + return r_serv_db.hkeys('user:all') + +def get_all_roles(): + return r_serv_db.zrange('ail:all_role', 0, -1) + # ============= ROUTES ============== @settings.route("/settings/", methods=['GET']) @@ -113,6 +132,96 @@ def new_token(): generate_new_token(current_user.get_id()) return redirect(url_for('settings.edit_profile')) +@settings.route("/settings/new_token_user", methods=['GET']) +@login_required +def new_token_user(): + user_id = request.args.get('user_id') + if r_serv_db.exists('user_metadata:{}'.format(user_id)): + generate_new_token(user_id) + return redirect(url_for('settings.users_list')) + +@settings.route("/settings/create_user", methods=['GET']) +@login_required +def create_user(): + user_id = request.args.get('user_id') + role = None + if r_serv_db.exists('user_metadata:{}'.format(user_id)): + role = r_serv_db.hget('user_metadata:{}'.format(user_id), 'role') + else: + user_id = None + all_roles = get_all_roles() + return render_template("create_user.html", all_roles=all_roles, user_id=user_id, user_role=role) + +@settings.route("/settings/create_user_post", methods=['POST']) +@login_required +def create_user_post(): + email = request.form.get('username') + role = request.form.get('user_role') + password1 = request.form.get('password1') + password2 = request.form.get('password2') + + all_roles = get_all_roles() + + if email and role: + if role in all_roles: + # password set + if password1 and password2: + if password1==password2: + if check_password_strength(password1): + password = password1 + else: + return render_template("create_user.html", all_roles=all_roles) + else: + return render_template("create_user.html", all_roles=all_roles) + # generate password + else: + password = secrets.token_urlsafe() + + if current_user.is_in_role('admin'): + # edit user + if r_serv_db.exists('user_metadata:{}'.format(email)): + if password1 and password2: + edit_user_db(email, password=password, role=role) + return redirect(url_for('settings.users_list', new_user=email, new_user_password=password, new_user_edited=True)) + else: + edit_user_db(email, role=role) + return redirect(url_for('settings.users_list', new_user=email, new_user_password='Password not changed', new_user_edited=True)) + # create user + else: + create_user_db(email, password, default=True, role=role) + return redirect(url_for('settings.users_list', new_user=email, new_user_password=password, new_user_edited=False)) + + else: + return render_template("create_user.html", all_roles=all_roles) + else: + return render_template("create_user.html", all_roles=all_roles) + +@settings.route("/settings/users_list", methods=['GET']) +@login_required +def users_list(): + all_users = get_users_metadata(get_all_users()) + new_user = request.args.get('new_user') + new_user_dict = {} + if new_user: + new_user_dict['email'] = new_user + new_user_dict['edited'] = request.args.get('new_user_edited') + new_user_dict['password'] = request.args.get('new_user_password') + print(new_user) + return render_template("users_list.html", all_users=all_users, new_user=new_user_dict) + +@settings.route("/settings/edit_user", methods=['GET']) +@login_required +def edit_user(): + user_id = request.args.get('user_id') + return redirect(url_for('settings.create_user', user_id=user_id)) + +@settings.route("/settings/delete_user", methods=['GET']) +@login_required +def delete_user(): + user_id = request.args.get('user_id') + delete_user_db(user_id) + return redirect(url_for('settings.users_list')) + @settings.route("/settings/get_background_update_stats_json", methods=['GET']) @login_required diff --git a/var/www/modules/settings/templates/create_user.html b/var/www/modules/settings/templates/create_user.html new file mode 100644 index 00000000..2a24094d --- /dev/null +++ b/var/www/modules/settings/templates/create_user.html @@ -0,0 +1,121 @@ + + + + + Server Management - AIL + + + + + + + + + + + + + + + + + + {% include 'nav_bar.html' %} + +
+
+ + {% include 'settings/menu_sidebar.html' %} + +
+ + + +
+
+
+ + + + + + diff --git a/var/www/modules/settings/templates/edit_profile.html b/var/www/modules/settings/templates/edit_profile.html index f0b8d476..8dfe4cf5 100644 --- a/var/www/modules/settings/templates/edit_profile.html +++ b/var/www/modules/settings/templates/edit_profile.html @@ -27,11 +27,11 @@ {% include 'settings/menu_sidebar.html' %} -
+
-
AIL-framework Status :
+
My Profile :
diff --git a/var/www/modules/settings/templates/users_list.html b/var/www/modules/settings/templates/users_list.html new file mode 100644 index 00000000..d29dbb8e --- /dev/null +++ b/var/www/modules/settings/templates/users_list.html @@ -0,0 +1,108 @@ + + + + + Server Management - AIL + + + + + + + + + + + + + + + + + + + + {% include 'nav_bar.html' %} + +
+
+ + {% include 'settings/menu_sidebar.html' %} + +
+ + {% if new_user %} +
+
+
+ {% if new_user['edited']=='True' %} +
User Edited
+ {% else %} +
User Created
+ {% endif %} +
+
+

User: {{new_user['email']}}

+

Password: {{new_user['password']}}

+ Hide +
+
+
+ {% endif %} + +
+ + + + + + + + + + + {% for user in all_users %} + + + + + + + {% endfor %} + +
EmailRoleApi KeyActions
{{user['email']}}{{user['role']}} + {{user['api_key']}} + + + + + + + + +
+
+ +
+
+
+ + + + + + diff --git a/var/www/templates/settings/menu_sidebar.html b/var/www/templates/settings/menu_sidebar.html index 558a901f..e7aa7a7f 100644 --- a/var/www/templates/settings/menu_sidebar.html +++ b/var/www/templates/settings/menu_sidebar.html @@ -38,18 +38,18 @@