diff --git a/.gitignore b/.gitignore index 02a40213..b7f2d2b3 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ env.bak/ venv.bak/ .idea/ +/imports/ /servers/ /backups/ /temp/ diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index 845b2886..20c8cbef 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -476,6 +476,12 @@ class AjaxHandler(BaseHandler): elif page == "unzip_server": path = self.get_argument("path", None) + if not path: + path = os.path.join( + self.controller.project_root, + "imports", + self.get_argument("file", ""), + ) if Helpers.check_file_exists(path): self.helper.unzip_server(path, exec_user["user_id"]) else: diff --git a/app/classes/web/upload_handler.py b/app/classes/web/upload_handler.py index 92892ed1..26f94a06 100644 --- a/app/classes/web/upload_handler.py +++ b/app/classes/web/upload_handler.py @@ -4,6 +4,7 @@ import time import tornado.web import tornado.options import tornado.httpserver +from app.classes.models.crafty_permissions import EnumPermissionsCrafty from app.classes.models.server_permissions import EnumPermissionsServer from app.classes.shared.console import Console @@ -33,115 +34,293 @@ class UploadHandler(BaseHandler): def prepare(self): # Class & Function Defination api_key, _token_data, exec_user = self.current_user - server_id = self.get_argument("server_id", None) - superuser = exec_user["superuser"] - if api_key is not None: - superuser = superuser and api_key.superuser - user_id = exec_user["user_id"] - stream_size_value = self.helper.get_setting("stream_size_GB") + self.upload_type = str(self.request.headers.get("X-Content-Upload-Type")) + print(self.upload_type) - max_streamed_size = (1024 * 1024 * 1024) * stream_size_value + if self.upload_type == "server_import": + superuser = exec_user["superuser"] + if api_key is not None: + superuser = superuser and api_key.superuser + user_id = exec_user["user_id"] + stream_size_value = self.helper.get_setting("stream_size_GB") - self.content_len = int(self.request.headers.get("Content-Length")) - if self.content_len > max_streamed_size: - logger.error( - f"User with ID {user_id} attempted to upload a file that" - f" exceeded the max body size." - ) - self.helper.websocket_helper.broadcast_user( - user_id, - "send_start_error", - { - "error": self.helper.translation.translate( - "error", - "fileTooLarge", - self.controller.users.get_user_lang_by_id(user_id), - ), - }, - ) - return - self.do_upload = True + max_streamed_size = (1024 * 1024 * 1024) * stream_size_value - if superuser: - exec_user_server_permissions = ( - self.controller.server_perms.list_defined_permissions() - ) - elif api_key is not None: - exec_user_server_permissions = ( - self.controller.server_perms.get_api_key_permissions_list( - api_key, server_id + self.content_len = int(self.request.headers.get("Content-Length")) + if self.content_len > max_streamed_size: + logger.error( + f"User with ID {user_id} attempted to upload a file that" + f" exceeded the max body size." ) - ) - else: - exec_user_server_permissions = ( - self.controller.server_perms.get_user_id_permissions_list( - exec_user["user_id"], server_id + self.helper.websocket_helper.broadcast_user( + user_id, + "send_start_error", + { + "error": self.helper.translation.translate( + "error", + "fileTooLarge", + self.controller.users.get_user_lang_by_id(user_id), + ), + }, ) - ) + return + self.do_upload = True - server_id = self.request.headers.get("X-ServerId", None) + if superuser: + exec_user_server_permissions = ( + self.controller.server_perms.list_defined_permissions() + ) + elif api_key is not None: + exec_user_server_permissions = ( + self.controller.crafty_perms.get_api_key_permissions_list(api_key) + ) + else: + exec_user_server_permissions = ( + self.controller.crafty_perms.get_crafty_permissions_list( + exec_user["user_id"] + ) + ) - if user_id is None: - logger.warning("User ID not found in upload handler call") - Console.warning("User ID not found in upload handler call") - self.do_upload = False + if user_id is None: + logger.warning("User ID not found in upload handler call") + Console.warning("User ID not found in upload handler call") + self.do_upload = False - if server_id is None: - logger.warning("Server ID not found in upload handler call") - Console.warning("Server ID not found in upload handler call") - self.do_upload = False + if ( + EnumPermissionsCrafty.SERVER_CREATION + not in exec_user_server_permissions + and not exec_user["superuser"] + ): + logger.warning( + f"User {user_id} tried to upload a server" " without permissions!" + ) + Console.warning( + f"User {user_id} tried to upload a server" " without permissions!" + ) + self.do_upload = False - if EnumPermissionsServer.FILES not in exec_user_server_permissions: - logger.warning( - f"User {user_id} tried to upload a file to " - f"{server_id} without permissions!" - ) - Console.warning( - f"User {user_id} tried to upload a file to " - f"{server_id} without permissions!" - ) - self.do_upload = False + path = os.path.join(self.controller.project_root, "imports") + # Delete existing files + if len(os.listdir(path)) > 0: + for item in os.listdir(): + try: + os.remove(os.path.join(path, item)) + except: + logger.debug("Could not delete file on user server upload") - path = self.request.headers.get("X-Path", None) - filename = self.request.headers.get("X-FileName", None) - full_path = os.path.join(path, filename) + self.helper.ensure_dir_exists(path) + filename = self.request.headers.get("X-FileName", None) + full_path = os.path.join(path, filename) - if not Helpers.in_path( - Helpers.get_os_understandable_path( - self.controller.servers.get_server_data_by_id(server_id)["path"] - ), - full_path, - ): - print( - user_id, - server_id, + if self.do_upload: + try: + self.f = open(full_path, "wb") + except Exception as e: + logger.error(f"Upload failed with error: {e}") + self.do_upload = False + # If max_body_size is not set, you cannot upload files > 100MB + self.request.connection.set_max_body_size(max_streamed_size) + + elif self.upload_type == "background": + superuser = exec_user["superuser"] + if api_key is not None: + superuser = superuser and api_key.superuser + user_id = exec_user["user_id"] + stream_size_value = self.helper.get_setting("stream_size_GB") + + max_streamed_size = (1024 * 1024 * 1024) * stream_size_value + + self.content_len = int(self.request.headers.get("Content-Length")) + if self.content_len > max_streamed_size: + logger.error( + f"User with ID {user_id} attempted to upload a file that" + f" exceeded the max body size." + ) + self.helper.websocket_helper.broadcast_user( + user_id, + "send_start_error", + { + "error": self.helper.translation.translate( + "error", + "fileTooLarge", + self.controller.users.get_user_lang_by_id(user_id), + ), + }, + ) + return + self.do_upload = True + + if superuser: + exec_user_server_permissions = ( + self.controller.server_perms.list_defined_permissions() + ) + elif api_key is not None: + exec_user_server_permissions = ( + self.controller.server_perms.get_api_key_permissions_list( + api_key, server_id + ) + ) + else: + exec_user_server_permissions = ( + self.controller.server_perms.get_user_id_permissions_list( + exec_user["user_id"], server_id + ) + ) + + server_id = self.request.headers.get("X-ServerId", None) + if server_id is None: + logger.warning("Server ID not found in upload handler call") + Console.warning("Server ID not found in upload handler call") + self.do_upload = False + + if user_id is None: + logger.warning("User ID not found in upload handler call") + Console.warning("User ID not found in upload handler call") + self.do_upload = False + + if EnumPermissionsServer.FILES not in exec_user_server_permissions: + logger.warning( + f"User {user_id} tried to upload a file to " + f"{server_id} without permissions!" + ) + Console.warning( + f"User {user_id} tried to upload a file to " + f"{server_id} without permissions!" + ) + self.do_upload = False + + path = self.request.headers.get("X-Path", None) + filename = self.request.headers.get("X-FileName", None) + full_path = os.path.join(path, filename) + + if not Helpers.in_path( Helpers.get_os_understandable_path( 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} " - f"but the path is not inside of the server!" - ) - Console.warning( - f"User {user_id} tried to upload a file to {server_id} " - f"but the path is not inside of the server!" - ) - self.do_upload = False - - if self.do_upload: - try: - self.f = open(full_path, "wb") - except Exception as e: - logger.error(f"Upload failed with error: {e}") + ): + logger.warning( + f"User {user_id} tried to upload a file to {server_id} " + f"but the path is not inside of the server!" + ) + Console.warning( + f"User {user_id} tried to upload a file to {server_id} " + f"but the path is not inside of the server!" + ) self.do_upload = False - # If max_body_size is not set, you cannot upload files > 100MB - self.request.connection.set_max_body_size(max_streamed_size) + + if self.do_upload: + try: + self.f = open(full_path, "wb") + except Exception as e: + logger.error(f"Upload failed with error: {e}") + self.do_upload = False + # If max_body_size is not set, you cannot upload files > 100MB + self.request.connection.set_max_body_size(max_streamed_size) + else: + server_id = self.get_argument("server_id", None) + superuser = exec_user["superuser"] + if api_key is not None: + superuser = superuser and api_key.superuser + user_id = exec_user["user_id"] + stream_size_value = self.helper.get_setting("stream_size_GB") + + max_streamed_size = (1024 * 1024 * 1024) * stream_size_value + + self.content_len = int(self.request.headers.get("Content-Length")) + if self.content_len > max_streamed_size: + logger.error( + f"User with ID {user_id} attempted to upload a file that" + f" exceeded the max body size." + ) + self.helper.websocket_helper.broadcast_user( + user_id, + "send_start_error", + { + "error": self.helper.translation.translate( + "error", + "fileTooLarge", + self.controller.users.get_user_lang_by_id(user_id), + ), + }, + ) + return + self.do_upload = True + + if superuser: + exec_user_server_permissions = ( + self.controller.server_perms.list_defined_permissions() + ) + elif api_key is not None: + exec_user_server_permissions = ( + self.controller.server_perms.get_api_key_permissions_list( + api_key, server_id + ) + ) + else: + exec_user_server_permissions = ( + self.controller.server_perms.get_user_id_permissions_list( + exec_user["user_id"], server_id + ) + ) + + server_id = self.request.headers.get("X-ServerId", None) + if server_id is None: + logger.warning("Server ID not found in upload handler call") + Console.warning("Server ID not found in upload handler call") + self.do_upload = False + + if user_id is None: + logger.warning("User ID not found in upload handler call") + Console.warning("User ID not found in upload handler call") + self.do_upload = False + + if EnumPermissionsServer.FILES not in exec_user_server_permissions: + logger.warning( + f"User {user_id} tried to upload a file to " + f"{server_id} without permissions!" + ) + Console.warning( + f"User {user_id} tried to upload a file to " + f"{server_id} without permissions!" + ) + self.do_upload = False + + path = self.request.headers.get("X-Path", None) + filename = self.request.headers.get("X-FileName", None) + full_path = os.path.join(path, filename) + + if not Helpers.in_path( + Helpers.get_os_understandable_path( + 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} " + f"but the path is not inside of the server!" + ) + Console.warning( + f"User {user_id} tried to upload a file to {server_id} " + f"but the path is not inside of the server!" + ) + self.do_upload = False + + if self.do_upload: + try: + self.f = open(full_path, "wb") + except Exception as e: + logger.error(f"Upload failed with error: {e}") + self.do_upload = False + # If max_body_size is not set, you cannot upload files > 100MB + self.request.connection.set_max_body_size(max_streamed_size) def post(self): logger.info("Upload completed") - files_left = int(self.request.headers.get("X-Files-Left", None)) + if self.upload_type == "server_files": + files_left = int(self.request.headers.get("X-Files-Left", None)) + else: + files_left = 0 if self.do_upload: time.sleep(5) diff --git a/app/frontend/templates/panel/server_files.html b/app/frontend/templates/panel/server_files.html index 800a55c3..ff7bf998 100644 --- a/app/frontend/templates/panel/server_files.html +++ b/app/frontend/templates/panel/server_files.html @@ -711,6 +711,7 @@ xmlHttpRequest.setRequestHeader('X-Content-Length', size); xmlHttpRequest.setRequestHeader('X-Content-Disposition', 'attachment; filename="' + fileName + '"'); xmlHttpRequest.setRequestHeader('X-Path', path); + xmlHttpRequest.setRequestHeader('X-Content-Upload-Type', 'server_files') xmlHttpRequest.setRequestHeader('X-Files-Left', left); xmlHttpRequest.setRequestHeader('X-FileName', fileName); xmlHttpRequest.setRequestHeader('X-ServerId', serverId); diff --git a/app/frontend/templates/server/wizard.html b/app/frontend/templates/server/wizard.html index 10b4d35a..481ab957 100644 --- a/app/frontend/templates/server/wizard.html +++ b/app/frontend/templates/server/wizard.html @@ -431,388 +431,614 @@

-
- +
+
+
+ +

{{ translate('serverWizard', 'uploadZip', data['lang']) }}

+
+

+ +

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

+
+
- - - - -{% end %} - -{% block js%} - - + + - + -{% end %} \ No newline at end of file + + {% end %} \ No newline at end of file diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index bd21b722..86f4db3f 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -502,6 +502,7 @@ "importServer": "Import an Existing Server", "importServerButton": "Import Server!", "importZip": "Import from a Zip File", + "uploadZip": "Upload Zip File For Server Import", "maxMem": "Maximum Memory", "minMem": "Minimum Memory", "myNewServer": "My New Server",