From 199c8a4fe6c92156e76f802632f43e44d5ba90d9 Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 8 Jan 2023 00:32:08 -0500 Subject: [PATCH 01/28] Fix local java server imports --- app/classes/web/server_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/classes/web/server_handler.py b/app/classes/web/server_handler.py index 62c549e5..1c0d5962 100644 --- a/app/classes/web/server_handler.py +++ b/app/classes/web/server_handler.py @@ -331,7 +331,7 @@ class ServerHandler(BaseHandler): return if import_type == "import_jar": - if not self.helper.is_subdir( + if self.helper.is_subdir( import_server_path, self.controller.project_root ): self.redirect( From 3c11f0120da11e436963f5458807c292db7f6d50 Mon Sep 17 00:00:00 2001 From: Silversthorn Date: Tue, 10 Jan 2023 00:53:47 +0100 Subject: [PATCH 02/28] Rework panel config for login page --- .../templates/panel/panel_config.html | 144 +++++++++++------- app/translations/en_EN.json | 2 + 2 files changed, 88 insertions(+), 58 deletions(-) diff --git a/app/frontend/templates/panel/panel_config.html b/app/frontend/templates/panel/panel_config.html index a4ee9f66..050ea9b4 100644 --- a/app/frontend/templates/panel/panel_config.html +++ b/app/frontend/templates/panel/panel_config.html @@ -34,8 +34,8 @@ }} {% if data['user_data']['hints'] %} + data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}" , + data-placement="top"> {% end %}
  {{ @@ -134,8 +134,8 @@ data['lang']) }} {% if data['user_data']['hints'] %} + data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}" , + data-placement="top"> {% end %}
  {{ translate('panelConfig', 'newRole', data['lang']) }}
@@ -230,64 +230,77 @@
-
+
+
+

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

+
- -

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

-
-

- -

- {% raw xsrf_form_html() %} - - -
-
- -
-
-
- - - - -
+
+
+

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

+
+ + {% raw xsrf_form_html() %} + +
+
+
+ +
+ +
+
+

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

+
+ + +
+
+
+
+
{{ translate('panelConfig', 'preview', data['lang']) }}:
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+ Responsive image +
+ + +
+
-
- -

-
-
-
-
-
-

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




