Skip to content

fix:validate the route to ensure wiki is not accepted#638

Open
wreckage0907 wants to merge 2 commits into
frappe:developfrom
wreckage0907:fix/validate-route
Open

fix:validate the route to ensure wiki is not accepted#638
wreckage0907 wants to merge 2 commits into
frappe:developfrom
wreckage0907:fix/validate-route

Conversation

@wreckage0907

@wreckage0907 wreckage0907 commented May 29, 2026

Copy link
Copy Markdown

Description

This pull request introduces validation to prevent the creation or update of Wiki Space documents with routes that conflict with the reserved /wiki namespace, which is used by the Wiki editor SPA. The changes ensure that routes cannot be set to wiki or any subpath under wiki/, both when creating, updating, or cloning a wiki space. Comprehensive tests are also added to verify this behavior.

Route validation enhancements:

  • Added the is_reserved_route function and a RESERVED_ROUTE constant to centralize logic for detecting reserved routes (wiki and its subpaths) in wiki_space.py.
  • Updated the validate, update_routes, and clone_wiki_space_in_background methods in the Wiki Space doctype to reject reserved routes by raising a frappe.ValidationError with a clear message. [1] [2] [3]

Testing improvements:

  • Added a new test class TestWikiSpaceRouteValidation to ensure that reserved routes are correctly rejected during creation and updates, and that valid routes are still allowed.

Adds validation so a Wiki Space can't be created or updated with a route of wiki or one starting with wiki/. That path is reserved for internal use (the editor SPA), so such spaces were unreachable and rendered a blank page. Users now get a clear error and are pointed to a valid route (e.g. docs).

Relevant technical information

  • is_reserved_route() helper added; validate() and update_routes() reject reserved routes.
  • Covers Desk, the API, and the route editor.
  • Tests added in test_wiki_space.py.

Screenshot

image

Fixes #637

Summary by CodeRabbit

  • New Features

    • Enforced route namespace rules for Wiki Spaces to block reserved routes (e.g., "wiki", "wiki/trial") across creation, updates, and cloning operations.
  • Tests

    • Added test coverage confirming reserved routes are rejected and non-reserved routes are accepted; tests clean up state after each run.

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fc4814cf-9e89-48bf-bce9-af4f3bfe286c

📥 Commits

Reviewing files that changed from the base of the PR and between b3e3d05 and c3203d8.

📒 Files selected for processing (2)
  • wiki/wiki/doctype/wiki_space/test_wiki_space.py
  • wiki/wiki/doctype/wiki_space/wiki_space.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • wiki/wiki/doctype/wiki_space/test_wiki_space.py

Walkthrough

This pull request adds route-namespace validation to the WikiSpace doctype to prevent creation or updates using routes reserved by the wiki editor. A new RESERVED_ROUTE constant and is_reserved_route() helper define the reserved pattern (wiki namespace and all wiki/... subpaths). The validate() method now calls validate_route_namespace() during insert to enforce this rule, and the update_routes() method validates new routes against the same pattern. Test coverage verifies that reserved routes raise ValidationError while non-reserved routes are accepted.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix:validate the route to ensure wiki is not accepted' directly describes the main change—adding route validation to prevent wiki and wiki/* routes.
Linked Issues check ✅ Passed The changes fully implement the requirements from issue #637: validation rejects routes equal to 'wiki' or starting with 'wiki/' across validation, updates, and cloning, with appropriate error messages.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing reserved-route validation as per issue #637; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
wiki/wiki/doctype/wiki_space/wiki_space.py (1)

243-248: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate reserved routes before enqueueing the clone job.

Currently, clone_wiki_space_in_background validates empty/duplicate routes but not reserved routes. The validation will eventually happen when _create_space_copy calls new_space.insert() (line 314), but that occurs asynchronously in the background job. If a user attempts to clone to a reserved route, they won't receive immediate feedback and the job will fail silently (or in logs), leading to a poor user experience.

🛡️ Proposed fix to add early validation
 	new_route = (new_space_route or "").strip().strip("/")
 	if not new_route:
 		frappe.throw(_("Route cannot be empty"))
 
