diff --git a/wiki/wiki/doctype/wiki_page/wiki_page.py b/wiki/wiki/doctype/wiki_page/wiki_page.py
index 0fc1acea..10d406f4 100644
--- a/wiki/wiki/doctype/wiki_page/wiki_page.py
+++ b/wiki/wiki/doctype/wiki_page/wiki_page.py
@@ -50,17 +50,23 @@ def on_update(self):
update_index(self)
def on_trash(self):
- frappe.db.sql("DELETE FROM `tabWiki Page Revision Item` WHERE wiki_page = %s", self.name)
-
- frappe.db.sql(
- """DELETE FROM `tabWiki Page Revision` WHERE name in
- (
- SELECT name FROM `tabWiki Page Revision`
- EXCEPT
- SELECT DISTINCT parent from `tabWiki Page Revision Item`
- )"""
+ frappe.delete_doc_if_exists('Wiki Page Revision Item', {'wiki_page': self.name})
+
+ # Get names of revisions that are not referenced in `Wiki Page Revision Item`
+ revisions_to_delete = frappe.db.get_all(
+ "Wiki Page Revision",
+ filters={
+ "name": ["not in", frappe.db.get_all(
+ "Wiki Page Revision Item",
+ fields=["distinct parent"]
+ )]
+ },
+ pluck="name"
)
+ if revisions_to_delete:
+ frappe.db.delete("Wiki Page Revision", {"name": ["in", revisions_to_delete]})
+
for name in frappe.get_all("Wiki Page Patch", {"wiki_page": self.name, "new": 0}, pluck="name"):
patch = frappe.get_doc("Wiki Page Patch", name)
try:
@@ -72,8 +78,7 @@ def on_trash(self):
for name in frappe.get_all("Wiki Page Patch", {"wiki_page": self.name, "new": 1}, pluck="name"):
frappe.db.set_value("Wiki Page Patch", name, "wiki_page", "")
- wiki_sidebar_name = frappe.get_value("Wiki Group Item", {"wiki_page": self.name})
- frappe.delete_doc("Wiki Group Item", wiki_sidebar_name)
+ frappe.db.delete("Wiki Group Item", {"wiki_page": self.name})
clear_sidebar_cache()
remove_index(self)
@@ -153,8 +158,7 @@ def update_page(self, title, content, edit_message, raised_by=None):
def verify_permission(self, permtype):
if permtype == "read" and self.allow_guest:
return True
- permitted = frappe.has_permission(self.doctype, permtype, self)
- if not permitted:
+ if not frappe.has_permission(self.doctype, permtype, self):
action = permtype
if action == "write":
action = "edit"
@@ -211,79 +215,80 @@ def get_context(self, context):
self.set_breadcrumbs(context)
wiki_settings = frappe.get_single("Wiki Settings")
+
+ if sbool(wiki_settings.enable_custom_permissions) and frappe.session.user != "Administrator" and not self.allow_guest:
+ user_permissions = frappe.db.get_all("User Permission", filters={"user": frappe.session.user, "allow": "Wiki Space"}, pluck="for_value")
+
+ if not user_permissions or not frappe.db.exists("Wiki Group Item", {"parent": ["in", user_permissions], "wiki_page": self.name}):
+ raise frappe.PermissionError(_("It seems you don't have access to this page. Please contact an administrator if you believe this is a mistake."))
+
wiki_space_name = frappe.get_value("Wiki Group Item", {"wiki_page": self.name}, "parent")
wiki_space = frappe.get_doc("Wiki Space", wiki_space_name)
- context.no_cache = 1
- context.navbar_search = wiki_settings.add_search_bar
- context.light_mode_logo = wiki_space.light_mode_logo or wiki_settings.logo
- context.dark_mode_logo = wiki_space.dark_mode_logo or wiki_settings.dark_mode_logo
- if wiki_space.light_mode_logo or wiki_space.dark_mode_logo:
- context.home_page = "/" + wiki_space.route
- context.script = wiki_settings.javascript
- context.show_feedback = wiki_settings.enable_feedback
- context.ask_for_contact_details = wiki_settings.ask_for_contact_details
- context.wiki_search_scope = self.get_space_route()
- context.metatags = {
- "title": self.title,
- "description": self.meta_description,
- "keywords": self.meta_keywords,
- "image": self.meta_image,
- "og:image:width": "1200",
- "og:image:height": "630",
- }
- context.edit_wiki_page = frappe.form_dict.get("editWiki")
- context.new_wiki_page = frappe.form_dict.get("newWiki")
- context.last_revision = self.get_last_revision()
- context.number_of_revisions = frappe.db.count("Wiki Page Revision Item", {"wiki_page": self.name})
- # TODO: group all context values
- context.hide_on_sidebar = frappe.get_value(
- "Wiki Group Item", {"wiki_page": self.name}, "hide_on_sidebar"
- )
- html = frappe.utils.md_to_html(self.content)
- context.content = html
- context.page_toc_html = (
- self.calculate_toc_html(html) if wiki_settings.enable_table_of_contents else None
- )
-
+ # Fetch values that are used more than once
+ navbar_items = wiki_space.navbar_items or wiki_settings.navbar
+ light_mode_logo = wiki_space.light_mode_logo or wiki_settings.logo
+ dark_mode_logo = wiki_space.dark_mode_logo or wiki_settings.dark_mode_logo
revisions = frappe.db.get_all(
"Wiki Page Revision",
filters=[["wiki_page", "=", self.name]],
fields=["content", "creation", "owner", "name", "raised_by", "raised_by_username"],
)
- context.current_revision = revisions[0]
- if len(revisions) > 1:
- context.previous_revision = revisions[1]
- else:
- context.previous_revision = {"content": "
No Revisions
", "name": ""}
- context.show_sidebar = True
- context.hide_login = True
- context.name = self.name
- if (frappe.form_dict.editWiki or frappe.form_dict.newWiki) and frappe.form_dict.wikiPagePatch:
- context.patch_new_code, context.patch_new_title = frappe.db.get_value(
+ # Prepare context updates in a single dictionary
+ context_updates = {
+ "no_cache": 1,
+ "navbar_search": wiki_settings.add_search_bar,
+ "light_mode_logo": light_mode_logo,
+ "dark_mode_logo": dark_mode_logo,
+ "home_page": f"/{wiki_space.route}" if light_mode_logo or dark_mode_logo else None,
+ "script": wiki_settings.javascript,
+ "show_feedback": wiki_settings.enable_feedback,
+ "ask_for_contact_details": wiki_settings.ask_for_contact_details,
+ "wiki_search_scope": self.get_space_route(),
+ "metatags": {
+ "title": self.title,
+ "description": self.meta_description,
+ "keywords": self.meta_keywords,
+ "image": self.meta_image,
+ "og:image:width": "1200",
+ "og:image:height": "630",
+ },
+ "edit_wiki_page": frappe.form_dict.get("editWiki"),
+ "new_wiki_page": frappe.form_dict.get("newWiki"),
+ "last_revision": self.get_last_revision(),
+ "number_of_revisions": frappe.db.count("Wiki Page Revision Item", {"wiki_page": self.name}),
+ "hide_on_sidebar": frappe.get_value("Wiki Group Item", {"wiki_page": self.name}, "hide_on_sidebar"),
+ "content": frappe.utils.md_to_html(self.content),
+ "page_toc_html": self.calculate_toc_html(
+ frappe.utils.md_to_html(self.content)) if wiki_settings.enable_table_of_contents else None,
+ "current_revision": revisions[0] if revisions else 0,
+ "previous_revision": revisions[1] if len(revisions) > 1 else {"content": "No Revisions
",
+ "name": ""},
+ "show_sidebar": True,
+ "hide_login": True,
+ "name": self.name,
+ "navbar_items": modify_header_footer_items(navbar_items),
+ "post_login": [
+ {"label": _("My Account"), "url": "/me"},
+ {"label": _("Logout"), "url": "/?cmd=web_logout"},
+ {"label": _("Contributions ") + get_open_contributions(), "url": "/contributions"},
+ {"label": _("My Drafts ") + get_open_drafts(), "url": "/drafts"},
+ ],
+ }
+
+ # Handle conditional patch updates
+ if (context_updates["edit_wiki_page"] or context_updates["new_wiki_page"]) and frappe.form_dict.wikiPagePatch:
+ context_updates["patch_new_code"], context_updates["patch_new_title"] = frappe.db.get_value(
"Wiki Page Patch", frappe.form_dict.wikiPagePatch, ["new_code", "new_title"]
)
- context = context.update(
- {
- "navbar_items": modify_header_footer_items(wiki_space.navbar_items or wiki_settings.navbar),
- "post_login": [
- {"label": _("My Account"), "url": "/me"},
- {"label": _("Logout"), "url": "/?cmd=web_logout"},
- {
- "label": _("Contributions ") + get_open_contributions(),
- "url": "/contributions",
- },
- {
- "label": _("My Drafts ") + get_open_drafts(),
- "url": "/drafts",
- },
- ],
- }
- )
+
+ # Apply all context updates in one go
+ context.update(context_updates)
def get_items(self, sidebar_items):
topmost = frappe.get_value("Wiki Group Item", {"wiki_page": self.name}, ["parent"])
+ wikiSpace = frappe.get_all('Wiki Space', pluck='name')
sidebar_html = frappe.cache().hget("wiki_sidebar", topmost)
if not sidebar_html or frappe.conf.disable_website_cache or frappe.conf.developer_mode:
@@ -295,6 +300,7 @@ def get_items(self, sidebar_items):
context.current_route = self.route
context.collapse_sidebar_groups = wiki_settings.collapse_sidebar_groups
context.sidebar_items = sidebar_items
+ context.wikiSpace = wikiSpace
context.wiki_search_scope = self.get_space_route()
sidebar_html = frappe.render_template(
"wiki/wiki/doctype/wiki_page/templates/web_sidebar.html", context
@@ -313,31 +319,18 @@ def get_sidebar_items(self):
wiki_page = frappe.get_doc("Wiki Page", sidebar_item.wiki_page)
- if not wiki_page.allow_guest:
- permitted = frappe.has_permission(wiki_page.doctype, "read", wiki_page)
- if not permitted:
- continue
-
- if sidebar_item.parent_label not in sidebar:
- sidebar[sidebar_item.parent_label] = [
- {
- "name": wiki_page.name,
- "type": "Wiki Page",
- "title": wiki_page.title,
- "route": wiki_page.route,
- "group_name": sidebar_item.parent_label,
- }
- ]
- else:
- sidebar[sidebar_item.parent_label] += [
- {
- "name": wiki_page.name,
- "type": "Wiki Page",
- "title": wiki_page.title,
- "route": wiki_page.route,
- "group_name": sidebar_item.parent_label,
- }
- ]
+ if wiki_page.allow_guest or frappe.has_permission(wiki_page.doctype, "read", wiki_page):
+ page_info = {
+ "name": wiki_page.name,
+ "type": "Wiki Page",
+ "title": wiki_page.title,
+ "route": wiki_page.route,
+ "group_name": sidebar_item.parent_label,
+ }
+ if sidebar_item.parent_label not in sidebar:
+ sidebar[sidebar_item.parent_label] = [page_info]
+ else:
+ sidebar[sidebar_item.parent_label].append(page_info)
return self.get_items(sidebar)
@@ -345,7 +338,8 @@ def get_last_revision(self):
last_revision = frappe.db.get_value(
"Wiki Page Revision Item", filters={"wiki_page": self.name}, fieldname="parent"
)
- return frappe.get_doc("Wiki Page Revision", last_revision)
+ if frappe.db.exists('Wiki Page Revision', last_revision):
+ return frappe.get_doc("Wiki Page Revision", last_revision)
def clone(self, original_space, new_space):
# used in after_insert of Wiki Page to resist create of Wiki Page Revision
diff --git a/wiki/wiki/doctype/wiki_settings/wiki_settings.json b/wiki/wiki/doctype/wiki_settings/wiki_settings.json
index c8ea81a0..a312a4b4 100644
--- a/wiki/wiki/doctype/wiki_settings/wiki_settings.json
+++ b/wiki/wiki/doctype/wiki_settings/wiki_settings.json
@@ -14,6 +14,8 @@
"table_of_contents_section",
"collapse_sidebar_groups",
"enable_table_of_contents",
+ "permission_settings_section",
+ "enable_custom_permissions",
"navbar_tab",
"navbar_column",
"navbar",
@@ -149,12 +151,24 @@
"fieldname": "feedback_tab",
"fieldtype": "Tab Break",
"label": "Feedback"
+ },
+ {
+ "default": "0",
+ "description": "Enable this to enforce permissions on Wiki pages.",
+ "fieldname": "enable_custom_permissions",
+ "fieldtype": "Check",
+ "label": "Enable Custom Permissions"
+ },
+ {
+ "fieldname": "permission_settings_section",
+ "fieldtype": "Section Break",
+ "label": "Permission Settings"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
- "modified": "2024-06-03 16:19:02.137667",
+ "modified": "2024-09-11 15:36:40.973302",
"modified_by": "Administrator",
"module": "Wiki",
"name": "Wiki Settings",