From 8a5cc6d1e693c189dd001c5290bb306a7a67be10 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 26 Jan 2023 19:21:39 -0500 Subject: [PATCH 01/26] Set up back end for master server dir --- .../controllers/management_controller.py | 11 +++++++++++ app/classes/models/management.py | 14 ++++++++++++++ app/classes/shared/main_controller.py | 4 ++++ app/migrations/20230126_master_server.py | 18 ++++++++++++++++++ main.py | 9 +++++++++ 5 files changed, 56 insertions(+) create mode 100644 app/migrations/20230126_master_server.py diff --git a/app/classes/controllers/management_controller.py b/app/classes/controllers/management_controller.py index 47860fe1..4c1d7397 100644 --- a/app/classes/controllers/management_controller.py +++ b/app/classes/controllers/management_controller.py @@ -159,3 +159,14 @@ class ManagementController: def del_excluded_backup_dir(self, server_id: int, dir_to_del: str): self.management_helper.del_excluded_backup_dir(server_id, dir_to_del) + + # ********************************************************************************** + # Crafty Methods + # ********************************************************************************** + @staticmethod + def get_master_server_dir(): + return HelpersManagement.get_master_server_dir() + + @staticmethod + def set_master_server_dir(server_dir): + HelpersManagement.set_master_server_dir(server_dir) diff --git a/app/classes/models/management.py b/app/classes/models/management.py index 55c86bb7..b56208f7 100644 --- a/app/classes/models/management.py +++ b/app/classes/models/management.py @@ -44,6 +44,7 @@ class AuditLog(BaseModel): class CraftySettings(BaseModel): secret_api_key = CharField(default="") login_photo = CharField(default="login_1.jpg") + master_server_dir = CharField(default="") class Meta: table_name = "crafty_settings" @@ -268,6 +269,19 @@ class HelpersManagement: CraftySettings.id == 1 ).execute() + @staticmethod + def get_master_server_dir(): + settings = CraftySettings.select(CraftySettings.master_server_dir).where( + CraftySettings.id == 1 + ) + return settings[0].master_server_dir + + @staticmethod + def set_master_server_dir(server_dir): + CraftySettings.update({CraftySettings.master_server_dir: server_dir}).where( + CraftySettings.id == 1 + ).execute() + # ********************************************************************************** # Schedules Methods # ********************************************************************************** diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index 3a229d20..1b033b49 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -972,3 +972,7 @@ class Controller: @staticmethod def clear_support_status(): HelperUsers.clear_support_status() + + def set_master_server_dir(self, server_dir): + self.helper.servers_dir = server_dir + HelpersManagement.set_master_server_dir(server_dir) diff --git a/app/migrations/20230126_master_server.py b/app/migrations/20230126_master_server.py new file mode 100644 index 00000000..03e83c80 --- /dev/null +++ b/app/migrations/20230126_master_server.py @@ -0,0 +1,18 @@ +# Generated by database migrator +import peewee + + +def migrate(migrator, database, **kwargs): + migrator.add_columns( + "crafty_settings", master_server_dir=peewee.CharField(default="") + ) + """ + Write your migrations here. + """ + + +def rollback(migrator, database, **kwargs): + migrator.drop_columns("crafty_settings", ["master_server_dir"]) + """ + Write your rollback migrations here. + """ diff --git a/main.py b/main.py index f46273e0..bfd25332 100644 --- a/main.py +++ b/main.py @@ -210,6 +210,15 @@ if __name__ == "__main__": running_mode = "Interactive" controller.set_project_root(application_path) + master_server_dir = controller.management.get_master_server_dir() + if master_server_dir == "": + Console.warning("Could not find master server path. Setting default") + controller.set_master_server_dir( + os.path.join(controller.project_root, "servers") + ) + else: + helper.servers_dir = master_server_dir + Console.debug(f"Execution Mode: {running_mode}") Console.debug(f"Application path : '{application_path}'") From aaefcb913b4a7a9d439de5b2428d061563b96a8a Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Mon, 30 Jan 2023 15:22:40 -0500 Subject: [PATCH 02/26] Append to subdir function for windows mapping --- app/classes/shared/helpers.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 92226425..57b44808 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -435,12 +435,20 @@ class Helpers: return data - @staticmethod - def is_subdir(server_path, root_dir): + def is_subdir(self, server_path, root_dir): server_path = os.path.realpath(server_path) root_dir = os.path.realpath(root_dir) - relative = os.path.relpath(server_path, root_dir) + if self.is_os_windows(): + try: + relative = os.path.relpath(server_path, root_dir) + except: + # Windows will crash out if two paths are on different + # Drives We can happily return false if this is the case. + # Since two different drives will not be relative to eachother. + return False + else: + relative = os.path.relpath(server_path, root_dir) if relative.startswith(os.pardir): return False @@ -887,12 +895,15 @@ class Helpers: try: os.makedirs(path) logger.debug(f"Created Directory : {path}") + return True # directory already exists - non-blocking error except FileExistsError: pass + return True except PermissionError as e: logger.critical(f"Check generated exception due to permssion error: {e}") + return False def create_self_signed_cert(self, cert_dir=None): From 863ded782a66e4f3b95d445fe8bc1ace63927137 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Mon, 30 Jan 2023 15:23:10 -0500 Subject: [PATCH 03/26] Add move servers dir functionality --- app/classes/shared/main_controller.py | 50 +++++++++++++++++++ app/classes/web/ajax_handler.py | 19 +++++++ app/classes/web/panel_handler.py | 3 ++ .../templates/panel/panel_config.html | 42 +++++++++++++++- 4 files changed, 112 insertions(+), 2 deletions(-) diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index 2aae7c64..d4c5535d 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -1005,5 +1005,55 @@ class Controller: HelperUsers.clear_support_status() def set_master_server_dir(self, server_dir): + # This method should only be used on a first run basis if the server dir is "" self.helper.servers_dir = server_dir HelpersManagement.set_master_server_dir(server_dir) + + def update_master_server_dir(self, server_dir, user_id): + if self.management.get_master_server_dir() == server_dir: + logger.info( + "Admin tried to change server dir to current server dir. Canceling..." + ) + return + if self.helper.is_subdir(server_dir, self.management.get_master_server_dir()): + logger.info( + "Admin tried to change server dir to be inside a sub directory of the" + " current server dir. This will result in a copy loop." + ) + self.helper.servers_dir = server_dir + + if not self.helper.ensure_dir_exists(os.path.join(server_dir, "servers")): + self.helper.websocket_helper.broadcast_user( + user_id, + "send_start_error", + { + "error": "Crafty failed to move server dir. " + "It seems Crafty lacks permission to write to " + "the new directory." + }, + ) + return + + HelpersManagement.set_master_server_dir(server_dir) + servers = self.servers.get_all_defined_servers() + for server in servers: + server_path = server.get("path") + new_server_path = os.path.join( + server_dir, "servers", server.get("server_uuid") + ) + if os.path.isdir(server_path): + self.file_helper.move_dir( + server_path, + new_server_path, + ) + server_obj = self.servers.get_server_obj(server.get("server_id")) + server_obj.path = new_server_path + failed = False + for s in self.servers.failed_servers: + if int(s["server_id"]) == int(server.get("server_id")): + failed = True + if not failed: + self.servers.update_server(server_obj) + else: + self.servers.update_unloaded_server(server_obj) + self.servers.init_all_servers() diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index 97de6b13..7484ccaa 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -575,6 +575,25 @@ class AjaxHandler(BaseHandler): self.controller.server_jars.manual_refresh_cache() return + elif page == "update_server_dir": + for server in self.controller.servers.get_all_servers_stats(): + if server["stats"]["running"]: + self.helper.websocket_helper.broadcast_user( + exec_user["user_id"], + "send_start_error", + { + "error": "You must stop all servers before " + "starting a storage migration." + }, + ) + return + if not superuser: + self.redirect("/panel/error?error=Not a super user") + return + new_dir = urllib.parse.unquote(self.get_argument("server_dir")) + self.controller.update_master_server_dir(new_dir, exec_user["user_id"]) + return + @tornado.web.authenticated def delete(self, page): api_key, _, exec_user = self.current_user diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 74c93b88..ddfdd5a2 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -841,6 +841,9 @@ class PanelHandler(BaseHandler): page_data["auth-servers"] = auth_servers page_data["role-servers"] = auth_role_servers page_data["user-roles"] = user_roles + page_data[ + "servers_dir" + ] = self.controller.management.get_master_server_dir() page_data["users"] = self.controller.users.user_query(exec_user["user_id"]) page_data["roles"] = self.controller.users.user_role_query( diff --git a/app/frontend/templates/panel/panel_config.html b/app/frontend/templates/panel/panel_config.html index 249daf70..2cc409de 100644 --- a/app/frontend/templates/panel/panel_config.html +++ b/app/frontend/templates/panel/panel_config.html @@ -50,7 +50,9 @@

