From 70ca82a08668daa969ed5958d661795e213ef78c Mon Sep 17 00:00:00 2001 From: Silversthorn Date: Thu, 9 Sep 2021 00:01:10 +0200 Subject: [PATCH] Rework architecture for better MVC --- .../controllers/crafty_perms_controller.py | 17 +- .../controllers/management_controller.py | 114 ++ app/classes/controllers/roles_controller.py | 93 ++ .../controllers/server_perms_controller.py | 91 ++ app/classes/controllers/servers_controller.py | 159 +++ app/classes/controllers/users_controller.py | 125 ++ app/classes/minecraft/serverjars.py | 2 +- app/classes/minecraft/stats.py | 6 +- app/classes/models/crafty_permissions.py | 194 +++ app/classes/models/management.py | 317 +++++ app/classes/models/roles.py | 87 ++ app/classes/models/server_permissions.py | 154 +++ app/classes/models/servers.py | 191 +++ app/classes/models/users.py | 237 ++++ app/classes/shared/helpers.py | 36 - .../{controller.py => main_controller.py} | 55 +- app/classes/shared/main_models.py | 94 ++ app/classes/shared/models.py | 1083 ----------------- .../models_folder/crafty_permissions.py | 102 -- app/classes/shared/server.py | 21 +- app/classes/shared/tasks.py | 23 +- app/classes/web/ajax_handler.py | 31 +- app/classes/web/api_handler.py | 3 +- app/classes/web/base_handler.py | 4 +- app/classes/web/http_handler.py | 2 +- app/classes/web/http_handler_page.py | 2 +- app/classes/web/panel_handler.py | 210 ++-- app/classes/web/public_handler.py | 8 +- app/classes/web/server_handler.py | 39 +- app/classes/web/status_handler.py | 6 +- app/classes/web/upload_handler.py | 8 +- app/classes/web/websocket_handler.py | 4 +- .../20210822092240_crafty_permissions.py | 2 +- .../20210822101530_delete_User_Servers.py | 3 +- main.py | 4 +- 35 files changed, 2080 insertions(+), 1447 deletions(-) rename app/classes/{shared => }/controllers/crafty_perms_controller.py (68%) create mode 100644 app/classes/controllers/management_controller.py create mode 100644 app/classes/controllers/roles_controller.py create mode 100644 app/classes/controllers/server_perms_controller.py create mode 100644 app/classes/controllers/servers_controller.py create mode 100644 app/classes/controllers/users_controller.py create mode 100644 app/classes/models/crafty_permissions.py create mode 100644 app/classes/models/management.py create mode 100644 app/classes/models/roles.py create mode 100644 app/classes/models/server_permissions.py create mode 100644 app/classes/models/servers.py create mode 100644 app/classes/models/users.py rename app/classes/shared/{controller.py => main_controller.py} (90%) create mode 100644 app/classes/shared/main_models.py delete mode 100644 app/classes/shared/models.py delete mode 100644 app/classes/shared/models_folder/crafty_permissions.py diff --git a/app/classes/shared/controllers/crafty_perms_controller.py b/app/classes/controllers/crafty_perms_controller.py similarity index 68% rename from app/classes/shared/controllers/crafty_perms_controller.py rename to app/classes/controllers/crafty_perms_controller.py index 8a60987b..31526c77 100644 --- a/app/classes/shared/controllers/crafty_perms_controller.py +++ b/app/classes/controllers/crafty_perms_controller.py @@ -12,8 +12,7 @@ from distutils import dir_util from app.classes.shared.helpers import helper from app.classes.shared.console import console -from app.classes.shared.models import db_helper, server_permissions, Enum_Permissions_Server -from app.classes.shared.models_folder.crafty_permissions import crafty_permissions, Enum_Permissions_Crafty +from app.classes.models.crafty_permissions import crafty_permissions, Enum_Permissions_Crafty from app.classes.shared.server import Server from app.classes.minecraft.server_props import ServerProps @@ -33,30 +32,34 @@ class Crafty_Perms_Controller: def get_mask_crafty_permissions(user_id): permissions_mask = crafty_permissions.get_crafty_permissions_mask(user_id) return permissions_mask + + @staticmethod + def set_permission(permission_mask, permission_tested: Enum_Permissions_Crafty, value): + return crafty_permissions.set_permission(permission_mask, permission_tested, value) @staticmethod def can_create_server(user_id): - return db_helper.can_add_in_crafty(user_id, Enum_Permissions_Crafty.Server_Creation) + return crafty_permissions.can_add_in_crafty(user_id, Enum_Permissions_Crafty.Server_Creation) @staticmethod def can_add_user(user_id): #TODO: Complete if we need a User Addition limit - #return db_helper.can_add_in_crafty(user_id, Enum_Permissions_Crafty.User_Config) + #return crafty_permissions.can_add_in_crafty(user_id, Enum_Permissions_Crafty.User_Config) return True @staticmethod def can_add_role(user_id): #TODO: Complete if we need a Role Addition limit - #return db_helper.can_add_in_crafty(user_id, Enum_Permissions_Crafty.Roles_Config) + #return crafty_permissions.can_add_in_crafty(user_id, Enum_Permissions_Crafty.Roles_Config) return True @staticmethod def list_all_crafty_permissions_quantity_limits(): - return db_helper.get_all_permission_quantity_list() + return crafty_permissions.get_all_permission_quantity_list() @staticmethod def list_crafty_permissions_quantity_limits(user_id): - return db_helper.get_permission_quantity_list(user_id) + return crafty_permissions.get_permission_quantity_list(user_id) @staticmethod def get_crafty_permissions_list(user_id): diff --git a/app/classes/controllers/management_controller.py b/app/classes/controllers/management_controller.py new file mode 100644 index 00000000..ba4a5118 --- /dev/null +++ b/app/classes/controllers/management_controller.py @@ -0,0 +1,114 @@ +import os +import time +import logging +import sys +import yaml +import asyncio +import shutil +import tempfile +import zipfile +from distutils import dir_util + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console + +from app.classes.models.management import management_helper + +from app.classes.shared.server import Server +from app.classes.minecraft.server_props import ServerProps +from app.classes.minecraft.serverjars import server_jar_obj +from app.classes.minecraft.stats import Stats + +logger = logging.getLogger(__name__) + +class Management_Controller: + + #************************************************************************************************ + # Host_Stats Methods + #************************************************************************************************ + @staticmethod + def get_latest_hosts_stats(): + return management_helper.get_latest_hosts_stats() + + @staticmethod + def new_api_token(): + return management_helper.new_api_token() + + #************************************************************************************************ + # Commands Methods + #************************************************************************************************ + @staticmethod + def get_unactioned_commands(): + return management_helper.get_unactioned_commands() + + @staticmethod + def send_command(user_id, server_id, remote_ip, command): + + server_name = servers_helper.get_server_friendly_name(server_id) + + # Example: Admin issued command start_server for server Survival + management_helper.add_to_audit_log(user_id, "issued command {} for server {}".format(command, server_name), + server_id, remote_ip) + + add_command(server_id, user_id, remote_ip, command) + + @staticmethod + def mark_command_complete(command_id=None): + return mark_command_complete(command_id) + + #************************************************************************************************ + # Audit_Log Methods + #************************************************************************************************ + @staticmethod + def get_actity_log(): + return management_helper.get_actity_log() + + @staticmethod + def add_to_audit_log(user_id, log_msg, server_id=None, source_ip=None): + return management_helper.add_to_audit_log(user_id, log_msg, server_id, source_ip) + + @staticmethod + def add_to_audit_log_raw(user_name, user_id, server_id, log_msg, source_ip): + return management_helper.add_to_audit_log_raw(user_name, user_id, server_id, log_msg, source_ip) + + #************************************************************************************************ + # Schedules Methods + #************************************************************************************************ + @staticmethod + def create_scheduled_task(server_id, action, interval, interval_type, start_time, command, comment=None, enabled=True): + return management_helper.create_scheduled_task(server_id, action, interval, interval_type, start_time, command, comment, enabled) + + @staticmethod + def delete_scheduled_task(schedule_id): + return management_helper.delete_scheduled_task(schedule_id) + + @staticmethod + def update_scheduled_task(schedule_id, updates): + return management_helper.update_scheduled_task(schedule_id, updates) + + @staticmethod + def get_scheduled_task(schedule_id): + return management_helper.get_scheduled_task(schedule_id) + + @staticmethod + def get_schedules_by_server(server_id): + return management_helper.get_schedules_by_server(server_id) + + @staticmethod + def get_schedules_all(): + return management_helper.get_schedules_all() + + @staticmethod + def get_schedules_enabled(): + return management_helper.get_schedules_enabled() + + #************************************************************************************************ + # Backups Methods + #************************************************************************************************ + @staticmethod + def get_backup_config(server_id): + return management_helper.get_backup_config(server_id) + + @staticmethod + def set_backup_config(server_id: int, backup_path: str = None, max_backups: int = None, auto_enabled: bool = True): + return set_backup_config(server_id, backup_path, max_backups, auto_enabled) diff --git a/app/classes/controllers/roles_controller.py b/app/classes/controllers/roles_controller.py new file mode 100644 index 00000000..c199d583 --- /dev/null +++ b/app/classes/controllers/roles_controller.py @@ -0,0 +1,93 @@ +import os +import time +import logging +import sys +import yaml +import asyncio +import shutil +import tempfile +import zipfile +from distutils import dir_util + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console + +from app.classes.models.roles import roles_helper +from app.classes.models.server_permissions import server_permissions + +from app.classes.shared.server import Server +from app.classes.minecraft.server_props import ServerProps +from app.classes.minecraft.serverjars import server_jar_obj +from app.classes.minecraft.stats import Stats + +logger = logging.getLogger(__name__) + +class Roles_Controller: + + @staticmethod + def get_all_roles(): + return roles_helper.get_all_roles() + + @staticmethod + def get_roleid_by_name(role_name): + return roles_helper.get_roleid_by_name(role_name) + + @staticmethod + def get_role(role_id): + return roles_helper.get_role(role_id) + + + @staticmethod + def update_role(role_id, role_data={}, permissions_mask="00000000"): + base_data = Roles_Controller.get_role_with_servers(role_id) + up_data = {} + added_servers = set() + edited_servers = set() + removed_servers = set() + for key in role_data: + if key == "role_id": + continue + elif key == "servers": + added_servers = role_data['servers'].difference(base_data['servers']) + removed_servers = base_data['servers'].difference(role_data['servers']) + elif base_data[key] != role_data[key]: + up_data[key] = role_data[key] + up_data['last_update'] = helper.get_time_as_string() + logger.debug("role: {} +server:{} -server{}".format(role_data, added_servers, removed_servers)) + for server in added_servers: + server_permissions.get_or_create(role_id, server, permissions_mask) + for server in base_data['servers']: + server_permissions.update_role_permission(role_id, server, permissions_mask) + # TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point + server_permissions.delete_roles_permissions(role_id, removed_servers) + if up_data: + roles_helper.update_role(role_id, up_data) + + @staticmethod + def add_role(role_name): + return roles_helper.add_role(role_name) + + @staticmethod + def remove_role(role_id): + return roles_helper.remove_role(role_id) + + @staticmethod + def role_id_exists(role_id): + return roles_helper.role_id_exists(role_id) + + @staticmethod + def get_role_with_servers(role_id): + role = roles_helper.get_role(role_id) + + if role: + servers_query = server_permissions.get_servers_from_role(role_id) + # TODO: this query needs to be narrower + servers = set() + for s in servers_query: + servers.add(s.server_id.server_id) + role['servers'] = servers + #logger.debug("role: ({}) {}".format(role_id, role)) + return role + else: + #logger.debug("role: ({}) {}".format(role_id, {})) + return {} \ No newline at end of file diff --git a/app/classes/controllers/server_perms_controller.py b/app/classes/controllers/server_perms_controller.py new file mode 100644 index 00000000..bdf3d38f --- /dev/null +++ b/app/classes/controllers/server_perms_controller.py @@ -0,0 +1,91 @@ +import os +import time +import logging +import sys +import yaml +import asyncio +import shutil +import tempfile +import zipfile +from distutils import dir_util + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console + +from app.classes.shared.main_models import db_helper +from app.classes.models.server_permissions import server_permissions, Enum_Permissions_Server +from app.classes.models.users import users_helper +from app.classes.models.roles import roles_helper +from app.classes.models.servers import servers_helper + +from app.classes.shared.server import Server +from app.classes.minecraft.server_props import ServerProps +from app.classes.minecraft.serverjars import server_jar_obj +from app.classes.minecraft.stats import Stats + +logger = logging.getLogger(__name__) + +class Server_Perms_Controller: + + @staticmethod + def list_defined_permissions(): + permissions_list = server_permissions.get_permissions_list() + return permissions_list + + @staticmethod + def get_mask_permissions(role_id, server_id): + permissions_mask = server_permissions.get_permissions_mask(role_id, server_id) + return permissions_mask + + @staticmethod + def get_role_permissions(role_id): + permissions_list = server_permissions.get_role_permissions_list(role_id) + return permissions_list + + @staticmethod + def get_server_permissions_foruser(user_id, server_id): + permissions_list = server_permissions.get_user_permissions_list(user_id, server_id) + return permissions_list + + #************************************************************************************************ + # Servers Permissions Methods + #************************************************************************************************ + @staticmethod + def get_permissions_mask(role_id, server_id): + return server_permissions.get_permissions_mask(role_id, server_id) + + @staticmethod + def set_permission(permission_mask, permission_tested: Enum_Permissions_Server, value): + return server_permissions.set_permission(permission_mask, permission_tested, value) + + @staticmethod + def get_role_permissions_list(role_id): + return server_permissions.get_role_permissions_list(role_id) + + @staticmethod + def get_user_permissions_list(user_id, server_id): + return get_user_permissions_list(user_id, server_id) + + @staticmethod + def get_authorized_servers_stats_from_roles(user_id): + user_roles = users_helper.get_user_roles_id(user_id) + roles_list = [] + role_server = [] + authorized_servers = [] + server_data = [] + + for u in user_roles: + roles_list.append(roles_helper.get_role(u.role_id)) + + for r in roles_list: + role_test = server_permissions.get_role_servers_from_role_id(r.get('role_id')) + for t in role_test: + role_server.append(t) + + for s in role_server: + authorized_servers.append(servers_helper.get_server_data_by_id(s.server_id)) + + for s in authorized_servers: + latest = servers_helper.get_latest_server_stats(s.get('server_id')) + server_data.append({'server_data': s, "stats": db_helper.return_rows(latest)[0]}) + return server_data diff --git a/app/classes/controllers/servers_controller.py b/app/classes/controllers/servers_controller.py new file mode 100644 index 00000000..934a8b4b --- /dev/null +++ b/app/classes/controllers/servers_controller.py @@ -0,0 +1,159 @@ +import os +import time +import logging +import sys +import yaml +import asyncio +import shutil +import tempfile +import zipfile +from distutils import dir_util + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console + +from app.classes.shared.main_models import db_helper +from app.classes.models.servers import servers_helper +from app.classes.models.users import users_helper +from app.classes.models.server_permissions import server_permissions, Enum_Permissions_Server + +from app.classes.shared.server import Server +from app.classes.minecraft.server_props import ServerProps +from app.classes.minecraft.serverjars import server_jar_obj +from app.classes.minecraft.stats import Stats + +logger = logging.getLogger(__name__) + +class Servers_Controller: + + #************************************************************************************************ + # Generic Servers Methods + #************************************************************************************************ + @staticmethod + def create_server(name: str, server_uuid: str, server_dir: str, backup_path: str, server_command: str, server_file: str, server_log_file: str, server_stop: str, server_port=25565): + return servers_helper.create_server(name, server_uuid, server_dir, backup_path, server_command, server_file, server_log_file, server_stop, server_port) + + @staticmethod + def remove_server(server_id): + return servers_helper.remove_server(server_id) + + @staticmethod + def get_server_data_by_id(server_id): + return servers_helper.get_server_data_by_id(server_id) + + #************************************************************************************************ + # Servers Methods + #************************************************************************************************ + @staticmethod + def get_all_defined_servers(): + return servers_helper.get_all_defined_servers() + + @staticmethod + def get_authorized_servers(user_id): + server_data = [] + user_roles = users_helper.user_role_query(user_id) + for us in user_roles: + role_servers = server_permissions.get_role_servers_from_role_id(us.role_id) + for role in role_servers: + server_data.append(servers_helper.get_server_data_by_id(role.server_id)) + + return server_data + + @staticmethod + def get_all_servers_stats(): + return servers_helper.get_all_servers_stats() + + @staticmethod + def get_authorized_servers_stats(user_id): + server_data = [] + authorized_servers = Servers_Controller.get_authorized_servers(user_id) + + for s in authorized_servers: + latest = servers_helper.get_latest_server_stats(s.get('server_id')) + user_permissions = server_permissions.get_user_permissions_list(user_id, s.get('server_id')) + if Enum_Permissions_Server.Commands in user_permissions: + user_command_permission = True + else: + user_command_permission = False + server_data.append({'server_data': s, "stats": db_helper.return_rows(latest)[0], "user_command_permission":user_command_permission}) + return server_data + + @staticmethod + def get_server_friendly_name(server_id): + return servers_helper.get_server_friendly_name(server_id) + + #************************************************************************************************ + # Servers_Stats Methods + #************************************************************************************************ + @staticmethod + def get_server_stats_by_id(server_id): + return servers_helper.get_server_stats_by_id(server_id) + + @staticmethod + def server_id_exists(server_id): + return servers_helper.server_id_exists(server_id) + + @staticmethod + def server_id_authorized(serverId, user_id): + authorized = 0 + user_roles = users_helper.user_role_query(user_id) + for role in user_roles: + authorized = server_permissions.get_role_servers_from_role_id(role.role_id) + + #authorized = db_helper.return_rows(authorized) + + if authorized.count() == 0: + return False + return True + + @staticmethod + def set_update(server_id, value): + return servers_helper.set_update(server_id, value) + + @staticmethod + def get_TTL_without_player(server_id): + return servers_helper.get_TTL_without_player(server_id) + + @staticmethod + def can_stop_no_players(server_id, time_limit): + return servers_helper.can_stop_no_players(server_id, time_limit) + + + #************************************************************************************************ + # Servers Helpers Methods + #************************************************************************************************ + @staticmethod + def get_banned_players(server_id): + stats = servers_helper.get_server_stats_by_id(server_id) + server_path = stats['server_id']['path'] + path = os.path.join(server_path, 'banned-players.json') + + try: + with open(path) as file: + content = file.read() + file.close() + except Exception as ex: + print (ex) + return None + + return json.loads(content) + + def check_for_old_logs(self): + servers = servers_helper.get_all_defined_servers() + for server in servers: + logs_path = os.path.split(server['log_path'])[0] + latest_log_file = os.path.split(server['log_path'])[1] + logs_delete_after = int(server['logs_delete_after']) + if logs_delete_after == 0: + continue + + log_files = list(filter( + lambda val: val != latest_log_file, + os.listdir(logs_path) + )) + for log_file in log_files: + log_file_path = os.path.join(logs_path, log_file) + if self.check_file_exists(log_file_path) and \ + self.is_file_older_than_x_days(log_file_path, logs_delete_after): + os.remove(log_file_path) + diff --git a/app/classes/controllers/users_controller.py b/app/classes/controllers/users_controller.py new file mode 100644 index 00000000..a33f0d4b --- /dev/null +++ b/app/classes/controllers/users_controller.py @@ -0,0 +1,125 @@ +import os +import time +import logging +import sys +import yaml +import asyncio +import shutil +import tempfile +import zipfile +from distutils import dir_util + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console + +from app.classes.models.users import Users, users_helper +from app.classes.models.crafty_permissions import crafty_permissions, Enum_Permissions_Crafty +from app.classes.models.management import management_helper + +logger = logging.getLogger(__name__) + +class Users_Controller: + + #************************************************************************************************ + # Users Methods + #************************************************************************************************ + @staticmethod + def get_all_users(): + return users_helper.get_all_users() + + @staticmethod + def get_id_by_name(username): + return users_helper.get_user_id_by_name(username) + + @staticmethod + def get_user_by_api_token(token: str): + return users_helper.get_user_by_api_token(token) + + @staticmethod + def get_user_by_id(user_id): + return users_helper.get_user(user_id) + + @staticmethod + def user_query(user_id): + return users_helper.user_query(user_id) + + @staticmethod + def update_user(user_id, user_data={}, user_crafty_data={}): + base_data = users_helper.get_user(user_id) + up_data = {} + added_roles = set() + removed_roles = set() + removed_servers = set() + for key in user_data: + if key == "user_id": + continue + elif key == "roles": + added_roles = user_data['roles'].difference(base_data['roles']) + removed_roles = base_data['roles'].difference(user_data['roles']) + elif key == "regen_api": + if user_data['regen_api']: + up_data['api_token'] = management_helper.new_api_token() + elif key == "password": + if user_data['password'] is not None and user_data['password'] != "": + up_data['password'] = helper.encode_pass(user_data['password']) + elif base_data[key] != user_data[key]: + up_data[key] = user_data[key] + up_data['last_update'] = helper.get_time_as_string() + logger.debug("user: {} +role:{} -role:{}".format(user_data, added_roles, removed_roles)) + for role in added_roles: + users_helper.get_or_create(user_id=user_id, role_id=role) + # TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point + + for key in user_crafty_data: + if key == "permissions_mask": + permissions_mask = user_crafty_data['permissions_mask'] + if key == "server_quantity": + limit_server_creation = user_crafty_data['server_quantity'][Enum_Permissions_Crafty.Server_Creation.name] + limit_user_creation = user_crafty_data['server_quantity'][Enum_Permissions_Crafty.User_Config.name] + limit_role_creation = user_crafty_data['server_quantity'][Enum_Permissions_Crafty.Roles_Config.name] + else: + limit_server_creation = 0 + limit_user_creation = 0 + limit_role_creation = 0 + + crafty_permissions.add_or_update_user(user_id, permissions_mask, limit_server_creation, limit_user_creation, limit_role_creation) + + users_helper.delete_user_roles(user_id, removed_roles) + + users_helper.update_user(user_id, up_data) + + @staticmethod + def add_user(username, password=None, api_token=None, enabled=True, superuser=False): + return users_helper.add_user(username, password=password, api_token=api_token, enabled=enabled, superuser=superuser) + + @staticmethod + def remove_user(user_id): + return users_helper.remove_user(user_id) + + @staticmethod + def user_id_exists(user_id): + return users_helper.user_id_exists(user_id) + + #************************************************************************************************ + # User Roles Methods + #************************************************************************************************ + + @staticmethod + def get_user_roles_id(user_id): + return users_helper.get_user_roles_id(user_id) + + @staticmethod + def get_user_roles_names(user_id): + return users_helper.get_user_roles_names(user_id) + + @staticmethod + def add_role_to_user(user_id, role_id): + return users_helper.add_role_to_user(user_id, role_id) + + @staticmethod + def add_user_roles(user): + return users_helper.add_user_roles(user) + + @staticmethod + def user_role_query(user_id): + return users_helper.user_role_query(user_id) diff --git a/app/classes/minecraft/serverjars.py b/app/classes/minecraft/serverjars.py index 66f90cbc..c0b9c8d5 100644 --- a/app/classes/minecraft/serverjars.py +++ b/app/classes/minecraft/serverjars.py @@ -9,7 +9,7 @@ from datetime import datetime from app.classes.shared.helpers import helper from app.classes.shared.console import console -from app.classes.shared.models import Servers +from app.classes.models.servers import Servers from app.classes.minecraft.server_props import ServerProps from app.classes.web.websocket_helper import websocket_helper diff --git a/app/classes/minecraft/stats.py b/app/classes/minecraft/stats.py index 30b78697..4c5ea793 100644 --- a/app/classes/minecraft/stats.py +++ b/app/classes/minecraft/stats.py @@ -9,8 +9,8 @@ import base64 from app.classes.shared.helpers import helper from app.classes.minecraft.mc_ping import ping -from app.classes.shared.models import db_helper -from app.classes.shared.models import Host_Stats, Server_Stats +from app.classes.models.management import Host_Stats +from app.classes.models.servers import Server_Stats, servers_helper logger = logging.getLogger(__name__) @@ -165,7 +165,7 @@ class Stats: def get_server_players(self, server_id): - server = db_helper.get_server_data_by_id(server_id) + server = servers_helper.get_server_data_by_id(server_id) logger.info("Getting players for server {}".format(server)) diff --git a/app/classes/models/crafty_permissions.py b/app/classes/models/crafty_permissions.py new file mode 100644 index 00000000..17218d08 --- /dev/null +++ b/app/classes/models/crafty_permissions.py @@ -0,0 +1,194 @@ +import os +import sys +import logging +import datetime + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console +from app.classes.models.users import Users + +logger = logging.getLogger(__name__) +peewee_logger = logging.getLogger('peewee') +peewee_logger.setLevel(logging.INFO) + +try: + from peewee import * + from playhouse.shortcuts import model_to_dict + from enum import Enum + import yaml + +except ModuleNotFoundError as e: + logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) + console.critical("Import Error: Unable to load {} module".format(e.name)) + sys.exit(1) + +database = SqliteDatabase(helper.db_path, pragmas={ + 'journal_mode': 'wal', + 'cache_size': -1024 * 10}) + + +#************************************************************************************************ +# User_Crafty Class +#************************************************************************************************ +class User_Crafty(Model): + user_id = ForeignKeyField(Users, backref='users_crafty') + permissions = CharField(default="00000000") + limit_server_creation = IntegerField(default=-1) + limit_user_creation = IntegerField(default=0) + limit_role_creation = IntegerField(default=0) + created_server = IntegerField(default=0) + created_user = IntegerField(default=0) + created_role = IntegerField(default=0) + + class Meta: + table_name = 'user_crafty' + database = database + +#************************************************************************************************ +# Crafty Permissions Class +#************************************************************************************************ +class Enum_Permissions_Crafty(Enum): + Server_Creation = 0 + User_Config = 1 + Roles_Config = 2 + +class Permissions_Crafty: + + #************************************************************************************************ + # Crafty Permissions Methods + #************************************************************************************************ + @staticmethod + def get_permissions_list(): + permissions_list = [] + for member in Enum_Permissions_Crafty.__members__.items(): + permissions_list.append(member[1]) + return permissions_list + + @staticmethod + def get_permissions(permissions_mask): + permissions_list = [] + for member in Enum_Permissions_Crafty.__members__.items(): + if crafty_permissions.has_permission(permissions_mask, member[1]): + permissions_list.append(member[1]) + return permissions_list + + @staticmethod + def has_permission(permission_mask, permission_tested: Enum_Permissions_Crafty): + result = False + if permission_mask[permission_tested.value] == '1': + result = True + return result + + @staticmethod + def set_permission(permission_mask, permission_tested: Enum_Permissions_Crafty, value): + l = list(permission_mask) + l[permission_tested.value] = str(value) + permission_mask = ''.join(l) + return permission_mask + + @staticmethod + def get_permission(permission_mask, permission_tested: Enum_Permissions_Crafty): + return permission_mask[permission_tested.value] + + @staticmethod + def get_crafty_permissions_mask(user_id): + permissions_mask = '' + user_crafty = crafty_permissions.get_User_Crafty(user_id) + permissions_mask = user_crafty.permissions + return permissions_mask + + @staticmethod + def get_all_permission_quantity_list(): + quantity_list = { + Enum_Permissions_Crafty.Server_Creation.name: -1, + Enum_Permissions_Crafty.User_Config.name: -1, + Enum_Permissions_Crafty.Roles_Config.name: -1, + } + return quantity_list + + @staticmethod + def get_permission_quantity_list(user_id): + user_crafty = crafty_permissions.get_User_Crafty(user_id) + quantity_list = { + Enum_Permissions_Crafty.Server_Creation.name: user_crafty.limit_server_creation, + Enum_Permissions_Crafty.User_Config.name: user_crafty.limit_user_creation, + Enum_Permissions_Crafty.Roles_Config.name: user_crafty.limit_role_creation, + } + return quantity_list + + #************************************************************************************************ + # User_Crafty Methods + #************************************************************************************************ + @staticmethod + def get_User_Crafty(user_id): + try: + user_crafty = User_Crafty.select().where(User_Crafty.user_id == user_id).get() + except User_Crafty.DoesNotExist: + user_crafty = User_Crafty.insert({ + User_Crafty.user_id: user_id, + User_Crafty.permissions: "000", + User_Crafty.limit_server_creation: 0, + User_Crafty.limit_user_creation: 0, + User_Crafty.limit_role_creation: 0, + User_Crafty.created_server: 0, + User_Crafty.created_user: 0, + User_Crafty.created_role: 0, + }).execute() + user_crafty = crafty_permissions.get_User_Crafty(user_id) + return user_crafty + + @staticmethod + def add_user_crafty(user_id, uc_permissions): + user_crafty = User_Crafty.insert({User_Crafty.user_id: user_id, User_Crafty.permissions: uc_permissions}).execute() + return user_crafty + + @staticmethod + def add_or_update_user(user_id, permissions_mask, limit_server_creation, limit_user_creation, limit_role_creation): + try: + user_crafty = User_Crafty.select().where(User_Crafty.user_id == user_id).get() + user_crafty.permissions = permissions_mask + user_crafty.limit_server_creation = limit_server_creation + user_crafty.limit_user_creation = limit_user_creation + user_crafty.limit_role_creation = limit_role_creation + User_Crafty.save(user_crafty) + except: + User_Crafty.insert({ + User_Crafty.user_id: user_id, + User_Crafty.permissions: permissions_mask, + User_Crafty.limit_server_creation: limit_server_creation, + User_Crafty.limit_user_creation: limit_user_creation, + User_Crafty.limit_role_creation: limit_role_creation + }).execute() + + @staticmethod + def get_created_quantity_list(user_id): + user_crafty = crafty_permissions.get_User_Crafty(user_id) + quantity_list = { + Enum_Permissions_Crafty.Server_Creation.name: user_crafty.created_server, + Enum_Permissions_Crafty.User_Config.name: user_crafty.created_user, + Enum_Permissions_Crafty.Roles_Config.name: user_crafty.created_role, + } + return quantity_list + + @staticmethod + def get_crafty_limit_value(user_id, permission): + user_crafty = crafty_permissions.get_User_Crafty(user_id) + quantity_list = get_permission_quantity_list(user_id) + return quantity_list[permission] + + @staticmethod + def can_add_in_crafty(user_id, permission): + user_crafty = crafty_permissions.get_User_Crafty(user_id) + can = crafty_permissions.has_permission(user_crafty.permissions, permission) + limit_list = crafty_permissions.get_permission_quantity_list(user_id) + quantity_list = crafty_permissions.get_created_quantity_list(user_id) + return can and ((quantity_list[permission.name] < limit_list[permission.name]) or limit_list[permission.name] == -1 ) + + @staticmethod + def add_server_creation(user_id): + user_crafty = crafty_permissions.get_User_Crafty(user_id) + user_crafty.created_server += 1 + User_Crafty.save(user_crafty) + return user_crafty.created_server + +crafty_permissions = Permissions_Crafty() \ No newline at end of file diff --git a/app/classes/models/management.py b/app/classes/models/management.py new file mode 100644 index 00000000..4e2fedef --- /dev/null +++ b/app/classes/models/management.py @@ -0,0 +1,317 @@ +import os +import sys +import logging +import datetime + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console +from app.classes.shared.main_models import db_helper +from app.classes.models.users import Users, users_helper +from app.classes.models.servers import Servers, servers_helper +from app.classes.web.websocket_helper import websocket_helper + + +logger = logging.getLogger(__name__) +peewee_logger = logging.getLogger('peewee') +peewee_logger.setLevel(logging.INFO) + +try: + from peewee import * + from playhouse.shortcuts import model_to_dict + from enum import Enum + import yaml + +except ModuleNotFoundError as e: + logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) + console.critical("Import Error: Unable to load {} module".format(e.name)) + sys.exit(1) + +database = SqliteDatabase(helper.db_path, pragmas={ + 'journal_mode': 'wal', + 'cache_size': -1024 * 10}) + +#************************************************************************************************ +# Audit_Log Class +#************************************************************************************************ +class Audit_Log(Model): + audit_id = AutoField() + created = DateTimeField(default=datetime.datetime.now) + user_name = CharField(default="") + user_id = IntegerField(default=0, index=True) + source_ip = CharField(default='127.0.0.1') + server_id = IntegerField(default=None, index=True) # When auditing global events, use server ID 0 + log_msg = TextField(default='') + + class Meta: + database = database + + +#************************************************************************************************ +# Host_Stats Class +#************************************************************************************************ +class Host_Stats(Model): + time = DateTimeField(default=datetime.datetime.now, index=True) + boot_time = CharField(default="") + cpu_usage = FloatField(default=0) + cpu_cores = IntegerField(default=0) + cpu_cur_freq = FloatField(default=0) + cpu_max_freq = FloatField(default=0) + mem_percent = FloatField(default=0) + mem_usage = CharField(default="") + mem_total = CharField(default="") + disk_json = TextField(default="") + + class Meta: + table_name = "host_stats" + database = database + + +#************************************************************************************************ +# Commands Class +#************************************************************************************************ +class Commands(Model): + command_id = AutoField() + created = DateTimeField(default=datetime.datetime.now) + server_id = ForeignKeyField(Servers, backref='server', index=True) + user = ForeignKeyField(Users, backref='user', index=True) + source_ip = CharField(default='127.0.0.1') + command = CharField(default='') + executed = BooleanField(default=False) + + class Meta: + table_name = "commands" + database = database + + +#************************************************************************************************ +# Webhooks Class +#************************************************************************************************ +class Webhooks(Model): + id = AutoField() + name = CharField(max_length=64, unique=True, index=True) + method = CharField(default="POST") + url = CharField(unique=True) + event = CharField(default="") + send_data = BooleanField(default=True) + + class Meta: + table_name = "webhooks" + database = database + + +#************************************************************************************************ +# Schedules Class +#************************************************************************************************ +class Schedules(Model): + schedule_id = IntegerField(unique=True, primary_key=True) + server_id = ForeignKeyField(Servers, backref='schedule_server') + enabled = BooleanField() + action = CharField() + interval = IntegerField() + interval_type = CharField() + start_time = CharField(null=True) + command = CharField(null=True) + comment = CharField() + + class Meta: + table_name = 'schedules' + database = database + + +#************************************************************************************************ +# Backups Class +#************************************************************************************************ +class Backups(Model): + directories = CharField(null=True) + max_backups = IntegerField() + server_id = ForeignKeyField(Servers, backref='backups_server') + schedule_id = ForeignKeyField(Schedules, backref='backups_schedule') + + class Meta: + table_name = 'backups' + database = database + +class helpers_management: + + #************************************************************************************************ + # Host_Stats Methods + #************************************************************************************************ + @staticmethod + def get_latest_hosts_stats(): + query = Host_Stats.select().order_by(Host_Stats.id.desc()).get() + return model_to_dict(query) + + #************************************************************************************************ + # Commands Methods + #************************************************************************************************ + @staticmethod + def add_command(server_id, user_id, remote_ip, command): + Commands.insert({ + Commands.server_id: server_id, + Commands.user: user_id, + Commands.source_ip: remote_ip, + Commands.command: command + }).execute() + + @staticmethod + def get_unactioned_commands(): + query = Commands.select().where(Commands.executed == 0) + return db_helper.return_rows(query) + + @staticmethod + def mark_command_complete(command_id=None): + if command_id is not None: + logger.debug("Marking Command {} completed".format(command_id)) + Commands.update({ + Commands.executed: True + }).where(Commands.command_id == command_id).execute() + + #************************************************************************************************ + # Audit_Log Methods + #************************************************************************************************ + @staticmethod + def get_actity_log(): + q = Audit_Log.select() + return db_helper.return_db_rows(q) + + @staticmethod + def add_to_audit_log(user_id, log_msg, server_id=None, source_ip=None): + logger.debug("Adding to audit log User:{} - Message: {} ".format(user_id, log_msg)) + user_data = users_helper.get_user(user_id) + + audit_msg = "{} {}".format(str(user_data['username']).capitalize(), log_msg) + + websocket_helper.broadcast('notification', audit_msg) + + Audit_Log.insert({ + Audit_Log.user_name: user_data['username'], + Audit_Log.user_id: user_id, + Audit_Log.server_id: server_id, + Audit_Log.log_msg: audit_msg, + Audit_Log.source_ip: source_ip + }).execute() + + @staticmethod + def add_to_audit_log_raw(user_name, user_id, server_id, log_msg, source_ip): + Audit_Log.insert({ + Audit_Log.user_name: user_name, + Audit_Log.user_id: user_id, + Audit_Log.server_id: server_id, + Audit_Log.log_msg: log_msg, + Audit_Log.source_ip: source_ip + }).execute() + + #************************************************************************************************ + # Schedules Methods + #************************************************************************************************ + @staticmethod + def create_scheduled_task(server_id, action, interval, interval_type, start_time, command, comment=None, enabled=True): + sch_id = Schedules.insert({ + Schedules.server_id: server_id, + Schedules.action: action, + Schedules.enabled: enabled, + Schedules.interval: interval, + Schedules.interval_type: interval_type, + Schedules.start_time: start_time, + Schedules.command: command, + Schedules.comment: comment + }).execute() + return sch_id + + @staticmethod + def delete_scheduled_task(schedule_id): + sch = Schedules.get(Schedules.schedule_id == schedule_id) + return Schedules.delete_instance(sch) + + @staticmethod + def update_scheduled_task(schedule_id, updates): + Schedules.update(updates).where(Schedules.schedule_id == schedule_id).execute() + + @staticmethod + def get_scheduled_task(schedule_id): + return model_to_dict(Schedules.get(Schedules.schedule_id == schedule_id)).execute() + + @staticmethod + def get_schedules_by_server(server_id): + return Schedules.select().where(Schedules.server_id == server_id).execute() + + @staticmethod + def get_schedules_all(): + return Schedules.select().execute() + + @staticmethod + def get_schedules_enabled(): + return Schedules.select().where(Schedules.enabled == True).execute() + + #************************************************************************************************ + # Backups Methods + #************************************************************************************************ + @staticmethod + def get_backup_config(server_id): + try: + row = Backups.select().where(Backups.server_id == server_id).join(Schedules).join(Servers)[0] + conf = { + "backup_path": row.server_id.backup_path, + "directories": row.directories, + "max_backups": row.max_backups, + "auto_enabled": row.schedule_id.enabled, + "server_id": row.server_id.server_id + } + except IndexError: + conf = { + "backup_path": None, + "directories": None, + "max_backups": 0, + "auto_enabled": True, + "server_id": server_id + } + return conf + + @staticmethod + def set_backup_config(server_id: int, backup_path: str = None, max_backups: int = None, auto_enabled: bool = True): + logger.debug("Updating server {} backup config with {}".format(server_id, locals())) + try: + row = Backups.select().where(Backups.server_id == server_id).join(Schedules).join(Servers)[0] + new_row = False + conf = {} + schd = {} + except IndexError: + conf = { + "directories": None, + "max_backups": 0, + "server_id": server_id + } + schd = { + "enabled": True, + "action": "backup_server", + "interval_type": "days", + "interval": 1, + "start_time": "00:00", + "server_id": server_id, + "comment": "Default backup job" + } + new_row = True + if max_backups is not None: + conf['max_backups'] = max_backups + schd['enabled'] = bool(auto_enabled) + if not new_row: + with database.atomic(): + if backup_path is not None: + u1 = Servers.update(backup_path=backup_path).where(Servers.server_id == server_id).execute() + else: + u1 = 0 + u2 = Backups.update(conf).where(Backups.server_id == server_id).execute() + u3 = Schedules.update(schd).where(Schedules.schedule_id == row.schedule_id).execute() + logger.debug("Updating existing backup record. {}+{}+{} rows affected".format(u1, u2, u3)) + else: + with database.atomic(): + conf["server_id"] = server_id + if backup_path is not None: + u = Servers.update(backup_path=backup_path).where(Servers.server_id == server_id) + s = Schedules.create(**schd) + conf['schedule_id'] = s.schedule_id + b = Backups.create(**conf) + logger.debug("Creating new backup record.") + + +management_helper = helpers_management() diff --git a/app/classes/models/roles.py b/app/classes/models/roles.py new file mode 100644 index 00000000..8684c3f0 --- /dev/null +++ b/app/classes/models/roles.py @@ -0,0 +1,87 @@ +import os +import sys +import logging +import datetime + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console + +logger = logging.getLogger(__name__) +peewee_logger = logging.getLogger('peewee') +peewee_logger.setLevel(logging.INFO) + +try: + from peewee import * + from playhouse.shortcuts import model_to_dict + from enum import Enum + import yaml + +except ModuleNotFoundError as e: + logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) + console.critical("Import Error: Unable to load {} module".format(e.name)) + sys.exit(1) + +database = SqliteDatabase(helper.db_path, pragmas={ + 'journal_mode': 'wal', + 'cache_size': -1024 * 10}) + +#************************************************************************************************ +# Roles Class +#************************************************************************************************ +class Roles(Model): + role_id = AutoField() + created = DateTimeField(default=datetime.datetime.now) + last_update = DateTimeField(default=datetime.datetime.now) + role_name = CharField(default="", unique=True, index=True) + + class Meta: + table_name = "roles" + database = database + +#************************************************************************************************ +# Roles Helpers +#************************************************************************************************ +class helper_roles: + @staticmethod + def get_all_roles(): + query = Roles.select() + return query + + @staticmethod + def get_roleid_by_name(role_name): + try: + return (Roles.get(Roles.role_name == role_name)).role_id + except DoesNotExist: + return None + + @staticmethod + def get_role(role_id): + return model_to_dict(Roles.get(Roles.role_id == role_id)) + + @staticmethod + def add_role(role_name): + role_id = Roles.insert({ + Roles.role_name: role_name.lower(), + Roles.created: helper.get_time_as_string() + }).execute() + return role_id + + @staticmethod + def update_role(role_id, up_data): + return Roles.update(up_data).where(Roles.role_id == role_id).execute() + + @staticmethod + def remove_role(role_id): + with database.atomic(): + Role_Servers.delete().where(Role_Servers.role_id == role_id).execute() + User_Roles.delete().where(User_Roles.role_id == role_id).execute() + role = Roles.get(Roles.role_id == role_id) + return role.delete_instance() + + @staticmethod + def role_id_exists(role_id): + if not roles_helper.get_role(role_id): + return False + return True + +roles_helper = helper_roles() diff --git a/app/classes/models/server_permissions.py b/app/classes/models/server_permissions.py new file mode 100644 index 00000000..be6aa4d3 --- /dev/null +++ b/app/classes/models/server_permissions.py @@ -0,0 +1,154 @@ +import os +import sys +import logging +import datetime + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console +from app.classes.models.servers import Servers +from app.classes.models.roles import Roles +from app.classes.models.users import users_helper + +logger = logging.getLogger(__name__) +peewee_logger = logging.getLogger('peewee') +peewee_logger.setLevel(logging.INFO) + +try: + from peewee import * + from playhouse.shortcuts import model_to_dict + from enum import Enum + import yaml + +except ModuleNotFoundError as e: + logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) + console.critical("Import Error: Unable to load {} module".format(e.name)) + sys.exit(1) + +database = SqliteDatabase(helper.db_path, pragmas={ + 'journal_mode': 'wal', + 'cache_size': -1024 * 10}) + + +#************************************************************************************************ +# Role Servers Class +#************************************************************************************************ +class Role_Servers(Model): + role_id = ForeignKeyField(Roles, backref='role_server') + server_id = ForeignKeyField(Servers, backref='role_server') + permissions = CharField(default="00000000") + + class Meta: + table_name = 'role_servers' + primary_key = CompositeKey('role_id', 'server_id') + database = database + +#************************************************************************************************ +# Servers Permissions Class +#************************************************************************************************ +class Enum_Permissions_Server(Enum): + Commands = 0 + Terminal = 1 + Logs = 2 + Schedule = 3 + Backup = 4 + Files = 5 + Config = 6 + Players = 7 + +class Permissions_Servers: + + @staticmethod + def get_or_create(role_id, server, permissions_mask): + return Role_Servers.get_or_create(role_id=role_id, server_id=server, permissions=permissions_mask) + + @staticmethod + def get_permissions_list(): + permissions_list = [] + for member in Enum_Permissions_Server.__members__.items(): + permissions_list.append(member[1]) + return permissions_list + + @staticmethod + def get_permissions(permissions_mask): + permissions_list = [] + for member in Enum_Permissions_Server.__members__.items(): + if server_permissions.has_permission(permissions_mask, member[1]): + permissions_list.append(member[1]) + return permissions_list + + @staticmethod + def has_permission(permission_mask, permission_tested: Enum_Permissions_Server): + result = False + if permission_mask[permission_tested.value] == '1': + result = True + return result + + @staticmethod + def set_permission(permission_mask, permission_tested: Enum_Permissions_Server, value): + list_perms = list(permission_mask) + list_perms[permission_tested.value] = str(value) + permission_mask = ''.join(list_perms) + return permission_mask + + @staticmethod + def get_permission(permission_mask, permission_tested: Enum_Permissions_Server): + return permission_mask[permission_tested.value] + + + #************************************************************************************************ + # Role_Servers Methods + #************************************************************************************************ + @staticmethod + def get_role_servers_from_role_id(roleid): + return Role_Servers.select().where(Role_Servers.role_id == roleid) + + @staticmethod + def get_servers_from_role(role_id): + return Role_Servers.select().join(Servers, JOIN.INNER).where(Role_Servers.role_id == role_id) + + @staticmethod + def add_role_server(server_id, role_id, rs_permissions="00000000"): + servers = Role_Servers.insert({Role_Servers.server_id: server_id, Role_Servers.role_id: role_id, Role_Servers.permissions: rs_permissions}).execute() + return servers + + @staticmethod + def get_permissions_mask(role_id, server_id): + permissions_mask = '' + role_server = Role_Servers.select().where(Role_Servers.role_id == role_id).where(Role_Servers.server_id == server_id).execute() + permissions_mask = role_server.permissions + return permissions_mask + + @staticmethod + def get_role_permissions_list(role_id): + permissions_mask = '' + role_server = Role_Servers.select().where(Role_Servers.role_id == role_id).execute() + permissions_mask = role_server[0].permissions + permissions_list = server_permissions.get_permissions(permissions_mask) + return permissions_list + + @staticmethod + def update_role_permission(role_id, server_id, permissions_mask): + role_server = Role_Servers.select().where(Role_Servers.role_id == role_id).where(Role_Servers.server_id == server_id).get() + role_server.permissions = permissions_mask + Role_Servers.save(role_server) + + @staticmethod + def delete_roles_permissions(role_id, removed_servers={}): + return Role_Servers.delete().where(Role_Servers.role_id == role_id).where(Role_Servers.server_id.in_(removed_servers)).execute() + + @staticmethod + def get_user_permissions_list(user_id, server_id): + permissions_mask = '' + permissions_list = [] + + user = users_helper.get_user(user_id) + if user['superuser'] == True: + permissions_list = server_permissions.get_permissions_list() + else: + roles_list = users_helper.get_user_roles_id(user_id) + role_server = Role_Servers.select().where(Role_Servers.role_id.in_(roles_list)).where(Role_Servers.server_id == int(server_id)).execute() + permissions_mask = role_server[0].permissions + permissions_list = server_permissions.get_permissions(permissions_mask) + return permissions_list + +server_permissions = Permissions_Servers() \ No newline at end of file diff --git a/app/classes/models/servers.py b/app/classes/models/servers.py new file mode 100644 index 00000000..a3df265d --- /dev/null +++ b/app/classes/models/servers.py @@ -0,0 +1,191 @@ +import os +import sys +import logging +import datetime + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console + +from app.classes.shared.main_models import db_helper + +logger = logging.getLogger(__name__) +peewee_logger = logging.getLogger('peewee') +peewee_logger.setLevel(logging.INFO) + +try: + from peewee import * + from playhouse.shortcuts import model_to_dict + from enum import Enum + import yaml + +except ModuleNotFoundError as e: + logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) + console.critical("Import Error: Unable to load {} module".format(e.name)) + sys.exit(1) + +database = SqliteDatabase(helper.db_path, pragmas={ + 'journal_mode': 'wal', + 'cache_size': -1024 * 10}) + +#************************************************************************************************ +# Servers Class +#************************************************************************************************ +class Servers(Model): + server_id = AutoField() + created = DateTimeField(default=datetime.datetime.now) + server_uuid = CharField(default="", index=True) + server_name = CharField(default="Server", index=True) + path = CharField(default="") + backup_path = CharField(default="") + executable = CharField(default="") + log_path = CharField(default="") + execution_command = CharField(default="") + auto_start = BooleanField(default=0) + auto_start_delay = IntegerField(default=10) + crash_detection = BooleanField(default=0) + stop_command = CharField(default="stop") + executable_update_url = CharField(default="") + server_ip = CharField(default="127.0.0.1") + server_port = IntegerField(default=25565) + logs_delete_after = IntegerField(default=0) + + class Meta: + table_name = "servers" + database = database + + +#************************************************************************************************ +# Servers Stats Class +#************************************************************************************************ +class Server_Stats(Model): + stats_id = AutoField() + created = DateTimeField(default=datetime.datetime.now) + server_id = ForeignKeyField(Servers, backref='server', index=True) + started = CharField(default="") + running = BooleanField(default=False) + cpu = FloatField(default=0) + mem = FloatField(default=0) + mem_percent = FloatField(default=0) + world_name = CharField(default="") + world_size = CharField(default="") + server_port = IntegerField(default=25565) + int_ping_results = CharField(default="") + online = IntegerField(default=0) + max = IntegerField(default=0) + players = CharField(default="") + desc = CharField(default="Unable to Connect") + version = CharField(default="") + updating = BooleanField(default=False) + + + class Meta: + table_name = "server_stats" + database = database + + +#************************************************************************************************ +# Servers Class +#************************************************************************************************ +class helper_servers: + + #************************************************************************************************ + # Generic Servers Methods + #************************************************************************************************ + @staticmethod + def create_server(name: str, server_uuid: str, server_dir: str, backup_path: str, server_command: str, server_file: str, server_log_file: str, server_stop: str, server_port=25565): + return Servers.insert({ + Servers.server_name: name, + Servers.server_uuid: server_uuid, + Servers.path: server_dir, + Servers.executable: server_file, + Servers.execution_command: server_command, + Servers.auto_start: False, + Servers.auto_start_delay: 10, + Servers.crash_detection: False, + Servers.log_path: server_log_file, + Servers.server_port: server_port, + Servers.stop_command: server_stop, + Servers.backup_path: backup_path + }).execute() + + @staticmethod + def remove_server(server_id): + with database.atomic(): + Role_Servers.delete().where(Role_Servers.server_id == server_id).execute() + Servers.delete().where(Servers.server_id == server_id).execute() + + @staticmethod + def get_server_data_by_id(server_id): + query = Servers.select().where(Servers.server_id == server_id).limit(1) + try: + return db_helper.return_rows(query)[0] + except IndexError: + return {} + + #************************************************************************************************ + # Servers Methods + #************************************************************************************************ + @staticmethod + def get_all_defined_servers(): + query = Servers.select() + return db_helper.return_rows(query) + + @staticmethod + def get_all_servers_stats(): + servers = servers_helper.get_all_defined_servers() + server_data = [] + + for s in servers: + latest = Server_Stats.select().where(Server_Stats.server_id == s.get('server_id')).order_by(Server_Stats.created.desc()).limit(1) + server_data.append({'server_data': s, "stats": db_helper.return_rows(latest)[0], "user_command_permission":True}) + return server_data + + @staticmethod + def get_server_friendly_name(server_id): + server_data = servers_helper.get_server_data_by_id(server_id) + friendly_name = "{} with ID: {}".format(server_data.get('server_name', None), server_data.get('server_id', 0)) + return friendly_name + + #************************************************************************************************ + # Servers_Stats Methods + #************************************************************************************************ + @staticmethod + def get_latest_server_stats(server_id): + return Server_Stats.select().where(Server_Stats.server_id == server_id).order_by(Server_Stats.created.desc()).limit(1) + + @staticmethod + def get_server_stats_by_id(server_id): + stats = Server_Stats.select().where(Server_Stats.server_id == server_id).order_by(Server_Stats.created.desc()).limit(1) + return db_helper.return_rows(stats)[0] + + @staticmethod + def server_id_exists(server_id): + if not servers_helper.get_server_data_by_id(server_id): + return False + return True + + @staticmethod + def set_update(server_id, value): + try: + row = Server_Stats.select().where(Server_Stats.server_id == server_id) + except Exception as ex: + logger.error("Database entry not found. ".format(ex)) + with database.atomic(): + Server_Stats.update(updating=value).where(Server_Stats.server_id == server_id).execute() + + @staticmethod + def get_TTL_without_player(server_id): + last_stat = Server_Stats.select().where(Server_Stats.server_id == server_id).order_by(Server_Stats.created.desc()).first() + last_stat_with_player = Server_Stats.select().where(Server_Stats.server_id == server_id).where(Server_Stats.online > 0).order_by(Server_Stats.created.desc()).first() + return last_stat.created - last_stat_with_player.created + + @staticmethod + def can_stop_no_players(server_id, time_limit): + can = False + ttl_no_players = get_TTL_without_player(server_id) + if (time_limit == -1) or (ttl_no_players > time_limit): + can = True + return can + + +servers_helper = helper_servers() \ No newline at end of file diff --git a/app/classes/models/users.py b/app/classes/models/users.py new file mode 100644 index 00000000..04f7875e --- /dev/null +++ b/app/classes/models/users.py @@ -0,0 +1,237 @@ +import os +import sys +import logging +import datetime + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console + +from app.classes.models.roles import Roles, roles_helper + +logger = logging.getLogger(__name__) +peewee_logger = logging.getLogger('peewee') +peewee_logger.setLevel(logging.INFO) + +try: + from peewee import * + from playhouse.shortcuts import model_to_dict + from enum import Enum + import yaml + +except ModuleNotFoundError as e: + logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) + console.critical("Import Error: Unable to load {} module".format(e.name)) + sys.exit(1) + +database = SqliteDatabase(helper.db_path, pragmas={ + 'journal_mode': 'wal', + 'cache_size': -1024 * 10}) + +#************************************************************************************************ +# Users Class +#************************************************************************************************ +class Users(Model): + user_id = AutoField() + created = DateTimeField(default=datetime.datetime.now) + last_login = DateTimeField(default=datetime.datetime.now) + last_update = DateTimeField(default=datetime.datetime.now) + last_ip = CharField(default="") + username = CharField(default="", unique=True, index=True) + password = CharField(default="") + enabled = BooleanField(default=True) + superuser = BooleanField(default=False) + api_token = CharField(default="", unique=True, index=True) # we may need to revisit this + + class Meta: + table_name = "users" + database = database + +#************************************************************************************************ +# User Roles Class +#************************************************************************************************ +class User_Roles(Model): + user_id = ForeignKeyField(Users, backref='user_role') + role_id = ForeignKeyField(Roles, backref='user_role') + + class Meta: + table_name = 'user_roles' + primary_key = CompositeKey('user_id', 'role_id') + database = database + +#************************************************************************************************ +# Users Helpers +#************************************************************************************************ +class helper_users: + + @staticmethod + def get_by_id(user_id): + return Users.get_by_id(user_id) + + @staticmethod + def get_all_users(): + query = Users.select() + return query + + @staticmethod + def get_user_id_by_name(username): + if username == "SYSTEM": + return 0 + try: + return (Users.get(Users.username == username)).user_id + except DoesNotExist: + return None + + @staticmethod + def get_user_by_api_token(token: str): + query = Users.select().where(Users.api_token == token) + + if query.exists(): + user = model_to_dict(Users.get(Users.api_token == token)) + # I know it should apply it without setting it but I'm just making sure + user = users_helper.add_user_roles(user) + return user + else: + return {} + + @staticmethod + def user_query(user_id): + user_query = Users.select().where(Users.user_id == user_id) + return user_query + + @staticmethod + def get_user(user_id): + if user_id == 0: + return { + 'user_id': 0, + 'created': None, + 'last_login': None, + 'last_update': None, + 'last_ip': "127.27.23.89", + 'username': "SYSTEM", + 'password': None, + 'enabled': True, + 'superuser': False, + 'api_token': None, + 'roles': [], + 'servers': [], + } + user = model_to_dict(Users.get(Users.user_id == user_id)) + + if user: + # I know it should apply it without setting it but I'm just making sure + user = users_helper.add_user_roles(user) + return user + else: + #logger.debug("user: ({}) {}".format(user_id, {})) + return {} + + @staticmethod + def add_user(username, password=None, api_token=None, enabled=True, superuser=False): + if password is not None: + pw_enc = helper.encode_pass(password) + else: + pw_enc = None + if api_token is None: + api_token = users_helper.new_api_token() + else: + if type(api_token) is not str and len(api_token) != 32: + raise ValueError("API token must be a 32 character string") + user_id = Users.insert({ + Users.username: username.lower(), + Users.password: pw_enc, + Users.api_token: api_token, + Users.enabled: enabled, + Users.superuser: superuser, + Users.created: helper.get_time_as_string() + }).execute() + return user_id + + @staticmethod + def update_user(user_id, up_data={}): + if up_data: + Users.update(up_data).where(Users.user_id == user_id).execute() + + @staticmethod + def remove_user(user_id): + with database.atomic(): + User_Roles.delete().where(User_Roles.user_id == user_id).execute() + user = Users.get(Users.user_id == user_id) + return user.delete_instance() + + @staticmethod + def user_id_exists(user_id): + if not users_helper.get_user(user_id): + return False + return True + + @staticmethod + def new_api_token(): + while True: + token = helper.random_string_generator(32) + test = list(Users.select(Users.user_id).where(Users.api_token == token)) + if len(test) == 0: + return token + +#************************************************************************************************ +# User_Roles Methods +#************************************************************************************************ + + @staticmethod + def get_or_create(user_id, role_id): + return User_Roles.get_or_create(user_id=user_id, role_id=role_id) + + @staticmethod + def get_user_roles_id(user_id): + roles_list = [] + roles = User_Roles.select().where(User_Roles.user_id == user_id) + for r in roles: + roles_list.append(roles_helper.get_role(r.role_id)['role_id']) + return roles_list + + @staticmethod + def get_user_roles_names(user_id): + roles_list = [] + roles = User_Roles.select().where(User_Roles.user_id == user_id) + for r in roles: + roles_list.append(roles_helper.get_role(r.role_id)['role_name']) + return roles_list + + @staticmethod + def add_role_to_user(user_id, role_id): + User_Roles.insert({ + User_Roles.user_id: user_id, + User_Roles.role_id: role_id + }).execute() + + @staticmethod + def add_user_roles(user): + if type(user) == dict: + user_id = user['user_id'] + else: + user_id = user.user_id + + # I just copied this code from get_user, it had those TODOs & comments made by mac - Lukas + + roles_query = User_Roles.select().join(Roles, JOIN.INNER).where(User_Roles.user_id == user_id) + # TODO: this query needs to be narrower + roles = set() + for r in roles_query: + roles.add(r.role_id.role_id) + + user['roles'] = roles + #logger.debug("user: ({}) {}".format(user_id, user)) + return user + + @staticmethod + def user_role_query(user_id): + user_query = User_Roles.select().where(User_Roles.user_id == user_id) + query = Roles.select().where(Roles.role_id == -1) + for u in user_query: + query = Roles.select().where(Roles.role_id == u.role_id) + return query + + @staticmethod + def delete_user_roles(user_id, removed_roles): + User_Roles.delete().where(User_Roles.user_id == user_id).where(User_Roles.role_id.in_(removed_roles)).execute() + +users_helper = helper_users() \ No newline at end of file diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 7a37f799..77accd0a 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -18,7 +18,6 @@ import shutil from datetime import datetime from socket import gethostname - from app.classes.shared.console import console logger = logging.getLogger(__name__) @@ -76,25 +75,6 @@ class Helpers: logger.error("{} does not exist".format(file)) return True - def check_for_old_logs(self, db_helper): - servers = db_helper.get_all_defined_servers() - for server in servers: - logs_path = os.path.split(server['log_path'])[0] - latest_log_file = os.path.split(server['log_path'])[1] - logs_delete_after = int(server['logs_delete_after']) - if logs_delete_after == 0: - continue - - log_files = list(filter( - lambda val: val != latest_log_file, - os.listdir(logs_path) - )) - for log_file in log_files: - log_file_path = os.path.join(logs_path, log_file) - if self.check_file_exists(log_file_path) and \ - self.is_file_older_than_x_days(log_file_path, logs_delete_after): - os.remove(log_file_path) - def get_setting(self, key, default_return=False): try: @@ -590,22 +570,6 @@ class Helpers: def in_path_old(x, y): return os.path.abspath(y).__contains__(os.path.abspath(x)) - @staticmethod - def get_banned_players(server_id, db_helper): - stats = db_helper.get_server_stats_by_id(server_id) - server_path = stats['server_id']['path'] - path = os.path.join(server_path, 'banned-players.json') - - try: - with open(path) as file: - content = file.read() - file.close() - except Exception as ex: - print (ex) - return None - - return json.loads(content) - @staticmethod def copy_files(source, dest): if os.path.isfile(source): diff --git a/app/classes/shared/controller.py b/app/classes/shared/main_controller.py similarity index 90% rename from app/classes/shared/controller.py rename to app/classes/shared/main_controller.py index f9e1ea16..b87f7a32 100644 --- a/app/classes/shared/controller.py +++ b/app/classes/shared/main_controller.py @@ -12,9 +12,17 @@ from distutils import dir_util from app.classes.shared.helpers import helper from app.classes.shared.console import console -from app.classes.shared.models import db_helper, server_permissions, Enum_Permissions_Server -from app.classes.shared.models_folder.crafty_permissions import crafty_permissions, Enum_Permissions_Crafty -from app.classes.shared.controllers.crafty_perms_controller import Crafty_Perms_Controller +#Importing Models +from app.classes.models.crafty_permissions import crafty_permissions, Enum_Permissions_Crafty +from app.classes.models.servers import servers_helper +#Importing Controllers +from app.classes.controllers.crafty_perms_controller import Crafty_Perms_Controller +from app.classes.controllers.management_controller import Management_Controller +from app.classes.controllers.users_controller import Users_Controller +from app.classes.controllers.roles_controller import Roles_Controller +from app.classes.controllers.server_perms_controller import Server_Perms_Controller +from app.classes.controllers.servers_controller import Servers_Controller + from app.classes.shared.server import Server from app.classes.minecraft.server_props import ServerProps from app.classes.minecraft.serverjars import server_jar_obj @@ -22,13 +30,17 @@ from app.classes.minecraft.stats import Stats logger = logging.getLogger(__name__) - class Controller: def __init__(self): self.servers_list = [] self.stats = Stats(self) self.crafty_perms = Crafty_Perms_Controller() + self.management = Management_Controller() + self.roles = Roles_Controller() + self.server_perms = Server_Perms_Controller() + self.servers = Servers_Controller() + self.users = Users_Controller() def check_server_loaded(self, server_id_to_check: int): @@ -47,7 +59,7 @@ class Controller: def init_all_servers(self): - servers = db_helper.get_all_defined_servers() + servers = self.servers.get_all_defined_servers() for s in servers: server_id = s.get('server_id') @@ -125,33 +137,8 @@ class Controller: @staticmethod def list_defined_servers(): - servers = db_helper.get_all_defined_servers() + servers = servers_helper.get_all_defined_servers() return servers - - @staticmethod - def list_defined_permissions(): - permissions_list = server_permissions.get_permissions_list() - return permissions_list - - @staticmethod - def get_mask_permissions(role_id, server_id): - permissions_mask = db_helper.get_permissions_mask(role_id, server_id) - return permissions_mask - - @staticmethod - def get_role_permissions(role_id): - permissions_list = db_helper.get_role_permissions_list(role_id) - return permissions_list - - @staticmethod - def get_server_permissions_foruser(user_id, server_id): - permissions_list = db_helper.get_user_permissions_list(user_id, server_id) - return permissions_list - - @staticmethod - def list_authorized_servers(userId): - server_list = db_helper.get_authorized_servers(userId) - return server_list def list_running_servers(self): running_servers = [] @@ -352,7 +339,7 @@ class Controller: def register_server(self, name: str, server_uuid: str, server_dir: str, backup_path: str, server_command: str, server_file: str, server_log_file: str, server_stop: str, server_port=25565): # put data in the db - new_id = db_helper.create_server(name, server_uuid, server_dir, backup_path, server_command, server_file, server_log_file, server_stop, server_port) + new_id = self.servers.create_server(name, server_uuid, server_dir, backup_path, server_command, server_file, server_log_file, server_stop, server_port) try: # place a file in the dir saying it's owned by crafty @@ -388,9 +375,9 @@ class Controller: if running: self.stop_server(server_id) if files: - shutil.rmtree(db_helper.get_server_data_by_id(server_id)['path']) + shutil.rmtree(self.servers.get_server_data_by_id(server_id)['path']) # remove the server from the DB - db_helper.remove_server(server_id) + self.servers.remove_server(server_id) # remove the server from servers list self.servers_list.pop(counter) diff --git a/app/classes/shared/main_models.py b/app/classes/shared/main_models.py new file mode 100644 index 00000000..83bcc5c2 --- /dev/null +++ b/app/classes/shared/main_models.py @@ -0,0 +1,94 @@ +import os +import sys +import logging +import datetime + +from app.classes.shared.helpers import helper +from app.classes.shared.console import console +from app.classes.models.users import Users, users_helper +from app.classes.minecraft.server_props import ServerProps +from app.classes.web.websocket_helper import websocket_helper + + +logger = logging.getLogger(__name__) +peewee_logger = logging.getLogger('peewee') +peewee_logger.setLevel(logging.INFO) + +try: + from peewee import * + from playhouse.shortcuts import model_to_dict + from enum import Enum + import yaml + +except ModuleNotFoundError as e: + logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) + console.critical("Import Error: Unable to load {} module".format(e.name)) + sys.exit(1) + +database = SqliteDatabase(helper.db_path, pragmas={ + 'journal_mode': 'wal', + 'cache_size': -1024 * 10}) + +class db_builder: + + @staticmethod + def default_settings(): + logger.info("Fresh Install Detected - Creating Default Settings") + console.info("Fresh Install Detected - Creating Default Settings") + default_data = helper.find_default_password() + + username = default_data.get("username", 'admin') + password = default_data.get("password", 'crafty') + #api_token = helper.random_string_generator(32) + # + #Users.insert({ + # Users.username: username.lower(), + # Users.password: helper.encode_pass(password), + # Users.api_token: api_token, + # Users.enabled: True, + # Users.superuser: True + #}).execute() + user_id = users_helper.add_user(username, password=password, superuser=True) + #users_helper.update_user(user_id, user_crafty_data={"permissions_mask":"111", "server_quantity":[-1,-1,-1]} ) + + #console.info("API token is {}".format(api_token)) + + @staticmethod + def is_fresh_install(): + try: + user = users_helper.get_by_id(1) + return False + except: + return True + pass + +class db_shortcuts: + + #************************************************************************************************ + # Generic Databse Methods + #************************************************************************************************ + @staticmethod + def return_rows(query): + rows = [] + + try: + if query.count() > 0: + for s in query: + rows.append(model_to_dict(s)) + except Exception as e: + logger.warning("Database Error: {}".format(e)) + pass + + return rows + + @staticmethod + def return_db_rows(model): + data = [model_to_dict(row) for row in model] + return data + + +#************************************************************************************************ +# Static Accessors +#************************************************************************************************ +installer = db_builder() +db_helper = db_shortcuts() diff --git a/app/classes/shared/models.py b/app/classes/shared/models.py deleted file mode 100644 index 07d456e2..00000000 --- a/app/classes/shared/models.py +++ /dev/null @@ -1,1083 +0,0 @@ -import os -import sys -import logging -import datetime - -from app.classes.shared.helpers import helper -from app.classes.shared.console import console -from app.classes.minecraft.server_props import ServerProps -from app.classes.web.websocket_helper import websocket_helper - -logger = logging.getLogger(__name__) -peewee_logger = logging.getLogger('peewee') -peewee_logger.setLevel(logging.INFO) - -try: - from peewee import * - from playhouse.shortcuts import model_to_dict - from enum import Enum - import yaml - -except ModuleNotFoundError as e: - logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) - console.critical("Import Error: Unable to load {} module".format(e.name)) - sys.exit(1) - -database = SqliteDatabase(helper.db_path, pragmas={ - 'journal_mode': 'wal', - 'cache_size': -1024 * 10}) - - -class Users(Model): - user_id = AutoField() - created = DateTimeField(default=datetime.datetime.now) - last_login = DateTimeField(default=datetime.datetime.now) - last_update = DateTimeField(default=datetime.datetime.now) - last_ip = CharField(default="") - username = CharField(default="", unique=True, index=True) - password = CharField(default="") - enabled = BooleanField(default=True) - superuser = BooleanField(default=False) - api_token = CharField(default="", unique=True, index=True) # we may need to revisit this - - class Meta: - table_name = "users" - database = database - - -class Roles(Model): - role_id = AutoField() - created = DateTimeField(default=datetime.datetime.now) - last_update = DateTimeField(default=datetime.datetime.now) - role_name = CharField(default="", unique=True, index=True) - - class Meta: - table_name = "roles" - database = database - - -class User_Roles(Model): - user_id = ForeignKeyField(Users, backref='user_role') - role_id = ForeignKeyField(Roles, backref='user_role') - - class Meta: - table_name = 'user_roles' - primary_key = CompositeKey('user_id', 'role_id') - database = database - - -class Audit_Log(Model): - audit_id = AutoField() - created = DateTimeField(default=datetime.datetime.now) - user_name = CharField(default="") - user_id = IntegerField(default=0, index=True) - source_ip = CharField(default='127.0.0.1') - server_id = IntegerField(default=None, index=True) # When auditing global events, use server ID 0 - log_msg = TextField(default='') - - class Meta: - database = database - - -class Host_Stats(Model): - time = DateTimeField(default=datetime.datetime.now, index=True) - boot_time = CharField(default="") - cpu_usage = FloatField(default=0) - cpu_cores = IntegerField(default=0) - cpu_cur_freq = FloatField(default=0) - cpu_max_freq = FloatField(default=0) - mem_percent = FloatField(default=0) - mem_usage = CharField(default="") - mem_total = CharField(default="") - disk_json = TextField(default="") - - class Meta: - table_name = "host_stats" - database = database - - -class Servers(Model): - server_id = AutoField() - created = DateTimeField(default=datetime.datetime.now) - server_uuid = CharField(default="", index=True) - server_name = CharField(default="Server", index=True) - path = CharField(default="") - backup_path = CharField(default="") - executable = CharField(default="") - log_path = CharField(default="") - execution_command = CharField(default="") - auto_start = BooleanField(default=0) - auto_start_delay = IntegerField(default=10) - crash_detection = BooleanField(default=0) - stop_command = CharField(default="stop") - executable_update_url = CharField(default="") - server_ip = CharField(default="127.0.0.1") - server_port = IntegerField(default=25565) - logs_delete_after = IntegerField(default=0) - - class Meta: - table_name = "servers" - database = database - -class Role_Servers(Model): - role_id = ForeignKeyField(Roles, backref='role_server') - server_id = ForeignKeyField(Servers, backref='role_server') - permissions = CharField(default="00000000") - - class Meta: - table_name = 'role_servers' - primary_key = CompositeKey('role_id', 'server_id') - database = database - -class User_Crafty(Model): - user_id = ForeignKeyField(Users, backref='users_crafty') - permissions = CharField(default="00000000") - limit_server_creation = IntegerField(default=-1) - limit_user_creation = IntegerField(default=0) - limit_role_creation = IntegerField(default=0) - created_server = IntegerField(default=0) - created_user = IntegerField(default=0) - created_role = IntegerField(default=0) - - class Meta: - table_name = 'user_crafty' - database = database - -class Server_Stats(Model): - stats_id = AutoField() - created = DateTimeField(default=datetime.datetime.now) - server_id = ForeignKeyField(Servers, backref='server', index=True) - started = CharField(default="") - running = BooleanField(default=False) - cpu = FloatField(default=0) - mem = FloatField(default=0) - mem_percent = FloatField(default=0) - world_name = CharField(default="") - world_size = CharField(default="") - server_port = IntegerField(default=25565) - int_ping_results = CharField(default="") - online = IntegerField(default=0) - max = IntegerField(default=0) - players = CharField(default="") - desc = CharField(default="Unable to Connect") - version = CharField(default="") - updating = BooleanField(default=False) - - - class Meta: - table_name = "server_stats" - database = database - - -class Commands(Model): - command_id = AutoField() - created = DateTimeField(default=datetime.datetime.now) - server_id = ForeignKeyField(Servers, backref='server', index=True) - user = ForeignKeyField(Users, backref='user', index=True) - source_ip = CharField(default='127.0.0.1') - command = CharField(default='') - executed = BooleanField(default=False) - - class Meta: - table_name = "commands" - database = database - - -class Webhooks(Model): - id = AutoField() - name = CharField(max_length=64, unique=True, index=True) - method = CharField(default="POST") - url = CharField(unique=True) - event = CharField(default="") - send_data = BooleanField(default=True) - - class Meta: - table_name = "webhooks" - database = database - - -class Schedules(Model): - schedule_id = IntegerField(unique=True, primary_key=True) - server_id = ForeignKeyField(Servers, backref='schedule_server') - enabled = BooleanField() - action = CharField() - interval = IntegerField() - interval_type = CharField() - start_time = CharField(null=True) - command = CharField(null=True) - comment = CharField() - - class Meta: - table_name = 'schedules' - database = database - - -class Backups(Model): - directories = CharField(null=True) - max_backups = IntegerField() - server_id = ForeignKeyField(Servers, backref='backups_server') - schedule_id = ForeignKeyField(Schedules, backref='backups_schedule') - - class Meta: - table_name = 'backups' - database = database - - -class db_builder: - - @staticmethod - def default_settings(): - logger.info("Fresh Install Detected - Creating Default Settings") - console.info("Fresh Install Detected - Creating Default Settings") - default_data = helper.find_default_password() - - username = default_data.get("username", 'admin') - password = default_data.get("password", 'crafty') - #api_token = helper.random_string_generator(32) - # - #Users.insert({ - # Users.username: username.lower(), - # Users.password: helper.encode_pass(password), - # Users.api_token: api_token, - # Users.enabled: True, - # Users.superuser: True - #}).execute() - user_id = db_shortcuts.add_user(username, password=password, superuser=True) - #db_shortcuts.update_user(user_id, user_crafty_data={"permissions_mask":"111", "server_quantity":[-1,-1,-1]} ) - - #console.info("API token is {}".format(api_token)) - - @staticmethod - def is_fresh_install(): - try: - user = Users.get_by_id(1) - return False - except: - return True - pass - -class db_shortcuts: - - #************************************************************************************************ - # Generic Databse Methods - #************************************************************************************************ - @staticmethod - def return_rows(query): - rows = [] - - try: - if query.count() > 0: - for s in query: - rows.append(model_to_dict(s)) - except Exception as e: - logger.warning("Database Error: {}".format(e)) - pass - - return rows - - @staticmethod - def return_db_rows(model): - data = [model_to_dict(row) for row in model] - return data - - #************************************************************************************************ - # Generic Servers Methods - #************************************************************************************************ - @staticmethod - def create_server(name: str, server_uuid: str, server_dir: str, backup_path: str, server_command: str, server_file: str, server_log_file: str, server_stop: str, server_port=25565): - return Servers.insert({ - Servers.server_name: name, - Servers.server_uuid: server_uuid, - Servers.path: server_dir, - Servers.executable: server_file, - Servers.execution_command: server_command, - Servers.auto_start: False, - Servers.auto_start_delay: 10, - Servers.crash_detection: False, - Servers.log_path: server_log_file, - Servers.server_port: server_port, - Servers.stop_command: server_stop, - Servers.backup_path: backup_path - }).execute() - - @staticmethod - def remove_server(server_id): - with database.atomic(): - Role_Servers.delete().where(Role_Servers.server_id == server_id).execute() - Servers.delete().where(Servers.server_id == server_id).execute() - - @staticmethod - def get_server_data_by_id(server_id): - query = Servers.select().where(Servers.server_id == server_id).limit(1) - try: - return db_helper.return_rows(query)[0] - except IndexError: - return {} - - #************************************************************************************************ - # Servers Methods - #************************************************************************************************ - @staticmethod - def get_all_defined_servers(): - query = Servers.select() - return db_helper.return_rows(query) - - @staticmethod - def get_authorized_servers(user_id): - server_data = [] - user_roles = User_Roles.select().where(User_Roles.user_id == user_id) - for us in user_roles: - role_servers = Role_Servers.select().where(Role_Servers.role_id == us.role_id) - for role in role_servers: - server_data.append(db_shortcuts.get_server_data_by_id(role.server_id)) - - return server_data - - @staticmethod - def get_all_servers_stats(): - servers = db_helper.get_all_defined_servers() - server_data = [] - - for s in servers: - latest = Server_Stats.select().where(Server_Stats.server_id == s.get('server_id')).order_by(Server_Stats.created.desc()).limit(1) - server_data.append({'server_data': s, "stats": db_helper.return_rows(latest)[0], "user_command_permission":True}) - return server_data - - @staticmethod - def get_authorized_servers_stats(user_id): - server_data = [] - authorized_servers = db_helper.get_authorized_servers(user_id) - - for s in authorized_servers: - latest = Server_Stats.select().where(Server_Stats.server_id == s.get('server_id')).order_by( - Server_Stats.created.desc()).limit(1) - user_permissions = db_helper.get_user_permissions_list(user_id, s.get('server_id')) - if Enum_Permissions_Server.Commands in user_permissions: - user_command_permission = True - else: - user_command_permission = False - server_data.append({'server_data': s, "stats": db_helper.return_rows(latest)[0], "user_command_permission":user_command_permission}) - return server_data - - @staticmethod - def get_server_friendly_name(server_id): - server_data = db_helper.get_server_data_by_id(server_id) - friendly_name = "{} with ID: {}".format(server_data.get('server_name', None), server_data.get('server_id', 0)) - return friendly_name - - #************************************************************************************************ - # Servers Permissions Methods - #************************************************************************************************ - @staticmethod - def get_permissions_mask(role_id, server_id): - permissions_mask = '' - role_server = Role_Servers.select().where(Role_Servers.role_id == role_id).where(Role_Servers.server_id == server_id).execute() - permissions_mask = role_server.permissions - return permissions_mask - - @staticmethod - def get_role_permissions_list(role_id): - permissions_mask = '' - role_server = Role_Servers.select().where(Role_Servers.role_id == role_id).execute() - permissions_mask = role_server[0].permissions - permissions_list = server_permissions.get_permissions(permissions_mask) - return permissions_list - - @staticmethod - def get_user_permissions_list(user_id, server_id): - permissions_mask = '' - permissions_list = [] - - user = db_helper.get_user(user_id) - if user['superuser'] == True: - permissions_list = server_permissions.get_permissions_list() - else: - roles_list = db_helper.get_user_roles_id(user_id) - role_server = Role_Servers.select().where(Role_Servers.role_id.in_(roles_list)).where(Role_Servers.server_id == int(server_id)).execute() - permissions_mask = role_server[0].permissions - permissions_list = server_permissions.get_permissions(permissions_mask) - return permissions_list - - @staticmethod - def get_authorized_servers_stats_from_roles(user_id): - user_roles = User_Roles.select().where(User_Roles.user_id == user_id) - roles_list = [] - role_server = [] - authorized_servers = [] - server_data = [] - - for u in user_roles: - roles_list.append(db_helper.get_role(u.role_id)) - - for r in roles_list: - role_test = Role_Servers.select().where(Role_Servers.role_id == r.get('role_id')) - for t in role_test: - role_server.append(t) - - for s in role_server: - authorized_servers.append(db_helper.get_server_data_by_id(s.server_id)) - - for s in authorized_servers: - latest = Server_Stats.select().where(Server_Stats.server_id == s.get('server_id')).order_by(Server_Stats.created.desc()).limit(1) - server_data.append({'server_data': s, "stats": db_helper.return_rows(latest)[0]}) - return server_data - - - #************************************************************************************************ - # Servers_Stats Methods - #************************************************************************************************ - @staticmethod - def get_server_stats_by_id(server_id): - stats = Server_Stats.select().where(Server_Stats.server_id == server_id).order_by(Server_Stats.created.desc()).limit(1) - return db_helper.return_rows(stats)[0] - - @staticmethod - def server_id_exists(server_id): - if not db_helper.get_server_data_by_id(server_id): - return False - return True - - @staticmethod - def server_id_authorized(serverId, user_id): - authorized = 0 - user_roles = User_Roles.select().where(User_Roles.user_id == user_id) - for role in user_roles: - authorized = (Role_Servers.select().where(Role_Servers.role_id == role.role_id)) - - #authorized = db_helper.return_rows(authorized) - - if authorized.count() == 0: - return False - return True - - @staticmethod - def set_update(server_id, value): - try: - row = Server_Stats.select().where(Server_Stats.server_id == server_id) - except Exception as ex: - logger.error("Database entry not found. ".format(ex)) - with database.atomic(): - Server_Stats.update(updating=value).where(Server_Stats.server_id == server_id).execute() - - @staticmethod - def get_TTL_without_player(server_id): - last_stat = Server_Stats.select().where(Server_Stats.server_id == server_id).order_by(Server_Stats.created.desc()).first() - last_stat_with_player = Server_Stats.select().where(Server_Stats.server_id == server_id).where(Server_Stats.online > 0).order_by(Server_Stats.created.desc()).first() - return last_stat.created - last_stat_with_player.created - - @staticmethod - def can_stop_no_players(server_id, time_limit): - can = False - ttl_no_players = get_TTL_without_player(server_id) - if (time_limit == -1) or (ttl_no_players > time_limit): - can = True - return can - - #************************************************************************************************ - # User_Crafty Methods - #************************************************************************************************ - @staticmethod - def get_User_Crafty(user_id): - try: - user_crafty = User_Crafty.select().where(User_Crafty.user_id == user_id).get() - except User_Crafty.DoesNotExist: - user_crafty = User_Crafty.insert({ - User_Crafty.user_id: user_id, - User_Crafty.permissions: "000", - User_Crafty.limit_server_creation: 0, - User_Crafty.limit_user_creation: 0, - User_Crafty.limit_role_creation: 0, - User_Crafty.created_server: 0, - User_Crafty.created_user: 0, - User_Crafty.created_role: 0, - }).execute() - user_crafty = db_helper.get_User_Crafty(user_id) - return user_crafty - - @staticmethod - def add_user_crafty(user_id, uc_permissions): - user_crafty = User_Crafty.insert({User_Crafty.user_id: user_id, User_Crafty.permissions: uc_permissions}).execute() - return user_crafty - - @staticmethod - def get_created_quantity_list(user_id): - user_crafty = db_helper.get_User_Crafty(user_id) - quantity_list = { - Enum_Permissions_Crafty.Server_Creation.name: user_crafty.created_server, - Enum_Permissions_Crafty.User_Config.name: user_crafty.created_user, - Enum_Permissions_Crafty.Roles_Config.name: user_crafty.created_role, - } - return quantity_list - - @staticmethod - def get_crafty_limit_value(user_id, permission): - user_crafty = db_helper.get_User_Crafty(user_id) - quantity_list = get_permission_quantity_list(user_id) - return quantity_list[permission] - - @staticmethod - def can_add_in_crafty(user_id, permission): - user_crafty = db_helper.get_User_Crafty(user_id) - can = crafty_permissions.has_permission(user_crafty.permissions, permission) - limit_list = db_helper.get_permission_quantity_list(user_id) - quantity_list = db_helper.get_created_quantity_list(user_id) - return can and ((quantity_list[permission.name] < limit_list[permission.name]) or limit_list[permission.name] == -1 ) - - @staticmethod - def add_server_creation(user_id): - user_crafty = db_helper.get_User_Crafty(user_id) - user_crafty.created_server += 1 - User_Crafty.save(user_crafty) - return user_crafty.created_server - - - #************************************************************************************************ - # Host_Stats Methods - #************************************************************************************************ - @staticmethod - def get_latest_hosts_stats(): - query = Host_Stats.select().order_by(Host_Stats.id.desc()).get() - return model_to_dict(query) - - @staticmethod - def new_api_token(): - while True: - token = helper.random_string_generator(32) - test = list(Users.select(Users.user_id).where(Users.api_token == token)) - if len(test) == 0: - return token - - - #************************************************************************************************ - # Users Methods - #************************************************************************************************ - @staticmethod - def get_all_users(): - query = Users.select() - return query - - @staticmethod - def get_user_id_by_name(username): - if username == "SYSTEM": - return 0 - try: - return (Users.get(Users.username == username)).user_id - except DoesNotExist: - return None - - @staticmethod - def get_user_by_api_token(token: str): - query = Users.select().where(Users.api_token == token) - - if query.exists(): - user = model_to_dict(Users.get(Users.api_token == token)) - # I know it should apply it without setting it but I'm just making sure - user = db_shortcuts.add_user_roles(user) - return user - else: - return {} - - @staticmethod - def user_query(user_id): - user_query = Users.select().where(Users.user_id == user_id) - return user_query - - @staticmethod - def get_user(user_id): - if user_id == 0: - return { - 'user_id': 0, - 'created': None, - 'last_login': None, - 'last_update': None, - 'last_ip': "127.27.23.89", - 'username': "SYSTEM", - 'password': None, - 'enabled': True, - 'superuser': False, - 'api_token': None, - 'roles': [], - 'servers': [], - } - user = model_to_dict(Users.get(Users.user_id == user_id)) - - if user: - # I know it should apply it without setting it but I'm just making sure - user = db_shortcuts.add_user_roles(user) - return user - else: - #logger.debug("user: ({}) {}".format(user_id, {})) - return {} - - @staticmethod - def update_user(user_id, user_data={}, user_crafty_data={}): - base_data = db_helper.get_user(user_id) - up_data = {} - added_roles = set() - removed_roles = set() - removed_servers = set() - for key in user_data: - if key == "user_id": - continue - elif key == "roles": - added_roles = user_data['roles'].difference(base_data['roles']) - removed_roles = base_data['roles'].difference(user_data['roles']) - elif key == "regen_api": - if user_data['regen_api']: - up_data['api_token'] = db_shortcuts.new_api_token() - elif key == "password": - if user_data['password'] is not None and user_data['password'] != "": - up_data['password'] = helper.encode_pass(user_data['password']) - elif base_data[key] != user_data[key]: - up_data[key] = user_data[key] - up_data['last_update'] = helper.get_time_as_string() - logger.debug("user: {} +role:{} -role:{}".format(user_data, added_roles, removed_roles)) - with database.atomic(): - for role in added_roles: - User_Roles.get_or_create(user_id=user_id, role_id=role) - # TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point - - for key in user_crafty_data: - if key == "permissions_mask": - permissions_mask = user_crafty_data['permissions_mask'] - if key == "server_quantity": - limit_server_creation = user_crafty_data['server_quantity'][Enum_Permissions_Crafty.Server_Creation.name] - limit_user_creation = user_crafty_data['server_quantity'][Enum_Permissions_Crafty.User_Config.name] - limit_role_creation = user_crafty_data['server_quantity'][Enum_Permissions_Crafty.Roles_Config.name] - - try: - user_crafty = User_Crafty.select().where(User_Crafty.user_id == user_id).get() - user_crafty.permissions = permissions_mask - user_crafty.limit_server_creation = limit_server_creation - user_crafty.limit_user_creation = limit_user_creation - user_crafty.limit_role_creation = limit_role_creation - User_Crafty.save(user_crafty) - except: - User_Crafty.insert({ - User_Crafty.user_id: user_id, - User_Crafty.permissions: permissions_mask, - User_Crafty.limit_server_creation: limit_server_creation, - User_Crafty.limit_user_creation: limit_user_creation, - User_Crafty.limit_role_creation: limit_role_creation - }).execute() - - User_Roles.delete().where(User_Roles.user_id == user_id).where(User_Roles.role_id.in_(removed_roles)).execute() - - if up_data: - Users.update(up_data).where(Users.user_id == user_id).execute() - - @staticmethod - def add_user(username, password=None, api_token=None, enabled=True, superuser=False): - if password is not None: - pw_enc = helper.encode_pass(password) - else: - pw_enc = None - if api_token is None: - api_token = db_shortcuts.new_api_token() - else: - if type(api_token) is not str and len(api_token) != 32: - raise ValueError("API token must be a 32 character string") - user_id = Users.insert({ - Users.username: username.lower(), - Users.password: pw_enc, - Users.api_token: api_token, - Users.enabled: enabled, - Users.superuser: superuser, - Users.created: helper.get_time_as_string() - }).execute() - return user_id - - @staticmethod - def remove_user(user_id): - with database.atomic(): - User_Roles.delete().where(User_Roles.user_id == user_id).execute() - user = Users.get(Users.user_id == user_id) - return user.delete_instance() - - @staticmethod - def user_id_exists(user_id): - if not db_shortcuts.get_user(user_id): - return False - return True - - #************************************************************************************************ - # Roles Methods - #************************************************************************************************ - @staticmethod - def get_all_roles(): - query = Roles.select() - return query - - @staticmethod - def get_roleid_by_name(role_name): - try: - return (Roles.get(Roles.role_name == role_name)).role_id - except DoesNotExist: - return None - - @staticmethod - def get_role(role_id): - role = model_to_dict(Roles.get(Roles.role_id == role_id)) - - if role: - servers_query = Role_Servers.select().join(Servers, JOIN.INNER).where(Role_Servers.role_id == role_id) - # TODO: this query needs to be narrower - servers = set() - for s in servers_query: - servers.add(s.server_id.server_id) - role['servers'] = servers - #logger.debug("role: ({}) {}".format(role_id, role)) - return role - else: - #logger.debug("role: ({}) {}".format(role_id, {})) - return {} - - @staticmethod - def update_role(role_id, role_data={}, permissions_mask="00000000"): - base_data = db_helper.get_role(role_id) - up_data = {} - added_servers = set() - edited_servers = set() - removed_servers = set() - for key in role_data: - if key == "role_id": - continue - elif key == "servers": - added_servers = role_data['servers'].difference(base_data['servers']) - removed_servers = base_data['servers'].difference(role_data['servers']) - elif base_data[key] != role_data[key]: - up_data[key] = role_data[key] - up_data['last_update'] = helper.get_time_as_string() - logger.debug("role: {} +server:{} -server{}".format(role_data, added_servers, removed_servers)) - with database.atomic(): - for server in added_servers: - Role_Servers.get_or_create(role_id=role_id, server_id=server, permissions=permissions_mask) - for server in base_data['servers']: - role_server = Role_Servers.select().where(Role_Servers.role_id == role_id).where(Role_Servers.server_id == server).get() - role_server.permissions = permissions_mask - Role_Servers.save(role_server) - # TODO: This is horribly inefficient and we should be using bulk queries but im going for functionality at this point - Role_Servers.delete().where(Role_Servers.role_id == role_id).where(Role_Servers.server_id.in_(removed_servers)).execute() - if up_data: - Roles.update(up_data).where(Roles.role_id == role_id).execute() - - @staticmethod - def add_role(role_name): - role_id = Roles.insert({ - Roles.role_name: role_name.lower(), - Roles.created: helper.get_time_as_string() - }).execute() - return role_id - - @staticmethod - def remove_role(role_id): - with database.atomic(): - Role_Servers.delete().where(Role_Servers.role_id == role_id).execute() - User_Roles.delete().where(User_Roles.role_id == role_id).execute() - role = Roles.get(Roles.role_id == role_id) - return role.delete_instance() - - @staticmethod - def role_id_exists(role_id): - if not db_shortcuts.get_role(role_id): - return False - return True - - #************************************************************************************************ - # User_Roles Methods - #************************************************************************************************ - @staticmethod - def get_user_roles_id(user_id): - roles_list = [] - roles = User_Roles.select().where(User_Roles.user_id == user_id) - for r in roles: - roles_list.append(db_helper.get_role(r.role_id)['role_id']) - return roles_list - - @staticmethod - def get_user_roles_names(user_id): - roles_list = [] - roles = User_Roles.select().where(User_Roles.user_id == user_id) - for r in roles: - roles_list.append(db_helper.get_role(r.role_id)['role_name']) - return roles_list - - @staticmethod - def add_role_to_user(user_id, role_id): - User_Roles.insert({ - User_Roles.user_id: user_id, - User_Roles.role_id: role_id - }).execute() - - @staticmethod - def add_user_roles(user): - if type(user) == dict: - user_id = user['user_id'] - else: - user_id = user.user_id - - # I just copied this code from get_user, it had those TODOs & comments made by mac - Lukas - - roles_query = User_Roles.select().join(Roles, JOIN.INNER).where(User_Roles.user_id == user_id) - # TODO: this query needs to be narrower - roles = set() - for r in roles_query: - roles.add(r.role_id.role_id) - - user['roles'] = roles - #logger.debug("user: ({}) {}".format(user_id, user)) - return user - - - #************************************************************************************************ - # Role_Servers Methods - #************************************************************************************************ - @staticmethod - def add_role_server(server_id, role_id, rs_permissions="00000000"): - servers = Role_Servers.insert({Role_Servers.server_id: server_id, Role_Servers.role_id: role_id, Role_Servers.permissions: rs_permissions}).execute() - return servers - - - @staticmethod - def user_role_query(user_id): - user_query = User_Roles.select().where(User_Roles.user_id == user_id) - query = Roles.select().where(Roles.role_id == -1) - for u in user_query: - query = Roles.select().where(Roles.role_id == u.role_id) - return query - - - #************************************************************************************************ - # Commands Methods - #************************************************************************************************ - @staticmethod - def get_unactioned_commands(): - query = Commands.select().where(Commands.executed == 0) - return db_helper.return_rows(query) - - @staticmethod - def send_command(user_id, server_id, remote_ip, command): - - server_name = db_helper.get_server_friendly_name(server_id) - - # Example: Admin issued command start_server for server Survival - db_helper.add_to_audit_log(user_id, "issued command {} for server {}".format(command, server_name), - server_id, remote_ip) - - Commands.insert({ - Commands.server_id: server_id, - Commands.user: user_id, - Commands.source_ip: remote_ip, - Commands.command: command - }).execute() - - @staticmethod - def mark_command_complete(command_id=None): - if command_id is not None: - logger.debug("Marking Command {} completed".format(command_id)) - Commands.update({ - Commands.executed: True - }).where(Commands.command_id == command_id).execute() - - #************************************************************************************************ - # Audit_Log Methods - #************************************************************************************************ - @staticmethod - def get_actity_log(): - q = Audit_Log.select() - return db_helper.return_db_rows(q) - - def add_to_audit_log(self, user_id, log_msg, server_id=None, source_ip=None): - logger.debug("Adding to audit log User:{} - Message: {} ".format(user_id, log_msg)) - user_data = self.get_user(user_id) - - audit_msg = "{} {}".format(str(user_data['username']).capitalize(), log_msg) - - websocket_helper.broadcast('notification', audit_msg) - - Audit_Log.insert({ - Audit_Log.user_name: user_data['username'], - Audit_Log.user_id: user_id, - Audit_Log.server_id: server_id, - Audit_Log.log_msg: audit_msg, - Audit_Log.source_ip: source_ip - }).execute() - - @staticmethod - def add_to_audit_log_raw(user_name, user_id, server_id, log_msg, source_ip): - Audit_Log.insert({ - Audit_Log.user_name: user_name, - Audit_Log.user_id: user_id, - Audit_Log.server_id: server_id, - Audit_Log.log_msg: log_msg, - Audit_Log.source_ip: source_ip - }).execute() - - #************************************************************************************************ - # Schedules Methods - #************************************************************************************************ - @staticmethod - def create_scheduled_task(server_id, action, interval, interval_type, start_time, command, comment=None, enabled=True): - sch_id = Schedules.insert({ - Schedules.server_id: server_id, - Schedules.action: action, - Schedules.enabled: enabled, - Schedules.interval: interval, - Schedules.interval_type: interval_type, - Schedules.start_time: start_time, - Schedules.command: command, - Schedules.comment: comment - }).execute() - return sch_id - - @staticmethod - def delete_scheduled_task(schedule_id): - sch = Schedules.get(Schedules.schedule_id == schedule_id) - return Schedules.delete_instance(sch) - - @staticmethod - def update_scheduled_task(schedule_id, updates): - Schedules.update(updates).where(Schedules.schedule_id == schedule_id).execute() - - @staticmethod - def get_scheduled_task(schedule_id): - return model_to_dict(Schedules.get(Schedules.schedule_id == schedule_id)).execute() - - @staticmethod - def get_schedules_by_server(server_id): - return Schedules.select().where(Schedules.server_id == server_id).execute() - - @staticmethod - def get_schedules_all(): - return Schedules.select().execute() - - @staticmethod - def get_schedules_enabled(): - return Schedules.select().where(Schedules.enabled == True).execute() - - #************************************************************************************************ - # Backups Methods - #************************************************************************************************ - @staticmethod - def get_backup_config(server_id): - try: - row = Backups.select().where(Backups.server_id == server_id).join(Schedules).join(Servers)[0] - conf = { - "backup_path": row.server_id.backup_path, - "directories": row.directories, - "max_backups": row.max_backups, - "auto_enabled": row.schedule_id.enabled, - "server_id": row.server_id.server_id - } - except IndexError: - conf = { - "backup_path": None, - "directories": None, - "max_backups": 0, - "auto_enabled": True, - "server_id": server_id - } - return conf - - @staticmethod - def set_backup_config(server_id: int, backup_path: str = None, max_backups: int = None, auto_enabled: bool = True): - logger.debug("Updating server {} backup config with {}".format(server_id, locals())) - try: - row = Backups.select().where(Backups.server_id == server_id).join(Schedules).join(Servers)[0] - new_row = False - conf = {} - schd = {} - except IndexError: - conf = { - "directories": None, - "max_backups": 0, - "server_id": server_id - } - schd = { - "enabled": True, - "action": "backup_server", - "interval_type": "days", - "interval": 1, - "start_time": "00:00", - "server_id": server_id, - "comment": "Default backup job" - } - new_row = True - if max_backups is not None: - conf['max_backups'] = max_backups - schd['enabled'] = bool(auto_enabled) - if not new_row: - with database.atomic(): - if backup_path is not None: - u1 = Servers.update(backup_path=backup_path).where(Servers.server_id == server_id).execute() - else: - u1 = 0 - u2 = Backups.update(conf).where(Backups.server_id == server_id).execute() - u3 = Schedules.update(schd).where(Schedules.schedule_id == row.schedule_id).execute() - logger.debug("Updating existing backup record. {}+{}+{} rows affected".format(u1, u2, u3)) - else: - with database.atomic(): - conf["server_id"] = server_id - if backup_path is not None: - u = Servers.update(backup_path=backup_path).where(Servers.server_id == server_id) - s = Schedules.create(**schd) - conf['schedule_id'] = s.schedule_id - b = Backups.create(**conf) - logger.debug("Creating new backup record.") - - -#************************************************************************************************ -# Servers Permissions Class -#************************************************************************************************ -class Enum_Permissions_Server(Enum): - Commands = 0 - Terminal = 1 - Logs = 2 - Schedule = 3 - Backup = 4 - Files = 5 - Config = 6 - Players = 7 - -class Permissions_Servers: - - @staticmethod - def get_permissions_list(): - permissions_list = [] - for member in Enum_Permissions_Server.__members__.items(): - permissions_list.append(member[1]) - return permissions_list - - @staticmethod - def get_permissions(permissions_mask): - permissions_list = [] - for member in Enum_Permissions_Server.__members__.items(): - if server_permissions.has_permission(permissions_mask, member[1]): - permissions_list.append(member[1]) - return permissions_list - - @staticmethod - def has_permission(permission_mask, permission_tested: Enum_Permissions_Server): - result = False - if permission_mask[permission_tested.value] == '1': - result = True - return result - - @staticmethod - def set_permission(permission_mask, permission_tested: Enum_Permissions_Server, value): - l = list(permission_mask) - l[permission_tested.value] = str(value) - permission_mask = ''.join(l) - return permission_mask - - @staticmethod - def get_permission(permission_mask, permission_tested: Enum_Permissions_Server): - return permission_mask[permission_tested.value] - - -#************************************************************************************************ -# Static Accessors -#************************************************************************************************ -installer = db_builder() -db_helper = db_shortcuts() -server_permissions = Permissions_Servers() diff --git a/app/classes/shared/models_folder/crafty_permissions.py b/app/classes/shared/models_folder/crafty_permissions.py deleted file mode 100644 index 18500645..00000000 --- a/app/classes/shared/models_folder/crafty_permissions.py +++ /dev/null @@ -1,102 +0,0 @@ -import os -import sys -import logging -import datetime - -from app.classes.shared.helpers import helper -from app.classes.shared.console import console -from app.classes.shared.models import db_helper, server_permissions, Enum_Permissions_Server - -logger = logging.getLogger(__name__) -peewee_logger = logging.getLogger('peewee') -peewee_logger.setLevel(logging.INFO) - -try: - from peewee import * - from playhouse.shortcuts import model_to_dict - from enum import Enum - import yaml - -except ModuleNotFoundError as e: - logger.critical("Import Error: Unable to load {} module".format(e.name), exc_info=True) - console.critical("Import Error: Unable to load {} module".format(e.name)) - sys.exit(1) - -database = SqliteDatabase(helper.db_path, pragmas={ - 'journal_mode': 'wal', - 'cache_size': -1024 * 10}) - - -#************************************************************************************************ -# Crafty Permissions Class -#************************************************************************************************ -class Enum_Permissions_Crafty(Enum): - Server_Creation = 0 - User_Config = 1 - Roles_Config = 2 - -class Permissions_Crafty: - - #************************************************************************************************ - # Crafty Permissions Methods - #************************************************************************************************ - @staticmethod - def get_permissions_list(): - permissions_list = [] - for member in Enum_Permissions_Crafty.__members__.items(): - permissions_list.append(member[1]) - return permissions_list - - @staticmethod - def get_permissions(permissions_mask): - permissions_list = [] - for member in Enum_Permissions_Crafty.__members__.items(): - if crafty_permissions.has_permission(permissions_mask, member[1]): - permissions_list.append(member[1]) - return permissions_list - - @staticmethod - def has_permission(permission_mask, permission_tested: Enum_Permissions_Crafty): - result = False - if permission_mask[permission_tested.value] == '1': - result = True - return result - - @staticmethod - def set_permission(permission_mask, permission_tested: Enum_Permissions_Crafty, value): - l = list(permission_mask) - l[permission_tested.value] = str(value) - permission_mask = ''.join(l) - return permission_mask - - @staticmethod - def get_permission(permission_mask, permission_tested: Enum_Permissions_Crafty): - return permission_mask[permission_tested.value] - - @staticmethod - def get_crafty_permissions_mask(user_id): - permissions_mask = '' - user_crafty = db_helper.get_User_Crafty(user_id) - permissions_mask = user_crafty.permissions - return permissions_mask - - @staticmethod - def get_all_permission_quantity_list(): - quantity_list = { - Enum_Permissions_Crafty.Server_Creation.name: -1, - Enum_Permissions_Crafty.User_Config.name: -1, - Enum_Permissions_Crafty.Roles_Config.name: -1, - } - return quantity_list - - @staticmethod - def get_permission_quantity_list(user_id): - user_crafty = db_helper.get_User_Crafty(user_id) - quantity_list = { - Enum_Permissions_Crafty.Server_Creation.name: user_crafty.limit_server_creation, - Enum_Permissions_Crafty.User_Config.name: user_crafty.limit_user_creation, - Enum_Permissions_Crafty.Roles_Config.name: user_crafty.limit_role_creation, - } - return quantity_list - -crafty_permissions = Permissions_Crafty() \ No newline at end of file diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index a504c15c..e9efb38d 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -18,7 +18,8 @@ import html from app.classes.shared.helpers import helper from app.classes.shared.console import console -from app.classes.shared.models import db_helper, Servers +from app.classes.models.servers import Servers, servers_helper +from app.classes.models.management import management_helper from app.classes.web.websocket_helper import websocket_helper logger = logging.getLogger(__name__) @@ -101,7 +102,7 @@ class Server: self.is_backingup = False def reload_server_settings(self): - server_data = db_helper.get_server_data_by_id(self.server_id) + server_data = servers_helper.get_server_data_by_id(self.server_id) self.settings = server_data def do_server_setup(self, server_data_obj): @@ -414,7 +415,7 @@ class Server: def a_backup_server(self): logger.info("Starting server {} (ID {}) backup".format(self.name, self.server_id)) self.is_backingup = True - conf = db_helper.get_backup_config(self.server_id) + conf = management_helper.get_backup_config(self.server_id) try: backup_filename = "{}/{}".format(self.settings['backup_path'], datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')) logger.info("Creating backup of server '{}' (ID#{}) at '{}'".format(self.settings['server_name'], self.server_id, backup_filename)) @@ -434,7 +435,7 @@ class Server: return def list_backups(self): - conf = db_helper.get_backup_config(self.server_id) + conf = management_helper.get_backup_config(self.server_id) if helper.check_path_exists(self.settings['backup_path']): files = helper.get_human_readable_files_sizes(helper.list_dir_by_date(self.settings['backup_path'])) return [{"path": os.path.relpath(f['path'], start=conf['backup_path']), "size": f["size"]} for f in files] @@ -442,12 +443,12 @@ class Server: return [] def jar_update(self): - db_helper.set_update(self.server_id, True) + servers_helper.set_update(self.server_id, True) update_thread = threading.Thread(target=self.a_jar_update, daemon=True, name="exe_update") update_thread.start() def check_update(self): - server_stats = db_helper.get_server_stats_by_id(self.server_id) + server_stats = servers_helper.get_server_stats_by_id(self.server_id) if server_stats['updating']: return True else: @@ -499,12 +500,12 @@ class Server: #boolean returns true for false for success downloaded = helper.download_file(self.settings['executable_update_url'], current_executable) - while db_helper.get_server_stats_by_id(self.server_id)['updating']: + while servers_helper.get_server_stats_by_id(self.server_id)['updating']: if downloaded and not self.is_backingup: print("Backup Status: " + str(self.is_backingup)) logger.info("Executable updated successfully. Starting Server") - db_helper.set_update(self.server_id, False) + servers_helper.set_update(self.server_id, False) if len(websocket_helper.clients) > 0: # There are clients self.check_update() @@ -517,12 +518,12 @@ class Server: }) websocket_helper.broadcast('notification', "Executable update finished for "+self.name) - db_helper.add_to_audit_log_raw('Alert', '-1', self.server_id, "Executable update finished for "+self.name, self.settings['server_ip']) + management_helper.add_to_audit_log_raw('Alert', '-1', self.server_id, "Executable update finished for "+self.name, self.settings['server_ip']) if wasStarted: self.start_server() elif not downloaded and not self.is_backingup: time.sleep(5) - db_helper.set_update(self.server_id, False) + servers_helper.set_update(self.server_id, False) websocket_helper.broadcast('notification', "Executable update failed for " + self.name + ". Check log file for details.") logger.error("Executable download failed.") diff --git a/app/classes/shared/tasks.py b/app/classes/shared/tasks.py index 91d8ff0b..9524a330 100644 --- a/app/classes/shared/tasks.py +++ b/app/classes/shared/tasks.py @@ -13,7 +13,8 @@ from app.classes.web.tornado import Webserver from app.classes.web.websocket_helper import websocket_helper from app.classes.minecraft.serverjars import server_jar_obj -from app.classes.shared.models import db_helper +from app.classes.models.servers import servers_helper +from app.classes.models.management import management_helper logger = logging.getLogger(__name__) @@ -75,7 +76,7 @@ class TasksManager: time.sleep(5) def reload_schedule_from_db(self): - jobs = db_helper.get_schedules_enabled() + jobs = management_helper.get_schedules_enabled() schedule.clear(tag='backup') schedule.clear(tag='db') for j in jobs: @@ -84,7 +85,7 @@ class TasksManager: i=j.schedule_id, a=j.action, n=j.interval, t=j.interval_type, s=j.start_time)) try: getattr(schedule.every(j.interval), j.interval_type).at(j.start_time).do( - db_helper.send_command, 0, j.server_id, "127.27.23.89", j.action) + management_helper.send_command, 0, j.server_id, "127.27.23.89", j.action) except schedule.ScheduleValueError as e: logger.critical("Scheduler value error occurred: {} on ID#{}".format(e, j.schedule_id)) else: @@ -93,7 +94,7 @@ class TasksManager: def command_watcher(self): while True: # select any commands waiting to be processed - commands = db_helper.get_unactioned_commands() + commands = management_helper.get_unactioned_commands() for c in commands: svr = self.controller.get_server_obj(c['server_id']['server_id']) @@ -113,7 +114,7 @@ class TasksManager: elif command == "update_executable": svr.jar_update() - db_helper.mark_command_complete(c.get('command_id', None)) + management_helper.mark_command_complete(c.get('command_id', None)) time.sleep(1) @@ -187,17 +188,17 @@ class TasksManager: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) - host_stats = db_helper.get_latest_hosts_stats() + host_stats = management_helper.get_latest_hosts_stats() while True: if host_stats.get('cpu_usage') != \ - db_helper.get_latest_hosts_stats().get('cpu_usage') or \ + management_helper.get_latest_hosts_stats().get('cpu_usage') or \ host_stats.get('mem_percent') != \ - db_helper.get_latest_hosts_stats().get('mem_percent'): + management_helper.get_latest_hosts_stats().get('mem_percent'): # Stats are different - host_stats = db_helper.get_latest_hosts_stats() + host_stats = management_helper.get_latest_hosts_stats() if len(websocket_helper.clients) > 0: # There are clients websocket_helper.broadcast_page('/panel/dashboard', 'update_host_stats', { @@ -211,6 +212,6 @@ class TasksManager: time.sleep(4) def log_watcher(self): - helper.check_for_old_logs(db_helper) - schedule.every(6).hours.do(lambda: helper.check_for_old_logs(db_helper)).tag('log-mgmt') + self.controller.servers.check_for_old_logs() + schedule.every(6).hours.do(lambda: self.controller.servers.check_for_old_logs()).tag('log-mgmt') diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index 12ffc318..4e6eae91 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -13,9 +13,8 @@ import html import re from app.classes.shared.console import console -from app.classes.shared.models import Users, installer +from app.classes.shared.main_models import Users, installer from app.classes.web.base_handler import BaseHandler -from app.classes.shared.models import db_helper from app.classes.shared.helpers import helper from app.classes.shared.server import ServerOutBuf @@ -58,7 +57,7 @@ class AjaxHandler(BaseHandler): server_id = bleach.clean(server_id) - server_data = db_helper.get_server_data_by_id(server_id) + server_data = ser.get_server_data_by_id(server_id) if not server_data: logger.warning("Server Data not found in server_log ajax call") self.redirect("/panel/error?error=Server ID Not Found") @@ -98,7 +97,7 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, 'get_file'): return else: server_id = bleach.clean(server_id) - if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path)\ + if not helper.in_path(self.controller.servers.get_server_data_by_id(server_id)['path'], file_path)\ or not helper.check_file_exists(os.path.abspath(file_path)): logger.warning("Invalid path in get_file ajax call ({})".format(file_path)) console.warning("Invalid path in get_file ajax call ({})".format(file_path)) @@ -126,8 +125,8 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, 'get_tree'): return else: server_id = bleach.clean(server_id) - self.write(db_helper.get_server_data_by_id(server_id)['path'] + '\n' + - helper.generate_tree(db_helper.get_server_data_by_id(server_id)['path'])) + self.write(self.controller.servers.get_server_data_by_id(server_id)['path'] + '\n' + + helper.generate_tree(self.controller.servers.get_server_data_by_id(server_id)['path'])) self.finish() @tornado.web.authenticated @@ -163,7 +162,7 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, 'create_file'): return else: server_id = bleach.clean(server_id) - if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path) \ + if not helper.in_path(self.controller.servers.get_server_data_by_id(server_id)['path'], file_path) \ or helper.check_file_exists(os.path.abspath(file_path)): logger.warning("Invalid path in create_file ajax call ({})".format(file_path)) console.warning("Invalid path in create_file ajax call ({})".format(file_path)) @@ -182,7 +181,7 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, 'create_dir'): return else: server_id = bleach.clean(server_id) - if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], dir_path) \ + if not helper.in_path(self.controller.servers.get_server_data_by_id(server_id)['path'], dir_path) \ or helper.check_path_exists(os.path.abspath(dir_path)): logger.warning("Invalid path in create_dir ajax call ({})".format(dir_path)) console.warning("Invalid path in create_dir ajax call ({})".format(dir_path)) @@ -208,7 +207,7 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, 'del_file'): return else: server_id = bleach.clean(server_id) - server_info = db_helper.get_server_data_by_id(server_id) + server_info = self.controller.servers.get_server_data_by_id(server_id) if not (helper.in_path(server_info['path'], file_path) \ or helper.in_path(server_info['backup_path'], file_path)) \ or not helper.check_file_exists(os.path.abspath(file_path)): @@ -228,7 +227,7 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, 'del_dir'): return else: server_id = bleach.clean(server_id) - server_info = db_helper.get_server_data_by_id(server_id) + server_info = self.controller.servers.get_server_data_by_id(server_id) if not helper.in_path(server_info['path'], dir_path) \ or not helper.check_path_exists(os.path.abspath(dir_path)): logger.warning("Invalid path in del_file ajax call ({})".format(dir_path)) @@ -242,13 +241,13 @@ class AjaxHandler(BaseHandler): elif page == "delete_server": server_id = self.get_argument('id', None) logger.info( - "Removing server from panel for server: {}".format(db_helper.get_server_friendly_name(server_id))) + "Removing server from panel for server: {}".format(self.controller.servers.get_server_friendly_name(server_id))) self.controller.remove_server(server_id, False) elif page == "delete_server_files": server_id = self.get_argument('id', None) logger.info( - "Removing server and all associated files for server: {}".format(db_helper.get_server_friendly_name(server_id))) + "Removing server and all associated files for server: {}".format(self.controller.servers.get_server_friendly_name(server_id))) self.controller.remove_server(server_id, True) @tornado.web.authenticated @@ -261,7 +260,7 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, 'save_file'): return else: server_id = bleach.clean(server_id) - if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], file_path)\ + if not helper.in_path(self.controller.servers.get_server_data_by_id(server_id)['path'], file_path)\ or not helper.check_file_exists(os.path.abspath(file_path)): logger.warning("Invalid path in save_file ajax call ({})".format(file_path)) console.warning("Invalid path in save_file ajax call ({})".format(file_path)) @@ -284,7 +283,7 @@ class AjaxHandler(BaseHandler): console.warning("Invalid path(s) in rename_item ajax call") return - if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], item_path) \ + if not helper.in_path(self.controller.servers.get_server_data_by_id(server_id)['path'], item_path) \ or not helper.check_path_exists(os.path.abspath(item_path)): logger.warning("Invalid old name path in rename_item ajax call ({})".format(server_id)) console.warning("Invalid old name path in rename_item ajax call ({})".format(server_id)) @@ -292,7 +291,7 @@ class AjaxHandler(BaseHandler): new_item_path = os.path.join(os.path.split(item_path)[0], new_item_name) - if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], new_item_path) \ + if not helper.in_path(self.controller.servers.get_server_data_by_id(server_id)['path'], new_item_path) \ or helper.check_path_exists(os.path.abspath(new_item_path)): logger.warning("Invalid new name path in rename_item ajax call ({})".format(server_id)) console.warning("Invalid new name path in rename_item ajax call ({})".format(server_id)) @@ -309,7 +308,7 @@ class AjaxHandler(BaseHandler): server_id = bleach.clean(server_id) # does this server id exist? - if not db_helper.server_id_exists(server_id): + if not self.controller.servers.server_id_exists(server_id): logger.warning("Server ID not found in {} ajax call ({})".format(page_name, server_id)) console.warning("Server ID not found in {} ajax call ({})".format(page_name, server_id)) return diff --git a/app/classes/web/api_handler.py b/app/classes/web/api_handler.py index 50035c9f..05f23c95 100644 --- a/app/classes/web/api_handler.py +++ b/app/classes/web/api_handler.py @@ -6,7 +6,6 @@ import tornado.escape import logging from app.classes.web.base_handler import BaseHandler -from app.classes.shared.models import db_shortcuts log = logging.getLogger(__name__) @@ -30,7 +29,7 @@ class ApiHandler(BaseHandler): try: log.debug("Searching for specified token") # TODO: YEET THIS - user_data = db_shortcuts.get_user_by_api_token(self.get_argument('token')) + user_data = self.controller.users.get_user_by_api_token(self.get_argument('token')) log.debug("Checking results") if user_data: # Login successful! Check perms diff --git a/app/classes/web/base_handler.py b/app/classes/web/base_handler.py index 04b0bd3a..e4046d1e 100644 --- a/app/classes/web/base_handler.py +++ b/app/classes/web/base_handler.py @@ -7,6 +7,8 @@ from typing import ( Optional ) +from app.classes.shared.main_controller import Controller + logger = logging.getLogger(__name__) @@ -15,7 +17,7 @@ class BaseHandler(tornado.web.RequestHandler): nobleach = {bool, type(None)} redactables = ("pass", "api") - def initialize(self, controller=None, tasks_manager=None, translator=None): + def initialize(self, controller : Controller = None, tasks_manager=None, translator=None): self.controller = controller self.tasks_manager = tasks_manager self.translator = translator diff --git a/app/classes/web/http_handler.py b/app/classes/web/http_handler.py index 95130dbe..f8646de5 100644 --- a/app/classes/web/http_handler.py +++ b/app/classes/web/http_handler.py @@ -8,7 +8,7 @@ import requests from app.classes.shared.helpers import helper from app.classes.web.base_handler import BaseHandler from app.classes.shared.console import console -from app.classes.shared.models import Users, fn, db_helper +from app.classes.shared.main_models import Users, fn logger = logging.getLogger(__name__) diff --git a/app/classes/web/http_handler_page.py b/app/classes/web/http_handler_page.py index 97871ae2..8b9e9c90 100644 --- a/app/classes/web/http_handler_page.py +++ b/app/classes/web/http_handler_page.py @@ -8,7 +8,7 @@ import requests from app.classes.shared.helpers import helper from app.classes.web.base_handler import BaseHandler from app.classes.shared.console import console -from app.classes.shared.models import Users, fn, db_helper +from app.classes.shared.main_models import Users, fn logger = logging.getLogger(__name__) diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index f6beaed4..c6be402a 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -10,10 +10,14 @@ import os from tornado import iostream from app.classes.shared.console import console -from app.classes.shared.models import Users, installer +from app.classes.shared.main_models import Users, installer + from app.classes.web.base_handler import BaseHandler -from app.classes.shared.models import db_helper, server_permissions, Servers, Enum_Permissions_Server -from app.classes.shared.models_folder.crafty_permissions import crafty_permissions, Enum_Permissions_Crafty + +from app.classes.models.servers import Servers +from app.classes.models.server_permissions import Enum_Permissions_Server +from app.classes.models.crafty_permissions import Enum_Permissions_Crafty + from app.classes.shared.helpers import helper logger = logging.getLogger(__name__) @@ -32,7 +36,7 @@ class PanelHandler(BaseHandler): exec_user_data = json.loads(self.get_secure_cookie("user_data")) exec_user_id = exec_user_data['user_id'] - exec_user = db_helper.get_user(exec_user_id) + exec_user = self.controller.users.get_user_by_id(exec_user_id) exec_user_role = set() if exec_user['superuser'] == 1: @@ -43,9 +47,9 @@ class PanelHandler(BaseHandler): exec_user_crafty_permissions = self.controller.crafty_perms.get_crafty_permissions_list(exec_user_id) logger.debug(exec_user['roles']) for r in exec_user['roles']: - role = db_helper.get_role(r) + role = self.controller.roles.get_role(r) exec_user_role.add(role['role_name']) - defined_servers = self.controller.list_authorized_servers(exec_user_id) + defined_servers = self.controller.servers.get_authorized_servers(exec_user_id) page_data = { # todo: make this actually pull and compare version data @@ -65,7 +69,7 @@ class PanelHandler(BaseHandler): 'stopped': (len(self.controller.list_defined_servers()) - len(self.controller.list_running_servers())) }, 'menu_servers': defined_servers, - 'hosts_data': db_helper.get_latest_hosts_stats(), + 'hosts_data': self.controller.management.get_latest_hosts_stats(), 'show_contribute': helper.get_setting("show_contribute_link", True), 'error': error, 'time': formatted_time @@ -111,7 +115,7 @@ class PanelHandler(BaseHandler): server_data = self.controller.get_server_data(server_id) server_name = server_data['server_name'] - db_helper.add_to_audit_log(exec_user_data['user_id'], + self.controller.management.add_to_audit_log(exec_user_data['user_id'], "Deleted server {} named {}".format(server_id, server_name), server_id, self.get_remote_ip()) @@ -122,9 +126,9 @@ class PanelHandler(BaseHandler): elif page == 'dashboard': if exec_user['superuser'] == 1: - page_data['servers'] = db_helper.get_all_servers_stats() + page_data['servers'] = self.controller.servers.get_all_servers_stats() else: - user_auth = db_helper.get_authorized_servers_stats(exec_user_id) + user_auth = self.controller.servers.get_authorized_servers_stats(exec_user_id) logger.debug("ASFR: {}".format(user_auth)) page_data['servers'] = user_auth @@ -146,13 +150,13 @@ class PanelHandler(BaseHandler): return else: # does this server id exist? - if not db_helper.server_id_exists(server_id): + if not self.controller.servers.server_id_exists(server_id): self.redirect("/panel/error?error=Invalid Server ID") return if exec_user['superuser'] != 1: - if not db_helper.server_id_authorized(server_id, exec_user_id): - if not db_helper.server_id_authorized(int(server_id), exec_user_id): + if not self.controller.servers.server_id_authorized(server_id, exec_user_id): + if not self.controller.servers.server_id_authorized(int(server_id), exec_user_id): self.redirect("/panel/error?error=Invalid Server ID") return False @@ -165,8 +169,8 @@ class PanelHandler(BaseHandler): server = self.controller.get_server_obj(server_id) # server_data isn't needed since the server_stats also pulls server data - page_data['server_data'] = db_helper.get_server_data_by_id(server_id) - page_data['server_stats'] = db_helper.get_server_stats_by_id(server_id) + page_data['server_data'] = self.controller.servers.get_server_data_by_id(server_id) + page_data['server_stats'] = self.controller.servers.get_server_stats_by_id(server_id) page_data['get_players'] = lambda: self.controller.stats.get_server_players(server_id) page_data['active_link'] = subpage page_data['permissions'] = { @@ -179,14 +183,14 @@ class PanelHandler(BaseHandler): 'Config': Enum_Permissions_Server.Config, 'Players': Enum_Permissions_Server.Players, } - page_data['user_permissions'] = self.controller.get_server_permissions_foruser(exec_user_id, server_id) + page_data['user_permissions'] = self.controller.server_perms.get_server_permissions_foruser(exec_user_id, server_id) if subpage == "backup": - page_data['backup_config'] = db_helper.get_backup_config(server_id) + page_data['backup_config'] = self.controller.management.get_backup_config(server_id) page_data['backup_list'] = server.list_backups() def get_banned_players_html(): - banned_players = helper.get_banned_players(server_id, db_helper) + banned_players = self.controller.servers.get_banned_players(server_id) if banned_players is None: return """
  • @@ -219,17 +223,17 @@ class PanelHandler(BaseHandler): return else: # does this server id exist? - if not db_helper.server_id_exists(server_id): + if not self.controller.servers.server_id_exists(server_id): self.redirect("/panel/error?error=Invalid Server ID") return if exec_user['superuser'] != 1: - #if not db_helper.server_id_authorized(server_id, exec_user_id): - if not db_helper.server_id_authorized(int(server_id), exec_user_id): + #if not self.controller.servers.server_id_authorized(server_id, exec_user_id): + if not self.controller.servers.server_id_authorized(int(server_id), exec_user_id): self.redirect("/panel/error?error=Invalid Server ID") return - server_info = db_helper.get_server_data_by_id(server_id) + server_info = self.controller.servers.get_server_data_by_id(server_id) backup_file = os.path.abspath(os.path.join(server_info["backup_path"], file)) if not helper.in_path(server_info["backup_path"], backup_file) \ or not os.path.isfile(backup_file): @@ -268,13 +272,13 @@ class PanelHandler(BaseHandler): return else: # does this server id exist? - if not db_helper.server_id_exists(server_id): + if not self.controller.servers.server_id_exists(server_id): self.redirect("/panel/error?error=Invalid Server ID") return if exec_user['superuser'] != 1: - #if not db_helper.server_id_authorized(server_id, exec_user_id): - if not db_helper.server_id_authorized(int(server_id), exec_user_id): + #if not self.controller.servers.server_id_authorized(server_id, exec_user_id): + if not self.controller.servers.server_id_authorized(int(server_id), exec_user_id): self.redirect("/panel/error?error=Invalid Server ID") return @@ -286,12 +290,12 @@ class PanelHandler(BaseHandler): auth_role_servers = {} users_list = [] role_users = {} - roles = db_helper.get_all_roles() + roles = self.controller.roles.get_all_roles() role_servers = [] user_roles = {} - for user in db_helper.get_all_users(): - user_roles_list = db_helper.get_user_roles_names(user.user_id) - user_servers = db_helper.get_authorized_servers(user.user_id) + for user in self.controller.users.get_all_users(): + user_roles_list = self.controller.users.get_user_roles_names(user.user_id) + user_servers = self.controller.servers.get_authorized_servers(user.user_id) servers = [] for server in user_servers: servers.append(server['server_name']) @@ -301,9 +305,9 @@ class PanelHandler(BaseHandler): user_roles.update(data) for role in roles: role_servers = [] - role = db_helper.get_role(role.role_id) + role = self.controller.roles.get_role_with_servers(role.role_id) for serv_id in role['servers']: - role_servers.append(db_helper.get_server_data_by_id(serv_id)['server_name']) + role_servers.append(self.controller.servers.get_server_data_by_id(serv_id)['server_name']) data = {role['role_id']: role_servers} auth_role_servers.update(data) @@ -313,11 +317,11 @@ class PanelHandler(BaseHandler): page_data['user-roles'] = user_roles if exec_user['superuser'] == 1: - page_data['users'] = db_helper.get_all_users() - page_data['roles'] = db_helper.get_all_roles() + page_data['users'] = self.controller.users.get_all_users() + page_data['roles'] = self.controller.roles.get_all_roles() else: - page_data['users'] = db_helper.user_query(exec_user['user_id']) - page_data['roles'] = db_helper.user_role_query(exec_user['user_id']) + page_data['users'] = self.controller.users.user_query(exec_user['user_id']) + page_data['roles'] = self.controller.users.user_role_query(exec_user['user_id']) for user in page_data['users']: if user.user_id != exec_user['user_id']: @@ -342,32 +346,32 @@ class PanelHandler(BaseHandler): self.redirect("/panel/error?error=Unauthorized access: not a user editor") return - page_data['roles_all'] = db_helper.get_all_roles() + page_data['roles_all'] = self.controller.roles.get_all_roles() page_data['servers'] = [] page_data['servers_all'] = self.controller.list_defined_servers() page_data['role-servers'] = [] - page_data['permissions_all'] = self.controller.list_defined_crafty_permissions() + page_data['permissions_all'] = self.controller.crafty_perms.list_defined_crafty_permissions() page_data['permissions_list'] = set() - page_data['quantity_server'] = self.controller.list_all_crafty_permissions_quantity_limits() + page_data['quantity_server'] = self.controller.crafty_perms.list_all_crafty_permissions_quantity_limits() template = "panel/panel_edit_user.html" elif page == "edit_user": user_id = self.get_argument('id', None) - role_servers = db_helper.get_authorized_servers(user_id) + role_servers = self.controller.servers.get_authorized_servers(user_id) page_role_servers = [] servers = set() for server in role_servers: page_role_servers.append(server['server_id']) page_data['new_user'] = False - page_data['user'] = db_helper.get_user(user_id) + page_data['user'] = self.controller.users.get_user_by_id(user_id) page_data['servers'] = servers page_data['role-servers'] = page_role_servers - page_data['roles_all'] = db_helper.get_all_roles() + page_data['roles_all'] = self.controller.roles.get_all_roles() page_data['servers_all'] = self.controller.list_defined_servers() - page_data['permissions_all'] = self.controller.list_defined_crafty_permissions() + page_data['permissions_all'] = self.controller.crafty_perms.list_defined_crafty_permissions() page_data['permissions_list'] = self.controller.crafty_perms.get_crafty_permissions_list(user_id) - page_data['quantity_server'] = self.controller.list_crafty_permissions_quantity_limits(user_id) + page_data['quantity_server'] = self.controller.crafty_perms.list_crafty_permissions_quantity_limits(user_id) if user_id is None: self.redirect("/panel/error?error=Invalid User ID") @@ -397,7 +401,7 @@ class PanelHandler(BaseHandler): return else: # does this user id exist? - target_user = db_helper.get_user(user_id) + target_user = self.controller.users.get_user_by_id(user_id) if not target_user: self.redirect("/panel/error?error=Invalid User ID") return @@ -405,9 +409,9 @@ class PanelHandler(BaseHandler): self.redirect("/panel/error?error=Cannot remove a superuser") return - db_helper.remove_user(user_id) + self.controller.users.remove_user(user_id) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Removed user {} (UID:{})".format(target_user['username'], user_id), server_id=0, source_ip=self.get_remote_ip()) @@ -415,9 +419,9 @@ class PanelHandler(BaseHandler): elif page == "add_role": user_roles = {} - for user in db_helper.get_all_users(): - user_roles_list = db_helper.get_user_roles_names(user.user_id) - user_servers = db_helper.get_authorized_servers(user.user_id) + for user in self.controller.users.get_all_users(): + user_roles_list = self.controller.users.get_user_roles_names(user.user_id) + user_servers = self.controller.servers.get_authorized_servers(user.user_id) data = {user.user_id: user_roles_list} user_roles.update(data) page_data['new_role'] = True @@ -428,14 +432,14 @@ class PanelHandler(BaseHandler): page_data['role']['last_update'] = "N/A" page_data['role']['servers'] = set() page_data['user-roles'] = user_roles - page_data['users'] = db_helper.get_all_users() + page_data['users'] = self.controller.users.get_all_users() if Enum_Permissions_Crafty.Roles_Config not in exec_user_crafty_permissions: self.redirect("/panel/error?error=Unauthorized access: not a role editor") return page_data['servers_all'] = self.controller.list_defined_servers() - page_data['permissions_all'] = self.controller.list_defined_permissions() + page_data['permissions_all'] = self.controller.server_perms.list_defined_permissions() page_data['permissions_list'] = set() template = "panel/panel_edit_role.html" @@ -443,19 +447,19 @@ class PanelHandler(BaseHandler): auth_servers = {} user_roles = {} - for user in db_helper.get_all_users(): - user_roles_list = db_helper.get_user_roles_names(user.user_id) - user_servers = db_helper.get_authorized_servers(user.user_id) + for user in self.controller.users.get_all_users(): + user_roles_list = self.controller.users.get_user_roles_names(user.user_id) + user_servers = self.controller.servers.get_authorized_servers(user.user_id) data = {user.user_id: user_roles_list} user_roles.update(data) page_data['new_role'] = False role_id = self.get_argument('id', None) - page_data['role'] = db_helper.get_role(role_id) + page_data['role'] = self.controller.roles.get_role_with_servers(role_id) page_data['servers_all'] = self.controller.list_defined_servers() - page_data['permissions_all'] = self.controller.list_defined_permissions() - page_data['permissions_list'] = self.controller.get_role_permissions(role_id) + page_data['permissions_all'] = self.controller.server_perms.list_defined_permissions() + page_data['permissions_list'] = self.controller.server_perms.get_role_permissions(role_id) page_data['user-roles'] = user_roles - page_data['users'] = db_helper.get_all_users() + page_data['users'] = self.controller.users.get_all_users() if Enum_Permissions_Crafty.Roles_Config not in exec_user_crafty_permissions: self.redirect("/panel/error?error=Unauthorized access: not a role editor") @@ -477,21 +481,21 @@ class PanelHandler(BaseHandler): return else: # does this user id exist? - target_role = db_helper.get_role(role_id) + target_role = self.controller.roles.get_role(role_id) if not target_role: self.redirect("/panel/error?error=Invalid Role ID") return - db_helper.remove_role(role_id) + self.controller.roles.remove_role(role_id) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Removed role {} (RID:{})".format(target_role['role_name'], role_id), server_id=0, source_ip=self.get_remote_ip()) self.redirect("/panel/panel_config") elif page == "activity_logs": - page_data['audit_logs'] = db_helper.get_actity_log() + page_data['audit_logs'] = self.controller.management.get_actity_log() template = "panel/activity_logs.html" @@ -505,17 +509,16 @@ class PanelHandler(BaseHandler): return else: # does this server id exist? - if not db_helper.server_id_exists(server_id): + if not self.controller.servers.server_id_exists(server_id): self.redirect("/panel/error?error=Invalid Server ID") return if exec_user['superuser'] != 1: - #if not db_helper.server_id_authorized(server_id, exec_user_id): - if not db_helper.server_id_authorized(int(server_id), exec_user_id): + if not self.controller.servers.server_id_authorized(int(server_id), exec_user_id): self.redirect("/panel/error?error=Invalid Server ID") return - server_info = db_helper.get_server_data_by_id(server_id) + server_info = self.controller.servers.get_server_data_by_id(server_id) if not helper.in_path(server_info["path"], file) \ or not os.path.isfile(file): @@ -559,18 +562,18 @@ class PanelHandler(BaseHandler): def post(self, page): exec_user_data = json.loads(self.get_secure_cookie("user_data")) exec_user_id = exec_user_data['user_id'] - exec_user = db_helper.get_user(exec_user_id) + exec_user = self.controller.users.get_user_by_id(exec_user_id) exec_user_role = set() if exec_user['superuser'] == 1: defined_servers = self.controller.list_defined_servers() exec_user_role.add("Super User") - exec_user_crafty_permissions = self.controller.list_defined_crafty_permissions() + exec_user_crafty_permissions = self.controller.crafty_perms.list_defined_crafty_permissions() else: exec_user_crafty_permissions = self.controller.crafty_perms.get_crafty_permissions_list(exec_user_id) - defined_servers = self.controller.list_authorized_servers(exec_user_id) + defined_servers = self.controller.servers.get_authorized_servers(exec_user_id) for r in exec_user['roles']: - role = db_helper.get_role(r) + role = self.controller.roles.get_role(r) exec_user_role.add(role['role_name']) if page == 'server_detail': @@ -591,7 +594,7 @@ class PanelHandler(BaseHandler): subpage = self.get_argument('subpage', None) if not exec_user['superuser']: - if not db_helper.server_id_authorized(server_id, exec_user_id): + if not self.controller.servers.server_id_authorized(server_id, exec_user_id): self.redirect("/panel/error?error=Unauthorized access: invalid server id") return elif server_id is None: @@ -599,10 +602,11 @@ class PanelHandler(BaseHandler): return else: # does this server id exist? - if not db_helper.server_id_exists(server_id): + if not self.controller.servers.server_id_exists(server_id): self.redirect("/panel/error?error=Invalid Server ID") return + #TODO use controller method Servers.update({ Servers.server_name: server_name, Servers.path: server_path, @@ -621,7 +625,7 @@ class PanelHandler(BaseHandler): self.controller.refresh_server_settings(server_id) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Edited server {} named {}".format(server_id, server_name), server_id, self.get_remote_ip()) @@ -643,7 +647,7 @@ class PanelHandler(BaseHandler): return else: # does this server id exist? - if not db_helper.server_id_exists(server_id): + if not self.controller.servers.server_id_exists(server_id): self.redirect("/panel/error?error=Invalid Server ID") return @@ -651,9 +655,9 @@ class PanelHandler(BaseHandler): Servers.update({ Servers.backup_path: backup_path }).where(Servers.server_id == server_id).execute() - db_helper.set_backup_config(server_id, max_backups=max_backups) + self.controller.management.set_backup_config(server_id, max_backups=max_backups) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Edited server {}: updated backups".format(server_id), server_id, self.get_remote_ip()) @@ -677,9 +681,9 @@ class PanelHandler(BaseHandler): "username": username, "password": password0, } - db_helper.update_user(user_id, user_data=user_data) + self.controller.users.update_user(user_id, user_data=user_data) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Edited user {} (UID:{}) password".format(username, user_id), server_id=0, @@ -694,7 +698,7 @@ class PanelHandler(BaseHandler): return else: # does this user id exist? - if not db_helper.user_id_exists(user_id): + if not self.controller.users.user_id_exists(user_id): self.redirect("/panel/error?error=Invalid User ID") return @@ -703,7 +707,7 @@ class PanelHandler(BaseHandler): return roles = set() - for role in db_helper.get_all_roles(): + for role in self.controller.roles.get_all_roles(): argument = int(float( bleach.clean( self.get_argument('role_{}_membership'.format(role.role_id), '0') @@ -714,14 +718,14 @@ class PanelHandler(BaseHandler): permissions_mask = "000" server_quantity = {} - for permission in self.controller.list_defined_crafty_permissions(): + for permission in self.controller.crafty_perms.list_defined_crafty_permissions(): argument = int(float( bleach.clean( self.get_argument('permission_{}'.format(permission.name), '0') ) )) if argument: - permissions_mask = crafty_permissions.set_permission(permissions_mask, permission, argument) + permissions_mask = self.controller.crafty_perms.set_permission(permissions_mask, permission, argument) q_argument = int(float( bleach.clean( @@ -744,9 +748,9 @@ class PanelHandler(BaseHandler): "permissions_mask": permissions_mask, "server_quantity": server_quantity } - db_helper.update_user(user_id, user_data=user_data, user_crafty_data=user_crafty_data) + self.controller.users.update_user(user_id, user_data=user_data, user_crafty_data=user_crafty_data) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Edited user {} (UID:{}) with roles {} and permissions {}".format(username, user_id, roles, permissions_mask), server_id=0, source_ip=self.get_remote_ip()) @@ -767,7 +771,7 @@ class PanelHandler(BaseHandler): return else: # does this user id exist? - if db_helper.get_user_id_by_name(username) is not None: + if self.controller.users.get_id_by_name(username) is not None: self.redirect("/panel/error?error=User exists") return @@ -776,7 +780,7 @@ class PanelHandler(BaseHandler): return roles = set() - for role in db_helper.get_all_roles(): + for role in self.controller.roles.get_all_roles(): argument = int(float( bleach.clean( self.get_argument('role_{}_membership'.format(role.role_id), '0') @@ -794,7 +798,7 @@ class PanelHandler(BaseHandler): ) )) if argument: - permissions_mask = crafty_permissions.set_permission(permissions_mask, permission, argument) + permissions_mask = self.controller.crafty_perms.set_permission(permissions_mask, permission, argument) q_argument = int(float( bleach.clean( @@ -806,7 +810,7 @@ class PanelHandler(BaseHandler): else: server_quantity[permission.name] = 0 - user_id = db_helper.add_user(username, password=password0, enabled=enabled) + user_id = self.controller.users.add_user(username, password=password0, enabled=enabled) user_data = { "roles": roles, } @@ -814,13 +818,13 @@ class PanelHandler(BaseHandler): "permissions_mask": permissions_mask, "server_quantity": server_quantity } - db_helper.update_user(user_id, user_data=user_data, user_crafty_data=user_crafty_data) + self.controller.users.update_user(user_id, user_data=user_data, user_crafty_data=user_crafty_data) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Added user {} (UID:{})".format(username, user_id), server_id=0, source_ip=self.get_remote_ip()) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Edited user {} (UID:{}) with roles {}".format(username, user_id, roles), server_id=0, source_ip=self.get_remote_ip()) @@ -841,7 +845,7 @@ class PanelHandler(BaseHandler): return else: # does this user id exist? - if not db_helper.role_id_exists(role_id): + if not self.controller.roles.role_id_exists(role_id): self.redirect("/panel/error?error=Invalid Role ID") return @@ -856,22 +860,22 @@ class PanelHandler(BaseHandler): servers.add(server['server_id']) permissions_mask = "00000000" - for permission in self.controller.list_defined_permissions(): + for permission in self.controller.server_perms.list_defined_permissions(): argument = int(float( bleach.clean( self.get_argument('permission_{}'.format(permission.name), '0') ) )) if argument: - permissions_mask = server_permissions.set_permission(permissions_mask, permission, argument) + permissions_mask = self.controller.server_perms.set_permission(permissions_mask, permission, argument) role_data = { "role_name": role_name, "servers": servers } - db_helper.update_role(role_id, role_data=role_data, permissions_mask=permissions_mask) + self.controller.roles.update_role(role_id, role_data=role_data, permissions_mask=permissions_mask) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Edited role {} (RID:{}) with servers {}".format(role_name, role_id, servers), server_id=0, source_ip=self.get_remote_ip()) @@ -889,7 +893,7 @@ class PanelHandler(BaseHandler): return else: # does this user id exist? - if db_helper.get_roleid_by_name(role_name) is not None: + if self.controller.roles.get_roleid_by_name(role_name) is not None: self.redirect("/panel/error?error=Role exists") return @@ -904,23 +908,23 @@ class PanelHandler(BaseHandler): servers.add(server['server_id']) permissions_mask = "00000000" - for permission in self.controller.list_defined_permissions(): + for permission in self.controller.server_perms.list_defined_permissions(): argument = int(float( bleach.clean( self.get_argument('permission_{}'.format(permission.name), '0') ) )) if argument: - permissions_mask = server_permissions.set_permission(permissions_mask, permission, argument) + permissions_mask = self.controller.server_perms.set_permission(permissions_mask, permission, argument) - role_id = db_helper.add_role(role_name) - db_helper.update_role(role_id, {"servers": servers}, permissions_mask) + role_id = self.controller.roles.add_role(role_name) + self.controller.roles.update_role(role_id, {"servers": servers}, permissions_mask) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Added role {} (RID:{})".format(role_name, role_id), server_id=0, source_ip=self.get_remote_ip()) - db_helper.add_to_audit_log(exec_user['user_id'], + self.controller.management.add_to_audit_log(exec_user['user_id'], "Edited role {} (RID:{}) with servers {}".format(role_name, role_id, servers), server_id=0, source_ip=self.get_remote_ip()) diff --git a/app/classes/web/public_handler.py b/app/classes/web/public_handler.py index 4388f909..7f7e1dcc 100644 --- a/app/classes/web/public_handler.py +++ b/app/classes/web/public_handler.py @@ -7,7 +7,9 @@ import tornado.escape from app.classes.shared.helpers import helper from app.classes.web.base_handler import BaseHandler from app.classes.shared.console import console -from app.classes.shared.models import Users, fn, db_helper +from app.classes.shared.main_models import fn + +from app.classes.models.users import Users logger = logging.getLogger(__name__) @@ -113,7 +115,7 @@ class PublicHandler(BaseHandler): q.save() # log this login - db_helper.add_to_audit_log(user_data.user_id, "Logged in", 0, self.get_remote_ip()) + self.controller.management.add_to_audit_log(user_data.user_id, "Logged in", 0, self.get_remote_ip()) cookie_data = { "username": user_data.username, @@ -129,7 +131,7 @@ class PublicHandler(BaseHandler): self.clear_cookie("user") self.clear_cookie("user_data") # log this failed login attempt - db_helper.add_to_audit_log(user_data.user_id, "Tried to log in", 0, self.get_remote_ip()) + self.controller.management.add_to_audit_log(user_data.user_id, "Tried to log in", 0, self.get_remote_ip()) self.redirect('/public/error?error=Login Failed') else: self.redirect("/public/login") diff --git a/app/classes/web/server_handler.py b/app/classes/web/server_handler.py index 2a5574d6..7f0e91b2 100644 --- a/app/classes/web/server_handler.py +++ b/app/classes/web/server_handler.py @@ -6,8 +6,7 @@ import shutil from app.classes.shared.console import console from app.classes.web.base_handler import BaseHandler -from app.classes.shared.models import db_helper -from app.classes.shared.models_folder.crafty_permissions import Enum_Permissions_Crafty +from app.classes.models.crafty_permissions import Enum_Permissions_Crafty from app.classes.minecraft.serverjars import server_jar_obj from app.classes.shared.helpers import helper @@ -32,7 +31,7 @@ class ServerHandler(BaseHandler): # name = tornado.escape.json_decode(self.current_user) exec_user_data = json.loads(self.get_secure_cookie("user_data")) exec_user_id = exec_user_data['user_id'] - exec_user = db_helper.get_user(exec_user_id) + exec_user = self.controller.users.get_user_by_id(exec_user_id) exec_user_role = set() if exec_user['superuser'] == 1: @@ -41,9 +40,9 @@ class ServerHandler(BaseHandler): exec_user_crafty_permissions = self.controller.list_defined_crafty_permissions() else: exec_user_crafty_permissions = self.controller.crafty_perms.get_crafty_permissions_list(exec_user_id) - defined_servers = self.controller.list_authorized_servers(exec_user_id) + defined_servers = self.controller.servers.get_authorized_servers(exec_user_id) for r in exec_user['roles']: - role = db_helper.get_role(r) + role = self.controller.roles.get_role(r) exec_user_role.add(role['role_name']) template = "public/404.html" @@ -63,14 +62,14 @@ class ServerHandler(BaseHandler): 'running': len(self.controller.list_running_servers()), 'stopped': (len(self.controller.list_defined_servers()) - len(self.controller.list_running_servers())) }, - 'hosts_data': db_helper.get_latest_hosts_stats(), + 'hosts_data': self.controller.management.get_latest_hosts_stats(), 'menu_servers': defined_servers, 'show_contribute': helper.get_setting("show_contribute_link", True) } if page == "step1": - if not exec_user['superuser'] and not self.controller.can_create_server(exec_user_id): + if not exec_user['superuser'] and not self.controller.crafty_perms.can_create_server(exec_user_id): self.redirect("/panel/error?error=Unauthorized access: not a server creator or server limit reached") return @@ -89,7 +88,7 @@ class ServerHandler(BaseHandler): exec_user_data = json.loads(self.get_secure_cookie("user_data")) exec_user_id = exec_user_data['user_id'] - exec_user = db_helper.get_user(exec_user_id) + exec_user = self.controller.users.get_user_by_id(exec_user_id) template = "public/404.html" page_data = { @@ -105,12 +104,12 @@ class ServerHandler(BaseHandler): if server_id is not None: if command == "clone_server": def is_name_used(name): - for server in db_helper.get_all_defined_servers(): + for server in self.controller.servers.get_all_defined_servers(): if server['server_name'] == name: return True return - server_data = db_helper.get_server_data_by_id(server_id) + server_data = self.controller.servers.get_server_data_by_id(server_id) server_uuid = server_data.get('server_uuid') new_server_name = server_data.get('server_name') + " (Copy)" @@ -137,13 +136,13 @@ class ServerHandler(BaseHandler): crash_detection = server_data.get('crash_detection') server_port = server_data.get('server_port') - db_helper.create_server(new_server_name, new_server_uuid, new_server_path, "", new_server_command, new_executable, new_server_log_file, stop_command, server_port) + self.controller.servers.create_server(new_server_name, new_server_uuid, new_server_path, "", new_server_command, new_executable, new_server_log_file, stop_command, server_port) self.controller.init_all_servers() return - db_helper.send_command(exec_user_data['user_id'], server_id, self.get_remote_ip(), command) + self.controller.management.send_command(exec_user_data['user_id'], server_id, self.get_remote_ip(), command) if page == "step1": @@ -169,7 +168,7 @@ class ServerHandler(BaseHandler): return new_server_id = self.controller.import_jar_server(server_name, import_server_path,import_server_jar, min_mem, max_mem, port) - db_helper.add_to_audit_log(exec_user_data['user_id'], + self.controller.management.add_to_audit_log(exec_user_data['user_id'], "imported a jar server named \"{}\"".format(server_name), # Example: Admin imported a server named "old creative" new_server_id, self.get_remote_ip()) @@ -184,7 +183,7 @@ class ServerHandler(BaseHandler): if new_server_id == "false": self.redirect("/panel/error?error=Zip file not accessible! You can fix this permissions issue with sudo chown -R crafty:crafty {} And sudo chmod 2775 -R {}".format(import_server_path, import_server_path)) return - db_helper.add_to_audit_log(exec_user_data['user_id'], + self.controller.management.add_to_audit_log(exec_user_data['user_id'], "imported a zip server named \"{}\"".format(server_name), # Example: Admin imported a server named "old creative" new_server_id, self.get_remote_ip()) @@ -194,19 +193,19 @@ class ServerHandler(BaseHandler): return server_type, server_version = server_parts # TODO: add server type check here and call the correct server add functions if not a jar - role_ids = db_helper.get_user_roles_id(exec_user_id) + role_ids = self.controller.roles.get_user_roles_id(exec_user_id) new_server_id = self.controller.create_jar_server(server_type, server_version, server_name, min_mem, max_mem, port) - db_helper.add_to_audit_log(exec_user_data['user_id'], + self.controller.management.add_to_audit_log(exec_user_data['user_id'], "created a {} {} server named \"{}\"".format(server_version, str(server_type).capitalize(), server_name), # Example: Admin created a 1.16.5 Bukkit server named "survival" new_server_id, self.get_remote_ip()) #These lines create a new Role for the Server with full permissions and add the user to it - role_id = db_helper.add_role("Creator of Server with id={}".format(new_server_id)) - db_helper.add_role_server(new_server_id, role_id, "11111111") - db_helper.add_role_to_user(exec_user_id, role_id) + role_id = self.controller.roles.add_role("Creator of Server with id={}".format(new_server_id)) + self.controller.server_permissions.add_role_server(new_server_id, role_id, "11111111") + self.controller.users.add_role_to_user(exec_user_id, role_id) if not exec_user['superuser']: - db_helper.add_server_creation(exec_user_id) + self.controller.server_permissions.add_server_creation(exec_user_id) self.controller.stats.record_stats() self.redirect("/panel/dashboard") diff --git a/app/classes/web/status_handler.py b/app/classes/web/status_handler.py index aeaba5c1..712e072b 100644 --- a/app/classes/web/status_handler.py +++ b/app/classes/web/status_handler.py @@ -9,7 +9,7 @@ import requests from app.classes.shared.helpers import helper from app.classes.web.base_handler import BaseHandler from app.classes.shared.console import console -from app.classes.shared.models import Users, fn, db_helper +from app.classes.shared.main_models import fn logger = logging.getLogger(__name__) @@ -25,7 +25,7 @@ except ModuleNotFoundError as e: class StatusHandler(BaseHandler): def get(self): page_data = {} - page_data['servers'] = db_helper.get_all_servers_stats() + page_data['servers'] = self.controller.servers.get_all_servers_stats() for srv in page_data['servers']: server_data = srv.get('server_data', False) server_id = server_data.get('server_id', False) @@ -40,7 +40,7 @@ class StatusHandler(BaseHandler): ) def post(self): page_data = {} - page_data['servers'] = db_helper.get_all_servers_stats() + page_data['servers'] = self.controller.servers.get_all_servers_stats() for srv in page_data['servers']: server_data = srv.get('server_data', False) server_id = server_data.get('server_id', False) diff --git a/app/classes/web/upload_handler.py b/app/classes/web/upload_handler.py index 90d59892..524dbee9 100644 --- a/app/classes/web/upload_handler.py +++ b/app/classes/web/upload_handler.py @@ -2,7 +2,7 @@ import tornado.options import tornado.web import tornado.httpserver from tornado.options import options -from app.classes.shared.models import db_helper, Enum_Permissions_Server +from app.classes.models.server_permissions import Enum_Permissions_Server from app.classes.shared.helpers import helper from app.classes.web.websocket_helper import websocket_helper from app.classes.shared.console import console @@ -35,7 +35,7 @@ class UploadHandler(tornado.web.RequestHandler): console.warning('Server ID not found in upload handler call') self.do_upload = False - user_permissions = db_helper.get_user_permissions_list(user_id, server_id) + user_permissions = self.controller.server_permissions.get_user_permissions_list(user_id, server_id) if Enum_Permissions_Server.Files not in user_permissions: logger.warning(f'User {user_id} tried to upload a file to {server_id} without permissions!') console.warning(f'User {user_id} tried to upload a file to {server_id} without permissions!') @@ -45,8 +45,8 @@ class UploadHandler(tornado.web.RequestHandler): filename = self.request.headers.get('X-FileName', None) full_path = os.path.join(path, filename) - if not helper.in_path(db_helper.get_server_data_by_id(server_id)['path'], full_path): - print(user_id, server_id, db_helper.get_server_data_by_id(server_id)['path'], full_path) + if not helper.in_path(self.controller.servers.get_server_data_by_id(server_id)['path'], full_path): + print(user_id, server_id, self.controller.servers.get_server_data_by_id(server_id)['path'], full_path) logger.warning(f'User {user_id} tried to upload a file to {server_id} but the path is not inside of the server!') console.warning(f'User {user_id} tried to upload a file to {server_id} but the path is not inside of the server!') self.do_upload = False diff --git a/app/classes/web/websocket_handler.py b/app/classes/web/websocket_handler.py index ad98c2ab..e1c1a737 100644 --- a/app/classes/web/websocket_handler.py +++ b/app/classes/web/websocket_handler.py @@ -3,7 +3,7 @@ import logging import asyncio from urllib.parse import parse_qsl -from app.classes.shared.models import Users, db_helper +from app.classes.models.users import Users from app.classes.shared.helpers import helper from app.classes.web.websocket_helper import websocket_helper @@ -50,7 +50,7 @@ class SocketHandler(tornado.websocket.WebSocketHandler): else: websocket_helper.send_message(self, 'notification', 'Not authenticated for WebSocket connection') self.close() - db_helper.add_to_audit_log_raw('unknown', 0, 0, 'Someone tried to connect via WebSocket without proper authentication', self.get_remote_ip()) + self.controller.management.add_to_audit_log_raw('unknown', 0, 0, 'Someone tried to connect via WebSocket without proper authentication', self.get_remote_ip()) websocket_helper.broadcast('notification', 'Someone tried to connect via WebSocket without proper authentication') logger.warning('Someone tried to connect via WebSocket without proper authentication') diff --git a/app/migrations/20210822092240_crafty_permissions.py b/app/migrations/20210822092240_crafty_permissions.py index c4a07fb6..e39884fa 100644 --- a/app/migrations/20210822092240_crafty_permissions.py +++ b/app/migrations/20210822092240_crafty_permissions.py @@ -1,6 +1,6 @@ # Generated by database migrator from peewee import * -from app.classes.shared.models import Users +from app.classes.models.users import Users def migrate(migrator, database, **kwargs): db = database diff --git a/app/migrations/20210822101530_delete_User_Servers.py b/app/migrations/20210822101530_delete_User_Servers.py index 3cb761b3..efe2a3a9 100644 --- a/app/migrations/20210822101530_delete_User_Servers.py +++ b/app/migrations/20210822101530_delete_User_Servers.py @@ -1,6 +1,7 @@ # Generated by database migrator from peewee import * -from app.classes.shared.models import Users, Servers +from app.classes.models.users import Users +from app.classes.models.servers import Servers def migrate(migrator, database, **kwargs): diff --git a/main.py b/main.py index 9d9e258e..cdd088e3 100644 --- a/main.py +++ b/main.py @@ -9,10 +9,10 @@ import signal """ Our custom classes / pip packages """ from app.classes.shared.console import console from app.classes.shared.helpers import helper -from app.classes.shared.models import installer, database +from app.classes.shared.main_models import installer, database from app.classes.shared.tasks import TasksManager -from app.classes.shared.controller import Controller +from app.classes.shared.main_controller import Controller from app.classes.shared.migration import MigrationManager from app.classes.shared.cmd import MainPrompt