From bfd4eb201df5b48701dcad2b8f82d2af0543a4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Sat, 16 Mar 2024 11:25:38 +0000 Subject: [PATCH] Refactor get_jobs_cache_files method and add cache content to cache files back in the web UI --- src/common/db/Database.py | 35 ++++++++++++---------- src/common/utils/jobs.py | 2 +- src/ui/Dockerfile | 4 +-- src/ui/utils.py | 63 ++++++++++++++++++++++++++++----------- 4 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/common/db/Database.py b/src/common/db/Database.py index ec0615f30..486dba07c 100644 --- a/src/common/db/Database.py +++ b/src/common/db/Database.py @@ -1753,42 +1753,47 @@ class Database: ret_data["data"] = data.data return ret_data - def get_jobs_cache_files(self, *, job_name: str = "", plugin_id: str = "", with_data: bool = False) -> List[Dict[str, Any]]: + def get_jobs_cache_files(self, *, job_name: str = "", plugin_id: str = "") -> List[Dict[str, Any]]: """Get jobs cache files.""" with self.__db_session() as session: - entities = [Jobs_cache.job_name, Jobs_cache.service_id, Jobs_cache.file_name] - if with_data: - entities.append(Jobs_cache.data) - - query = session.query(Jobs_cache).with_entities(*entities) + filters = {} + query = session.query(Jobs_cache).with_entities(Jobs_cache.job_name, Jobs_cache.service_id, Jobs_cache.file_name, Jobs_cache.data) if job_name: query = query.filter_by(job_name=job_name) + filters["name"] = job_name db_cache = query.all() if not db_cache: return [] - job_names = [] if plugin_id: - filters = {"plugin_id": plugin_id} - if job_name: - filters["name"] = job_name - job_names = [job.name for job in session.query(Jobs).with_entities(Jobs.name).filter_by(**filters)] - if not job_names: - return [] + filters["plugin_id"] = plugin_id + + query = session.query(Jobs).with_entities(Jobs.name, Jobs.plugin_id) + + if filters: + query = query.filter_by(**filters) + + jobs = {} + for job in query: + jobs[job.name] = job.plugin_id + + if not jobs: + return [] cache_files = [] for cache in db_cache: - if job_name and cache.job_name not in job_names: + if cache.job_name not in jobs: continue cache_files.append( { + "plugin_id": jobs[cache.job_name], "job_name": cache.job_name, "service_id": cache.service_id, "file_name": cache.file_name, - "data": "Download file to view content" if not with_data else cache.data, + "data": cache.data, } ) return cache_files diff --git a/src/common/utils/jobs.py b/src/common/utils/jobs.py index 5f2b510b6..f9f253476 100644 --- a/src/common/utils/jobs.py +++ b/src/common/utils/jobs.py @@ -54,7 +54,7 @@ class Job: """Restore job cache files from database.""" ret = True with LOCK: - job_cache_files = self.db.get_jobs_cache_files(plugin_id=plugin_id or self.job_path.name, with_data=True) # type: ignore + job_cache_files = self.db.get_jobs_cache_files(plugin_id=plugin_id or self.job_path.name) # type: ignore job_name = job_name or self.job_name plugin_cache_files = set() diff --git a/src/ui/Dockerfile b/src/ui/Dockerfile index 487147c8c..8af619ba3 100644 --- a/src/ui/Dockerfile +++ b/src/ui/Dockerfile @@ -38,8 +38,8 @@ COPY --from=builder --chown=0:101 /usr/share/bunkerweb /usr/share/bunkerweb WORKDIR /usr/share/bunkerweb -# Add ui user, drop bwcli, install runtime dependencies, create data folders and set permissions -RUN apk add --no-cache bash && \ +# Add ui user, install runtime dependencies, create data folders and set permissions +RUN apk add --no-cache bash libmagic && \ addgroup -g 101 ui && \ adduser -h /var/cache/nginx -g ui -s /bin/sh -G ui -D -H -u 101 ui && \ echo "Docker" > INTEGRATION && \ diff --git a/src/ui/utils.py b/src/ui/utils.py index 346dec009..20ae27c95 100644 --- a/src/ui/utils.py +++ b/src/ui/utils.py @@ -5,6 +5,7 @@ from io import BytesIO from os.path import join from typing import List, Optional +from magic import Magic from qrcode.main import QRCode @@ -131,40 +132,68 @@ def path_to_dict( "can_create_folders": False, "can_edit": False, "can_delete": False, - "children": [ - { - "name": service, - "type": "folder", - "path": join(path, service), - "can_create_files": False, - "can_create_folders": False, - "can_edit": False, - "can_delete": False, - "children": [], - } - for service in services - ], + "children": [], } + plugins = [] + paths = [] for conf in db_data: + if conf["plugin_id"] not in plugins: + d["children"].append( + { + "name": conf["plugin_id"], + "type": "folder", + "path": join(path, conf["plugin_id"]), + "can_create_files": True, + "can_create_folders": False, + "can_edit": False, + "can_delete": False, + "children": [], + } + ) + plugins.append(conf["plugin_id"]) + paths.append(join(path, conf["plugin_id"])) + + mime = Magic(mime=True) + file_type = mime.from_buffer(conf["data"]) + + print(join(path, conf["plugin_id"], conf["service_id"] or "", conf["file_name"]), file_type, flush=True) + file_info = { - "name": join(conf["job_name"], conf["file_name"]), + "name": conf["file_name"], "type": "file", "path": join( path, + conf["plugin_id"], conf["service_id"] or "", conf["file_name"], ), "can_edit": False, "can_delete": False, "can_download": True, - "content": conf["data"], + "content": "Download file to view content" if file_type != "text/plain" else conf["data"].decode("utf-8"), } if conf["service_id"]: - d["children"][[x["name"] for x in d["children"]].index(conf["service_id"])]["children"].append(file_info) + if join(conf["plugin_id"], conf["service_id"]) not in paths: + d["children"][[x["name"] for x in d["children"]].index(conf["plugin_id"])]["children"].append( + { + "name": conf["service_id"], + "type": "folder", + "path": join(path, conf["plugin_id"], conf["service_id"]), + "can_create_files": True, + "can_create_folders": False, + "can_edit": False, + "can_delete": False, + "children": [], + } + ) + paths.append(join(conf["plugin_id"], conf["service_id"])) + + data_plugin = d["children"][[x["name"] for x in d["children"]].index(conf["plugin_id"])] + data_plugin["children"][[x["name"] for x in data_plugin["children"]].index(conf["service_id"])]["children"].append(file_info) else: - d["children"].append(file_info) + d["children"][[x["name"] for x in d["children"]].index(conf["plugin_id"])]["children"].append(file_info) return d