-
- -
-
-
{{ translate('panelConfig', 'preview', data['lang']) }}:
- -
-
-
- - -
+
@@ -404,10 +417,25 @@ }); }) + function updateBackgroundSelect() { + $("#photo").val($("#try_photo").val()).change(); + } + + function updateBackgroundPreview() { + var img = document.getElementById('bg-preview'); + if ($("#photo").val() == "login_1.jpg") { + var src_path = "../../static/assets/images/auth/".concat($("#photo").val()); + } + else { + var src_path = "../../static/assets/images/auth/custom/".concat($("#photo").val()); + } + img.src = src_path; + } + var file; function sendFile() { file = $("#file")[0].files[0] - document.getElementById("upload_input").innerHTML = '
 
' + document.getElementById("upload_input").innerHTML = '
 
'; let xmlHttpRequest = new XMLHttpRequest(); let token = getCookie("_xsrf") let fileName = file.name diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 49271004..df422c79 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -228,9 +228,11 @@ "superConfirmTitle": "Enable superuser? Are you sure?", "user": "User", "users": "Users", + "customLoginPage": "Customise the Login Page", "loginImage": "Upload a background image for the login screen.", "backgroundUpload": "Background Upload", "loginBackground": "Login Background Image", + "loginOpacity": "Select the Login Window Opacity", "select": "Select", "selectImage": "Select an image", "preview": "Preview" From 944d01ab1981740c078dd8dd2d67400bfd53dd59 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 16 Jan 2023 11:20:15 -0500 Subject: [PATCH 03/28] Fix schedule restores --- app/classes/controllers/management_controller.py | 10 +++++++++- app/classes/web/ajax_handler.py | 11 ++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/classes/controllers/management_controller.py b/app/classes/controllers/management_controller.py index 47860fe1..e1b4d8da 100644 --- a/app/classes/controllers/management_controller.py +++ b/app/classes/controllers/management_controller.py @@ -78,6 +78,10 @@ class ManagementController: command, name, enabled=True, + one_time=False, + cron_string="* * * * *", + parent=None, + delay=0, ): return HelpersManagement.create_scheduled_task( server_id, @@ -87,7 +91,11 @@ class ManagementController: start_time, command, name, - enabled, + enabled=True, + one_time=False, + cron_string="* * * * *", + parent=None, + delay=0, ) @staticmethod diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index cdd67146..0428410f 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -440,15 +440,8 @@ class AjaxHandler(BaseHandler): for schedule in self.controller.management.get_schedules_by_server( server_id ): - self.controller.management.create_scheduled_task( - new_server_id, - schedule.action, - schedule.interval, - schedule.interval_type, - schedule.start_time, - schedule.command, - schedule.name, - schedule.enabled, + self.tasks_manager.update_job( + schedule.schedule_id, {"server_id": new_server_id} ) # preserve execution command new_server_obj = self.controller.servers.get_server_obj( From 1802a7e7ef3a49340aaa13c0cd1303d8b99a1728 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 16 Jan 2023 14:15:45 -0500 Subject: [PATCH 04/28] Add backup preservation Add update job to bedrock --- app/classes/web/ajax_handler.py | 59 ++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index 0428410f..e311cc91 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -449,6 +449,30 @@ class AjaxHandler(BaseHandler): ) new_server_obj.execution_command = server_data["execution_command"] self.controller.servers.update_server(new_server_obj) + + # preserve backup config + backup_config = self.controller.management.get_backup_config( + server_id + ) + excluded_dirs = [] + server_obj = self.controller.servers.get_server_obj(server_id) + loop_backup_path = self.helper.wtol_path(server_obj.path) + for item in self.controller.management.get_excluded_backup_dirs( + server_id + ): + item_path = self.helper.wtol_path(item) + bu_path = os.path.relpath(item_path, loop_backup_path) + bu_path = os.path.join(new_server_obj.path, bu_path) + print(bu_path) + excluded_dirs.append(bu_path) + self.controller.management.set_backup_config( + new_server_id, + new_server_obj.backup_path, + backup_config["max_backups"], + excluded_dirs, + backup_config["compress"], + backup_config["shutdown"], + ) # remove old server's tasks try: self.tasks_manager.remove_all_server_tasks(server_id) @@ -477,15 +501,8 @@ class AjaxHandler(BaseHandler): for schedule in self.controller.management.get_schedules_by_server( server_id ): - self.controller.management.create_scheduled_task( - new_server_id, - schedule.action, - schedule.interval, - schedule.interval_type, - schedule.start_time, - schedule.command, - schedule.name, - schedule.enabled, + self.tasks_manager.update_job( + schedule.schedule_id, {"server_id": new_server_id} ) # preserve execution command new_server_obj = self.controller.servers.get_server_obj( @@ -493,6 +510,30 @@ class AjaxHandler(BaseHandler): ) new_server_obj.execution_command = server_data["execution_command"] self.controller.servers.update_server(new_server_obj) + + # preserve backup config + backup_config = self.controller.management.get_backup_config( + server_id + ) + excluded_dirs = [] + server_obj = self.controller.servers.get_server_obj(server_id) + loop_backup_path = self.helper.wtol_path(server_obj.path) + for item in self.controller.management.get_excluded_backup_dirs( + server_id + ): + item_path = self.helper.wtol_path(item) + bu_path = os.path.relpath(item_path, loop_backup_path) + bu_path = os.path.join(new_server_obj.path, bu_path) + print(bu_path) + excluded_dirs.append(bu_path) + self.controller.management.set_backup_config( + new_server_id, + new_server_obj.backup_path, + backup_config["max_backups"], + excluded_dirs, + backup_config["compress"], + backup_config["shutdown"], + ) try: self.tasks_manager.remove_all_server_tasks(server_id) except: From 2e25ed84c5cb3965a7917a26ea4ae075505ed2fa Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 16 Jan 2023 14:30:55 -0500 Subject: [PATCH 05/28] Remove print statements --- app/classes/web/ajax_handler.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index e311cc91..82be1fb6 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -463,7 +463,6 @@ class AjaxHandler(BaseHandler): item_path = self.helper.wtol_path(item) bu_path = os.path.relpath(item_path, loop_backup_path) bu_path = os.path.join(new_server_obj.path, bu_path) - print(bu_path) excluded_dirs.append(bu_path) self.controller.management.set_backup_config( new_server_id, @@ -524,7 +523,6 @@ class AjaxHandler(BaseHandler): item_path = self.helper.wtol_path(item) bu_path = os.path.relpath(item_path, loop_backup_path) bu_path = os.path.join(new_server_obj.path, bu_path) - print(bu_path) excluded_dirs.append(bu_path) self.controller.management.set_backup_config( new_server_id, From ede865bf332b2975c41774d11a2baa540c6a09cb Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 16 Jan 2023 15:16:43 -0500 Subject: [PATCH 06/28] Appease the linter and fix stinky code --- app/classes/controllers/management_controller.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/classes/controllers/management_controller.py b/app/classes/controllers/management_controller.py index e1b4d8da..0a1701e3 100644 --- a/app/classes/controllers/management_controller.py +++ b/app/classes/controllers/management_controller.py @@ -91,11 +91,11 @@ class ManagementController: start_time, command, name, - enabled=True, - one_time=False, - cron_string="* * * * *", - parent=None, - delay=0, + enabled, + one_time, + cron_string, + parent, + delay, ) @staticmethod From 6dfabab4afa9950e14b288ec6500111f078e232e Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 17 Jan 2023 10:27:55 -0500 Subject: [PATCH 07/28] Set backup filename to use same time as schedule --- app/classes/shared/server.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index 745d840d..3f726aab 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -131,13 +131,13 @@ class ServerInstance: self.stats_helper = HelperServerStats(self.server_id) self.last_backup_failed = False try: - tz = get_localzone() + self.tz = get_localzone() except ZoneInfoNotFoundError: logger.error( "Could not capture time zone from system. Falling back to Europe/London" ) - tz = "Europe/London" - self.server_scheduler = BackgroundScheduler(timezone=str(tz)) + self.tz = "Europe/London" + self.server_scheduler = BackgroundScheduler(timezone=str(self.tz)) self.server_scheduler.start() self.backup_thread = threading.Thread( target=self.a_backup_server, daemon=True, name=f"backup_{self.name}" @@ -1037,7 +1037,7 @@ class ServerInstance: try: backup_filename = ( f"{self.settings['backup_path']}/" - f"{datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}" + f"{datetime.datetime.now().astimezone(self.tz).strftime('%Y-%m-%d_%H-%M-%S')}" # pylint: disable=line-too-long ) logger.info( f"Creating backup of server '{self.settings['server_name']}'" From 7984ca8157fce96e9d29ffd8a7aa57dee9b203d3 Mon Sep 17 00:00:00 2001 From: Silversthorn Date: Tue, 17 Jan 2023 20:40:16 +0100 Subject: [PATCH 08/28] Add Personalized Transparency for Login Page's Form --- .../controllers/management_controller.py | 27 ++-- app/classes/models/management.py | 17 +++ app/classes/web/ajax_handler.py | 2 + app/classes/web/panel_handler.py | 4 + app/classes/web/public_handler.py | 1 + .../templates/panel/panel_config.html | 127 ++++++++++++++++-- app/frontend/templates/public/login.html | 20 ++- .../20230111_adding_login_opacity.py | 18 +++ app/translations/en_EN.json | 1 + 9 files changed, 191 insertions(+), 26 deletions(-) create mode 100644 app/migrations/20230111_adding_login_opacity.py diff --git a/app/classes/controllers/management_controller.py b/app/classes/controllers/management_controller.py index 47860fe1..7e7a38b0 100644 --- a/app/classes/controllers/management_controller.py +++ b/app/classes/controllers/management_controller.py @@ -10,6 +10,25 @@ class ManagementController: def __init__(self, management_helper): self.management_helper = management_helper + # ********************************************************************************** + # Config Methods + # ********************************************************************************** + @staticmethod + def set_login_image(path): + HelpersManagement.set_login_image(path) + + @staticmethod + def get_login_image(): + return HelpersManagement.get_login_image() + + @staticmethod + def set_login_opacity(opacity): + return HelpersManagement.set_login_opacity(opacity) + + @staticmethod + def get_login_opacity(): + return HelpersManagement.get_login_opacity() + # ********************************************************************************** # Host_Stats Methods # ********************************************************************************** @@ -94,14 +113,6 @@ class ManagementController: def delete_scheduled_task(schedule_id): return HelpersManagement.delete_scheduled_task(schedule_id) - @staticmethod - def set_login_image(path): - HelpersManagement.set_login_image(path) - - @staticmethod - def get_login_image(): - return HelpersManagement.get_login_image() - @staticmethod def update_scheduled_task(schedule_id, updates): return HelpersManagement.update_scheduled_task(schedule_id, updates) diff --git a/app/classes/models/management.py b/app/classes/models/management.py index 55c86bb7..7eab07a3 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") + login_opacity = IntegerField(default=100) class Meta: table_name = "crafty_settings" @@ -255,6 +256,9 @@ class HelpersManagement: ) return settings[0].secret_api_key + # ********************************************************************************** + # Config Methods + # ********************************************************************************** @staticmethod def get_login_image(): settings = CraftySettings.select(CraftySettings.login_photo).where( @@ -268,6 +272,19 @@ class HelpersManagement: CraftySettings.id == 1 ).execute() + @staticmethod + def get_login_opacity(): + settings = CraftySettings.select(CraftySettings.login_opacity).where( + CraftySettings.id == 1 + ) + return settings[0].login_opacity + + @staticmethod + def set_login_opacity(opacity): + CraftySettings.update({CraftySettings.login_opacity: opacity}).where( + CraftySettings.id == 1 + ).execute() + # ********************************************************************************** # Schedules Methods # ********************************************************************************** diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index cdd67146..2ce94b1b 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -356,6 +356,8 @@ class AjaxHandler(BaseHandler): elif page == "select_photo": if exec_user["superuser"]: photo = self.get_argument("photo", None) + opacity = self.get_argument("opacity", 100) + self.controller.management.set_login_opacity(int(opacity)) if photo == "login_1.jpg": self.controller.management.set_login_image("login_1.jpg") self.controller.cached_login = f"{photo}" diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 582517db..0e61f640 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -291,6 +291,7 @@ class PanelHandler(BaseHandler): # todo: make this actually pull and compare version data "update_available": self.helper.update_available, "background": self.controller.cached_login, + "login_opacity": self.controller.management.get_login_opacity(), "serverTZ": tz, "version_data": self.helper.get_version_string(), "failed_servers": self.controller.servers.failed_servers, @@ -883,6 +884,9 @@ class PanelHandler(BaseHandler): if item not in page_data["backgrounds"]: page_data["backgrounds"].append(item) page_data["background"] = self.controller.cached_login + page_data[ + "login_opacity" + ] = self.controller.management.get_login_opacity() else: page_data["managed_users"] = self.controller.users.get_managed_users( exec_user["user_id"] diff --git a/app/classes/web/public_handler.py b/app/classes/web/public_handler.py index 7f3f0c26..846402c3 100644 --- a/app/classes/web/public_handler.py +++ b/app/classes/web/public_handler.py @@ -40,6 +40,7 @@ class PublicHandler(BaseHandler): "lang_page": self.helper.get_lang_page(self.helper.get_setting("language")), "query": "", "background": self.controller.cached_login, + "login_opacity": self.controller.management.get_login_opacity(), } if self.request.query: diff --git a/app/frontend/templates/panel/panel_config.html b/app/frontend/templates/panel/panel_config.html index 050ea9b4..019c8009 100644 --- a/app/frontend/templates/panel/panel_config.html +++ b/app/frontend/templates/panel/panel_config.html @@ -237,16 +237,16 @@
-
+

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


-
+ {% raw xsrf_form_html() %} -
+
-
+
@@ -264,10 +264,10 @@ 'delete', data['lang']) }}
-
+
{{ translate('panelConfig', 'preview', data['lang']) }}:
-
+
@@ -286,16 +286,106 @@
-
- + +
+ +
+
+
+ Responsive image +
+
- Responsive image
+ 'apply', data['lang']) }} + 'cancel', data['lang']) }}
@@ -407,16 +497,29 @@ $('.select-photo').click(function () { var token = getCookie("_xsrf") let photo = $('#photo').find(":selected").val(); + let opacity = $('#modal_opacity').val(); $.ajax({ type: "POST", headers: { 'X-XSRFToken': token }, - url: '/ajax/select_photo?photo=' + photo, + url: '/ajax/select_photo?photo=' + photo + '&opacity=' + opacity, success: function (data) { window.location.reload(); }, }); }) + $(document).ready(function () { + let opacity = parseInt($("#modal_opacity").val()); + document.getElementById('login-form-background').style.background = 'rgb(34, 36, 55, ' + (opacity / 100) + ')'; + }); + + function previewOpacity() { + let opacity = parseInt($("#modal_opacity").val()) + console.debug("Selected Opacity = " + opacity + "%"); + document.getElementById('opacityValue').innerHTML = (opacity) + "%"; + document.getElementById('login-form-background').style.background = 'rgb(34, 36, 55, ' + (opacity / 100) + ')'; + } + function updateBackgroundSelect() { $("#photo").val($("#try_photo").val()).change(); } diff --git a/app/frontend/templates/public/login.html b/app/frontend/templates/public/login.html index e172a9a8..3974e539 100644 --- a/app/frontend/templates/public/login.html +++ b/app/frontend/templates/public/login.html @@ -36,8 +36,9 @@
-