Safer handling of file download paths

This commit is contained in:
Daniel Markstedt 2023-11-01 00:06:11 +09:00
parent 797055703d
commit 9ebb77fe1d
3 changed files with 8 additions and 8 deletions

View File

@ -486,14 +486,14 @@ class FileCmds:
file_name = PurePath(url).name file_name = PurePath(url).name
iso_filename = Path(server_info["image_dir"]) / f"{file_name}.iso" iso_filename = Path(server_info["image_dir"]) / f"{file_name}.iso"
tmp_full_path = Path(tmp_dir) / file_name
with TemporaryDirectory() as tmp_dir: with TemporaryDirectory() as tmp_dir:
req_proc = self.download_to_dir(quote(url, safe=URL_SAFE), tmp_dir, file_name) req_proc = self.download_to_dir(quote(url, safe=URL_SAFE), tmp_full_path)
logging.info("Downloaded %s to %s", file_name, tmp_dir) logging.info("Downloaded %s to %s", file_name, tmp_dir)
if not req_proc["status"]: if not req_proc["status"]:
return {"status": False, "msg": req_proc["msg"]} return {"status": False, "msg": req_proc["msg"]}
tmp_full_path = Path(tmp_dir) / file_name
if is_zipfile(tmp_full_path): if is_zipfile(tmp_full_path):
if "XtraStuf.mac" in str(ZipFile(str(tmp_full_path)).namelist()): if "XtraStuf.mac" in str(ZipFile(str(tmp_full_path)).namelist()):
logging.info( logging.info(
@ -565,9 +565,9 @@ class FileCmds:
} }
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
def download_to_dir(self, url, save_dir, file_name): def download_to_dir(self, url, target_path):
""" """
Takes (str) url, (str) save_dir, (str) file_name Takes (str) url, (Path) target_path
Returns (dict) with (bool) status and (str) msg Returns (dict) with (bool) status and (str) msg
""" """
logging.info("Making a request to download %s", url) logging.info("Making a request to download %s", url)
@ -580,7 +580,7 @@ class FileCmds:
) as req: ) as req:
req.raise_for_status() req.raise_for_status()
try: try:
with open(f"{save_dir}/{file_name}", "wb") as download: with open(str(target_path), "wb") as download:
for chunk in req.iter_content(chunk_size=8192): for chunk in req.iter_content(chunk_size=8192):
download.write(chunk) download.write(chunk)
except FileNotFoundError as error: except FileNotFoundError as error:
@ -593,7 +593,7 @@ class FileCmds:
logging.info("Response content-type: %s", req.headers["content-type"]) logging.info("Response content-type: %s", req.headers["content-type"])
logging.info("Response status code: %s", req.status_code) logging.info("Response status code: %s", req.status_code)
parameters = {"file_name": file_name, "save_dir": save_dir} parameters = {"target_path": str(target_path)}
return { return {
"status": True, "status": True,
"return_code": ReturnCodes.DOWNLOADTODIR_SUCCESS, "return_code": ReturnCodes.DOWNLOADTODIR_SUCCESS,

View File

@ -23,7 +23,7 @@ class ReturnCodeMapper:
ReturnCodes.DOWNLOADFILETOISO_SUCCESS: ReturnCodes.DOWNLOADFILETOISO_SUCCESS:
_("Created CD-ROM ISO image with arguments \"%(value)s\""), _("Created CD-ROM ISO image with arguments \"%(value)s\""),
ReturnCodes.DOWNLOADTODIR_SUCCESS: ReturnCodes.DOWNLOADTODIR_SUCCESS:
_("%(file_name)s downloaded to %(save_dir)s"), _("Downloaded file to %(target_path)s"),
ReturnCodes.WRITEFILE_SUCCESS: ReturnCodes.WRITEFILE_SUCCESS:
_("File created: %(target_path)s"), _("File created: %(target_path)s"),
ReturnCodes.WRITEFILE_COULD_NOT_WRITE: ReturnCodes.WRITEFILE_COULD_NOT_WRITE:

View File

@ -991,7 +991,7 @@ def download_file():
else: else:
return response(error=True, message=_("Unknown destination")) return response(error=True, message=_("Unknown destination"))
process = file_cmd.download_to_dir(url, destination_dir, Path(url).name) process = file_cmd.download_to_dir(url, Path(destination_dir) / Path(url).name)
process = ReturnCodeMapper.add_msg(process) process = ReturnCodeMapper.add_msg(process)
if process["status"]: if process["status"]:
return response(message=process["msg"]) return response(message=process["msg"])