diff --git a/frappe/model/document.py b/frappe/model/document.py index c58e09ef5a..9a6baf63c4 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -577,14 +577,17 @@ class Document(BaseDocument): def get_permlevel_access(self, permission_type='write'): if not hasattr(self, "_has_access_to"): + self._has_access_to = {} + + if not self._has_access_to.get(permission_type): + self._has_access_to[permission_type] = [] roles = frappe.get_roles() - self._has_access_to = [] for perm in self.get_permissions(): if perm.role in 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) + if perm.permlevel not in self._has_access_to[permission_type]: + self._has_access_to[permission_type].append(perm.permlevel) - return self._has_access_to + return self._has_access_to[permission_type] def has_permlevel_access_to(self, fieldname, df=None, permission_type='read'): if not df: diff --git a/frappe/tests/test_form_load.py b/frappe/tests/test_form_load.py index 95dc19c0f1..fc53e21fef 100644 --- a/frappe/tests/test_form_load.py +++ b/frappe/tests/test_form_load.py @@ -4,8 +4,10 @@ from __future__ import unicode_literals import frappe, unittest from frappe.desk.form.load import getdoctype, getdoc -from frappe.core.page.permission_manager.permission_manager import update, reset +from frappe.core.page.permission_manager.permission_manager import update, reset, add +from frappe.custom.doctype.property_setter.property_setter import make_property_setter +test_dependencies = ['Blog Category', 'Blogger'] class TestFormLoad(unittest.TestCase): def test_load(self): @@ -20,56 +22,65 @@ class TestFormLoad(unittest.TestCase): self.assertTrue(meta.get("__calendar_js")) def test_fieldlevel_permissions_in_load(self): + blog = frappe.get_doc({ + "doctype": "Blog Post", + "blog_category": "_Test Blog Category 1", + "blog_intro": "Test Blog Intro", + "blogger": "_Test Blogger 1", + "content": "Test Blog Content", + "title": "_Test Blog Post {}".format(frappe.utils.now()), + "published": 0 + }) + + blog.insert() + user = frappe.get_doc('User', 'test@example.com') - user.remove_roles('Website Manager') + + user_roles = frappe.get_roles() + user.remove_roles(*user_roles) user.add_roles('Blogger') + + make_property_setter('Blog Post', 'published', 'permlevel', 1, 'Int') reset('Blog Post') - - frappe.db.set_value('DocField', { - 'fieldname': 'published', - 'parent': 'Blog Post' - }, 'permlevel', 1) - - update('Blog Post', 'Website Manager', 0, 'permlevel', 1) + add('Blog Post', 'Website Manager', 1) + update('Blog Post', 'Website Manager', 1, 'write', 1) frappe.set_user(user.name) - # print frappe.as_json(get_valid_perms('Blog Post')) + blog_doc = get_blog(blog.name) - frappe.clear_cache(doctype='Blog Post') + self.assertEqual(blog_doc.name, blog.name) + # since published field has higher permlevel + self.assertEqual(blog_doc.published, None) - 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.assertEqual(doc.published, None) - checked = True - - self.assertTrue(checked, True) - - frappe.db.set_value('DocField', { - 'fieldname': 'published', - 'parent': 'Blog Post' - }, 'permlevel', 0) - - reset('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.assertEqual(doc.published, 1) - checked = True - - self.assertTrue(checked, True) + # this will be ignored because user does not + # have write access on `published` field (or on permlevel 1 fields) + blog_doc.published = 1 + blog_doc.save() + # since published field has higher permlevel + self.assertEqual(blog_doc.published, 0) frappe.set_user('Administrator') + user.add_roles('Website Manager') + frappe.set_user(user.name) + + doc = frappe.get_doc('Blog Post', blog.name) + doc.published = 1 + doc.save() + + blog_doc = get_blog(blog.name) + # now user should be allowed to read field with higher permlevel + # (after adding Website Manager role) + self.assertEqual(blog_doc.published, 1) + + frappe.set_user('Administrator') + + # reset user roles + user.remove_roles('Blogger', 'Website Manager') + user.add_roles(*user_roles) + +def get_blog(blog_name): + frappe.response.docs = [] + getdoc('Blog Post', blog_name) + doc = frappe.response.docs[0] + return doc \ No newline at end of file