From 879aa8c54c8ab7d0af29d8afe239e33aa177c5cf Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 15 Feb 2024 07:15:53 -0500 Subject: [PATCH 01/15] Make sure default.json is read from correct loc --- 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 9c63a323..0e091a56 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -1112,7 +1112,7 @@ class Helpers: return os.path.normpath(path) def find_default_password(self): - default_file = os.path.join(self.root_dir, "default.json") + default_file = os.path.join(self.root_dir, "app", "config", "default.json") data = {} if Helpers.check_file_exists(default_file): From c570bdeda04b4cf926884a5de164bd9dbf056f18 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Mon, 19 Feb 2024 19:30:51 +0000 Subject: [PATCH 02/15] Bump openssl & cryptography Resolves: CVE-2024-0727 CVE-2023-50782 --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 7b1adcfc..30414b35 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,13 +4,13 @@ argon2-cffi==23.1.0 cached_property==1.5.2 colorama==0.4.6 croniter==1.4.1 -cryptography==41.0.7 +cryptography==42.0.2 libgravatar==1.0.4 nh3==0.2.14 packaging==23.2 peewee==3.13 psutil==5.9.5 -pyOpenSSL==23.3.0 +pyOpenSSL==24.0.0 pyjwt==2.8.0 PyYAML==6.0.1 requests==2.31.0 From bbf08a6690c8c4c64839f4c52baedf2e814a8008 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Mon, 19 Feb 2024 19:58:31 +0000 Subject: [PATCH 03/15] Update changelog !716 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1a8dd9e..a0f25dc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ TBD ### Bug fixes TBD ### Tweaks -TBD +- Bump pyOpenSSL & cryptography for CVE-2024-0727, CVE-2023-50782 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/716)) ### Lang TBD

