fix: skip virtual fields in perm level checks during DB Query

DB Query can't access virtual fields so it should ignore all virtual
fields.
This commit is contained in:
Ankush Menat 2023-12-20 11:56:36 +05:30
parent 2564d0e939
commit 5deabdde21
4 changed files with 26 additions and 3 deletions

View file

@ -194,6 +194,8 @@ def get_permitted_fields(
parenttype: str | None = None,
user: str | None = None,
permission_type: str | None = None,
*,
ignore_virtual=False,
) -> list[str]:
meta = frappe.get_meta(doctype)
valid_columns = meta.get_valid_columns()
@ -209,7 +211,10 @@ def get_permitted_fields(
permission_type = "select" if frappe.only_has_select_perm(doctype, user=user) else "read"
if permitted_fields := meta.get_permitted_fieldnames(
parenttype=parenttype, user=user, permission_type=permission_type
parenttype=parenttype,
user=user,
permission_type=permission_type,
with_virtual_fields=not ignore_virtual,
):
if permission_type == "select":
return permitted_fields

View file

@ -635,6 +635,7 @@ class DatabaseQuery:
doctype=self.doctype,
parenttype=self.parent_doctype,
permission_type=self.permission_map.get(self.doctype),
ignore_virtual=True,
)
for i, field in enumerate(self.fields):

View file

@ -565,7 +565,14 @@ class Meta(Document):
self.high_permlevel_fields = [df for df in self.fields if df.permlevel > 0]
return self.high_permlevel_fields
def get_permitted_fieldnames(self, parenttype=None, *, user=None, permission_type="read"):
def get_permitted_fieldnames(
self,
parenttype=None,
*,
user=None,
permission_type="read",
with_virtual_fields=True,
):
"""Build list of `fieldname` with read perm level and all the higher perm levels defined.
Note: If permissions are not defined for DocType, return all the fields with value.
@ -590,7 +597,9 @@ class Meta(Document):
permitted_fieldnames.extend(
df.fieldname
for df in self.get_fieldnames_with_value(with_field_meta=True, with_virtual_fields=True)
for df in self.get_fieldnames_with_value(
with_field_meta=True, with_virtual_fields=with_virtual_fields
)
if df.permlevel in permlevel_access
)
return permitted_fieldnames

View file

@ -753,6 +753,14 @@ class TestDBQuery(FrappeTestCase):
limit=50,
)
def test_virtual_field_get_list(self):
try:
frappe.get_list("Prepared Report", ["*"])
frappe.get_list("Scheduled Job Type", ["*"])
except Exception as e:
print(frappe.get_traceback())
self.fail("get_list not working with virtual field")
def test_pluck_name(self):
names = DatabaseQuery("DocType").execute(filters={"name": "DocType"}, pluck="name")
self.assertEqual(names, ["DocType"])