fix: ignore fieldname validating ignore_user_permissions for Link fields (#37942)

* fix: validate ignore_user_permissions for alternative Link fields

* fix: handle alternative Link fields with ignore_user_permissions

* fix: move early exit earlier to avoid edge cases

* test: validate case of bulk edit

---------

Co-authored-by: Sagar Vora <sagarvora@users.noreply.github.com>
This commit is contained in:
Ejaaz Khan 2026-03-12 02:24:03 +05:30 committed by GitHub
parent 89bfdcf7fb
commit e7b4bd5666
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 5 deletions

View file

@ -256,8 +256,16 @@ def validate_ignore_user_permissions(form_doctype, link_fieldname, link_doctype)
frappe.throw(message, title=_('Error validating "Ignore User Permissions"'))
meta = frappe.get_meta(form_doctype)
link_field = meta.get_field(link_fieldname)
# special early exit - link_fieldname is not being considered here
# to avoid cases like bulk edit which have link_fieldname as "value" from failing
if any(
(field.fieldtype == "Link" and field.options == link_doctype and field.ignore_user_permissions)
for field in meta.fields
):
return
link_field = meta.get_field(link_fieldname)
if not link_field:
_throw(
_("Field <code>{0}</code> not found in {1}").format(
@ -268,9 +276,6 @@ def validate_ignore_user_permissions(form_doctype, link_fieldname, link_doctype)
ignore_user_permissions = link_field.ignore_user_permissions
found_doctype = None
if link_field.fieldtype == "Link":
found_doctype = link_field.options
if link_field.fieldtype == "Table MultiSelect":
child_meta = frappe.get_meta(link_field.options)
child_link_field = next((field for field in child_meta.fields if field.fieldtype == "Link"), None)
@ -297,6 +302,11 @@ def validate_ignore_user_permissions(form_doctype, link_fieldname, link_doctype)
if link_field.fieldtype == "Dynamic Link":
return # skip doctype check for Dynamic Link fields
# all cases of valid Link fields are already covered in the early exit above
# the following block only serves to show appropriate error message
if link_field.fieldtype == "Link":
found_doctype = link_field.options
if found_doctype != link_doctype:
_throw(
_("The field {0} in {1} links to {2} and not {3}").format(

View file

@ -290,7 +290,12 @@ class TestSearch(IntegrationTestCase):
"""Test that ignore_user_permissions is validated correctly"""
# Clean up any leftover doctypes from previous test runs
for dt in ("Test Search Form No Ignore", "Test Search Form Wrong Link", "Test Search Linked2"):
for dt in (
"Test Search Form No Ignore",
"Test Search Form Wrong Link",
"Test Search Form With Ignore",
"Test Search Linked2",
):
if frappe.db.exists("DocType", dt):
frappe.delete_doc("DocType", dt, force=True)
@ -375,6 +380,30 @@ class TestSearch(IntegrationTestCase):
link_fieldname="wrong_link",
)
# Should NOT throw when link_fieldname is bogus (e.g. bulk edit sends "value")
# but a Link field with ignore_user_permissions exists on the form doctype
new_doctype(
name="Test Search Form With Ignore",
fields=[
{
"label": "Linked Doc",
"fieldname": "linked_doc",
"fieldtype": "Link",
"options": "Test Search Linked2",
"ignore_user_permissions": 1,
}
],
).insert()
self.addCleanup(lambda: frappe.delete_doc("DocType", "Test Search Form With Ignore", force=True))
search_link(
doctype="Test Search Linked2",
txt="test",
ignore_user_permissions=True,
reference_doctype="Test Search Form With Ignore",
link_fieldname="value",
)
@frappe.validate_and_sanitize_search_inputs
def get_data(doctype, txt, searchfield, start, page_len, filters):