From 108773c564344a340cbb69533d49e5cd2652c7a9 Mon Sep 17 00:00:00 2001 From: Aidaho Date: Sat, 3 Aug 2024 09:25:02 +0300 Subject: [PATCH] v8.0: Refactor user module and simplify server status check Refactor user-related modules, updating data handling, roles, and methods. Simplify server status check process by removing event-based handling and replacing it with straightforward AJAX requests. --- app/api/routes/routes.py | 2 +- app/create_db.py | 110 ++--------------------- app/modules/db/db_model.py | 2 +- app/modules/db/user.py | 56 ++---------- app/modules/roxywi/auth.py | 2 +- app/modules/roxywi/class_models.py | 7 +- app/modules/service/installation.py | 3 +- app/routes/server/routes.py | 51 +++++------ app/static/js/admin/server.js | 101 ++++++++++----------- app/static/js/admin/user.js | 4 +- app/static/js/script.js | 3 +- app/templates/ajax/new_receiver.html | 1 - app/templates/include/admin_servers.html | 11 +-- app/views/user/views.py | 97 +++++++++----------- 14 files changed, 145 insertions(+), 305 deletions(-) diff --git a/app/api/routes/routes.py b/app/api/routes/routes.py index 379760a0..37cd2f8e 100644 --- a/app/api/routes/routes.py +++ b/app/api/routes/routes.py @@ -90,7 +90,7 @@ def register_api_with_group(view, endpoint, url_beg, url_end, pk='user_id', pk_t register_api(UserView, 'user', '/user', 'user_id') -register_api_with_group(UserGroupView, 'user_group', '/user', 'groups') +register_api_with_group(UserGroupView, 'user_group', 'user', 'groups') bp.add_url_rule('/user/roles', view_func=UserRoles.as_view('roles')) def register_api_channel(view, endpoint, url_beg, pk='receiver', pk_type='int', pk_end='channel_id', pk_type_end='int'): diff --git a/app/create_db.py b/app/create_db.py index 0d0d317a..913c716b 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -1,11 +1,9 @@ -#!/usr/bin/env python3.11 import distro from app.modules.db.db_model import ( - connect, Setting, Role, User, UserGroups, Groups, Services, RoxyTool, Version, SmonHttpCheck, GeoipCodes, SmonTcpCheck, SMON, - SmonPingCheck, migrate, mysql_enable + connect, Setting, Role, User, UserGroups, Groups, Services, RoxyTool, Version, GeoipCodes, migrate, mysql_enable ) -from peewee import DateTimeField, IntegerField, CharField, SQL +from peewee import IntegerField, CharField, SQL conn = connect() @@ -105,9 +103,9 @@ def default_values(): print(str(e)) data_source = [ - {'username': 'admin', 'email': 'admin@localhost', 'password': '21232f297a57a5a743894a0e4a801fc3', 'role': '1', 'group_id': '1'}, - {'username': 'editor', 'email': 'editor@localhost', 'password': '5aee9dbd2a188839105073571bee1b1f', 'role': '2', 'group_id': '1'}, - {'username': 'guest', 'email': 'guest@localhost', 'password': '084e0343a0486ff05530df6c705c8bb4', 'role': '4', 'group_id': '1'} + {'username': 'admin', 'email': 'admin@localhost', 'password': '21232f297a57a5a743894a0e4a801fc3', 'role_id': '1', 'group_id': '1'}, + {'username': 'editor', 'email': 'editor@localhost', 'password': '5aee9dbd2a188839105073571bee1b1f', 'role_id': '2', 'group_id': '1'}, + {'username': 'guest', 'email': 'guest@localhost', 'password': '084e0343a0486ff05530df6c705c8bb4', 'role_id': '4', 'group_id': '1'} ] try: @@ -471,94 +469,6 @@ def update_db_v_4_3_0(): print("An error occurred:", e) -def update_db_v_6_3_13_1(): - try: - SmonTcpCheck.insert_from( - SMON.select(SMON.id, SMON.ip, SMON.port).where( - (SMON.http == '') & (SMON.check_type == 'tcp') - ), fields=[SmonTcpCheck.smon_id, SmonTcpCheck.ip, SmonTcpCheck.port] - ).on_conflict_ignore().execute() - except Exception as e: - if e.args[0] == 'no such column: t1.name' or str(e) == 'type object \'SMON\' has no attribute \'ip\'': - print('Updating... DB has been updated to version 6.3.13-1') - else: - print("An error occurred:", e) - - -def update_db_v_6_3_13_2(): - query = SMON.select().where(SMON.http != '') - try: - query_res = query.execute() - except Exception as e: - print("An error occurred:", e) - else: - for i in query_res: - try: - proto = i.http.split(':')[0] - uri = i.http.split(':')[1] - except Exception: - proto = '' - uri = '' - url = f'{proto}://{i.name}:{i.port}{uri}' - SmonHttpCheck.insert(smon_id=i.id, url=url, body=i.body).on_conflict_ignore().execute() - - -def update_db_v_6_3_13_3(): - try: - SmonPingCheck.insert_from( - SMON.select(SMON.id, SMON.ip).where(SMON.check_type == 'ping'), fields=[SmonPingCheck.smon_id, SmonPingCheck.ip] - ).on_conflict_ignore().execute() - except Exception as e: - if e.args[0] == 'duplicate column name: haproxy' or str(e) == 'type object \'SMON\' has no attribute \'ip\'': - print('Updating... DB has been updated to version 6.3.13-2') - else: - print("An error occurred:", e) - - -def update_db_v_6_3_13_4(): - try: - migrate( - migrator.alter_column_type('smon', 'time_state', DateTimeField()), - migrator.rename_column('smon', 'ip', 'name'), - migrator.drop_column('smon', 'script', cascade=False), - migrator.drop_column('smon', 'http_status', cascade=False), - ) - except Exception as e: - if e.args[0] == 'duplicate column name: check_type' or str(e) == '(1091, "Can\'t DROP COLUMN `script`; check that it exists")': - print('Updating... DB has been updated to version 6.3.13-3') - elif e.args[0] == 'duplicate column name: check_type' or str(e) == '(1091, "Can\'t DROP COLUMN `http_status`; check that it exists")': - print('Updating... DB has been updated to version 6.3.13-3') - elif e.args[0] == 'table smon__tmp__ has no column named UNIQUE' or str(e) == "'bool' object has no attribute 'sql'": - print('Updating... DB has been updated to version 6.3.13-3') - else: - print("An error occurred:", e) - - -def update_db_v_6_3_13_5(): - try: - SMON.update(check_type='http').where(SMON.http != '').execute() - except Exception as e: - print("An error occurred:", e) - - -def update_db_v_6_3_17(): - try: - Setting.delete().where(Setting.param == 'lists_path').execute() - except Exception as e: - print("An error occurred:", e) - else: - print("Updating... DB has been updated to version 6.3.17") - - -def update_db_v_6_3_18(): - try: - Setting.delete().where(Setting.param == 'ssl_local_path').execute() - except Exception as e: - print("An error occurred:", e) - else: - print("Updating... DB has been updated to version 6.3.18") - - def update_db_v_7_1_2(): try: Setting.delete().where(Setting.param == 'stats_user').execute() @@ -666,6 +576,7 @@ def update_db_v_7_3_1(): def update_db_v_7_4(): try: migrate( + migrator.rename_column('user', 'role', 'role_id'), migrator.rename_column('backups', 'cred', 'cred_id'), migrator.rename_column('backups', 'backup_type', 'type'), migrator.rename_column('servers', 'active', 'haproxy_active'), @@ -687,7 +598,7 @@ def update_db_v_7_4(): migrator.rename_column('cred', 'groups', 'group_id'), ) except Exception as e: - if e.args[0] == 'no such column: "cred"' or str(e) == '(1060, no such column: "cred")': + if e.args[0] == 'no such column: "role"' or str(e) == '(1060, no such column: "role")': print("Updating... DB has been updated to version 7.4") elif e.args[0] == "'bool' object has no attribute 'sql'": print("Updating... DB has been updated to version 7.4") @@ -715,13 +626,6 @@ def update_all(): if check_ver() is None: update_db_v_3_4_5_22() update_db_v_4_3_0() - update_db_v_6_3_13_1() - update_db_v_6_3_13_2() - update_db_v_6_3_13_3() - update_db_v_6_3_13_4() - update_db_v_6_3_13_5() - update_db_v_6_3_17() - update_db_v_6_3_18() update_db_v_7_1_2() update_db_v_7_1_2_1() update_db_v_7_2_0() diff --git a/app/modules/db/db_model.py b/app/modules/db/db_model.py index f06914b7..b099ea88 100644 --- a/app/modules/db/db_model.py +++ b/app/modules/db/db_model.py @@ -47,7 +47,7 @@ class User(BaseModel): username = CharField(constraints=[SQL('UNIQUE')]) email = CharField(constraints=[SQL('UNIQUE')]) password = CharField(null=True) - role = CharField() + role_id = CharField() group_id = CharField() ldap_user = IntegerField(constraints=[SQL('DEFAULT "0"')]) enabled = IntegerField(constraints=[SQL('DEFAULT "1"')]) diff --git a/app/modules/db/user.py b/app/modules/db/user.py index 8dbb47b2..13ac5921 100644 --- a/app/modules/db/user.py +++ b/app/modules/db/user.py @@ -12,7 +12,7 @@ def add_user(user, email, password, role, enabled, group): try: hashed_pass = roxy_wi_tools.Tools.get_hash(password) last_id = User.insert( - username=user, email=email, password=hashed_pass, role=role, enabled=enabled, group_id=group + username=user, email=email, password=hashed_pass, role_id=role, enabled=enabled, group_id=group ).execute() except Exception as e: out_error(e) @@ -31,14 +31,16 @@ def add_user(user, email, password, role, enabled, group): def update_user(user, email, role, user_id, enabled): try: - User.update(username=user, email=email, role=role, enabled=enabled).where(User.user_id == user_id).execute() + User.update(username=user, email=email, role_id=role, enabled=enabled).where(User.user_id == user_id).execute() except Exception as e: out_error(e) def update_user_from_admin_area(user_id, **kwargs): try: - User.update(**kwargs).where(User.user_id == user_id).execute() + query = User.update(**kwargs).where(User.user_id == user_id) + print(query) + query.execute() except Exception as e: out_error(e) @@ -70,6 +72,8 @@ def update_user_current_groups_by_id(groups, user_id): def update_user_password(password, user_id): + if password == '': + return try: hashed_pass = roxy_wi_tools.Tools.get_hash(password) user_update = User.update(password=hashed_pass).where(User.user_id == user_id) @@ -258,7 +262,7 @@ def get_super_admin_count() -> int: def select_users_emails_by_group_id(group_id: int): - query = User.select(User.email).where((User.group_id == group_id) & (User.role != 'guest')) + query = User.select(User.email).where((User.group_id == group_id) & (User.role_id != 'guest')) try: query_res = query.execute() except Exception as e: @@ -282,50 +286,6 @@ def is_user_super_admin(user_id: int) -> bool: return False -def get_api_token(token): - try: - user_token = ApiToken.get(ApiToken.token == token) - except Exception as e: - return str(e) - else: - return True if token == user_token.token else False - - -def get_user_id_by_api_token(token): - query = (User.select(User.user_id).join(ApiToken, on=( - ApiToken.user_name == User.username - )).where(ApiToken.token == token)) - try: - query_res = query.execute() - except Exception as e: - return str(e) - for i in query_res: - return i.user_id - - -def write_api_token(user_token, group_id, user_role, user_name): - token_ttl = int(get_setting('token_ttl')) - get_date = roxy_wi_tools.GetDate() - cur_date = get_date.return_date('regular', timedelta=token_ttl) - cur_date_token_ttl = get_date.return_date('regular', timedelta=token_ttl) - - try: - ApiToken.insert( - token=user_token, user_name=user_name, user_group_id=group_id, user_role=user_role, - create_date=cur_date, expire_date=cur_date_token_ttl).execute() - except Exception as e: - out_error(e) - - -def get_username_group_id_from_api_token(token): - try: - user_name = ApiToken.get(ApiToken.token == token) - except Exception as e: - return str(e) - else: - return user_name.user_name, user_name.user_group_id, user_name.user_role - - def get_role_id(user_id: int, group_id: int) -> int: try: role_id = UserGroups.get((UserGroups.user_id == user_id) & (UserGroups.user_group_id == group_id)) diff --git a/app/modules/roxywi/auth.py b/app/modules/roxywi/auth.py index d512fb42..2312e48a 100644 --- a/app/modules/roxywi/auth.py +++ b/app/modules/roxywi/auth.py @@ -60,7 +60,7 @@ def is_admin(level=1, **kwargs): def page_for_admin(level=1) -> None: if not is_admin(level=level): - return abort(400, 'bad permission') + abort(400, 'bad permission') def check_in_ldap(user, password): diff --git a/app/modules/roxywi/class_models.py b/app/modules/roxywi/class_models.py index 6e81d905..a8fd5027 100644 --- a/app/modules/roxywi/class_models.py +++ b/app/modules/roxywi/class_models.py @@ -83,15 +83,16 @@ class UdpListenerRequest(BaseModel): class UserPost(BaseModel): username: EscapedString - password: str + password: EscapedString email: EscapedString enabled: Optional[bool] = 1 - user_group: int - role: Annotated[int, Gt(0), Le(4)] = 4 + group_id: Optional[int] = 0 + role_id: Annotated[int, Gt(0), Le(4)] = 4 class UserPut(BaseModel): username: EscapedString + password: Optional[EscapedString] = '' email: EscapedString enabled: Optional[bool] = 1 diff --git a/app/modules/service/installation.py b/app/modules/service/installation.py index 9695cc60..afce318b 100644 --- a/app/modules/service/installation.py +++ b/app/modules/service/installation.py @@ -68,7 +68,6 @@ def generate_grafana_inv() -> object: def generate_kp_inv(json_data: json, installed_service) -> object: inv = {"server": {"hosts": {}}} server_ips = [] - print(json_data) cluster_id = int(json_data['cluster_id']) haproxy = json_data['services']['haproxy']['enabled'] nginx = json_data['services']['nginx']['enabled'] @@ -181,7 +180,7 @@ def generate_service_inv(json_data: ServiceInstall, installed_service: str) -> o if installed_service == 'nginx' and not os.path.isdir('/var/www/haproxy-wi/app/scripts/ansible/roles/nginxinc.nginx'): os.system('ansible-galaxy install nginxinc.nginx,0.24.3 -f --roles-path /var/www/haproxy-wi/app/scripts/ansible/roles/') - for k, v in json_data['servers'].items(): + for v in json_data['servers']: server_ip = v['ip'] if installed_service == 'apache': correct_service_name = service_common.get_correct_apache_service_name(server_ip=server_ip, server_id=None) diff --git a/app/routes/server/routes.py b/app/routes/server/routes.py index 60d05360..89044c4c 100644 --- a/app/routes/server/routes.py +++ b/app/routes/server/routes.py @@ -1,7 +1,6 @@ import json -import time -from flask import render_template, request, g, jsonify, Response +from flask import render_template, request, g, jsonify from flask_jwt_extended import jwt_required from app.routes.server import bp @@ -58,34 +57,26 @@ def check_ssh(server_ip): @bp.route('/check/server/') def check_server(server_id): - def get_check(): - while True: - try: - server = server_sql.get_server_by_id(server_id) - except Exception as e: - raise e - result = server_mod.server_is_up(server.ip) - status = { - "status": result, - 'name': server.hostname, - 'ip': server.ip, - 'port': server.port, - 'enabled': server.enabled, - 'creds_id': server.cred_id, - 'group_id': server.group_id, - 'firewall': server.firewall_enable, - 'slave': server.master, - 'type_ip': server.type_ip, - 'description': server.description, - 'protected': server.protected, - } - yield f'data:{json.dumps(status)}\n\n' - time.sleep(10) - - response = Response(get_check(), mimetype="text/event-stream") - response.headers["Cache-Control"] = "no-cache" - response.headers["X-Accel-Buffering"] = "no" - return response + try: + server = server_sql.get_server_by_id(server_id) + except Exception as e: + raise e + result = server_mod.server_is_up(server.ip) + status = { + "status": result, + 'name': server.hostname, + 'ip': server.ip, + 'port': server.port, + 'enabled': server.enabled, + 'creds_id': server.cred_id, + 'group_id': server.group_id, + 'firewall': server.firewall_enable, + 'slave': server.master, + 'type_ip': server.type_ip, + 'description': server.description, + 'protected': server.protected, + } + return jsonify(status) @bp.route('/show/if/') diff --git a/app/static/js/admin/server.js b/app/static/js/admin/server.js index b2ec3dbd..67152675 100644 --- a/app/static/js/admin/server.js +++ b/app/static/js/admin/server.js @@ -357,60 +357,57 @@ function showServerInfo(id, ip) { }); } async function serverIsUp(server_id) { - let random_sleep = getRandomArbitrary(1000, 10000); - await sleep(random_sleep); - const source = new EventSource(`/server/check/server/${server_id}`); let server_div = $('#server_status-' + server_id); - source.onmessage = function (event) { - let data = JSON.parse(event.data); - if (data.status === 'up') { - server_div.removeClass('serverNone'); - server_div.removeClass('serverDown'); - server_div.addClass('serverUp'); - server_div.attr('title', 'Server is reachable'); - } else if (data.status === 'down') { - server_div.removeClass('serverNone'); - server_div.removeClass('serverUp'); - server_div.addClass('serverDown'); - server_div.attr('title', 'Server is unreachable'); - } else { - server_div.removeClass('serverDown'); - server_div.removeClass('serverUp'); - server_div.addClass('serverNone'); - server_div.attr('title', 'Cannot get server status'); + $.ajax({ + url: "/server/check/server/" + server_id, + contentType: "application/json; charset=utf-8", + success: function (data) { + if (data.status === 'up') { + server_div.removeClass('serverNone'); + server_div.removeClass('serverDown'); + server_div.addClass('serverUp'); + server_div.attr('title', 'Server is reachable'); + } else if (data.status === 'down') { + server_div.removeClass('serverNone'); + server_div.removeClass('serverUp'); + server_div.addClass('serverDown'); + server_div.attr('title', 'Server is unreachable'); + } else { + server_div.removeClass('serverDown'); + server_div.removeClass('serverUp'); + server_div.addClass('serverNone'); + server_div.attr('title', 'Cannot get server status'); + } + $('#hostname-' + server_id).val(data.name); + $('#ip-' + server_id).val(data.ip); + $('#port-' + server_id).val(data.port); + $('#desc-' + server_id).val(data.description); + if (data.enabled === 1) { + $('#enable-' + server_id).prop('checked', true); + } else { + $('#enable-' + server_id).prop('checked', false); + } + if (data.protected === 1) { + $('#protected-' + server_id).prop('checked', true); + } else { + $('#protected-' + server_id).prop('checked', false); + } + if (data.type_ip === 1) { + $('#type_ip-' + server_id).prop('checked', true); + } else { + $('#type_ip-' + server_id).prop('checked', false); + } + $('#type_ip-' + server_id).checkboxradio("refresh"); + $('#protected-' + server_id).checkboxradio("refresh"); + $('#enable-' + server_id).checkboxradio("refresh"); + $('#servergroup-' + server_id).val(data.group_id).change(); + $('#credentials-' + server_id).val(data.creds_id).change(); + $('#slavefor-' + server_id).val(data.slave).change(); + $('#servergroup-' + server_id).selectmenu("refresh"); + $('#credentials-' + server_id).selectmenu("refresh"); + $('#slavefor-' + server_id).selectmenu("refresh"); } - $('#hostname-' + server_id).val(data.name); - $('#ip-' + server_id).val(data.ip); - $('#port-' + server_id).val(data.port); - $('#desc-' + server_id).val(data.description); - if (data.enabled === 1) { - $('#enable-' + server_id).prop('checked', true); - } else { - $('#enable-' + server_id).prop('checked', false); - } - if (data.protected === 1) { - $('#protected-' + server_id).prop('checked', true); - } else { - $('#protected-' + server_id).prop('checked', false); - } - if (data.type_ip === 1) { - $('#type_ip-' + server_id).prop('checked', true); - } else { - $('#type_ip-' + server_id).prop('checked', false); - } - $('#type_ip-' + server_id).checkboxradio("refresh"); - $('#protected-' + server_id).checkboxradio("refresh"); - $('#enable-' + server_id).checkboxradio("refresh"); - $('#servergroup-' + server_id).val(data.group_id).change(); - $('#credentials-' + server_id).val(data.creds_id).change(); - $('#slavefor-' + server_id).val(data.slave).change(); - $('#servergroup-' + server_id).selectmenu("refresh"); - $('#credentials-' + server_id).selectmenu("refresh"); - $('#slavefor-' + server_id).selectmenu("refresh"); - } - source.onerror = function (event) { - source.close(); - } + }); } function openChangeServerServiceDialog(server_id) { let user_groups_word = translate_div.attr('data-user_groups'); diff --git a/app/static/js/admin/user.js b/app/static/js/admin/user.js index fd0bd8ce..dd7ead2a 100644 --- a/app/static/js/admin/user.js +++ b/app/static/js/admin/user.js @@ -109,9 +109,9 @@ function addUser(dialog_id) { "username": new_username_div.val(), "password": password_div.val(), "email": email_div.val(), - "role": $('#new-role').val(), + "role_id": $('#new-role').val(), "enabled": enabled, - "user_group": user_group, + "group_id": user_group, } $.ajax({ url: "/user", diff --git a/app/static/js/script.js b/app/static/js/script.js index 9a9b66a5..2aeb92c7 100644 --- a/app/static/js/script.js +++ b/app/static/js/script.js @@ -430,10 +430,9 @@ function showUploadConfig() { } function showListOfVersion(for_delver) { let cur_url = window.location.href.split('/').pop(); - cur_url = cur_url.split('/'); let service = $('#service').val(); let serv = $("#serv").val(); - let configver = cur_url[4]; + let configver = cur_url; clearAllAjaxFields(); $.ajax( { url: "/config/version/" + service + "/list", diff --git a/app/templates/ajax/new_receiver.html b/app/templates/ajax/new_receiver.html index cc7f8b17..69069eb0 100644 --- a/app/templates/ajax/new_receiver.html +++ b/app/templates/ajax/new_receiver.html @@ -7,7 +7,6 @@ -{{ g.user_params['role'] }} {% if g.user_params['role'] == 1 %}