@@ -35,6 +35,8 @@ def getdoc(doctype, name, user=None): | |||
if not doc.has_permission("read"): | |||
raise frappe.PermissionError, ("read", doctype, name) | |||
doc.apply_fieldlevel_read_permissions() | |||
# add file list | |||
get_docinfo(doc) | |||
@@ -410,6 +410,29 @@ class Document(BaseDocument): | |||
for d in children: | |||
d._extract_images_from_text_editor() | |||
def apply_fieldlevel_read_permissions(self): | |||
'''Remove values the user is not allowed to read (called when loading in desk)''' | |||
has_higher_permlevel = False | |||
for p in self.get_permissions(): | |||
if p.permlevel > 0: | |||
has_higher_permlevel = True | |||
break | |||
if not has_higher_permlevel: | |||
return | |||
has_access_to = self.get_permlevel_access('read') | |||
for df in self.meta.fields: | |||
if not df.permlevel in has_access_to: | |||
self.set(df.fieldname, None) | |||
for table_field in self.meta.get_table_fields(): | |||
for df in frappe.get_meta(table_field.options): | |||
if not df.permlevel in has_access_to: | |||
for child in self.get(table_field.fieldname) or []: | |||
child.set(df.fieldname, None) | |||
def validate_higher_perm_levels(self): | |||
"""If the user does not have permissions at permlevel > 0, then reset the values to original / default""" | |||
if self.flags.ignore_permissions or frappe.flags.in_install: | |||
@@ -428,18 +451,18 @@ class Document(BaseDocument): | |||
for d in self.get(df.fieldname): | |||
d.reset_values_if_no_permlevel_access(has_access_to, high_permlevel_fields) | |||
def get_permlevel_access(self): | |||
def get_permlevel_access(self, permission_type='write'): | |||
if not hasattr(self, "_has_access_to"): | |||
user_roles = frappe.get_roles() | |||
self._has_access_to = [] | |||
for perm in self.get_permissions(): | |||
if perm.role in user_roles and perm.permlevel > 0 and perm.write: | |||
if perm.role in user_roles and perm.permlevel > 0 and perm.get(permission_type): | |||
if perm.permlevel not in self._has_access_to: | |||
self._has_access_to.append(perm.permlevel) | |||
return self._has_access_to | |||
def has_permlevel_access_to(self, fieldname, df=None): | |||
def has_permlevel_access_to(self, fieldname, df=None, permission_type='read'): | |||
if not df: | |||
df = self.meta.get_field(fieldname) | |||
@@ -3,8 +3,7 @@ | |||
from __future__ import unicode_literals | |||
import frappe, unittest | |||
from frappe.desk.form.meta import get_meta | |||
from frappe.desk.form.load import getdoctype, getdoc | |||
from frappe.desk.form.load import getdoctype, getdoc | |||
class TestFormLoad(unittest.TestCase): | |||
def test_load(self): | |||
@@ -14,6 +13,48 @@ class TestFormLoad(unittest.TestCase): | |||
self.assertTrue(meta.get("__js")) | |||
frappe.response.docs = [] | |||
d = getdoctype("Event") | |||
getdoctype("Event") | |||
meta = filter(lambda d: d.name=="Event", frappe.response.docs)[0] | |||
self.assertTrue(meta.get("__calendar_js")) | |||
def test_fieldlevel_permissions_in_load(self): | |||
user = frappe.get_doc('User', 'test@example.com') | |||
user.remove_roles('Website Manager') | |||
user.add_roles('Blogger') | |||
frappe.set_user(user.name) | |||
frappe.db.sql('update tabDocField set permlevel=1 where fieldname="published" and parent="Blog Post"') | |||
frappe.db.sql('update tabDocPerm set permlevel=1 where role="Website Manager" and parent="Blog Post"') | |||
frappe.clear_cache(doctype='Blog Post') | |||
blog = frappe.db.get_value('Blog Post', {'title': '_Test Blog Post'}) | |||
getdoc('Blog Post', blog) | |||
checked = False | |||
for doc in frappe.response.docs: | |||
if doc.name == blog: | |||
self.assertEquals(doc.published, None) | |||
checked = True | |||
self.assertTrue(checked, True) | |||
frappe.db.sql('update tabDocField set permlevel=0 where fieldname="published" and parent="Blog Post"') | |||
frappe.db.sql('update tabDocPerm set permlevel=0 where role="Website Manager" and parent="Blog Post"') | |||
frappe.clear_cache(doctype='Blog Post') | |||
frappe.response.docs = [] | |||
getdoc('Blog Post', blog) | |||
checked = False | |||
for doc in frappe.response.docs: | |||
if doc.name == blog: | |||
self.assertEquals(doc.published, 1) | |||
checked = True | |||
self.assertTrue(checked, True) | |||
frappe.set_user('Administrator') |