+	if is_reserved_route(new_route):
+		frappe.throw(
+			_(
+				"Route cannot be '{0}' or start with '{0}/' — that path is reserved for the "
+				"Wiki editor. Use a different route, e.g. 'docs'."
+			).format(RESERVED_ROUTE),
+			frappe.ValidationError
+		)
+
 	if new_route == self.route:
 		frappe.throw(_("New route is the same as current route"))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wiki/wiki/doctype/wiki_space/wiki_space.py` around lines 243 - 248, The
clone_wiki_space_in_background function currently only checks empty/duplicate
routes but defers reserved-route validation to the async _create_space_copy
(which calls new_space.insert()), so add an early synchronous reserved-route
check before enqueueing: reuse the same route validation logic used by
_create_space_copy/new_space.insert() (or call the shared route validation
helper if one exists) and call frappe.throw with a clear message if the route is
reserved; ensure this check references clone_wiki_space_in_background,
_create_space_copy, and new_space.insert() so the validation happens immediately
and prevents enqueueing a job for a reserved route.
🧹 Nitpick comments (3)
wiki/wiki/doctype/wiki_space/test_wiki_space.py (1)

311-337: ⚡ Quick win

Consider adding test coverage for the update_routes() method.

The current tests verify that reserved routes are rejected during insert, which is good. However, the update_routes() method also validates reserved routes (wiki_space.py:174-179) and should be tested to ensure that existing spaces cannot be updated to use reserved routes.

🧪 Suggested test case
def test_update_routes_rejects_reserved_route(self):
	# Create a space with a valid route
	space = frappe.get_doc(
		{
			"doctype": "Wiki Space",
			"space_name": f"Update Test {frappe.generate_hash(length=6)}",
			"route": f"docs-{frappe.generate_hash(length=6)}",
		}
	).insert()
	
	# Attempt to update to a reserved route should fail
	with self.assertRaises(frappe.ValidationError):
		space.update_routes("wiki")
	
	with self.assertRaises(frappe.ValidationError):
		space.update_routes("wiki/updated")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wiki/wiki/doctype/wiki_space/test_wiki_space.py` around lines 311 - 337, Add
a new unit test in TestWikiSpaceRouteValidation that asserts Wiki
Space.update_routes() rejects reserved routes: create a Wiki Space with a valid
route (use frappe.generate_hash like other tests), then call the instance method
update_routes("wiki") and update_routes("wiki/updated") inside with
self.assertRaises(frappe.ValidationError) blocks to ensure the validation logic
in update_routes() is covered; reference the TestWikiSpaceRouteValidation class
and the update_routes() method when adding the test.
wiki/wiki/doctype/wiki_space/wiki_space.py (2)

174-179: ⚡ Quick win

Pass exception type explicitly and align error message with validate_route_namespace().

Two issues:

  1. Missing explicit frappe.ValidationError (same as Line 69-76)
  2. The error message omits the helpful suggestion "Use a different route, e.g. 'docs'." that appears in validate_route_namespace(). Consistent messaging improves UX.
♻️ Proposed fix
 if is_reserved_route(new_route):
 	frappe.throw(
 		_(
-			"Route cannot be '{0}' or start with '{0}/' — that path is reserved for the Wiki editor."
-		).format(RESERVED_ROUTE)
+			"Route cannot be '{0}' or start with '{0}/' — that path is reserved for the "
+			"Wiki editor. Use a different route, e.g. 'docs'."
+		).format(RESERVED_ROUTE),
+		frappe.ValidationError
 	)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wiki/wiki/doctype/wiki_space/wiki_space.py` around lines 174 - 179, Replace
the generic frappe.throw call in the is_reserved_route check with an explicit
frappe.ValidationError (same pattern used in validate_route_namespace) and
update the error message to match validate_route_namespace() by adding the
suggestion text "Use a different route, e.g. 'docs'."; specifically modify the
block that calls is_reserved_route(new_route) in wiki_space.py to throw
frappe.ValidationError and include the full message: "Route cannot be '{0}' or
start with '{0}/' — that path is reserved for the Wiki editor. Use a different
route, e.g. 'docs'." so messaging and exception type are consistent with
validate_route_namespace().

69-76: ⚡ Quick win

Pass exception type explicitly to frappe.throw() for consistency.

While frappe.throw() defaults to frappe.ValidationError, the codebase pattern is to pass it explicitly for clarity. As per coding guidelines, wiki/frappe_wiki/doctype/wiki_change_request/wiki_change_request.py:777-807 shows frappe.throw(_("..."), frappe.ValidationError).

♻️ Proposed fix
 def validate_route_namespace(self):
 	if is_reserved_route(self.route):
 		frappe.throw(
 			_(
 				"Route cannot be '{0}' or start with '{0}/' — that path is reserved for the "
 				"Wiki editor. Use a different route, e.g. 'docs'."
-			).format(RESERVED_ROUTE)
+			).format(RESERVED_ROUTE),
+			frappe.ValidationError
 		)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wiki/wiki/doctype/wiki_space/wiki_space.py` around lines 69 - 76, The