{{ translate('panelConfig', 'users', data['lang']) }}

{% if data['user_data']['hints'] %} - + {% end %}
  {{ @@ -148,7 +150,9 @@

{{ translate('panelConfig', 'roles', data['lang']) }}

{% if data['user_data']['hints'] %} - + {% end %}
  {{ translate('panelConfig', 'newRole', data['lang']) }}
@@ -234,6 +238,16 @@

{{ translate('panelConfig', 'adminControls', data['lang']) }}

+
+
+ + + +   +
@@ -258,6 +272,30 @@ {% block js %} + integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA==" + crossorigin="anonymous" referrerpolicy="no-referrer"> + integrity="sha512-UXumZrZNiOwnTcZSHLOfcTs0aos2MzBWHXOHOuB0J/R44QB0dwY5JgfbvljXcklVf65Gc4El6RjZ+lnwd2az2g==" + crossorigin="anonymous" referrerpolicy="no-referrer"> + integrity="sha512-klQv6lz2YR+MecyFYMFRuU2eAl8IPRo6zHnsc9n142TJuJHS8CG0ix4Oq9na9ceeg1u5EkBfZsFcV3U7J51iew==" + crossorigin="anonymous" referrerpolicy="no-referrer"> @@ -82,7 +82,7 @@ {% include notify.html %} @@ -174,7 +174,7 @@ + src="https://cdn.datatables.net/v/bs4/dt-1.10.22/fh-3.1.7/r-2.2.6/sc-2.0.3/sp-1.2.2/datatables.min.js"> diff --git a/app/frontend/templates/blank_base.html b/app/frontend/templates/blank_base.html index 95893acc..50f4e815 100644 --- a/app/frontend/templates/blank_base.html +++ b/app/frontend/templates/blank_base.html @@ -1,60 +1,63 @@ - - - - - {% block title %}{{ _('Default') }}{% end %} - - - - - - - - - - - - - - - - - - -
-
-
-
-
+ + + + + + {% block title %}{{ _('Default') }}{% end %} + + + + + + + + + + + + + + + + + + + +
+
+
+
+
{% block content %} {% end %} -
-
- +
- - - - - - - - - - - - - {% block js %} - - - {% end %} - - + +
+ + + + + + + + + + + + + {% block js %} + + + {% end %} + + + \ No newline at end of file diff --git a/app/frontend/templates/main_menu.html b/app/frontend/templates/main_menu.html index 6f5da3d0..10ec95f7 100644 --- a/app/frontend/templates/main_menu.html +++ b/app/frontend/templates/main_menu.html @@ -68,14 +68,14 @@ {% end %} {% if data['permissions']['Logs'] in data['user_permissions'] and data['server_data']['type'] != 'minecraft-bedrock'%} {% end %} {% if data['permissions']['Schedule'] in data['user_permissions'] %} @@ -51,6 +51,6 @@ {% end %} \ No newline at end of file diff --git a/app/frontend/templates/public_base.html b/app/frontend/templates/public_base.html index 33972b79..0f40b4ad 100644 --- a/app/frontend/templates/public_base.html +++ b/app/frontend/templates/public_base.html @@ -13,7 +13,7 @@ - + From ca0a53b326bafde1f893b963ce59b5c3e4f09765 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Fri, 3 Feb 2023 16:00:13 -0500 Subject: [PATCH 12/26] Add translations to Crafty Config Page and wizard --- .../templates/panel/parts/crafty_config_list.html | 15 +++++++++------ app/frontend/templates/server/bedrock_wizard.html | 5 +++-- app/frontend/templates/server/wizard.html | 5 +++-- app/translations/en_EN.json | 4 ++++ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app/frontend/templates/panel/parts/crafty_config_list.html b/app/frontend/templates/panel/parts/crafty_config_list.html index 5ef6b922..3f62d579 100644 --- a/app/frontend/templates/panel/parts/crafty_config_list.html +++ b/app/frontend/templates/panel/parts/crafty_config_list.html @@ -1,14 +1,17 @@ \ No newline at end of file diff --git a/app/frontend/templates/server/bedrock_wizard.html b/app/frontend/templates/server/bedrock_wizard.html index 38d0b021..624ec91a 100644 --- a/app/frontend/templates/server/bedrock_wizard.html +++ b/app/frontend/templates/server/bedrock_wizard.html @@ -346,11 +346,12 @@
-
+
- +
diff --git a/app/frontend/templates/server/wizard.html b/app/frontend/templates/server/wizard.html index 0f70d6b1..b34d52f6 100644 --- a/app/frontend/templates/server/wizard.html +++ b/app/frontend/templates/server/wizard.html @@ -456,11 +456,12 @@
-
+
- +
diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 15a8ed27..2eb9691b 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -222,6 +222,8 @@ "newRole": "Add New Role", "newUser": "Add New User", "pageTitle": "Panel Config", + "json": "Config.json", + "custom": "Customize Crafty", "role": "Role", "roles": "Roles", "roleUsers": "Role Users", @@ -548,7 +550,9 @@ "serverType": "Server Type", "serverSelect": "Server Select", "serverVersion": "Server Version", + "serverUpload": "Upload Zipped Server", "sizeInGB": "Size in GB", + "uploadButton": "Upload", "zipPath": "Server Path" }, "sidebar": { From edddfca8bce8b18be83b6e6b7eadfe024fc87a40 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Fri, 3 Feb 2023 18:24:42 -0500 Subject: [PATCH 13/26] Fix spacing on moble server controls --- app/frontend/templates/panel/parts/m_server_controls_list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/frontend/templates/panel/parts/m_server_controls_list.html b/app/frontend/templates/panel/parts/m_server_controls_list.html index c22ca89f..e4447428 100644 --- a/app/frontend/templates/panel/parts/m_server_controls_list.html +++ b/app/frontend/templates/panel/parts/m_server_controls_list.html @@ -30,7 +30,7 @@ {% if data['permissions']['Players'] in data['user_permissions'] and data['server_data']['type'] != 'minecraft-bedrock' %} {{ translate('serverDetails', 'playerControls', data['lang']) }} {% end %} - {{ translate('serverDetails', 'metrics', data['lang']) }} + {{ translate('serverDetails', 'metrics', data['lang']) }}
\ No newline at end of file From 9d2164a1b346999f72f0660cb84889f7c558cea8 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Fri, 10 Feb 2023 15:36:46 -0500 Subject: [PATCH 14/26] Bump Cryptography/pyOpenSSL for CVE-2020-36242 --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index cf65cd9f..4cbb29e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,12 +5,12 @@ bleach==4.1 cached_property==1.5.2 colorama==0.4 croniter==1.3.5 -cryptography==3.4.8 +cryptography==39.0.1 libgravatar==1.0.0 peewee==3.13 pexpect==4.8 psutil==5.9 -pyOpenSSL==19.1.0 +pyOpenSSL==23.0.0 pyjwt==2.4.0 PyYAML==5.4 requests==2.26 From be17d7fded235cd7404550acf59dc7968d943607 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Sat, 11 Feb 2023 21:58:43 +0000 Subject: [PATCH 15/26] Update changelog !549 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f15d616c..8e70e1ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,10 @@ - Cleanup authentication helpers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/545)) - Optimize file upload progress WS ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/546)) - Truncate sidebar servers to a max of 10 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/552)) +- Upgrade to FA 6. Add Translations ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/549)) ### Lang - Add additional translations to backups page strings ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/543)) +- Add additional missing translations ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/549))

