From 0d664cfae504edb0fc7e3b5cc92dcfda2441ff59 Mon Sep 17 00:00:00 2001 From: luukas Date: Tue, 14 Jun 2022 00:16:49 +0300 Subject: [PATCH 01/14] Remove a useless session.log warning This fixes an error being sent when session.log doesn't exist. This usually occurs when the logs directory is deleted. --- app/classes/shared/helpers.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index e99a73c3..bb6ca9fe 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -1,3 +1,4 @@ +import contextlib import os import re import sys @@ -491,9 +492,10 @@ class Helpers: # del any old session.lock file as this is a new session try: - os.remove(session_log_file) + with contextlib.suppress(FileNotFoundError): + os.remove(session_log_file) except Exception as e: - logger.error(f"Deleting Session.lock failed with error: {e}") + Console.error(f"Deleting Session.lock failed with error: {e}") @staticmethod def get_time_as_string(): From 73a6d1cd78c50b4e41a8c3296e7ef4cbde15f0fc Mon Sep 17 00:00:00 2001 From: luukas Date: Tue, 14 Jun 2022 00:30:28 +0300 Subject: [PATCH 02/14] Fix the error message while deleting session.log --- app/classes/shared/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index bb6ca9fe..0d0e7fd2 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -495,7 +495,7 @@ class Helpers: with contextlib.suppress(FileNotFoundError): os.remove(session_log_file) except Exception as e: - Console.error(f"Deleting Session.lock failed with error: {e}") + Console.error(f"Deleting logs/session.log failed with error: {e}") @staticmethod def get_time_as_string(): From 2b0900d95b3f097b26698be7c4e883f589aa55dd Mon Sep 17 00:00:00 2001 From: Analicia A Date: Mon, 13 Jun 2022 21:40:45 +0000 Subject: [PATCH 03/14] Correct translation - Dutch - added a space between two words --- app/translations/nl_NL.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/translations/nl_NL.json b/app/translations/nl_NL.json index 0e94d1cc..82f2f204 100644 --- a/app/translations/nl_NL.json +++ b/app/translations/nl_NL.json @@ -450,7 +450,7 @@ "absoluteZipPath": "Absoluut pad naar de server", "addRole": "Server toevoegen aan bestaande rol(len)", "autoCreate": "Als er niks is geselecteerd maakt Crafty er één.", - "bePatient": "Wees geduldig, we' + (importing ? 'importeren' : 'downloaden') + ' de server", + "bePatient": "Wees geduldig, we ' + (importing ? 'importeren' : 'downloaden') + ' de server", "buildServer": "Maak server!", "clickRoot": "Klik hier om je root-map te selecteren", "close": "Sluiten", From 034af1b10cbda910e2454750e6a2dbff895bf60c Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 14 Jun 2022 12:08:34 +0100 Subject: [PATCH 04/14] Remove no-else pylint excemptions --- .pylintrc | 3 --- 1 file changed, 3 deletions(-) diff --git a/.pylintrc b/.pylintrc index 89cad4e0..d9913e68 100644 --- a/.pylintrc +++ b/.pylintrc @@ -97,9 +97,6 @@ disable=abstract-method, logging-fstring-interpolation, logging-not-lazy, missing-docstring, - no-else-break, - no-else-continue, - no-else-return, no-value-for-parameter, not-an-iterable, protected-access, From e73dd682c8f224c66b41bfc113b246df1222bd63 Mon Sep 17 00:00:00 2001 From: luukas Date: Tue, 14 Jun 2022 15:40:57 +0300 Subject: [PATCH 05/14] Fix no-else-* QA warnings --- app/classes/controllers/roles_controller.py | 7 +- app/classes/controllers/users_controller.py | 2 +- app/classes/minecraft/bedrock_ping.py | 3 +- app/classes/minecraft/mc_ping.py | 14 +- app/classes/minecraft/server_props.py | 3 +- app/classes/minecraft/stats.py | 14 +- app/classes/models/crafty_permissions.py | 25 ++- app/classes/models/server_permissions.py | 41 +++-- app/classes/models/users.py | 5 +- app/classes/shared/authentication.py | 3 +- app/classes/shared/helpers.py | 50 ++---- app/classes/shared/server.py | 99 +++++------ app/classes/shared/translation.py | 4 +- app/classes/web/ajax_handler.py | 27 ++- app/classes/web/api_handler.py | 9 +- app/classes/web/base_handler.py | 13 +- app/classes/web/file_handler.py | 51 +++--- app/classes/web/panel_handler.py | 182 +++++++++----------- 18 files changed, 227 insertions(+), 325 deletions(-) diff --git a/app/classes/controllers/roles_controller.py b/app/classes/controllers/roles_controller.py index dbd58578..5e7925a3 100644 --- a/app/classes/controllers/roles_controller.py +++ b/app/classes/controllers/roles_controller.py @@ -40,7 +40,7 @@ class RolesController: for key in role_data: if key == "role_id": continue - elif key == "servers": + if key == "servers": added_servers = set(role_data["servers"]).difference( set(base_data["servers"]) ) @@ -175,6 +175,5 @@ class RolesController: role["servers"] = server_ids # logger.debug("role: ({}) {}".format(role_id, role)) return role - else: - # logger.debug("role: ({}) {}".format(role_id, {})) - return {} + # logger.debug("role: ({}) {}".format(role_id, {})) + return {} diff --git a/app/classes/controllers/users_controller.py b/app/classes/controllers/users_controller.py index 8874804e..bc5656a9 100644 --- a/app/classes/controllers/users_controller.py +++ b/app/classes/controllers/users_controller.py @@ -140,7 +140,7 @@ class UsersController: for key in user_data: if key == "user_id": continue - elif key == "roles": + if key == "roles": added_roles = set(user_data["roles"]).difference( set(base_data["roles"]) ) diff --git a/app/classes/minecraft/bedrock_ping.py b/app/classes/minecraft/bedrock_ping.py index d2be6449..54784112 100644 --- a/app/classes/minecraft/bedrock_ping.py +++ b/app/classes/minecraft/bedrock_ping.py @@ -120,8 +120,7 @@ class BedrockPing: ret["server_port_ipv4"] = server_info[10] ret["server_port_ipv6"] = server_info[11] return ret - else: - raise ValueError(f"Incorrect packet type ({data[0]} detected") + raise ValueError(f"Incorrect packet type ({data[0]} detected") def ping(self, retries=3): rtr = retries diff --git a/app/classes/minecraft/mc_ping.py b/app/classes/minecraft/mc_ping.py index 1693ca41..edc28325 100644 --- a/app/classes/minecraft/mc_ping.py +++ b/app/classes/minecraft/mc_ping.py @@ -104,12 +104,9 @@ def get_code_format(format_name): if format_name in data.keys(): return data.get(format_name) - else: - logger.error(f"Format MOTD Error: format name {format_name} does not exist") - Console.error( - f"Format MOTD Error: format name {format_name} does not exist" - ) - return "" + logger.error(f"Format MOTD Error: format name {format_name} does not exist") + Console.error(f"Format MOTD Error: format name {format_name} does not exist") + return "" except Exception as e: logger.critical(f"Config File Error: Unable to read {format_file} due to {e}") @@ -154,10 +151,7 @@ def ping(ip, port): sock.sendall(data + b"\x01\x00") # handshake + status ping length = read_var_int() # full packet length if length < 10: - if length < 0: - return False - else: - return False + return not length < 0 sock.recv(1) # packet type, 0 for pings length = read_var_int() # string length diff --git a/app/classes/minecraft/server_props.py b/app/classes/minecraft/server_props.py index 834810e8..cc54a148 100644 --- a/app/classes/minecraft/server_props.py +++ b/app/classes/minecraft/server_props.py @@ -43,8 +43,7 @@ class ServerProps: if key in self.props.keys(): self.props[key] = val return True - else: - return False + return False def save(self): # Writes to the new file diff --git a/app/classes/minecraft/stats.py b/app/classes/minecraft/stats.py index 28564945..d309e023 100644 --- a/app/classes/minecraft/stats.py +++ b/app/classes/minecraft/stats.py @@ -134,10 +134,8 @@ class Stats: @staticmethod def _get_process_stats(process): if process is None: - process_stats = {"cpu_usage": 0, "memory_usage": 0, "mem_percentage": 0} - return process_stats - else: - process_pid = process.pid + return {"cpu_usage": 0, "memory_usage": 0, "mem_percentage": 0} + process_pid = process.pid try: p = psutil.Process(process_pid) dummy = p.cpu_percent() @@ -162,13 +160,7 @@ class Stats: logger.error( f"Unable to get process details for pid: {process_pid} Error: {e}" ) - - # Dummy Data - process_stats = { - "cpu_usage": 0, - "memory_usage": 0, - } - return process_stats + return {"cpu_usage": 0, "memory_usage": 0, "mem_percentage": 0} @staticmethod def _try_all_disk_usage(): diff --git a/app/classes/models/crafty_permissions.py b/app/classes/models/crafty_permissions.py index 8e61670f..9b99bfb0 100644 --- a/app/classes/models/crafty_permissions.py +++ b/app/classes/models/crafty_permissions.py @@ -213,18 +213,17 @@ class PermissionsCrafty: user = HelperUsers.get_user(key.user_id) if user["superuser"] and key.superuser: return PermissionsCrafty.get_permissions_list() + if user["superuser"]: + # User is superuser but API key isn't + user_permissions_mask = "111" else: - if user["superuser"]: - # User is superuser but API key isn't - user_permissions_mask = "111" - else: - # Not superuser - user_permissions_mask = PermissionsCrafty.get_crafty_permissions_mask( - user["user_id"] - ) - key_permissions_mask: str = key.crafty_permissions - permissions_mask = PermissionHelper.combine_masks( - user_permissions_mask, key_permissions_mask + # Not superuser + user_permissions_mask = PermissionsCrafty.get_crafty_permissions_mask( + user["user_id"] ) - permissions_list = PermissionsCrafty.get_permissions(permissions_mask) - return permissions_list + key_permissions_mask: str = key.crafty_permissions + permissions_mask = PermissionHelper.combine_masks( + user_permissions_mask, key_permissions_mask + ) + permissions_list = PermissionsCrafty.get_permissions(permissions_mask) + return permissions_list diff --git a/app/classes/models/server_permissions.py b/app/classes/models/server_permissions.py index 529e279d..8844b3df 100644 --- a/app/classes/models/server_permissions.py +++ b/app/classes/models/server_permissions.py @@ -265,24 +265,23 @@ class PermissionsServers: user = HelperUsers.get_user(key.user_id) if user["superuser"] and key.superuser: return PermissionsServers.get_permissions_list() - else: - roles_list = HelperUsers.get_user_roles_id(user["user_id"]) - role_server = ( - RoleServers.select() - .where(RoleServers.role_id.in_(roles_list)) - .where(RoleServers.server_id == server_id) - .execute() - ) - try: - user_permissions_mask = role_server[0].permissions - except: - if user["superuser"]: - user_permissions_mask = "11111111" - else: - user_permissions_mask = "00000000" - key_permissions_mask = key.server_permissions - permissions_mask = PermissionHelper.combine_masks( - user_permissions_mask, key_permissions_mask - ) - permissions_list = PermissionsServers.get_permissions(permissions_mask) - return permissions_list + roles_list = HelperUsers.get_user_roles_id(user["user_id"]) + role_server = ( + RoleServers.select() + .where(RoleServers.role_id.in_(roles_list)) + .where(RoleServers.server_id == server_id) + .execute() + ) + try: + user_permissions_mask = role_server[0].permissions + except: + if user["superuser"]: + user_permissions_mask = "11111111" + else: + user_permissions_mask = "00000000" + key_permissions_mask = key.server_permissions + permissions_mask = PermissionHelper.combine_masks( + user_permissions_mask, key_permissions_mask + ) + permissions_list = PermissionsServers.get_permissions(permissions_mask) + return permissions_list diff --git a/app/classes/models/users.py b/app/classes/models/users.py index 8d5d9d52..ca27caac 100644 --- a/app/classes/models/users.py +++ b/app/classes/models/users.py @@ -148,9 +148,8 @@ class HelperUsers: # I know it should apply it without setting it but I'm just making sure user = HelperUsers.add_user_roles(user) return user - else: - # logger.debug("user: ({}) {}".format(user_id, {})) - return {} + # logger.debug("user: ({}) {}".format(user_id, {})) + return {} @staticmethod def get_user_columns( diff --git a/app/classes/shared/authentication.py b/app/classes/shared/authentication.py index 3596ae9e..330a8883 100644 --- a/app/classes/shared/authentication.py +++ b/app/classes/shared/authentication.py @@ -62,8 +62,7 @@ class Authentication: if int(user.get("valid_tokens_from").timestamp()) < iat: # Success! return key, data, user - else: - return None + return None def check_err( self, diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 0d0e7fd2..4c5a3daa 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -94,10 +94,7 @@ class Helpers: if Helpers.check_file_exists(file): file_time = os.path.getmtime(file) # Check against 24 hours - if (time.time() - file_time) / 3600 > 24 * days: - return True - else: - return False + return (time.time() - file_time) / 3600 > 24 * days logger.error(f"{file} does not exist") return True @@ -126,10 +123,7 @@ class Helpers: a_socket.close() - if result_of_check == 0: - return True - else: - return False + return result_of_check == 0 @staticmethod def check_server_conn(server_port): @@ -141,10 +135,7 @@ class Helpers: result_of_check = a_socket.connect_ex(location) a_socket.close() - if result_of_check == 0: - return True - else: - return False + return result_of_check == 0 @staticmethod def cmdparse(cmd_in): @@ -164,10 +155,9 @@ class Helpers: # Continue the loop. if char == " ": continue - else: - cmd_index += 1 - cmd_out.append("") - new_param = False + cmd_index += 1 + cmd_out.append("") + new_param = False if esc: # if we encountered an escape character on the last loop, # append this char regardless of what it is if char not in Helpers.allowed_quotes: @@ -349,8 +339,7 @@ class Helpers: common_path = pathlib.Path(os.path.commonpath([base, fileabs])) if base == common_path: return fileabs - else: - raise ValueError("Path traversal detected") + raise ValueError("Path traversal detected") @staticmethod def tail_file(file_name, number_lines=20): @@ -406,15 +395,8 @@ class Helpers: @staticmethod def check_root(): if Helpers.is_os_windows(): - if ctypes.windll.shell32.IsUserAnAdmin() == 1: - return True - else: - return False - else: - if os.geteuid() == 0: - return True - else: - return False + return ctypes.windll.shell32.IsUserAnAdmin() == 1 + return os.geteuid() == 0 @staticmethod def unzip_file(zip_path): @@ -531,8 +513,7 @@ class Helpers: if os.path.exists(path) and os.path.isfile(path): logger.debug(f"Found path: {path}") return True - else: - return False + return False @staticmethod def human_readable_file_size(num: int, suffix="B"): @@ -553,8 +534,7 @@ class Helpers: if os.path.exists(path): logger.debug(f"Found path: {path}") return True - else: - return False + return False @staticmethod def get_file_contents(path: str, lines=100): @@ -770,10 +750,7 @@ class Helpers: @staticmethod def is_os_windows(): - if os.name == "nt": - return True - else: - return False + return os.name == "nt" @staticmethod def wtol_path(w_path): @@ -948,8 +925,7 @@ class Helpers: # extracts archive to temp directory zip_ref.extractall(temp_dir) return temp_dir - else: - return False + return False @staticmethod def in_path(parent_path, child_path): diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index d69f2fa4..292feb08 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -409,10 +409,9 @@ class ServerInstance: }, ) return False - else: - logger.error( - f"Server {self.name} failed to start with error code: {ex}" - ) + logger.error( + f"Server {self.name} failed to start with error code: {ex}" + ) if user_id: self.helper.websocket_helper.broadcast_user( user_id, @@ -646,9 +645,8 @@ class ServerInstance: poll = self.process.poll() if poll is None: return True - else: - self.last_rc = poll - return False + self.last_rc = poll + return False def send_command(self, command): if not self.check_running() and command.lower() != "start": @@ -685,16 +683,15 @@ class ServerInstance: ) self.run_threaded_server(None) return True - else: - logger.critical( - f"The server {name} has crashed, " - f"crash detection is disabled and it will not be restarted" - ) - Console.critical( - f"The server {name} has crashed, " - f"crash detection is disabled and it will not be restarted" - ) - return False + logger.critical( + f"The server {name} has crashed, " + f"crash detection is disabled and it will not be restarted" + ) + Console.critical( + f"The server {name} has crashed, " + f"crash detection is disabled and it will not be restarted" + ) + return False def kill(self): logger.info(f"Terminating server {self.server_id} and all child processes") @@ -720,16 +717,10 @@ class ServerInstance: self.process.kill() def get_start_time(self): - if self.check_running(): - return self.start_time - else: - return False + return self.start_time if self.check_running() else False def get_pid(self): - if self.process is not None: - return self.process.pid - else: - return None + return self.process.pid if self.process is not None else None def detect_crash(self): @@ -793,12 +784,6 @@ class ServerInstance: f.close() self.run_threaded_server(user_id) - def is_backup_running(self): - if self.is_backingup: - return True - else: - return False - def backup_server(self): if self.settings["backup_path"] == "": logger.critical("Backup path is None. Canceling Backup!") @@ -988,34 +973,32 @@ class ServerInstance: return {"percent": 0, "total_files": 0} def list_backups(self): - if self.settings["backup_path"]: - if Helpers.check_path_exists( - Helpers.get_os_understandable_path(self.settings["backup_path"]) - ): - files = Helpers.get_human_readable_files_sizes( - Helpers.list_dir_by_date( - Helpers.get_os_understandable_path(self.settings["backup_path"]) - ) - ) - return [ - { - "path": os.path.relpath( - f["path"], - start=Helpers.get_os_understandable_path( - self.settings["backup_path"] - ), - ), - "size": f["size"], - } - for f in files - ] - else: - return [] - else: + if not self.settings["backup_path"]: logger.info( f"Error putting backup file list for server with ID: {self.server_id}" ) return [] + if not Helpers.check_path_exists( + Helpers.get_os_understandable_path(self.settings["backup_path"]) + ): + return [] + files = Helpers.get_human_readable_files_sizes( + Helpers.list_dir_by_date( + Helpers.get_os_understandable_path(self.settings["backup_path"]) + ) + ) + return [ + { + "path": os.path.relpath( + f["path"], + start=Helpers.get_os_understandable_path( + self.settings["backup_path"] + ), + ), + "size": f["size"], + } + for f in files + ] def jar_update(self): self.stats_helper.set_update(True) @@ -1025,11 +1008,7 @@ class ServerInstance: update_thread.start() def check_update(self): - - if self.stats_helper.get_server_stats()["updating"]: - return True - else: - return False + return self.stats_helper.get_server_stats()["updating"] def a_jar_update(self): was_started = "-1" diff --git a/app/classes/shared/translation.py b/app/classes/shared/translation.py index 5c79c911..0e441808 100644 --- a/app/classes/shared/translation.py +++ b/app/classes/shared/translation.py @@ -31,10 +31,10 @@ class Translation: if isinstance(translated_word, dict): # JSON objects return json.dumps(translated_word) - elif isinstance(translated_word, str): + if isinstance(translated_word, str): # Basic strings return translated_word - elif hasattr(translated_word, "__iter__"): + if hasattr(translated_word, "__iter__"): # Multiline strings return "\n".join(translated_word) return "Error while getting translation" diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index 8f5789fe..d78a4f0b 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -242,8 +242,7 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, "get_tree"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if Helpers.validate_traversal( self.controller.servers.get_server_data_by_id(server_id)["path"], path @@ -495,8 +494,7 @@ class AjaxHandler(BaseHandler): if not self.check_server_id(server_id, "del_backup"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) server_info = self.controller.servers.get_server_data_by_id(server_id) if not ( @@ -576,16 +574,15 @@ class AjaxHandler(BaseHandler): f"Server ID not defined in {page_name} ajax call ({server_id})" ) return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) - # does this server id exist? - if not self.controller.servers.server_id_exists(server_id): - logger.warning( - f"Server ID not found in {page_name} ajax call ({server_id})" - ) - Console.warning( - f"Server ID not found in {page_name} ajax call ({server_id})" - ) - return + # does this server id exist? + if not self.controller.servers.server_id_exists(server_id): + logger.warning( + f"Server ID not found in {page_name} ajax call ({server_id})" + ) + Console.warning( + f"Server ID not found in {page_name} ajax call ({server_id})" + ) + return return True diff --git a/app/classes/web/api_handler.py b/app/classes/web/api_handler.py index c1790212..ae525dbb 100644 --- a/app/classes/web/api_handler.py +++ b/app/classes/web/api_handler.py @@ -74,10 +74,9 @@ class ApiHandler(BaseHandler): logger.info(f"User {user_data['username']} has authenticated to API") return True # This is to set the "authenticated" - else: - logging.debug("Auth unsuccessful") - self.access_denied("unknown", "the user provided an invalid token") - return False + logging.debug("Auth unsuccessful") + self.access_denied("unknown", "the user provided an invalid token") + return False except Exception as e: logger.warning("An error occured while authenticating an API user: %s", e) self.finish( @@ -225,7 +224,7 @@ class StartServer(ApiHandler): ): self.access_denied("unknown") return - elif not self.permissions[ + if not self.permissions[ "Commands" ] in self.controller.server_perms.get_api_key_permissions_list( self.controller.users.get_api_key_by_token(self.api_token), server_id diff --git a/app/classes/web/base_handler.py b/app/classes/web/base_handler.py index 89ad88ce..fd3ee638 100644 --- a/app/classes/web/base_handler.py +++ b/app/classes/web/base_handler.py @@ -88,13 +88,11 @@ class BaseHandler(tornado.web.RequestHandler): if r in name: logger.debug(f"Auto-bleaching {name}: [**REDACTED**]") break - else: - logger.debug(f"Auto-bleaching {name}: {text}") + logger.debug(f"Auto-bleaching {name}: {text}") if type(text) in self.nobleach: logger.debug("Auto-bleaching - bypass type") return text - else: - return bleach.clean(text) + return bleach.clean(text) def get_argument( self, @@ -216,10 +214,9 @@ class BaseHandler(tornado.web.RequestHandler): superuser, user, ) - else: - logging.debug("Auth unsuccessful") - self.access_denied(None, "the user provided an invalid token") - return None + logging.debug("Auth unsuccessful") + self.access_denied(None, "the user provided an invalid token") + return None except Exception as auth_exception: logger.debug( "An error occured while authenticating an API user:", diff --git a/app/classes/web/file_handler.py b/app/classes/web/file_handler.py index d82c21a1..886441ed 100644 --- a/app/classes/web/file_handler.py +++ b/app/classes/web/file_handler.py @@ -55,8 +55,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "get_file"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if not Helpers.in_path( Helpers.get_os_understandable_path( @@ -93,8 +92,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "get_tree"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if Helpers.validate_traversal( self.controller.servers.get_server_data_by_id(server_id)["path"], path @@ -115,8 +113,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "get_tree"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if Helpers.validate_traversal( self.controller.servers.get_server_data_by_id(server_id)["path"], path @@ -164,8 +161,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "create_file"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if not Helpers.in_path( Helpers.get_os_understandable_path( @@ -198,8 +194,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "create_dir"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if not Helpers.in_path( Helpers.get_os_understandable_path( @@ -264,8 +259,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "del_file"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) server_info = self.controller.servers.get_server_data_by_id(server_id) if not ( @@ -299,8 +293,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "del_dir"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) server_info = self.controller.servers.get_server_data_by_id(server_id) if not Helpers.in_path( @@ -353,8 +346,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "save_file"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if not Helpers.in_path( Helpers.get_os_understandable_path( @@ -388,8 +380,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "rename_file"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if item_path is None or new_item_name is None: logger.warning("Invalid path(s) in rename_file file ajax call") @@ -464,8 +455,7 @@ class FileHandler(BaseHandler): if not self.check_server_id(server_id, "rename_file"): return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) if item_path is None or new_item_name is None: logger.warning("Invalid path(s) in rename_file file ajax call") @@ -514,16 +504,15 @@ class FileHandler(BaseHandler): f"Server ID not defined in {page_name} file ajax call ({server_id})" ) return - else: - server_id = bleach.clean(server_id) + server_id = bleach.clean(server_id) - # does this server id exist? - if not self.controller.servers.server_id_exists(server_id): - logger.warning( - f"Server ID not found in {page_name} file ajax call ({server_id})" - ) - Console.warning( - f"Server ID not found in {page_name} file ajax call ({server_id})" - ) - return + # does this server id exist? + if not self.controller.servers.server_id_exists(server_id): + logger.warning( + f"Server ID not found in {page_name} file ajax call ({server_id})" + ) + Console.warning( + f"Server ID not found in {page_name} file ajax call ({server_id})" + ) + return return True diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index bd0822a2..610c74eb 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -158,34 +158,31 @@ class PanelHandler(BaseHandler): if server_id is None: self.redirect("/panel/error?error=Invalid Server ID") return None - else: - # Does this server exist? - if not self.controller.servers.server_id_exists(server_id): + # Does this server exist? + if not self.controller.servers.server_id_exists(server_id): + self.redirect("/panel/error?error=Invalid Server ID") + return None + + # Does the user have permission? + if superuser: # TODO: Figure out a better solution + return server_id + if api_key is not None: + if not self.controller.servers.server_id_authorized_api_key( + server_id, api_key + ): + logger.debug( + f"API key {api_key.name} (id: {api_key.token_id}) " + f"does not have permission" + ) + self.redirect("/panel/error?error=Invalid Server ID") + return None + else: + if not self.controller.servers.server_id_authorized( + server_id, exec_user["user_id"] + ): + logger.debug(f'User {exec_user["user_id"]} does not have permission') self.redirect("/panel/error?error=Invalid Server ID") return None - - # Does the user have permission? - if not superuser: # TODO: Figure out a better solution - if api_key is not None: - if not self.controller.servers.server_id_authorized_api_key( - server_id, api_key - ): - logger.debug( - f"API key {api_key.name} (id: {api_key.token_id}) " - f"does not have permission" - ) - self.redirect("/panel/error?error=Invalid Server ID") - return None - else: - if not self.controller.servers.server_id_authorized( - server_id, exec_user["user_id"] - ): - logger.debug( - f'User {exec_user["user_id"]} does not have permission' - ) - self.redirect("/panel/error?error=Invalid Server ID") - return None - return server_id # Server fetching, spawned asynchronously # TODO: Make the related front-end elements update with AJAX @@ -1026,7 +1023,7 @@ class PanelHandler(BaseHandler): if user_id is None: self.redirect("/panel/error?error=Invalid User ID") return - elif EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions: + if EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions: if str(user_id) != str(exec_user["user_id"]): self.redirect( "/panel/error?error=Unauthorized access: not a user editor" @@ -1074,23 +1071,22 @@ class PanelHandler(BaseHandler): self.redirect("/panel/error?error=Unauthorized access: not superuser") return - elif str(exec_user["user_id"]) == str(user_id): + if str(exec_user["user_id"]) == str(user_id): self.redirect( "/panel/error?error=Unauthorized access: you cannot delete yourself" ) return - elif user_id is None: + if user_id is None: self.redirect("/panel/error?error=Invalid User ID") return - else: - # does this user id exist? - target_user = self.controller.users.get_user_by_id(user_id) - if not target_user: - self.redirect("/panel/error?error=Invalid User ID") - return - elif target_user["superuser"]: - self.redirect("/panel/error?error=Cannot remove a superuser") - return + # does this user id exist? + target_user = self.controller.users.get_user_by_id(user_id) + if not target_user: + self.redirect("/panel/error?error=Invalid User ID") + return + if target_user["superuser"]: + self.redirect("/panel/error?error=Cannot remove a superuser") + return self.controller.users.remove_user(user_id) @@ -1170,7 +1166,7 @@ class PanelHandler(BaseHandler): "/panel/error?error=Unauthorized access: not a role editor" ) return - elif role_id is None: + if role_id is None: self.redirect("/panel/error?error=Invalid Role ID") return @@ -1182,15 +1178,14 @@ class PanelHandler(BaseHandler): if not superuser: self.redirect("/panel/error?error=Unauthorized access: not superuser") return - elif role_id is None: + if role_id is None: + self.redirect("/panel/error?error=Invalid Role ID") + return + # does this user id exist? + target_role = self.controller.roles.get_role(role_id) + if not target_role: self.redirect("/panel/error?error=Invalid Role ID") return - else: - # does this user id exist? - target_role = self.controller.roles.get_role(role_id) - if not target_role: - self.redirect("/panel/error?error=Invalid Role ID") - return self.controller.roles.remove_role(role_id) @@ -1809,6 +1804,12 @@ class PanelHandler(BaseHandler): else: superuser = False if not exec_user["superuser"]: + if username is None or username == "": + self.redirect("/panel/error?error=Invalid username") + return + if user_id is None: + self.redirect("/panel/error?error=Invalid User ID") + return if ( EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions @@ -1836,17 +1837,10 @@ class PanelHandler(BaseHandler): ) self.redirect("/panel/panel_config") return - elif username is None or username == "": - self.redirect("/panel/error?error=Invalid username") - return - elif user_id is None: + # does this user id exist? + if not self.controller.users.user_id_exists(user_id): self.redirect("/panel/error?error=Invalid User ID") return - else: - # does this user id exist? - if not self.controller.users.user_id_exists(user_id): - self.redirect("/panel/error?error=Invalid User ID") - return else: if password0 != password1: self.redirect("/panel/error?error=Passwords must match") @@ -1893,14 +1887,13 @@ class PanelHandler(BaseHandler): if name is None or name == "": self.redirect("/panel/error?error=Invalid API key name") return - elif user_id is None: + if user_id is None: + self.redirect("/panel/error?error=Invalid User ID") + return + # does this user id exist? + if not self.controller.users.user_id_exists(user_id): self.redirect("/panel/error?error=Invalid User ID") return - else: - # does this user id exist? - if not self.controller.users.user_id_exists(user_id): - self.redirect("/panel/error?error=Invalid User ID") - return crafty_permissions_mask = self.get_perms() server_permissions_mask = self.get_perms_server() @@ -1929,12 +1922,11 @@ class PanelHandler(BaseHandler): if key_id is None: self.redirect("/panel/error?error=Invalid Key ID") return - else: - key = self.controller.users.get_user_api_key(key_id) - # does this user id exist? - if key is None: - self.redirect("/panel/error?error=Invalid Key ID") - return + key = self.controller.users.get_user_api_key(key_id) + # does this user id exist? + if key is None: + self.redirect("/panel/error?error=Invalid Key ID") + return self.controller.management.add_to_audit_log( exec_user["user_id"], @@ -1952,14 +1944,14 @@ class PanelHandler(BaseHandler): self.finish() elif page == "add_user": - if bleach.clean(self.get_argument("username", None)).lower() == "system": + username = bleach.clean(self.get_argument("username", None)) + if username.lower() == "system": self.redirect( "/panel/error?error=Unauthorized access: " "username system is reserved for the Crafty system." " Please choose a different username." ) return - username = bleach.clean(self.get_argument("username", None)) password0 = bleach.clean(self.get_argument("password0", None)) password1 = bleach.clean(self.get_argument("password1", None)) email = bleach.clean(self.get_argument("email", "default@example.com")) @@ -1992,14 +1984,13 @@ class PanelHandler(BaseHandler): "/panel/error?error=Unauthorized access: quantity limit reached" ) return - elif username is None or username == "": + if username is None or username == "": self.redirect("/panel/error?error=Invalid username") return - else: - # does this user id exist? - if self.controller.users.get_id_by_name(username) is not None: - self.redirect("/panel/error?error=User exists") - return + # does this user id exist? + if self.controller.users.get_id_by_name(username) is not None: + self.redirect("/panel/error?error=User exists") + return if password0 != password1: self.redirect("/panel/error?error=Passwords must match") @@ -2048,17 +2039,16 @@ class PanelHandler(BaseHandler): "/panel/error?error=Unauthorized access: not a role editor" ) return - elif role_name is None or role_name == "": + if role_name is None or role_name == "": self.redirect("/panel/error?error=Invalid username") return - elif role_id is None: + if role_id is None: + self.redirect("/panel/error?error=Invalid Role ID") + return + # does this user id exist? + if not self.controller.roles.role_id_exists(role_id): self.redirect("/panel/error?error=Invalid Role ID") return - else: - # does this user id exist? - if not self.controller.roles.role_id_exists(role_id): - self.redirect("/panel/error?error=Invalid Role ID") - return servers = self.get_role_servers() @@ -2080,7 +2070,7 @@ class PanelHandler(BaseHandler): "/panel/error?error=Unauthorized access: not a role editor" ) return - elif ( + if ( not self.controller.crafty_perms.can_add_role(exec_user["user_id"]) and not exec_user["superuser"] ): @@ -2088,14 +2078,13 @@ class PanelHandler(BaseHandler): "/panel/error?error=Unauthorized access: quantity limit reached" ) return - elif role_name is None or role_name == "": + if role_name is None or role_name == "": self.redirect("/panel/error?error=Invalid role name") return - else: - # does this user id exist? - if self.controller.roles.get_roleid_by_name(role_name) is not None: - self.redirect("/panel/error?error=Role exists") - return + # does this user id exist? + if self.controller.roles.get_roleid_by_name(role_name) is not None: + self.redirect("/panel/error?error=Role exists") + return servers = self.get_role_servers() @@ -2146,17 +2135,14 @@ class PanelHandler(BaseHandler): if not superuser: self.redirect("/panel/error?error=Unauthorized access: not superuser") return - elif ( - key_id is None or self.controller.users.get_user_api_key(key_id) is None - ): + if key_id is None or self.controller.users.get_user_api_key(key_id) is None: + self.redirect("/panel/error?error=Invalid Key ID") + return + # does this user id exist? + target_key = self.controller.users.get_user_api_key(key_id) + if not target_key: self.redirect("/panel/error?error=Invalid Key ID") return - else: - # does this user id exist? - target_key = self.controller.users.get_user_api_key(key_id) - if not target_key: - self.redirect("/panel/error?error=Invalid Key ID") - return self.controller.users.delete_user_api_key(key_id) From d16e83686e4f79b8eb2ba8c4ecf9bc67eeae7bd8 Mon Sep 17 00:00:00 2001 From: hofq <8595960-gammeltonne@users.noreply.gitlab.com> Date: Tue, 14 Jun 2022 13:11:53 +0000 Subject: [PATCH 06/14] Update unRAID xml readability. --- docker/unraid.xml | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/docker/unraid.xml b/docker/unraid.xml index 7db86a27..8784ea8f 100644 --- a/docker/unraid.xml +++ b/docker/unraid.xml @@ -1,7 +1,7 @@ True - Crafty + Crafty-4 registry.gitlab.com/crafty-controller/crafty-4:latest registry.gitlab.com/crafty-controller/crafty-4 bridge @@ -40,11 +40,6 @@ For migration from 3.x please refer to the documentation: https://wiki.craftycon 8443 tcp - - 8000 - 8000 - tcp - 25500-25600 25500-25600 @@ -64,41 +59,40 @@ For migration from 3.x please refer to the documentation: https://wiki.craftycon - /mnt/user/appdata/Crafty-4/servers/ + /mnt/user/appdata/crafty-4/servers/ /crafty/servers rw - /mnt/user/appdata/Crafty-4/backups/ + /mnt/user/appdata/crafty-4/backups/ /crafty/backups rw - /mnt/user/appdata/Crafty-4/logs/ + /mnt/user/appdata/crafty-4/logs/ /crafty/logs rw - /mnt/user/appdata/Crafty-4/config/ + /mnt/user/appdata/crafty-4/config/ /crafty/app/config rw - /mnt/user/appdata/Crafty-4/import/ + /mnt/user/appdata/crafty-4/import/ /crafty/import rw - 8443 - 8000 + 8443 25500-25600 - 8123 + 8123 19132 - /mnt/user/appdata/Crafty-4/servers/ - /mnt/user/appdata/Crafty-4/backups/ - /mnt/user/appdata/Crafty-4/logs/ - /mnt/user/appdata/Crafty-4/config/ - /mnt/user/appdata/Crafty-4/import/ + /mnt/user/appdata/crafty-4/servers/ + /mnt/user/appdata/crafty-4/backups/ + /mnt/user/appdata/crafty-4/logs/ + /mnt/user/appdata/crafty-4/config/ + /mnt/user/appdata/crafty-4/import/ From cda2120579083d447db5dbeb5489822880f4cae7 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 14 Jun 2022 22:33:02 -0400 Subject: [PATCH 07/14] Fix window java issue causing no stats --- app/classes/shared/helpers.py | 34 ++++++++++++++++++++++++++++++++++ app/classes/shared/server.py | 15 +++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 4c5a3daa..ca58b5c2 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -1,6 +1,7 @@ import contextlib import os import re +import winreg import sys import json import tempfile @@ -101,6 +102,39 @@ class Helpers: def get_servers_root_dir(self): return self.servers_dir + @staticmethod + def which_java(): + # Adapted from LeeKamentsky's https://github.com/LeeKamentsky/python-javabridge/blob/master/javabridge/locate.py + jdk_key_paths = ( + "SOFTWARE\\JavaSoft\\JDK", + "SOFTWARE\\JavaSoft\\Java Development Kit", + ) + for jdk_key_path in jdk_key_paths: + try: + with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, jdk_key_path) as kjdk: + kjdk_values = dict( + [ + winreg.EnumValue(kjdk, i)[:2] + for i in range(winreg.QueryInfoKey(kjdk)[1]) + ] + ) + current_version = kjdk_values["CurrentVersion"] + kjdk_current = winreg.OpenKey( + winreg.HKEY_LOCAL_MACHINE, jdk_key_path + "\\" + current_version + ) + kjdk_current_values = dict( + [ + winreg.EnumValue(kjdk_current, i)[:2] + for i in range(winreg.QueryInfoKey(kjdk_current)[1]) + ] + ) + return kjdk_current_values["JavaHome"] + except WindowsError as e: + if e.errno == 2: + continue + else: + raise + @staticmethod def check_internet(): try: diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index 292feb08..b28fabb4 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -234,6 +234,21 @@ class ServerInstance: self.settings["executable"] ) self.server_command = Helpers.cmdparse(self.settings["execution_command"]) + if self.helper.is_os_windows() and self.server_command[0] == "java": + logger.info( + "Detected nebulous java in start command. Replacing with full java path." + ) + which_java_raw = self.helper.which_java() + java_path = which_java_raw + "\\bin\\java" + if not str(which_java_raw) == str(self.helper.get_servers_root_dir) or str( + self.helper.get_servers_root_dir + ) in str(which_java_raw): + self.server_command[0] = java_path + else: + logger.critcal( + "Possible attack detected. User attempted to exec java binary from server directory." + ) + return self.server_path = Helpers.get_os_understandable_path(self.settings["path"]) # let's do some quick checking to make sure things actually exists From 1cfc926b160941c186a8c4b3f436b7f0b4acc2d2 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Wed, 15 Jun 2022 04:11:40 +0100 Subject: [PATCH 08/14] Fix line length CQ --- app/classes/shared/helpers.py | 3 ++- app/classes/shared/server.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index ca58b5c2..bd0aec4b 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -104,7 +104,8 @@ class Helpers: @staticmethod def which_java(): - # Adapted from LeeKamentsky's https://github.com/LeeKamentsky/python-javabridge/blob/master/javabridge/locate.py + # Adapted from LeeKamentsky >>> + # https://github.com/LeeKamentsky/python-javabridge/blob/master/javabridge/locate.py jdk_key_paths = ( "SOFTWARE\\JavaSoft\\JDK", "SOFTWARE\\JavaSoft\\Java Development Kit", diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index b28fabb4..0db1871e 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -236,7 +236,8 @@ class ServerInstance: self.server_command = Helpers.cmdparse(self.settings["execution_command"]) if self.helper.is_os_windows() and self.server_command[0] == "java": logger.info( - "Detected nebulous java in start command. Replacing with full java path." + "Detected nebulous java in start command. " + "Replacing with full java path." ) which_java_raw = self.helper.which_java() java_path = which_java_raw + "\\bin\\java" @@ -246,7 +247,8 @@ class ServerInstance: self.server_command[0] = java_path else: logger.critcal( - "Possible attack detected. User attempted to exec java binary from server directory." + "Possible attack detected. User attempted to exec " + "java binary from server directory." ) return self.server_path = Helpers.get_os_understandable_path(self.settings["path"]) From 9ed5cc3c5a40b853476a26d1ee4fe3a5c44e916e Mon Sep 17 00:00:00 2001 From: Zedifus Date: Wed, 15 Jun 2022 04:15:46 +0100 Subject: [PATCH 09/14] Fix pylint R1724 --- app/classes/shared/helpers.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index bd0aec4b..00b6287a 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -133,8 +133,7 @@ class Helpers: except WindowsError as e: if e.errno == 2: continue - else: - raise + raise @staticmethod def check_internet(): From 5f8dbd4dc7dd285d9176721766651e5434d9cb68 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Wed, 15 Jun 2022 04:27:27 +0100 Subject: [PATCH 10/14] Fix C0113 & Exempting R0201 Line as self required. --- app/classes/minecraft/stats.py | 2 +- app/classes/shared/server.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/classes/minecraft/stats.py b/app/classes/minecraft/stats.py index d309e023..f9c66d54 100644 --- a/app/classes/minecraft/stats.py +++ b/app/classes/minecraft/stats.py @@ -212,7 +212,7 @@ class Stats: return level_total_size - def get_server_players(self, server_id): + def get_server_players(self, server_id): # pylint: disable=no-self-use server = HelperServers.get_server_data_by_id(server_id) diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index 0db1871e..cdd5f796 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -241,7 +241,7 @@ class ServerInstance: ) which_java_raw = self.helper.which_java() java_path = which_java_raw + "\\bin\\java" - if not str(which_java_raw) == str(self.helper.get_servers_root_dir) or str( + if str(which_java_raw) != str(self.helper.get_servers_root_dir) or str( self.helper.get_servers_root_dir ) in str(which_java_raw): self.server_command[0] = java_path From 0f82ba3084806c1464b650966780ed144761bb71 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Wed, 15 Jun 2022 04:44:19 +0100 Subject: [PATCH 11/14] Line exempt E0602 It's not an undefined var it's the Base class for I/O related errors. False positive. --- app/classes/shared/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 00b6287a..0fab02c4 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -130,7 +130,7 @@ class Helpers: ] ) return kjdk_current_values["JavaHome"] - except WindowsError as e: + except WindowsError as e: # pylint: disable=E0602 if e.errno == 2: continue raise From 00466719ea5209349cb9d80490c5eeda2fa5ab34 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Wed, 15 Jun 2022 04:52:19 +0100 Subject: [PATCH 12/14] Exempt R1717 consideration --- app/classes/shared/helpers.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 0fab02c4..8e42f489 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -113,21 +113,25 @@ class Helpers: for jdk_key_path in jdk_key_paths: try: with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, jdk_key_path) as kjdk: - kjdk_values = dict( - [ - winreg.EnumValue(kjdk, i)[:2] - for i in range(winreg.QueryInfoKey(kjdk)[1]) - ] + kjdk_values = ( + dict( # pylint: disable=consider-using-dict-comprehension + [ + winreg.EnumValue(kjdk, i)[:2] + for i in range(winreg.QueryInfoKey(kjdk)[1]) + ] + ) ) current_version = kjdk_values["CurrentVersion"] kjdk_current = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, jdk_key_path + "\\" + current_version ) - kjdk_current_values = dict( - [ - winreg.EnumValue(kjdk_current, i)[:2] - for i in range(winreg.QueryInfoKey(kjdk_current)[1]) - ] + kjdk_current_values = ( + dict( # pylint: disable=consider-using-dict-comprehension + [ + winreg.EnumValue(kjdk_current, i)[:2] + for i in range(winreg.QueryInfoKey(kjdk_current)[1]) + ] + ) ) return kjdk_current_values["JavaHome"] except WindowsError as e: # pylint: disable=E0602 From 5d4ba079bb0247797a07f2477d45912e421b8937 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Wed, 15 Jun 2022 04:53:49 +0100 Subject: [PATCH 13/14] Bump version patch/sub --- app/config/version.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/config/version.json b/app/config/version.json index a5fca0c2..1b3a7c55 100644 --- a/app/config/version.json +++ b/app/config/version.json @@ -1,6 +1,6 @@ { "major": 4, "minor": 0, - "sub": 0, + "sub": 1, "meta": "beta" -} \ No newline at end of file +} From 1d9053a549c9514f04f7627010372e7d523b4a6c Mon Sep 17 00:00:00 2001 From: Iain Powrie Date: Wed, 15 Jun 2022 04:02:53 +0000 Subject: [PATCH 14/14] Bump README badge version --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 077be5f7..2b1e2b3d 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Supported Python Versions](https://shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20-blue)](https://www.python.org) -[![Version(temp-hardcoded)](https://img.shields.io/badge/release-v4.0.0--beta-orange)](https://gitlab.com/crafty-controller/crafty-4) +[![Version(temp-hardcoded)](https://img.shields.io/badge/release-v4.0.1--beta-orange)](https://gitlab.com/crafty-controller/crafty-4) [![Code Quality(temp-hardcoded)](https://img.shields.io/badge/code%20quality-10-brightgreen)](https://gitlab.com/crafty-controller/crafty-4) [![Build Status](https://gitlab.com/crafty-controller/crafty-4/badges/master/pipeline.svg)](https://gitlab.com/crafty-controller/crafty-4/-/commits/master) -# Crafty Controller 4.0.0-beta +# Crafty Controller 4.0.1-beta > Python based Control Panel for your Minecraft Server ## What is Crafty Controller?