diff --git a/frappe/core/doctype/role/role.json b/frappe/core/doctype/role/role.json index 1b147e3ddb..c963badf6b 100644 --- a/frappe/core/doctype/role/role.json +++ b/frappe/core/doctype/role/role.json @@ -64,7 +64,7 @@ "options": "Domain" }, { - "description": "Route: Example \"/desk\"", + "description": "Route: Example \"/app\"", "fieldname": "home_page", "fieldtype": "Data", "label": "Home Page" @@ -148,7 +148,7 @@ "idx": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2023-12-08 15:52:37.525003", + "modified": "2024-03-13 20:59:37.875253", "modified_by": "Administrator", "module": "Core", "name": "Role", diff --git a/frappe/core/doctype/role/role.py b/frappe/core/doctype/role/role.py index e868b5b978..4539093fc9 100644 --- a/frappe/core/doctype/role/role.py +++ b/frappe/core/doctype/role/role.py @@ -3,6 +3,7 @@ import frappe from frappe.model.document import Document +from frappe.website.path_resolver import validate_path desk_properties = ( "search_bar", @@ -14,6 +15,7 @@ desk_properties = ( "timeline", "dashboard", ) +from frappe.website.router import clear_routing_cache STANDARD_ROLES = ("Administrator", "System Manager", "Script Manager", "All", "Guest") @@ -56,6 +58,7 @@ class Role(Document): self.disable_role() else: self.set_desk_properties() + self.validate_homepage() def disable_role(self): if self.name in STANDARD_ROLES: @@ -63,6 +66,13 @@ class Role(Document): else: self.remove_roles() + def validate_homepage(self): + if frappe.request and self.home_page: + validate_path(self.home_page) + + if self.has_value_changed("home_page"): + clear_routing_cache() + def set_desk_properties(self): # set if desk_access is not allowed, unset all desk properties if self.name == "Guest": diff --git a/frappe/tests/test_caching.py b/frappe/tests/test_caching.py index 083cfa8a6b..9a0da1935f 100644 --- a/frappe/tests/test_caching.py +++ b/frappe/tests/test_caching.py @@ -297,7 +297,7 @@ class TestRedisWrapper(FrappeAPITestCase): frappe.clear_cache(user=user1) # Check that the keys for user1 are gone - for key in user_cache_keys: + for key in set(user_cache_keys) - {"home_page"}: self.assertFalse(frappe.cache.hexists(key, user1)) self.assertTrue(frappe.cache.hexists(key, user2)) diff --git a/frappe/website/doctype/portal_settings/portal_settings.py b/frappe/website/doctype/portal_settings/portal_settings.py index a531557f5e..6885fbb82a 100644 --- a/frappe/website/doctype/portal_settings/portal_settings.py +++ b/frappe/website/doctype/portal_settings/portal_settings.py @@ -3,6 +3,7 @@ import frappe from frappe.model.document import Document +from frappe.website.path_resolver import validate_path class PortalSettings(Document): @@ -73,3 +74,7 @@ class PortalSettings(Document): for menu_item in list(self.get("menu") + self.get("custom_menu")): if menu_item.reference_doctype not in existing_doctypes: self.remove(menu_item) + + def validate(self): + if frappe.request and self.default_portal_home: + validate_path(self.default_portal_home) diff --git a/frappe/website/path_resolver.py b/frappe/website/path_resolver.py index 0585dda631..f6771a3d6e 100644 --- a/frappe/website/path_resolver.py +++ b/frappe/website/path_resolver.py @@ -190,3 +190,8 @@ def get_website_rules(): return _get() return frappe.cache.get_value("website_route_rules", _get) + + +def validate_path(path: str): + if not PathResolver(path).is_valid_path(): + frappe.throw(frappe._("Path {0} it not a valid path").format(frappe.bold(path))) diff --git a/frappe/website/router.py b/frappe/website/router.py index 41c8706331..84efd4e6c6 100644 --- a/frappe/website/router.py +++ b/frappe/website/router.py @@ -328,3 +328,4 @@ def clear_routing_cache(): get_dynamic_web_pages.clear_cache() get_published_web_forms.clear_cache() get_public_pages_from_doctypes.clear_cache() + frappe.cache.delete_value("home_page")