## --- [4.0.20] - 2023/01/29 From 1152e9881c00b3fffd75068f705df9fb6ab723bb Mon Sep 17 00:00:00 2001 From: Zedifus Date: Sat, 11 Feb 2023 22:26:01 +0000 Subject: [PATCH 16/26] Update changelog !554 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e70e1ee..ed216490 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Fix exception related to page data on server start ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/544)) - Fix logical issue with uploading dynamic files ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/555)) - Fix backups failing by correctly using tz objects ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/556)) +- Bump Cryptography/pyOpenSSL for CVE-2023-23931 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/554)) ### Tweaks - Cleanup authentication helpers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/545)) - Optimize file upload progress WS ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/546)) From fdf7bd76214fc506108e31ae01498b56e75c2d3f Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Sun, 12 Feb 2023 12:28:37 -0500 Subject: [PATCH 17/26] Add helper to check docker environment --- app/classes/shared/helpers.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index e5d609c2..5b8e7a9c 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -987,6 +987,15 @@ class Helpers: def is_os_windows(): return os.name == "nt" + @staticmethod + def is_env_docker(): + path = "/proc/self/cgroup" + return ( + os.path.exists("/.dockerenv") + or os.path.isfile(path) + and any("docker" in line for line in open(path, encoding="utf-8")) + ) + @staticmethod def wtol_path(w_path): l_path = w_path.replace("\\", "/") From dd317a3460a8de47c1e6d4e1bec568eeb3784779 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Sun, 12 Feb 2023 12:29:05 -0500 Subject: [PATCH 18/26] Only support changing server dir in non-docker env --- app/classes/web/ajax_handler.py | 6 ++++++ app/classes/web/panel_handler.py | 1 + app/frontend/templates/panel/panel_config.html | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index 7484ccaa..d7dc90ee 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -590,6 +590,12 @@ class AjaxHandler(BaseHandler): if not superuser: self.redirect("/panel/error?error=Not a super user") return + if self.helper.is_env_docker(): + self.redirect( + "/panel/error?error=This feature is not" + " supported on docker environments" + ) + return new_dir = urllib.parse.unquote(self.get_argument("server_dir")) self.controller.update_master_server_dir(new_dir, exec_user["user_id"]) return diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 7d82933e..7944ad99 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -290,6 +290,7 @@ class PanelHandler(BaseHandler): page_data: t.Dict[str, t.Any] = { # todo: make this actually pull and compare version data "update_available": self.helper.update_available, + "docker": self.helper.is_env_docker(), "background": self.controller.cached_login, "login_opacity": self.controller.management.get_login_opacity(), "serverTZ": tz, diff --git a/app/frontend/templates/panel/panel_config.html b/app/frontend/templates/panel/panel_config.html index 8d53afb0..535fe094 100644 --- a/app/frontend/templates/panel/panel_config.html +++ b/app/frontend/templates/panel/panel_config.html @@ -230,7 +230,7 @@
- {% if data['superuser'] %} + {% if data['superuser'] and not data["docker"] %}
From b4e47151cedd1d1eb8cada278b278aeaaec587f9 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Mon, 13 Feb 2023 11:48:06 -0500 Subject: [PATCH 19/26] We'll wtol the path coming in --- app/classes/shared/main_controller.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index 971b493f..b953906c 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -1023,6 +1023,7 @@ class Controller: move_thread.start() def t_update_master_server_dir(self, server_dir, user_id): + server_dir = self.helper.wtol_path(server_dir) self.helper.websocket_helper.broadcast_page( "/panel/panel_config", "move_status", "Checking dir" ) @@ -1051,7 +1052,9 @@ class Controller: }, ) return - + current_master = self.helper.wtol_path( + HelpersManagement.get_master_server_dir() + ) HelpersManagement.set_master_server_dir(server_dir) servers = self.servers.get_all_defined_servers() for server in servers: @@ -1070,6 +1073,14 @@ class Controller: new_server_path, ) server_obj = self.servers.get_server_obj(server.get("server_id")) + if current_master in server["executable"]: + server_obj.executable = str(server["executable"]).replace( + current_master, server_dir + ) + if current_master in server["execution_command"]: + server_obj.executable = str(server["execution_command"]).replace( + current_master, server_dir + ) server_obj.path = new_server_path failed = False for s in self.servers.failed_servers: From b3fba650e71c4b674eb0c124615a6b33b57034e2 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Mon, 13 Feb 2023 13:05:54 -0500 Subject: [PATCH 20/26] Put try catch around move block Reset run command, executable, log path if abs --- app/classes/shared/main_controller.py | 49 +++++++++++++++++++++------ 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index b953906c..da5ac5d2 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -1027,17 +1027,31 @@ class Controller: self.helper.websocket_helper.broadcast_page( "/panel/panel_config", "move_status", "Checking dir" ) - if self.management.get_master_server_dir() == server_dir: + current_master = self.helper.wtol_path( + HelpersManagement.get_master_server_dir() + ) + if current_master == server_dir: logger.info( "Admin tried to change server dir to current server dir. Canceling..." ) + self.helper.websocket_helper.broadcast_page( + "/panel/panel_config", + "move_status", + "done", + ) return - if self.helper.is_subdir(server_dir, self.management.get_master_server_dir()): + if self.helper.is_subdir(server_dir, current_master): logger.info( "Admin tried to change server dir to be inside a sub directory of the" " current server dir. This will result in a copy loop." ) - self.helper.servers_dir = server_dir + self.helper.websocket_helper.broadcast_page( + "/panel/panel_config", + "move_status", + "done", + ) + return + self.helper.websocket_helper.broadcast_page( "/panel/panel_config", "move_status", "Checking permissions" ) @@ -1052,11 +1066,12 @@ class Controller: }, ) return - current_master = self.helper.wtol_path( - HelpersManagement.get_master_server_dir() - ) + # set the cached serve dir + self.helper.servers_dir = server_dir + # set DB server dir HelpersManagement.set_master_server_dir(server_dir) servers = self.servers.get_all_defined_servers() + # move the servers for server in servers: server_path = server.get("path") new_server_path = os.path.join( @@ -1068,17 +1083,29 @@ class Controller: "move_status", f"Moving {server.get('server_name')}", ) - self.file_helper.move_dir( - server_path, - new_server_path, - ) + try: + self.file_helper.move_dir( + server_path, + new_server_path, + ) + except FileExistsError as e: + logger.error(f"Failed to move server with error: {e}") + server_obj = self.servers.get_server_obj(server.get("server_id")) + + # reset executable path if current_master in server["executable"]: server_obj.executable = str(server["executable"]).replace( current_master, server_dir ) + # reset run command path if current_master in server["execution_command"]: - server_obj.executable = str(server["execution_command"]).replace( + server_obj.execution_command = str(server["execution_command"]).replace( + current_master, server_dir + ) + # reset log path + if current_master in server["log_path"]: + server_obj.log_path = str(server["log_path"]).replace( current_master, server_dir ) server_obj.path = new_server_path From 33ff921b4545b7090186dfd8487b40bab28363f0 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Mon, 13 Feb 2023 14:08:02 -0500 Subject: [PATCH 21/26] Silently log no server dir setting --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 2833c4d6..4c9517a6 100644 --- a/main.py +++ b/main.py @@ -229,7 +229,7 @@ if __name__ == "__main__": controller.set_project_root(application_path) master_server_dir = controller.management.get_master_server_dir() if master_server_dir == "": - Console.warning("Could not find master server path. Setting default") + logger.debug("Could not find master server path. Setting default") controller.set_master_server_dir( os.path.join(controller.project_root, "servers") ) From 491415c7fa60d9327422a287b984a3eff796503c Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 15 Feb 2023 18:01:21 -0500 Subject: [PATCH 22/26] Re-black codebase with new standard --- app/classes/controllers/servers_controller.py | 2 -- app/classes/minecraft/mc_ping.py | 1 - app/classes/minecraft/serverjars.py | 1 - app/classes/minecraft/stats.py | 3 --- app/classes/models/crafty_permissions.py | 1 + app/classes/models/management.py | 1 + app/classes/models/roles.py | 1 + app/classes/models/server_permissions.py | 1 + app/classes/models/server_stats.py | 1 + app/classes/models/servers.py | 1 + app/classes/models/users.py | 2 ++ app/classes/shared/command.py | 1 - app/classes/shared/helpers.py | 6 ------ app/classes/shared/import_helper.py | 1 - app/classes/shared/installer.py | 1 - app/classes/shared/main_controller.py | 1 - app/classes/shared/server.py | 8 -------- app/classes/shared/tasks.py | 1 - app/classes/web/default_handler.py | 1 - app/classes/web/public_handler.py | 4 ---- app/classes/web/routes/api/auth/login.py | 1 - app/classes/web/routes/api/servers/index.py | 1 - app/classes/web/server_handler.py | 1 - app/classes/web/tornado_handler.py | 2 -- app/classes/web/upload_handler.py | 2 -- app/classes/web/websocket_handler.py | 1 - 26 files changed, 8 insertions(+), 39 deletions(-) diff --git a/app/classes/controllers/servers_controller.py b/app/classes/controllers/servers_controller.py index 4c97a6c7..1503b78f 100644 --- a/app/classes/controllers/servers_controller.py +++ b/app/classes/controllers/servers_controller.py @@ -166,7 +166,6 @@ class ServersController(metaclass=Singleton): raise Exception(f"Unable to find server object for server id {server_id}") def init_all_servers(self): - servers = self.get_all_defined_servers() self.failed_servers = [] @@ -227,7 +226,6 @@ class ServersController(metaclass=Singleton): ) def check_server_loaded(self, server_id_to_check: int): - logger.info(f"Checking to see if we already registered {server_id_to_check}") for server in self.servers_list: diff --git a/app/classes/minecraft/mc_ping.py b/app/classes/minecraft/mc_ping.py index 1c52ab98..79610d8d 100644 --- a/app/classes/minecraft/mc_ping.py +++ b/app/classes/minecraft/mc_ping.py @@ -19,7 +19,6 @@ class Server: self.description = data.get("description") # print(self.description) if isinstance(self.description, dict): - # cat server if "translate" in self.description: self.description = self.description["translate"] diff --git a/app/classes/minecraft/serverjars.py b/app/classes/minecraft/serverjars.py index 3ecfdb8f..b70a8c40 100644 --- a/app/classes/minecraft/serverjars.py +++ b/app/classes/minecraft/serverjars.py @@ -104,7 +104,6 @@ class ServerJars: logger.error(f"Unable to update serverjars.com cache file: {e}") def refresh_cache(self): - cache_file = self.helper.serverjar_cache cache_old = self.helper.is_file_older_than_x_days(cache_file) diff --git a/app/classes/minecraft/stats.py b/app/classes/minecraft/stats.py index 07dd9c0d..8001b1d1 100644 --- a/app/classes/minecraft/stats.py +++ b/app/classes/minecraft/stats.py @@ -211,7 +211,6 @@ class Stats: @staticmethod def get_world_size(server_path): - total_size = 0 total_size = Helpers.get_dir_size(server_path) @@ -221,7 +220,6 @@ class Stats: return level_total_size def get_server_players(self, server_id): - server = HelperServers.get_server_data_by_id(server_id) logger.info(f"Getting players for server {server}") @@ -295,7 +293,6 @@ class Stats: @staticmethod def parse_server_raknet_ping(ping_obj: object): - try: server_icon = base64.encodebytes(ping_obj["icon"]) except Exception as e: diff --git a/app/classes/models/crafty_permissions.py b/app/classes/models/crafty_permissions.py index 22383408..7430f332 100644 --- a/app/classes/models/crafty_permissions.py +++ b/app/classes/models/crafty_permissions.py @@ -15,6 +15,7 @@ from app.classes.shared.permission_helper import PermissionHelper logger = logging.getLogger(__name__) + # ********************************************************************************** # User_Crafty Class # ********************************************************************************** diff --git a/app/classes/models/management.py b/app/classes/models/management.py index c2b5afde..3c2c0bf2 100644 --- a/app/classes/models/management.py +++ b/app/classes/models/management.py @@ -20,6 +20,7 @@ from app.classes.shared.main_models import DatabaseShortcuts logger = logging.getLogger(__name__) + # ********************************************************************************** # Audit_Log Class # ********************************************************************************** diff --git a/app/classes/models/roles.py b/app/classes/models/roles.py index 541f67e8..abc98735 100644 --- a/app/classes/models/roles.py +++ b/app/classes/models/roles.py @@ -15,6 +15,7 @@ from app.classes.shared.helpers import Helpers logger = logging.getLogger(__name__) + # ********************************************************************************** # Roles Class # ********************************************************************************** diff --git a/app/classes/models/server_permissions.py b/app/classes/models/server_permissions.py index 8844b3df..eb5e3f35 100644 --- a/app/classes/models/server_permissions.py +++ b/app/classes/models/server_permissions.py @@ -16,6 +16,7 @@ from app.classes.shared.permission_helper import PermissionHelper logger = logging.getLogger(__name__) + # ********************************************************************************** # Role Servers Class # ********************************************************************************** diff --git a/app/classes/models/server_stats.py b/app/classes/models/server_stats.py index ccb21879..14f85ad3 100644 --- a/app/classes/models/server_stats.py +++ b/app/classes/models/server_stats.py @@ -29,6 +29,7 @@ logger = logging.getLogger(__name__) peewee_logger = logging.getLogger("peewee") peewee_logger.setLevel(logging.INFO) + # ********************************************************************************** # Servers Stats Class # ********************************************************************************** diff --git a/app/classes/models/servers.py b/app/classes/models/servers.py index 96f606a9..a83fd0a2 100644 --- a/app/classes/models/servers.py +++ b/app/classes/models/servers.py @@ -15,6 +15,7 @@ from app.classes.models.base_model import BaseModel logger = logging.getLogger(__name__) + # ********************************************************************************** # Servers Model # ********************************************************************************** diff --git a/app/classes/models/users.py b/app/classes/models/users.py index 9b4805a3..496e8d2c 100644 --- a/app/classes/models/users.py +++ b/app/classes/models/users.py @@ -21,6 +21,7 @@ from app.classes.models.roles import Roles, HelperRoles logger = logging.getLogger(__name__) + # ********************************************************************************** # Users Class # ********************************************************************************** @@ -58,6 +59,7 @@ PUBLIC_USER_ATTRS: t.Final = [ "lang", # maybe remove? ] + # ********************************************************************************** # API Keys Class # ********************************************************************************** diff --git a/app/classes/shared/command.py b/app/classes/shared/command.py index 7e1e9456..26fdd2f0 100644 --- a/app/classes/shared/command.py +++ b/app/classes/shared/command.py @@ -58,7 +58,6 @@ class MainPrompt(cmd.Cmd): Console.info("Unknown migration command") def do_set_passwd(self, line): - try: username = str(line).lower() # If no user is found it returns None diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 6320d60e..ba333e92 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -596,7 +596,6 @@ class Helpers: # open our file with open(file_name, "r", encoding="utf-8") as f: - # seek f.seek(0, 2) @@ -761,7 +760,6 @@ class Helpers: @staticmethod def get_file_contents(path: str, lines=100): - contents = "" if os.path.exists(path) and os.path.isfile(path): @@ -782,12 +780,10 @@ class Helpers: return False def create_session_file(self, ignore=False): - if ignore and os.path.exists(self.session_file): os.remove(self.session_file) if os.path.exists(self.session_file): - file_data = self.get_file_contents(self.session_file) try: data = json.loads(file_data) @@ -895,7 +891,6 @@ class Helpers: logger.critical(f"Check generated exception due to permssion error: {e}") def create_self_signed_cert(self, cert_dir=None): - if cert_dir is None: cert_dir = os.path.join(self.config_dir, "web", "certs") @@ -1047,7 +1042,6 @@ class Helpers: return output def generate_dir(self, folder, output=""): - dir_list = [] unsorted_files = [] file_list = os.listdir(folder) diff --git a/app/classes/shared/import_helper.py b/app/classes/shared/import_helper.py index 88ee91fc..e3762aad 100644 --- a/app/classes/shared/import_helper.py +++ b/app/classes/shared/import_helper.py @@ -226,7 +226,6 @@ class ImportHelpers: download_thread.start() def download_threaded_bedrock_server(self, path, new_id): - # downloads zip from remote url try: bedrock_url = Helpers.get_latest_bedrock_url() diff --git a/app/classes/shared/installer.py b/app/classes/shared/installer.py index d82d2399..6e0cec77 100644 --- a/app/classes/shared/installer.py +++ b/app/classes/shared/installer.py @@ -10,7 +10,6 @@ class Install: ) def do_install(self): - # are we in a venv? if not self.is_venv(): print("Crafty Requires a venv to install") diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index 3bbe05f8..52bb6a72 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -941,7 +941,6 @@ class Controller: def remove_server(self, server_id, files): counter = 0 for server in self.servers.servers_list: - # if this is the droid... im mean server we are looking for... if str(server["server_id"]) == str(server_id): server_data = self.servers.get_server_data(server_id) diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index 8a6cd4cd..906ed9b8 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -590,7 +590,6 @@ class ServerInstance: # We need to grab the exact forge version number. # We know we can find it here in the run.sh/bat script. try: - # Getting the forge version from the executable command version = re.findall( r"forge-([0-9\.]+)((?:)|(?:-([0-9\.]+)-[a-zA-Z]+)).jar", @@ -850,7 +849,6 @@ class ServerInstance: return True def crash_detected(self, name): - # clear the old scheduled watcher task self.server_scheduler.remove_job(f"c_{self.server_id}") # remove the stats polling job since server is stopped @@ -912,7 +910,6 @@ class ServerInstance: return self.process.pid if self.process is not None else None def detect_crash(self): - logger.info(f"Detecting possible crash for server: {self.name} ") running = self.check_running() @@ -935,7 +932,6 @@ class ServerInstance: self.stats_helper.sever_crashed() # if we haven't tried to restart more 3 or more times if self.restart_count <= 3: - # start the server if needed server_restarted = self.crash_detected(self.name) @@ -1461,7 +1457,6 @@ class ServerInstance: Console.critical("Can't broadcast server status to websocket") def get_servers_stats(self): - server_stats = {} logger.info("Getting Stats for Server " + self.name + " ...") @@ -1548,7 +1543,6 @@ class ServerInstance: return server_stats def get_server_players(self): - server = HelperServers.get_server_data_by_id(self.server_id) logger.info(f"Getting players for server {server}") @@ -1569,7 +1563,6 @@ class ServerInstance: return [] def get_raw_server_stats(self, server_id): - try: server = HelperServers.get_server_obj(server_id) except: @@ -1718,7 +1711,6 @@ class ServerInstance: return server_stats def record_server_stats(self): - server_stats = self.get_servers_stats() self.stats_helper.insert_server_stats(server_stats) diff --git a/app/classes/shared/tasks.py b/app/classes/shared/tasks.py index e96acd14..320d0829 100644 --- a/app/classes/shared/tasks.py +++ b/app/classes/shared/tasks.py @@ -672,7 +672,6 @@ class TasksManager: host_stats = HelpersManagement.get_latest_hosts_stats() while True: - if host_stats.get( "cpu_usage" ) != HelpersManagement.get_latest_hosts_stats().get( diff --git a/app/classes/web/default_handler.py b/app/classes/web/default_handler.py index dc5c79bb..f41878f1 100644 --- a/app/classes/web/default_handler.py +++ b/app/classes/web/default_handler.py @@ -6,7 +6,6 @@ logger = logging.getLogger(__name__) class DefaultHandler(BaseHandler): - # Override prepare() instead of get() to cover all possible HTTP methods. def prepare(self, page=None): # pylint: disable=arguments-differ if page is not None: diff --git a/app/classes/web/public_handler.py b/app/classes/web/public_handler.py index d5bff692..dad74881 100644 --- a/app/classes/web/public_handler.py +++ b/app/classes/web/public_handler.py @@ -10,7 +10,6 @@ logger = logging.getLogger(__name__) class PublicHandler(BaseHandler): def set_current_user(self, user_id: str = None): - expire_days = self.helper.get_setting("cookie_expire") # if helper comes back with false @@ -29,7 +28,6 @@ class PublicHandler(BaseHandler): # self.clear_cookie("user_data") def get(self, page=None): - error = bleach.clean(self.get_argument("error", "Invalid Login!")) error_msg = bleach.clean(self.get_argument("error_msg", "")) @@ -81,7 +79,6 @@ class PublicHandler(BaseHandler): ) def post(self, page=None): - error = bleach.clean(self.get_argument("error", "Invalid Login!")) error_msg = bleach.clean(self.get_argument("error_msg", "")) @@ -96,7 +93,6 @@ class PublicHandler(BaseHandler): page_data["query"] = self.request.query if page == "login": - next_page = "/login" if self.request.query: next_page = "/login?" + self.request.query diff --git a/app/classes/web/routes/api/auth/login.py b/app/classes/web/routes/api/auth/login.py index 8583dce5..84ae2815 100644 --- a/app/classes/web/routes/api/auth/login.py +++ b/app/classes/web/routes/api/auth/login.py @@ -26,7 +26,6 @@ login_schema = { class ApiAuthLoginHandler(BaseApiHandler): def post(self): - try: data = json.loads(self.request.body) except json.decoder.JSONDecodeError as e: diff --git a/app/classes/web/routes/api/servers/index.py b/app/classes/web/routes/api/servers/index.py index a68e845b..edfec8fc 100644 --- a/app/classes/web/routes/api/servers/index.py +++ b/app/classes/web/routes/api/servers/index.py @@ -631,7 +631,6 @@ class ApiServersIndexHandler(BaseApiHandler): self.finish_json(200, {"status": "ok", "data": auth_data[0]}) def post(self): - auth_data = self.authenticate_user() if not auth_data: return diff --git a/app/classes/web/server_handler.py b/app/classes/web/server_handler.py index da854cc5..722c38fd 100644 --- a/app/classes/web/server_handler.py +++ b/app/classes/web/server_handler.py @@ -552,7 +552,6 @@ class ServerHandler(BaseHandler): self.get_remote_ip(), ) else: - new_server_id = self.controller.create_bedrock_server( server_name, exec_user["user_id"], diff --git a/app/classes/web/tornado_handler.py b/app/classes/web/tornado_handler.py index d0413beb..d2b047d7 100644 --- a/app/classes/web/tornado_handler.py +++ b/app/classes/web/tornado_handler.py @@ -59,7 +59,6 @@ class Webserver: @staticmethod def log_function(handler): - info = { "Status_Code": handler.get_status(), "Method": handler.request.method, @@ -103,7 +102,6 @@ class Webserver: logger.debug("Applied asyncio patch") def run_tornado(self): - # let's verify we have an SSL cert self.helper.create_self_signed_cert() diff --git a/app/classes/web/upload_handler.py b/app/classes/web/upload_handler.py index 11e1c4b8..39752a35 100644 --- a/app/classes/web/upload_handler.py +++ b/app/classes/web/upload_handler.py @@ -18,7 +18,6 @@ logger = logging.getLogger(__name__) @tornado.web.stream_request_body class UploadHandler(BaseHandler): - # noinspection PyAttributeOutsideInit def initialize( self, @@ -173,7 +172,6 @@ class UploadHandler(BaseHandler): if not self.request.headers.get("X-Content-Type", None).startswith( "image/" ): - return self.finish_json( 415, { diff --git a/app/classes/web/websocket_handler.py b/app/classes/web/websocket_handler.py index 64648fd8..78b33951 100644 --- a/app/classes/web/websocket_handler.py +++ b/app/classes/web/websocket_handler.py @@ -79,7 +79,6 @@ class SocketHandler(tornado.websocket.WebSocketHandler): # pylint: disable=arguments-renamed @staticmethod def on_message(raw_message): - logger.debug(f"Got message from WebSocket connection {raw_message}") message = json.loads(raw_message) logger.debug(f"Event Type: {message['event']}, Data: {message['data']}") From e52294dbb3603ea0af168142ee80fb556bb0ffcc Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 15 Feb 2023 18:40:20 -0500 Subject: [PATCH 23/26] Appease the linter --- app/classes/controllers/servers_controller.py | 2 +- app/classes/minecraft/mc_ping.py | 2 +- app/classes/shared/helpers.py | 8 ++++---- app/classes/shared/main_controller.py | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/classes/controllers/servers_controller.py b/app/classes/controllers/servers_controller.py index 1503b78f..8a74d3b8 100644 --- a/app/classes/controllers/servers_controller.py +++ b/app/classes/controllers/servers_controller.py @@ -163,7 +163,7 @@ class ServersController(metaclass=Singleton): return server["server_obj"] logger.warning(f"Unable to find server object for server id {server_id}") - raise Exception(f"Unable to find server object for server id {server_id}") + raise ValueError(f"Unable to find server object for server id {server_id}") def init_all_servers(self): servers = self.get_all_defined_servers() diff --git a/app/classes/minecraft/mc_ping.py b/app/classes/minecraft/mc_ping.py index 79610d8d..f760a8f9 100644 --- a/app/classes/minecraft/mc_ping.py +++ b/app/classes/minecraft/mc_ping.py @@ -123,7 +123,7 @@ def ping(ip, port): try: k = sock.recv(1) if not k: - raise Exception() + raise ValueError() except: return 0 k = k[0] diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index ba333e92..6f814a95 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -94,7 +94,7 @@ class Helpers: try: # Get tags from Gitlab, select the latest and parse the semver response = get( - "https://gitlab.com/api/v4/projects/20430749/repository/tags" + "https://gitlab.com/api/v4/projects/20430749/repository/tags", timeout=1 ) if response.status_code == 200: remote_version = pkg_version.parse(json.loads(response.text)[0]["name"]) @@ -131,7 +131,7 @@ class Helpers: try: # Get minecraft server download page # (hopefully the don't change the structure) - download_page = get(url, headers=headers) + download_page = get(url, headers=headers, timeout=1) # Search for our string targets win_download_url = re.search(target_win, download_page.text).group(0) @@ -281,7 +281,7 @@ class Helpers: @staticmethod def check_port(server_port): try: - ip = get("https://api.ipify.org").content.decode("utf8") + ip = get("https://api.ipify.org", timeout=1).content.decode("utf8") except: ip = "google.com" a_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -751,7 +751,7 @@ class Helpers: use_ssl=True, ) # + "?d=404" try: - if requests.head(url).status_code != 404: + if requests.head(url, timeout=1).status_code != 404: profile_url = url except Exception as e: logger.debug(f"Could not pull resource from Gravatar with error {e}") diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index 52bb6a72..3207be9d 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -347,7 +347,7 @@ class Controller: elif root_create_data["create_type"] == "import_zip": # TODO: Copy files from the zip file to the new server directory server_file = create_data["jarfile"] - raise Exception("Not yet implemented") + raise NotImplementedError("Not yet implemented") _create_server_properties_if_needed( create_data["server_properties_port"], ) @@ -379,7 +379,7 @@ class Controller: logger.error(f"Server import failed with error: {ex}") elif root_create_data["create_type"] == "import_zip": # TODO: Copy files from the zip file to the new server directory - raise Exception("Not yet implemented") + raise NotImplementedError("Not yet implemented") _create_server_properties_if_needed(0, True) @@ -401,7 +401,7 @@ class Controller: logger.error(f"Server import failed with error: {ex}") elif root_create_data["create_type"] == "import_zip": # TODO: Copy files from the zip file to the new server directory - raise Exception("Not yet implemented") + raise NotImplementedError("Not yet implemented") _create_server_properties_if_needed(0, True) From 224e55429f1293698623f1dacdf577bcdf2ce6c0 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 15 Feb 2023 18:44:53 -0500 Subject: [PATCH 24/26] appease the linter --- app/classes/shared/authentication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/classes/shared/authentication.py b/app/classes/shared/authentication.py index 1a809bfc..fad8b730 100644 --- a/app/classes/shared/authentication.py +++ b/app/classes/shared/authentication.py @@ -76,7 +76,7 @@ class Authentication: output = self.check(token) if output is None: - raise Exception("Invalid token") + raise ValueError("Invalid token") return output def check_bool(self, token) -> bool: From de17278255fe384dbe51b4a8d41bd4c8697bf96b Mon Sep 17 00:00:00 2001 From: Zedifus Date: Thu, 16 Feb 2023 23:22:34 +0000 Subject: [PATCH 25/26] Update changelog !539 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f15d616c..4166a1a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ### New features - Add better feedback for uploads with a progress bar ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/546)) - Add ignored exit codes for crash detection ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/553)) +- Allow users to change the directory where Crafty Stores Servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/539))
+ *(Only for non-docker, docker users should change host volume mount)* ### Bug fixes - Fix exception related to page data on server start ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/544)) - Fix logical issue with uploading dynamic files ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/555)) From 34f1acd3e2d6477a44c068326475b52fbbe1e5cb Mon Sep 17 00:00:00 2001 From: Zedifus Date: Thu, 16 Feb 2023 23:29:06 +0000 Subject: [PATCH 26/26] Appease black --- app/classes/controllers/servers_controller.py | 2 -- app/classes/minecraft/mc_ping.py | 1 - app/classes/minecraft/serverjars.py | 1 - app/classes/minecraft/stats.py | 3 --- app/classes/models/crafty_permissions.py | 1 + app/classes/models/management.py | 1 + app/classes/models/roles.py | 1 + app/classes/models/server_permissions.py | 1 + app/classes/models/server_stats.py | 1 + app/classes/models/servers.py | 1 + app/classes/models/users.py | 2 ++ app/classes/shared/command.py | 1 - app/classes/shared/helpers.py | 6 ------ app/classes/shared/import_helper.py | 1 - app/classes/shared/installer.py | 1 - app/classes/shared/main_controller.py | 1 - app/classes/shared/server.py | 8 -------- app/classes/shared/tasks.py | 1 - app/classes/web/default_handler.py | 1 - app/classes/web/public_handler.py | 4 ---- app/classes/web/routes/api/auth/login.py | 1 - app/classes/web/routes/api/servers/index.py | 1 - app/classes/web/server_handler.py | 1 - app/classes/web/tornado_handler.py | 2 -- app/classes/web/upload_handler.py | 2 -- app/classes/web/websocket_handler.py | 1 - 26 files changed, 8 insertions(+), 39 deletions(-) diff --git a/app/classes/controllers/servers_controller.py b/app/classes/controllers/servers_controller.py index 7914d4a1..46c64322 100644 --- a/app/classes/controllers/servers_controller.py +++ b/app/classes/controllers/servers_controller.py @@ -167,7 +167,6 @@ class ServersController(metaclass=Singleton): raise Exception(f"Unable to find server object for server id {server_id}") def init_all_servers(self): - servers = self.get_all_defined_servers() self.failed_servers = [] @@ -228,7 +227,6 @@ class ServersController(metaclass=Singleton): ) def check_server_loaded(self, server_id_to_check: int): - logger.info(f"Checking to see if we already registered {server_id_to_check}") for server in self.servers_list: diff --git a/app/classes/minecraft/mc_ping.py b/app/classes/minecraft/mc_ping.py index 1c52ab98..79610d8d 100644 --- a/app/classes/minecraft/mc_ping.py +++ b/app/classes/minecraft/mc_ping.py @@ -19,7 +19,6 @@ class Server: self.description = data.get("description") # print(self.description) if isinstance(self.description, dict): - # cat server if "translate" in self.description: self.description = self.description["translate"] diff --git a/app/classes/minecraft/serverjars.py b/app/classes/minecraft/serverjars.py index 3ecfdb8f..b70a8c40 100644 --- a/app/classes/minecraft/serverjars.py +++ b/app/classes/minecraft/serverjars.py @@ -104,7 +104,6 @@ class ServerJars: logger.error(f"Unable to update serverjars.com cache file: {e}") def refresh_cache(self): - cache_file = self.helper.serverjar_cache cache_old = self.helper.is_file_older_than_x_days(cache_file) diff --git a/app/classes/minecraft/stats.py b/app/classes/minecraft/stats.py index 07dd9c0d..8001b1d1 100644 --- a/app/classes/minecraft/stats.py +++ b/app/classes/minecraft/stats.py @@ -211,7 +211,6 @@ class Stats: @staticmethod def get_world_size(server_path): - total_size = 0 total_size = Helpers.get_dir_size(server_path) @@ -221,7 +220,6 @@ class Stats: return level_total_size def get_server_players(self, server_id): - server = HelperServers.get_server_data_by_id(server_id) logger.info(f"Getting players for server {server}") @@ -295,7 +293,6 @@ class Stats: @staticmethod def parse_server_raknet_ping(ping_obj: object): - try: server_icon = base64.encodebytes(ping_obj["icon"]) except Exception as e: diff --git a/app/classes/models/crafty_permissions.py b/app/classes/models/crafty_permissions.py index 22383408..7430f332 100644 --- a/app/classes/models/crafty_permissions.py +++ b/app/classes/models/crafty_permissions.py @@ -15,6 +15,7 @@ from app.classes.shared.permission_helper import PermissionHelper logger = logging.getLogger(__name__) + # ********************************************************************************** # User_Crafty Class # ********************************************************************************** diff --git a/app/classes/models/management.py b/app/classes/models/management.py index ee1b378d..73a0d9f4 100644 --- a/app/classes/models/management.py +++ b/app/classes/models/management.py @@ -20,6 +20,7 @@ from app.classes.shared.main_models import DatabaseShortcuts logger = logging.getLogger(__name__) + # ********************************************************************************** # Audit_Log Class # ********************************************************************************** diff --git a/app/classes/models/roles.py b/app/classes/models/roles.py index 541f67e8..abc98735 100644 --- a/app/classes/models/roles.py +++ b/app/classes/models/roles.py @@ -15,6 +15,7 @@ from app.classes.shared.helpers import Helpers logger = logging.getLogger(__name__) + # ********************************************************************************** # Roles Class # ********************************************************************************** diff --git a/app/classes/models/server_permissions.py b/app/classes/models/server_permissions.py index 8844b3df..eb5e3f35 100644 --- a/app/classes/models/server_permissions.py +++ b/app/classes/models/server_permissions.py @@ -16,6 +16,7 @@ from app.classes.shared.permission_helper import PermissionHelper logger = logging.getLogger(__name__) + # ********************************************************************************** # Role Servers Class # ********************************************************************************** diff --git a/app/classes/models/server_stats.py b/app/classes/models/server_stats.py index ccb21879..14f85ad3 100644 --- a/app/classes/models/server_stats.py +++ b/app/classes/models/server_stats.py @@ -29,6 +29,7 @@ logger = logging.getLogger(__name__) peewee_logger = logging.getLogger("peewee") peewee_logger.setLevel(logging.INFO) + # ********************************************************************************** # Servers Stats Class # ********************************************************************************** diff --git a/app/classes/models/servers.py b/app/classes/models/servers.py index 96f606a9..a83fd0a2 100644 --- a/app/classes/models/servers.py +++ b/app/classes/models/servers.py @@ -15,6 +15,7 @@ from app.classes.models.base_model import BaseModel logger = logging.getLogger(__name__) + # ********************************************************************************** # Servers Model # ********************************************************************************** diff --git a/app/classes/models/users.py b/app/classes/models/users.py index 9b4805a3..496e8d2c 100644 --- a/app/classes/models/users.py +++ b/app/classes/models/users.py @@ -21,6 +21,7 @@ from app.classes.models.roles import Roles, HelperRoles logger = logging.getLogger(__name__) + # ********************************************************************************** # Users Class # ********************************************************************************** @@ -58,6 +59,7 @@ PUBLIC_USER_ATTRS: t.Final = [ "lang", # maybe remove? ] + # ********************************************************************************** # API Keys Class # ********************************************************************************** diff --git a/app/classes/shared/command.py b/app/classes/shared/command.py index 7e1e9456..26fdd2f0 100644 --- a/app/classes/shared/command.py +++ b/app/classes/shared/command.py @@ -58,7 +58,6 @@ class MainPrompt(cmd.Cmd): Console.info("Unknown migration command") def do_set_passwd(self, line): - try: username = str(line).lower() # If no user is found it returns None diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 5b8e7a9c..5ac92564 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -604,7 +604,6 @@ class Helpers: # open our file with open(file_name, "r", encoding="utf-8") as f: - # seek f.seek(0, 2) @@ -769,7 +768,6 @@ class Helpers: @staticmethod def get_file_contents(path: str, lines=100): - contents = "" if os.path.exists(path) and os.path.isfile(path): @@ -790,12 +788,10 @@ class Helpers: return False def create_session_file(self, ignore=False): - if ignore and os.path.exists(self.session_file): os.remove(self.session_file) if os.path.exists(self.session_file): - file_data = self.get_file_contents(self.session_file) try: data = json.loads(file_data) @@ -905,7 +901,6 @@ class Helpers: return False def create_self_signed_cert(self, cert_dir=None): - if cert_dir is None: cert_dir = os.path.join(self.config_dir, "web", "certs") @@ -1066,7 +1061,6 @@ class Helpers: return output def generate_dir(self, folder, output=""): - dir_list = [] unsorted_files = [] file_list = os.listdir(folder) diff --git a/app/classes/shared/import_helper.py b/app/classes/shared/import_helper.py index 88ee91fc..e3762aad 100644 --- a/app/classes/shared/import_helper.py +++ b/app/classes/shared/import_helper.py @@ -226,7 +226,6 @@ class ImportHelpers: download_thread.start() def download_threaded_bedrock_server(self, path, new_id): - # downloads zip from remote url try: bedrock_url = Helpers.get_latest_bedrock_url() diff --git a/app/classes/shared/installer.py b/app/classes/shared/installer.py index d82d2399..6e0cec77 100644 --- a/app/classes/shared/installer.py +++ b/app/classes/shared/installer.py @@ -10,7 +10,6 @@ class Install: ) def do_install(self): - # are we in a venv? if not self.is_venv(): print("Crafty Requires a venv to install") diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index da5ac5d2..ab582b09 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -942,7 +942,6 @@ class Controller: def remove_server(self, server_id, files): counter = 0 for server in self.servers.servers_list: - # if this is the droid... im mean server we are looking for... if str(server["server_id"]) == str(server_id): server_data = self.servers.get_server_data(server_id) diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index 03f39d23..423f4b7a 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -592,7 +592,6 @@ class ServerInstance: # We need to grab the exact forge version number. # We know we can find it here in the run.sh/bat script. try: - # Getting the forge version from the executable command version = re.findall( r"forge-([0-9\.]+)((?:)|(?:-([0-9\.]+)-[a-zA-Z]+)).jar", @@ -852,7 +851,6 @@ class ServerInstance: return True def crash_detected(self, name): - # clear the old scheduled watcher task self.server_scheduler.remove_job(f"c_{self.server_id}") # remove the stats polling job since server is stopped @@ -914,7 +912,6 @@ class ServerInstance: return self.process.pid if self.process is not None else None def detect_crash(self): - logger.info(f"Detecting possible crash for server: {self.name} ") running = self.check_running() @@ -937,7 +934,6 @@ class ServerInstance: self.stats_helper.sever_crashed() # if we haven't tried to restart more 3 or more times if self.restart_count <= 3: - # start the server if needed server_restarted = self.crash_detected(self.name) @@ -1463,7 +1459,6 @@ class ServerInstance: Console.critical("Can't broadcast server status to websocket") def get_servers_stats(self): - server_stats = {} logger.info("Getting Stats for Server " + self.name + " ...") @@ -1550,7 +1545,6 @@ class ServerInstance: return server_stats def get_server_players(self): - server = HelperServers.get_server_data_by_id(self.server_id) logger.info(f"Getting players for server {server}") @@ -1571,7 +1565,6 @@ class ServerInstance: return [] def get_raw_server_stats(self, server_id): - try: server = HelperServers.get_server_obj(server_id) except: @@ -1720,7 +1713,6 @@ class ServerInstance: return server_stats def record_server_stats(self): - server_stats = self.get_servers_stats() self.stats_helper.insert_server_stats(server_stats) diff --git a/app/classes/shared/tasks.py b/app/classes/shared/tasks.py index e96acd14..320d0829 100644 --- a/app/classes/shared/tasks.py +++ b/app/classes/shared/tasks.py @@ -672,7 +672,6 @@ class TasksManager: host_stats = HelpersManagement.get_latest_hosts_stats() while True: - if host_stats.get( "cpu_usage" ) != HelpersManagement.get_latest_hosts_stats().get( diff --git a/app/classes/web/default_handler.py b/app/classes/web/default_handler.py index dc5c79bb..f41878f1 100644 --- a/app/classes/web/default_handler.py +++ b/app/classes/web/default_handler.py @@ -6,7 +6,6 @@ logger = logging.getLogger(__name__) class DefaultHandler(BaseHandler): - # Override prepare() instead of get() to cover all possible HTTP methods. def prepare(self, page=None): # pylint: disable=arguments-differ if page is not None: diff --git a/app/classes/web/public_handler.py b/app/classes/web/public_handler.py index d5bff692..dad74881 100644 --- a/app/classes/web/public_handler.py +++ b/app/classes/web/public_handler.py @@ -10,7 +10,6 @@ logger = logging.getLogger(__name__) class PublicHandler(BaseHandler): def set_current_user(self, user_id: str = None): - expire_days = self.helper.get_setting("cookie_expire") # if helper comes back with false @@ -29,7 +28,6 @@ class PublicHandler(BaseHandler): # self.clear_cookie("user_data") def get(self, page=None): - error = bleach.clean(self.get_argument("error", "Invalid Login!")) error_msg = bleach.clean(self.get_argument("error_msg", "")) @@ -81,7 +79,6 @@ class PublicHandler(BaseHandler): ) def post(self, page=None): - error = bleach.clean(self.get_argument("error", "Invalid Login!")) error_msg = bleach.clean(self.get_argument("error_msg", "")) @@ -96,7 +93,6 @@ class PublicHandler(BaseHandler): page_data["query"] = self.request.query if page == "login": - next_page = "/login" if self.request.query: next_page = "/login?" + self.request.query diff --git a/app/classes/web/routes/api/auth/login.py b/app/classes/web/routes/api/auth/login.py index 8583dce5..84ae2815 100644 --- a/app/classes/web/routes/api/auth/login.py +++ b/app/classes/web/routes/api/auth/login.py @@ -26,7 +26,6 @@ login_schema = { class ApiAuthLoginHandler(BaseApiHandler): def post(self): - try: data = json.loads(self.request.body) except json.decoder.JSONDecodeError as e: diff --git a/app/classes/web/routes/api/servers/index.py b/app/classes/web/routes/api/servers/index.py index a68e845b..edfec8fc 100644 --- a/app/classes/web/routes/api/servers/index.py +++ b/app/classes/web/routes/api/servers/index.py @@ -631,7 +631,6 @@ class ApiServersIndexHandler(BaseApiHandler): self.finish_json(200, {"status": "ok", "data": auth_data[0]}) def post(self): - auth_data = self.authenticate_user() if not auth_data: return diff --git a/app/classes/web/server_handler.py b/app/classes/web/server_handler.py index da854cc5..722c38fd 100644 --- a/app/classes/web/server_handler.py +++ b/app/classes/web/server_handler.py @@ -552,7 +552,6 @@ class ServerHandler(BaseHandler): self.get_remote_ip(), ) else: - new_server_id = self.controller.create_bedrock_server( server_name, exec_user["user_id"], diff --git a/app/classes/web/tornado_handler.py b/app/classes/web/tornado_handler.py index d0413beb..d2b047d7 100644 --- a/app/classes/web/tornado_handler.py +++ b/app/classes/web/tornado_handler.py @@ -59,7 +59,6 @@ class Webserver: @staticmethod def log_function(handler): - info = { "Status_Code": handler.get_status(), "Method": handler.request.method, @@ -103,7 +102,6 @@ class Webserver: logger.debug("Applied asyncio patch") def run_tornado(self): - # let's verify we have an SSL cert self.helper.create_self_signed_cert() diff --git a/app/classes/web/upload_handler.py b/app/classes/web/upload_handler.py index 11e1c4b8..39752a35 100644 --- a/app/classes/web/upload_handler.py +++ b/app/classes/web/upload_handler.py @@ -18,7 +18,6 @@ logger = logging.getLogger(__name__) @tornado.web.stream_request_body class UploadHandler(BaseHandler): - # noinspection PyAttributeOutsideInit def initialize( self, @@ -173,7 +172,6 @@ class UploadHandler(BaseHandler): if not self.request.headers.get("X-Content-Type", None).startswith( "image/" ): - return self.finish_json( 415, { diff --git a/app/classes/web/websocket_handler.py b/app/classes/web/websocket_handler.py index 64648fd8..78b33951 100644 --- a/app/classes/web/websocket_handler.py +++ b/app/classes/web/websocket_handler.py @@ -79,7 +79,6 @@ class SocketHandler(tornado.websocket.WebSocketHandler): # pylint: disable=arguments-renamed @staticmethod def on_message(raw_message): - logger.debug(f"Got message from WebSocket connection {raw_message}") message = json.loads(raw_message) logger.debug(f"Event Type: {message['event']}, Data: {message['data']}")