diff --git a/cypress/e2e/course_creation.cy.js b/cypress/e2e/course_creation.cy.js index 8a8e0f2d..8d9f577c 100644 --- a/cypress/e2e/course_creation.cy.js +++ b/cypress/e2e/course_creation.cy.js @@ -176,7 +176,10 @@ describe("Course Creation", () => { cy.get("div").contains("Test Course").click(); cy.get("button").contains("Settings").click(); cy.get("header").within(() => { - cy.get("svg.lucide.lucide-trash2-icon").click(); + cy.get("svg.lucide.lucide-ellipsis-icon").click(); + }); + cy.get("div[role=menu]").within(() => { + cy.get("span").contains("Delete").click(); }); cy.get("span").contains("Delete").click(); cy.wait(500); diff --git a/lms/lms/course_import_export.py b/lms/lms/course_import_export.py index d626713d..74d44110 100644 --- a/lms/lms/course_import_export.py +++ b/lms/lms/course_import_export.py @@ -11,6 +11,7 @@ from urllib.parse import urlparse import frappe from frappe import _ from frappe.utils import escape_html, validate_email_address +from frappe.utils.file_manager import is_safe_path def export_course_zip(course_name): @@ -151,6 +152,8 @@ def read_asset_content(url): try: file_doc = frappe.get_doc("File", {"file_url": url}) file_path = file_doc.get_full_path() + if not is_safe_path(file_path): + return None with open(file_path, "rb") as f: return f.read() except Exception: @@ -657,8 +660,7 @@ def create_asset_doc(asset_name, content): def process_asset_file(zip_file, file): - if is_unsafe_path(file): - frappe.log_error(f"Unsafe asset path: {file}") + if not is_safe_path(file): return with zip_file.open(file) as f: create_asset_doc(file.split("/")[-1], f.read()) @@ -719,7 +721,3 @@ def sanitize_filename(filename): def validate_zip_file(zip_file_path): if not os.path.exists(zip_file_path) or not zipfile.is_zipfile(zip_file_path): frappe.throw(_("Invalid ZIP file")) - - -def is_unsafe_path(path): - return ".." in path or path.startswith("/") or path.startswith("\\") or re.search(r'[<>:"|?*]', path) diff --git a/lms/lms/test_api.py b/lms/lms/test_api.py index d75c50f3..0b88cc3f 100644 --- a/lms/lms/test_api.py +++ b/lms/lms/test_api.py @@ -146,7 +146,7 @@ class TestLMSAPI(BaseTestUtils): def get_imported_course(self): latest_file = self.get_latest_zip_file() self.assertTrue(latest_file) - zip_file_path = f"/{latest_file.lstrip(frappe.get_site_path())}" + zip_file_path = f"/{"/".join(latest_file.split("/")[2:])}" imported_course_name = import_course_from_zip(zip_file_path) imported_course = frappe.get_doc("LMS Course", imported_course_name) return imported_course