validate_route_namespace method currently calls frappe.throw without an explicit
exception type; update the call in validate_route_namespace (inside class/method
validate_route_namespace) to pass frappe.ValidationError as the second argument
so it matches project convention (use the same pattern as wiki_change_request's
throw calls), keeping the existing formatted message that references
RESERVED_ROUTE and is_reserved_route.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@wiki/wiki/doctype/wiki_space/wiki_space.py`:
- Around line 243-248: The clone_wiki_space_in_background function currently
only checks empty/duplicate routes but defers reserved-route validation to the
async _create_space_copy (which calls new_space.insert()), so add an early
synchronous reserved-route check before enqueueing: reuse the same route
validation logic used by _create_space_copy/new_space.insert() (or call the
shared route validation helper if one exists) and call frappe.throw with a clear
message if the route is reserved; ensure this check references
clone_wiki_space_in_background, _create_space_copy, and new_space.insert() so
the validation happens immediately and prevents enqueueing a job for a reserved
route.

---

Nitpick comments:
In `@wiki/wiki/doctype/wiki_space/test_wiki_space.py`:
- Around line 311-337: Add a new unit test in TestWikiSpaceRouteValidation that
asserts Wiki Space.update_routes() rejects reserved routes: create a Wiki Space
with a valid route (use frappe.generate_hash like other tests), then call the
instance method update_routes("wiki") and update_routes("wiki/updated") inside
with self.assertRaises(frappe.ValidationError) blocks to ensure the validation
logic in update_routes() is covered; reference the TestWikiSpaceRouteValidation
class and the update_routes() method when adding the test.

In `@wiki/wiki/doctype/wiki_space/wiki_space.py`:
- Around line 174-179: Replace the generic frappe.throw call in the
is_reserved_route check with an explicit frappe.ValidationError (same pattern
used in validate_route_namespace) and update the error message to match
validate_route_namespace() by adding the suggestion text "Use a different route,
e.g. 'docs'."; specifically modify the block that calls
is_reserved_route(new_route) in wiki_space.py to throw frappe.ValidationError
and include the full message: "Route cannot be '{0}' or start with '{0}/' — that
path is reserved for the Wiki editor. Use a different route, e.g. 'docs'." so
messaging and exception type are consistent with validate_route_namespace().
- Around line 69-76: The validate_route_namespace method currently calls
frappe.throw without an explicit exception type; update the call in
validate_route_namespace (inside class/method validate_route_namespace) to pass
frappe.ValidationError as the second argument so it matches project convention
(use the same pattern as wiki_change_request's throw calls), keeping the
existing formatted message that references RESERVED_ROUTE and is_reserved_route.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 80e1fd6e-f96e-4519-8eba-e9d6c66fc4fd

📥 Commits

Reviewing files that changed from the base of the PR and between e183f28 and b3e3d05.

📒 Files selected for processing (2)
  • wiki/wiki/doctype/wiki_space/test_wiki_space.py
  • wiki/wiki/doctype/wiki_space/wiki_space.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG : Route accepts /wiki but doesnt render the page

1 participant