@@ -35,6 +35,8 @@ def getdoc(doctype, name, user=None): | |||||
if not doc.has_permission("read"): | if not doc.has_permission("read"): | ||||
raise frappe.PermissionError, ("read", doctype, name) | raise frappe.PermissionError, ("read", doctype, name) | ||||
doc.apply_fieldlevel_read_permissions() | |||||
# add file list | # add file list | ||||
get_docinfo(doc) | get_docinfo(doc) | ||||
@@ -410,6 +410,29 @@ class Document(BaseDocument): | |||||
for d in children: | for d in children: | ||||
d._extract_images_from_text_editor() | 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): | def validate_higher_perm_levels(self): | ||||
"""If the user does not have permissions at permlevel > 0, then reset the values to original / default""" | """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: | if self.flags.ignore_permissions or frappe.flags.in_install: | ||||
@@ -428,18 +451,18 @@ class Document(BaseDocument): | |||||
for d in self.get(df.fieldname): | for d in self.get(df.fieldname): | ||||
d.reset_values_if_no_permlevel_access(has_access_to, high_permlevel_fields) | 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"): | if not hasattr(self, "_has_access_to"): | ||||
user_roles = frappe.get_roles() | user_roles = frappe.get_roles() | ||||
self._has_access_to = [] | self._has_access_to = [] | ||||
for perm in self.get_permissions(): | 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: | if perm.permlevel not in self._has_access_to: | ||||
self._has_access_to.append(perm.permlevel) | self._has_access_to.append(perm.permlevel) | ||||
return self._has_access_to | 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: | if not df: | ||||
df = self.meta.get_field(fieldname) | df = self.meta.get_field(fieldname) | ||||
@@ -3,8 +3,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe, unittest | 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): | class TestFormLoad(unittest.TestCase): | ||||
def test_load(self): | def test_load(self): | ||||
@@ -14,6 +13,48 @@ class TestFormLoad(unittest.TestCase): | |||||
self.assertTrue(meta.get("__js")) | self.assertTrue(meta.get("__js")) | ||||
frappe.response.docs = [] | frappe.response.docs = [] | ||||
d = getdoctype("Event") | |||||
getdoctype("Event") | |||||
meta = filter(lambda d: d.name=="Event", frappe.response.docs)[0] | meta = filter(lambda d: d.name=="Event", frappe.response.docs)[0] | ||||
self.assertTrue(meta.get("__calendar_js")) | 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') |