From 0422a2ecdf51db2820b84d5f965e30e1cd0c3614 Mon Sep 17 00:00:00 2001 From: Zedifus Date: Mon, 19 Feb 2024 20:02:09 +0000 Subject: [PATCH 04/15] Fix assorted black issues currently in dev --- app/classes/models/server_permissions.py | 6 +- app/classes/web/panel_handler.py | 248 +++++++++--------- .../web/routes/api/crafty/config/index.py | 20 +- .../routes/api/crafty/config/server_dir.py | 10 +- app/classes/web/routes/api/roles/index.py | 10 +- .../web/routes/api/roles/role/servers.py | 10 +- app/classes/web/server_handler.py | 20 +- 7 files changed, 173 insertions(+), 151 deletions(-) diff --git a/app/classes/models/server_permissions.py b/app/classes/models/server_permissions.py index eb5e3f35..56f9d8ac 100644 --- a/app/classes/models/server_permissions.py +++ b/app/classes/models/server_permissions.py @@ -172,9 +172,9 @@ class PermissionsServers: RoleServers.server_id, RoleServers.permissions ).where(RoleServers.role_id == role_id) for role_server in role_servers: - permissions_dict[ - role_server.server_id_id - ] = PermissionsServers.get_permissions(role_server.permissions) + permissions_dict[role_server.server_id_id] = ( + PermissionsServers.get_permissions(role_server.permissions) + ) return permissions_dict @staticmethod diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index a7e54974..e8c93c68 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -345,15 +345,17 @@ class PanelHandler(BaseHandler): self.controller.users.get_user_lang_by_id(exec_user["user_id"]) ), "super_user": superuser, - "api_key": { - "name": api_key.name, - "created": api_key.created, - "server_permissions": api_key.server_permissions, - "crafty_permissions": api_key.crafty_permissions, - "superuser": api_key.superuser, - } - if api_key is not None - else None, + "api_key": ( + { + "name": api_key.name, + "created": api_key.created, + "server_permissions": api_key.server_permissions, + "crafty_permissions": api_key.crafty_permissions, + "superuser": api_key.superuser, + } + if api_key is not None + else None + ), "superuser": superuser, } try: @@ -417,14 +419,14 @@ class PanelHandler(BaseHandler): self.controller.first_login = False if superuser: # TODO: Figure out a better solution try: - page_data[ - "servers" - ] = self.controller.servers.get_all_servers_stats() + page_data["servers"] = ( + self.controller.servers.get_all_servers_stats() + ) except IndexError: self.controller.servers.stats.record_stats() - page_data[ - "servers" - ] = self.controller.servers.get_all_servers_stats() + page_data["servers"] = ( + self.controller.servers.get_all_servers_stats() + ) else: try: user_auth = self.controller.servers.get_authorized_servers_stats( @@ -454,19 +456,19 @@ class PanelHandler(BaseHandler): for server_id in user_order[:]: for server in un_used_servers[:]: if flag == 0: - server["stats"][ - "importing" - ] = self.controller.servers.get_import_status( - str(server["stats"]["server_id"]["server_id"]) + server["stats"]["importing"] = ( + self.controller.servers.get_import_status( + str(server["stats"]["server_id"]["server_id"]) + ) ) server["stats"]["crashed"] = self.controller.servers.is_crashed( str(server["stats"]["server_id"]["server_id"]) ) try: - server["stats"][ - "waiting_start" - ] = self.controller.servers.get_waiting_start( - str(server["stats"]["server_id"]["server_id"]) + server["stats"]["waiting_start"] = ( + self.controller.servers.get_waiting_start( + str(server["stats"]["server_id"]["server_id"]) + ) ) except Exception as e: logger.error(f"Failed to get server waiting to start: {e}") @@ -543,9 +545,9 @@ class PanelHandler(BaseHandler): server_id ) if not self.failed_server: - page_data[ - "server_stats" - ] = self.controller.servers.get_server_stats_by_id(server_id) + page_data["server_stats"] = ( + self.controller.servers.get_server_stats_by_id(server_id) + ) else: server_temp_obj = self.controller.servers.get_server_data_by_id( server_id @@ -611,19 +613,19 @@ class PanelHandler(BaseHandler): "Config": EnumPermissionsServer.CONFIG, "Players": EnumPermissionsServer.PLAYERS, } - page_data[ - "user_permissions" - ] = self.controller.server_perms.get_user_id_permissions_list( - exec_user["user_id"], server_id + page_data["user_permissions"] = ( + self.controller.server_perms.get_user_id_permissions_list( + exec_user["user_id"], server_id + ) ) if not self.failed_server: - page_data["server_stats"][ - "crashed" - ] = self.controller.servers.is_crashed(server_id) + page_data["server_stats"]["crashed"] = ( + self.controller.servers.is_crashed(server_id) + ) if not self.failed_server: - page_data["server_stats"][ - "server_type" - ] = self.controller.servers.get_server_type_by_id(server_id) + page_data["server_stats"]["server_type"] = ( + self.controller.servers.get_server_type_by_id(server_id) + ) if not subpage: for spage, perm in SUBPAGE_PERMS.items(): @@ -674,23 +676,23 @@ class PanelHandler(BaseHandler): page_data["java_versions"] = page_java if subpage == "backup": server_info = self.controller.servers.get_server_data_by_id(server_id) - page_data[ - "backup_config" - ] = self.controller.management.get_backup_config(server_id) + page_data["backup_config"] = ( + self.controller.management.get_backup_config(server_id) + ) exclusions = [] - page_data[ - "exclusions" - ] = self.controller.management.get_excluded_backup_dirs(server_id) - page_data[ - "backing_up" - ] = self.controller.servers.get_server_instance_by_id( - server_id - ).is_backingup - page_data[ - "backup_stats" - ] = self.controller.servers.get_server_instance_by_id( - server_id - ).send_backup_status() + page_data["exclusions"] = ( + self.controller.management.get_excluded_backup_dirs(server_id) + ) + page_data["backing_up"] = ( + self.controller.servers.get_server_instance_by_id( + server_id + ).is_backingup + ) + page_data["backup_stats"] = ( + self.controller.servers.get_server_instance_by_id( + server_id + ).send_backup_status() + ) # makes it so relative path is the only thing shown for file in page_data["exclusions"]: if Helpers.is_os_windows(): @@ -723,10 +725,10 @@ class PanelHandler(BaseHandler): server_id, hours=(days * 24) ) if subpage == "webhooks": - page_data[ - "webhooks" - ] = self.controller.management.get_webhooks_by_server( - server_id, model=True + page_data["webhooks"] = ( + self.controller.management.get_webhooks_by_server( + server_id, model=True + ) ) page_data["triggers"] = WebhookFactory.get_monitored_events() @@ -758,9 +760,9 @@ class PanelHandler(BaseHandler): if not superuser: self.redirect("/panel/error?error=Unauthorized access") page_data["banned_players_html"] = get_banned_players_html() - page_data[ - "banned_players" - ] = self.controller.servers.get_banned_players(server_id) + page_data["banned_players"] = ( + self.controller.servers.get_banned_players(server_id) + ) server_instance = self.controller.servers.get_server_instance_by_id( server_id ) @@ -925,9 +927,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() + page_data["login_opacity"] = ( + self.controller.management.get_login_opacity() + ) page_data["active_link"] = "custom_login" template = "panel/custom_login.html" @@ -959,13 +961,11 @@ class PanelHandler(BaseHandler): page_data["servers"] = [] page_data["servers_all"] = self.controller.servers.get_all_defined_servers() page_data["role-servers"] = [] - page_data[ - "permissions_all" - ] = self.controller.crafty_perms.list_defined_crafty_permissions() + page_data["permissions_all"] = ( + self.controller.crafty_perms.list_defined_crafty_permissions() + ) page_data["permissions_list"] = set() - page_data[ - "quantity_server" - ] = ( + page_data["quantity_server"] = ( self.controller.crafty_perms.list_all_crafty_permissions_quantity_limits() # pylint: disable=line-too-long ) page_data["languages"] = [] @@ -1007,10 +1007,10 @@ class PanelHandler(BaseHandler): page_data["server_data"] = self.controller.servers.get_server_data_by_id( server_id ) - page_data[ - "user_permissions" - ] = self.controller.server_perms.get_user_id_permissions_list( - exec_user["user_id"], server_id + page_data["user_permissions"] = ( + self.controller.server_perms.get_user_id_permissions_list( + exec_user["user_id"], server_id + ) ) page_data["permissions"] = { "Commands": EnumPermissionsServer.COMMANDS, @@ -1025,9 +1025,9 @@ class PanelHandler(BaseHandler): page_data["server_stats"] = self.controller.servers.get_server_stats_by_id( server_id ) - page_data["server_stats"][ - "server_type" - ] = self.controller.servers.get_server_type_by_id(server_id) + page_data["server_stats"]["server_type"] = ( + self.controller.servers.get_server_type_by_id(server_id) + ) page_data["new_webhook"] = True page_data["webhook"] = {} page_data["webhook"]["webhook_type"] = "Custom" @@ -1061,10 +1061,10 @@ class PanelHandler(BaseHandler): page_data["server_data"] = self.controller.servers.get_server_data_by_id( server_id ) - page_data[ - "user_permissions" - ] = self.controller.server_perms.get_user_id_permissions_list( - exec_user["user_id"], server_id + page_data["user_permissions"] = ( + self.controller.server_perms.get_user_id_permissions_list( + exec_user["user_id"], server_id + ) ) page_data["permissions"] = { "Commands": EnumPermissionsServer.COMMANDS, @@ -1079,9 +1079,9 @@ class PanelHandler(BaseHandler): page_data["server_stats"] = self.controller.servers.get_server_stats_by_id( server_id ) - page_data["server_stats"][ - "server_type" - ] = self.controller.servers.get_server_type_by_id(server_id) + page_data["server_stats"]["server_type"] = ( + self.controller.servers.get_server_type_by_id(server_id) + ) page_data["new_webhook"] = False page_data["webhook"] = self.controller.management.get_webhook_by_id( webhook_id @@ -1121,10 +1121,10 @@ class PanelHandler(BaseHandler): "Config": EnumPermissionsServer.CONFIG, "Players": EnumPermissionsServer.PLAYERS, } - page_data[ - "user_permissions" - ] = self.controller.server_perms.get_user_id_permissions_list( - exec_user["user_id"], server_id + page_data["user_permissions"] = ( + self.controller.server_perms.get_user_id_permissions_list( + exec_user["user_id"], server_id + ) ) page_data["server_data"] = self.controller.servers.get_server_data_by_id( server_id @@ -1132,9 +1132,9 @@ class PanelHandler(BaseHandler): page_data["server_stats"] = self.controller.servers.get_server_stats_by_id( server_id ) - page_data["server_stats"][ - "server_type" - ] = self.controller.servers.get_server_type_by_id(server_id) + page_data["server_stats"]["server_type"] = ( + self.controller.servers.get_server_type_by_id(server_id) + ) page_data["new_schedule"] = True page_data["schedule"] = {} page_data["schedule"]["children"] = [] @@ -1189,10 +1189,10 @@ class PanelHandler(BaseHandler): "Config": EnumPermissionsServer.CONFIG, "Players": EnumPermissionsServer.PLAYERS, } - page_data[ - "user_permissions" - ] = self.controller.server_perms.get_user_id_permissions_list( - exec_user["user_id"], server_id + page_data["user_permissions"] = ( + self.controller.server_perms.get_user_id_permissions_list( + exec_user["user_id"], server_id + ) ) page_data["server_data"] = self.controller.servers.get_server_data_by_id( server_id @@ -1200,9 +1200,9 @@ class PanelHandler(BaseHandler): page_data["server_stats"] = self.controller.servers.get_server_stats_by_id( server_id ) - page_data["server_stats"][ - "server_type" - ] = self.controller.servers.get_server_type_by_id(server_id) + page_data["server_stats"]["server_type"] = ( + self.controller.servers.get_server_type_by_id(server_id) + ) page_data["new_schedule"] = False page_data["schedule"] = {} page_data["schedule"]["server_id"] = server_id @@ -1212,9 +1212,9 @@ class PanelHandler(BaseHandler): page_data["schedule"]["name"] = schedule.name else: page_data["schedule"]["name"] = "" - page_data["schedule"][ - "children" - ] = self.controller.management.get_child_schedules(sch_id) + page_data["schedule"]["children"] = ( + self.controller.management.get_child_schedules(sch_id) + ) # We check here to see if the command is any of the default ones. # We do not want a user changing to a custom command # and seeing our command there. @@ -1280,16 +1280,16 @@ class PanelHandler(BaseHandler): } if exec_user["superuser"]: page_data["users"] = self.controller.users.get_all_users() - page_data[ - "permissions_all" - ] = self.controller.crafty_perms.list_defined_crafty_permissions() - page_data[ - "permissions_list" - ] = self.controller.crafty_perms.get_crafty_permissions_list(user_id) - page_data[ - "quantity_server" - ] = self.controller.crafty_perms.list_crafty_permissions_quantity_limits( - user_id + page_data["permissions_all"] = ( + self.controller.crafty_perms.list_defined_crafty_permissions() + ) + page_data["permissions_list"] = ( + self.controller.crafty_perms.get_crafty_permissions_list(user_id) + ) + page_data["quantity_server"] = ( + self.controller.crafty_perms.list_crafty_permissions_quantity_limits( + user_id + ) ) page_data["languages"] = [] page_data["languages"].append( @@ -1349,12 +1349,12 @@ class PanelHandler(BaseHandler): page_data["user"] = self.controller.users.get_user_by_id(user_id) page_data["api_keys"] = self.controller.users.get_user_api_keys(user_id) # self.controller.crafty_perms.list_defined_crafty_permissions() - page_data[ - "server_permissions_all" - ] = self.controller.server_perms.list_defined_permissions() - page_data[ - "crafty_permissions_all" - ] = self.controller.crafty_perms.list_defined_crafty_permissions() + page_data["server_permissions_all"] = ( + self.controller.server_perms.list_defined_permissions() + ) + page_data["crafty_permissions_all"] = ( + self.controller.crafty_perms.list_defined_crafty_permissions() + ) if user_id is None: self.redirect("/panel/error?error=Invalid User ID") @@ -1442,9 +1442,9 @@ class PanelHandler(BaseHandler): DatabaseShortcuts.get_data_obj(server.server_object) ) page_data["servers_all"] = page_servers - page_data[ - "permissions_all" - ] = self.controller.server_perms.list_defined_permissions() + page_data["permissions_all"] = ( + self.controller.server_perms.list_defined_permissions() + ) page_data["permissions_dict"] = {} template = "panel/panel_edit_role.html" @@ -1467,12 +1467,12 @@ class PanelHandler(BaseHandler): DatabaseShortcuts.get_data_obj(server.server_object) ) page_data["servers_all"] = page_servers - page_data[ - "permissions_all" - ] = self.controller.server_perms.list_defined_permissions() - page_data[ - "permissions_dict" - ] = self.controller.server_perms.get_role_permissions_dict(role_id) + page_data["permissions_all"] = ( + self.controller.server_perms.list_defined_permissions() + ) + page_data["permissions_dict"] = ( + self.controller.server_perms.get_role_permissions_dict(role_id) + ) page_data["user-roles"] = user_roles page_data["users"] = self.controller.users.get_all_users() diff --git a/app/classes/web/routes/api/crafty/config/index.py b/app/classes/web/routes/api/crafty/config/index.py index a2bff723..c901732c 100644 --- a/app/classes/web/routes/api/crafty/config/index.py +++ b/app/classes/web/routes/api/crafty/config/index.py @@ -80,9 +80,13 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler): 200, { "status": "ok", - "data": self.controller.roles.get_all_role_ids() - if get_only_ids - else [model_to_dict(r) for r in self.controller.roles.get_all_roles()], + "data": ( + self.controller.roles.get_all_role_ids() + if get_only_ids + else [ + model_to_dict(r) for r in self.controller.roles.get_all_roles() + ] + ), }, ) @@ -158,9 +162,13 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler): 200, { "status": "ok", - "data": self.controller.roles.get_all_role_ids() - if get_only_ids - else [model_to_dict(r) for r in self.controller.roles.get_all_roles()], + "data": ( + self.controller.roles.get_all_role_ids() + if get_only_ids + else [ + model_to_dict(r) for r in self.controller.roles.get_all_roles() + ] + ), }, ) diff --git a/app/classes/web/routes/api/crafty/config/server_dir.py b/app/classes/web/routes/api/crafty/config/server_dir.py index 4e41be14..91c4cc89 100644 --- a/app/classes/web/routes/api/crafty/config/server_dir.py +++ b/app/classes/web/routes/api/crafty/config/server_dir.py @@ -36,9 +36,13 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler): 200, { "status": "ok", - "data": self.controller.roles.get_all_role_ids() - if get_only_ids - else [model_to_dict(r) for r in self.controller.roles.get_all_roles()], + "data": ( + self.controller.roles.get_all_role_ids() + if get_only_ids + else [ + model_to_dict(r) for r in self.controller.roles.get_all_roles() + ] + ), }, ) diff --git a/app/classes/web/routes/api/roles/index.py b/app/classes/web/routes/api/roles/index.py index b0c773a7..dce6f453 100644 --- a/app/classes/web/routes/api/roles/index.py +++ b/app/classes/web/routes/api/roles/index.py @@ -87,9 +87,13 @@ class ApiRolesIndexHandler(BaseApiHandler): 200, { "status": "ok", - "data": self.controller.roles.get_all_role_ids() - if get_only_ids - else [model_to_dict(r) for r in self.controller.roles.get_all_roles()], + "data": ( + self.controller.roles.get_all_role_ids() + if get_only_ids + else [ + model_to_dict(r) for r in self.controller.roles.get_all_roles() + ] + ), }, ) diff --git a/app/classes/web/routes/api/roles/role/servers.py b/app/classes/web/routes/api/roles/role/servers.py index b9b920ca..0a0eff6f 100644 --- a/app/classes/web/routes/api/roles/role/servers.py +++ b/app/classes/web/routes/api/roles/role/servers.py @@ -25,8 +25,12 @@ class ApiRolesRoleServersHandler(BaseApiHandler): 200, { "status": "ok", - "data": PermissionsServers.get_server_ids_from_role(role_id) - if get_only_ids - else self.controller.roles.get_server_ids_and_perms_from_role(role_id), + "data": ( + PermissionsServers.get_server_ids_from_role(role_id) + if get_only_ids + else self.controller.roles.get_server_ids_and_perms_from_role( + role_id + ) + ), }, ) diff --git a/app/classes/web/server_handler.py b/app/classes/web/server_handler.py index e940352e..545029aa 100644 --- a/app/classes/web/server_handler.py +++ b/app/classes/web/server_handler.py @@ -118,15 +118,17 @@ class ServerHandler(BaseHandler): "lang_page": Helpers.get_lang_page( self.controller.users.get_user_lang_by_id(exec_user["user_id"]) ), - "api_key": { - "name": api_key.name, - "created": api_key.created, - "server_permissions": api_key.server_permissions, - "crafty_permissions": api_key.crafty_permissions, - "superuser": api_key.superuser, - } - if api_key is not None - else None, + "api_key": ( + { + "name": api_key.name, + "created": api_key.created, + "server_permissions": api_key.server_permissions, + "crafty_permissions": api_key.crafty_permissions, + "superuser": api_key.superuser, + } + if api_key is not None + else None + ), "superuser": superuser, } From e053f4a750dd540a7f5f51c10417837bdc9da829 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Mon, 19 Feb 2024 18:07:17 -0500 Subject: [PATCH 05/15] Check server creation for clone server call --- .../web/routes/api/servers/server/action.py | 6 +++- app/frontend/templates/panel/dashboard.html | 35 ++++++++++--------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/app/classes/web/routes/api/servers/server/action.py b/app/classes/web/routes/api/servers/server/action.py index 153b889d..d23262f5 100644 --- a/app/classes/web/routes/api/servers/server/action.py +++ b/app/classes/web/routes/api/servers/server/action.py @@ -30,7 +30,11 @@ class ApiServersServerActionHandler(BaseApiHandler): return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"}) if action == "clone_server": - return self._clone_server(server_id, auth_data[4]["user_id"]) + if self.controller.crafty_perms.can_create_server(auth_data[4]["user_id"]): + return self._clone_server(server_id, auth_data[4]["user_id"]) + return self.finish_json( + 200, {"status": "error", "error": "SERVER_LIMIT_REACHED"} + ) if action == "eula": return self._agree_eula(server_id, auth_data[4]["user_id"]) diff --git a/app/frontend/templates/panel/dashboard.html b/app/frontend/templates/panel/dashboard.html index 0d4fc0ac..7778300a 100644 --- a/app/frontend/templates/panel/dashboard.html +++ b/app/frontend/templates/panel/dashboard.html @@ -598,26 +598,27 @@