[refactor] user permissions (#3713)
* [refactor] user permissions * [fix] tests * [ux] user-permissions * [minor] cleanup system settings * [minor] end progress
This commit is contained in:
parent
c519122929
commit
f609a478ae
36 changed files with 646 additions and 689 deletions
|
|
@ -17,6 +17,7 @@ from frappe.utils.change_log import get_versions
|
|||
from frappe.translate import get_lang_dict
|
||||
from frappe.email.inbox import get_email_accounts
|
||||
from frappe.core.doctype.feedback_trigger.feedback_trigger import get_enabled_feedback_trigger
|
||||
from frappe.core.doctype.user_permission.user_permission import get_user_permissions
|
||||
|
||||
def get_bootinfo():
|
||||
"""build and return boot info"""
|
||||
|
|
@ -30,6 +31,7 @@ def get_bootinfo():
|
|||
|
||||
# system info
|
||||
bootinfo.sysdefaults = frappe.defaults.get_defaults()
|
||||
bootinfo.user_permissions = get_user_permissions()
|
||||
bootinfo.server_date = frappe.utils.nowdate()
|
||||
|
||||
if frappe.session['user'] != 'Guest':
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe.defaults
|
||||
import frappe.permissions
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_fullname
|
||||
|
|
@ -68,7 +67,7 @@ def get_feed_match_conditions(user=None, force=True):
|
|||
|
||||
conditions = ['`tabCommunication`.owner="{user}" or `tabCommunication`.reference_owner="{user}"'.format(user=frappe.db.escape(user))]
|
||||
|
||||
user_permissions = frappe.defaults.get_user_permissions(user)
|
||||
user_permissions = frappe.permissions.get_user_permissions(user)
|
||||
can_read = frappe.get_user().get_can_read()
|
||||
|
||||
can_read_doctypes = ['"{}"'.format(doctype) for doctype in
|
||||
|
|
|
|||
|
|
@ -521,6 +521,99 @@
|
|||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "permissions",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Permissions",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "If Apply User Permissions is checked for Report DocType but no User Permissions are defined for Report for a User, then all Reports are shown to that User",
|
||||
"fieldname": "ignore_user_permissions_if_missing",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Ignore User Permissions If Missing",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"description": "If Apply Strict User Permission is checked and User Permission is defined for a DocType for a User, then all the documents where value of the link is blank, will not be shown to that User",
|
||||
"fieldname": "apply_strict_user_permissions",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Apply Strict User Permissions",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -739,69 +832,6 @@
|
|||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "If Apply User Permissions is checked for Report DocType but no User Permissions are defined for Report for a User, then all Reports are shown to that User",
|
||||
"fieldname": "ignore_user_permissions_if_missing",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Ignore User Permissions If Missing",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"description": "If Apply Strict User Permission is checked and User Permission is defined for a DocType for a User, then all the documents where value of the link is blank, will not be shown to that User",
|
||||
"fieldname": "apply_strict_user_permissions",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Apply Strict User Permissions",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -997,7 +1027,7 @@
|
|||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-23 07:48:10.453011",
|
||||
"modified": "2017-07-20 22:57:56.466867",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "System Settings",
|
||||
|
|
@ -1032,4 +1062,4 @@
|
|||
"sort_order": "ASC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,7 @@ class SystemSettings(Document):
|
|||
|
||||
frappe.cache().delete_value('system_settings')
|
||||
frappe.cache().delete_value('time_zone')
|
||||
frappe.local.system_settings = {}
|
||||
|
||||
@frappe.whitelist()
|
||||
def load():
|
||||
|
|
|
|||
23
frappe/core/doctype/system_settings/test_system_settings.js
Normal file
23
frappe/core/doctype/system_settings/test_system_settings.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: System Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially('System Settings', [
|
||||
// insert a new System Settings
|
||||
() => frappe.tests.make([
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
|
|
@ -59,9 +59,13 @@ frappe.ui.form.on('User', {
|
|||
frappe.route_options = {
|
||||
"user": doc.name
|
||||
};
|
||||
frappe.set_route("user-permissions");
|
||||
frappe.set_route('List', 'User Permission');
|
||||
}, null, "btn-default")
|
||||
|
||||
frm.add_custom_button(__('View Permitted Documents'),
|
||||
() => frappe.set_route('query-report', 'Permitted Documents For User',
|
||||
{user: frm.doc.name}));
|
||||
|
||||
frm.toggle_display(['sb1', 'sb3', 'modules_access'], true);
|
||||
}
|
||||
|
||||
|
|
|
|||
0
frappe/core/doctype/user_permission/__init__.py
Normal file
0
frappe/core/doctype/user_permission/__init__.py
Normal file
23
frappe/core/doctype/user_permission/test_user_permission.js
Normal file
23
frappe/core/doctype/user_permission/test_user_permission.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: User Permission", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially('User Permission', [
|
||||
// insert a new User Permission
|
||||
() => frappe.tests.make([
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
10
frappe/core/doctype/user_permission/test_user_permission.py
Normal file
10
frappe/core/doctype/user_permission/test_user_permission.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
#import frappe
|
||||
import unittest
|
||||
|
||||
class TestUserPermission(unittest.TestCase):
|
||||
pass
|
||||
10
frappe/core/doctype/user_permission/user_permission.js
Normal file
10
frappe/core/doctype/user_permission/user_permission.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) 2017, Frappe Technologies and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('User Permission', {
|
||||
refresh: function(frm) {
|
||||
frm.add_custom_button(__('View Permitted Documents'),
|
||||
() => frappe.set_route('query-report', 'Permitted Documents For User',
|
||||
{user: frm.doc.user}));
|
||||
}
|
||||
});
|
||||
188
frappe/core/doctype/user_permission/user_permission.json
Normal file
188
frappe/core/doctype/user_permission/user_permission.json
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-07-17 14:25:27.881871",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "User",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "allow",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Allow",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "for_value",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "For Value",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "allow",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"description": "If you un-check this, you will have to apply manually for each Role + Document Type combination",
|
||||
"fieldname": "apply_for_all_roles",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Apply for all Roles for this User",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-27 22:55:58.647315",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "User Permission",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "user",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
80
frappe/core/doctype/user_permission/user_permission.py
Normal file
80
frappe/core/doctype/user_permission/user_permission.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
from frappe.model.document import Document
|
||||
from frappe.permissions import (get_valid_perms, update_permission_property)
|
||||
from frappe import _
|
||||
|
||||
class UserPermission(Document):
|
||||
def on_update(self):
|
||||
frappe.cache().delete_value('user_permissions')
|
||||
|
||||
if self.apply_for_all_roles:
|
||||
self.apply_user_permissions_to_all_roles()
|
||||
|
||||
def apply_user_permissions_to_all_roles(self):
|
||||
# add apply user permissions for all roles that
|
||||
# for this doctype
|
||||
def show_progress(i, l):
|
||||
if l > 2:
|
||||
frappe.publish_realtime("progress",
|
||||
dict(progress=[i, l], title=_('Updating...')),
|
||||
user=frappe.session.user)
|
||||
|
||||
|
||||
roles = frappe.get_roles(self.user)
|
||||
linked = frappe.db.sql('''select distinct parent from tabDocField
|
||||
where fieldtype="Link" and options=%s''', self.allow)
|
||||
for i, link in enumerate(linked):
|
||||
doctype = link[0]
|
||||
for perm in get_valid_perms(doctype, self.user):
|
||||
# if the role is applicable to the user
|
||||
show_progress(i+1, len(linked))
|
||||
if perm.role in roles:
|
||||
if not perm.apply_user_permissions:
|
||||
update_permission_property(doctype, perm.role, 0,
|
||||
'apply_user_permissions', '1')
|
||||
|
||||
try:
|
||||
user_permission_doctypes = json.loads(perm.user_permission_doctypes or '[]')
|
||||
except ValueError:
|
||||
user_permission_doctypes = []
|
||||
|
||||
if self.allow not in user_permission_doctypes:
|
||||
user_permission_doctypes.append(self.allow)
|
||||
update_permission_property(doctype, perm.role, 0,
|
||||
'user_permission_doctypes', json.dumps(user_permission_doctypes), validate=False)
|
||||
|
||||
show_progress(len(linked), len(linked))
|
||||
|
||||
def on_trash(self): # pylint: disable=no-self-use
|
||||
frappe.cache().delete_value('user_permissions')
|
||||
|
||||
def get_user_permissions(user=None):
|
||||
'''Get all users permissions for the user as a dict of doctype'''
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
||||
out = frappe.cache().hget("user_permissions", user)
|
||||
|
||||
if not out:
|
||||
out = {}
|
||||
try:
|
||||
for perm in frappe.get_all('User Permission',
|
||||
fields=['allow', 'for_value'], filters=dict(user=user)):
|
||||
out.setdefault(perm.allow, []).append(perm.for_value)
|
||||
|
||||
# add profile match
|
||||
if user not in out.get("User", []):
|
||||
out.setdefault("User", []).append(user)
|
||||
|
||||
frappe.cache().hset("user_permissions", user, out)
|
||||
except frappe.SQLError, e:
|
||||
if e.args[0]==1146:
|
||||
# called from patch
|
||||
pass
|
||||
|
||||
return out
|
||||
|
|
@ -21,6 +21,7 @@ frappe.pages['permission-manager'].refresh = function(wrapper) {
|
|||
frappe.PermissionEngine = Class.extend({
|
||||
init: function(wrapper) {
|
||||
this.wrapper = wrapper;
|
||||
this.page = wrapper.page;
|
||||
this.body = $(this.wrapper).find(".perm-engine");
|
||||
this.make();
|
||||
this.refresh();
|
||||
|
|
@ -55,6 +56,10 @@ frappe.PermissionEngine = Class.extend({
|
|||
.change(function() {
|
||||
me.refresh();
|
||||
});
|
||||
|
||||
this.page.add_inner_button(__('Set User Permissions'), () => {
|
||||
return frappe.set_route('List', 'User Permission');
|
||||
});
|
||||
this.set_from_route();
|
||||
},
|
||||
set_from_route: function() {
|
||||
|
|
@ -133,11 +138,11 @@ frappe.PermissionEngine = Class.extend({
|
|||
refresh: function() {
|
||||
var me = this;
|
||||
if(!me.doctype_select) {
|
||||
this.body.html("<p class='text-muted'>" + __("Loading") + "...</div>");
|
||||
this.body.html("<p class='text-muted'>" + __("Loading") + "...</p>");
|
||||
return;
|
||||
}
|
||||
if(!me.get_doctype() && !me.get_role()) {
|
||||
this.body.html("<p class='text-muted'>"+__("Select Document Type or Role to start.")+"</div>");
|
||||
this.body.html("<p class='text-muted'>"+__("Select Document Type or Role to start.")+"</p>");
|
||||
return;
|
||||
}
|
||||
// get permissions
|
||||
|
|
@ -247,10 +252,13 @@ frappe.PermissionEngine = Class.extend({
|
|||
|
||||
setup_user_permissions: function(d, role_cell) {
|
||||
var me = this;
|
||||
d.help = frappe.render('<ul class="user-permission-help small hidden" style="margin-left: -10px;">\
|
||||
<li style="margin-top: 7px;"><a class="show-user-permission-doctypes grey">{%= __("Select Document Types") %}</a></li>\
|
||||
<li style="margin-top: 3px;"><a class="show-user-permissions grey">{%= __("Show User Permissions") %}</a></li>\
|
||||
</ul>', {});
|
||||
d.help = `<ul class="user-permission-help small hidden"
|
||||
style="margin-left: -10px;">
|
||||
<li style="margin-top: 7px;"><a class="show-user-permission-doctypes">
|
||||
${__("Select Document Types")}</a></li>
|
||||
<li style="margin-top: 3px;"><a class="show-user-permissions">
|
||||
${__("Show User Permissions")}</a></li>
|
||||
</ul>`;
|
||||
|
||||
var checkbox = this.add_check(role_cell, d, "apply_user_permissions")
|
||||
.removeClass("col-md-4")
|
||||
|
|
@ -336,8 +344,8 @@ frappe.PermissionEngine = Class.extend({
|
|||
var me = this;
|
||||
|
||||
this.body.on("click", ".show-user-permissions", function() {
|
||||
frappe.route_options = { doctype: me.get_doctype() || "" };
|
||||
frappe.set_route("user-permissions");
|
||||
frappe.route_options = { allow: me.get_doctype() || "" };
|
||||
frappe.set_route('List', 'User Permission');
|
||||
});
|
||||
|
||||
this.body.on("click", "input[type='checkbox']", function() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import frappe.defaults
|
|||
from frappe.modules.import_file import get_file_path, read_doc_from_file
|
||||
from frappe.translate import send_translations
|
||||
from frappe.permissions import (reset_perms, get_linked_doctypes, get_all_perms,
|
||||
setup_custom_perms, add_permission)
|
||||
setup_custom_perms, add_permission, update_permission_property)
|
||||
from frappe.core.doctype.doctype.doctype import (clear_permissions_cache,
|
||||
validate_permissions_for_doctype)
|
||||
from frappe import _
|
||||
|
|
@ -68,18 +68,8 @@ def add(parent, role, permlevel):
|
|||
@frappe.whitelist()
|
||||
def update(doctype, role, permlevel, ptype, value=None):
|
||||
frappe.only_for("System Manager")
|
||||
|
||||
out = None
|
||||
if setup_custom_perms(doctype):
|
||||
out = 'refresh'
|
||||
|
||||
name = frappe.get_value('Custom DocPerm', dict(parent=doctype, role=role, permlevel=permlevel))
|
||||
|
||||
frappe.db.sql("""update `tabCustom DocPerm` set `%s`=%s where name=%s"""\
|
||||
% (frappe.db.escape(ptype), '%s', '%s'), (value, name))
|
||||
validate_permissions_for_doctype(doctype)
|
||||
|
||||
return out
|
||||
out = update_permission_property(doctype, role, permlevel, ptype, value)
|
||||
return 'refresh' if out else None
|
||||
|
||||
@frappe.whitelist()
|
||||
def remove(doctype, role, permlevel):
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Interface to set user defaults (DefaultValue).
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
|
||||
|
|
@ -1,365 +0,0 @@
|
|||
frappe.pages['user-permissions'].on_page_load = function(wrapper) {
|
||||
var page = frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __("User Permissions Manager"),
|
||||
icon: "fa fa-shield",
|
||||
single_column: true
|
||||
});
|
||||
|
||||
frappe.breadcrumbs.add("Setup");
|
||||
|
||||
$("<div class='user-settings' \
|
||||
style='min-height: 200px; padding: 15px;'></div>\
|
||||
<p style='padding: 15px; padding-bottom: 0px;'>\
|
||||
<a class='view-role-permissions grey'>" + __("Edit Role Permissions") + "</a>\
|
||||
</p><hr><div style='padding: 0px 15px;'>\
|
||||
<h4>"+__("Help for User Permissions")+":</h4>\
|
||||
<ol>\
|
||||
<li>"
|
||||
+ __("Apart from Role based Permission Rules, you can apply User Permissions based on DocTypes.")
|
||||
+ "</li>"
|
||||
|
||||
+ "<li>"
|
||||
+ __("These permissions will apply for all transactions where the permitted record is linked. For example, if Company C is added to User Permissions of user X, user X will only be able to see transactions that has company C as a linked value.")
|
||||
+ "</li>"
|
||||
|
||||
+ "<li>"
|
||||
+ __("These will also be set as default values for those links, if only one such permission record is defined.")
|
||||
+ "</li>"
|
||||
|
||||
+ "<li>"
|
||||
+ __("A user can be permitted to multiple records of the same DocType.")
|
||||
+ "</li>\
|
||||
</ol></div>").appendTo(page.main);
|
||||
wrapper.user_permissions = new frappe.UserPermissions(wrapper);
|
||||
}
|
||||
|
||||
frappe.pages['user-permissions'].refresh = function(wrapper) {
|
||||
wrapper.user_permissions.set_from_route();
|
||||
}
|
||||
|
||||
frappe.UserPermissions = Class.extend({
|
||||
init: function(wrapper) {
|
||||
this.wrapper = wrapper;
|
||||
this.body = $(this.wrapper).find(".user-settings");
|
||||
this.filters = {};
|
||||
this.make();
|
||||
this.refresh();
|
||||
},
|
||||
make: function() {
|
||||
var me = this;
|
||||
|
||||
$(this.wrapper).find(".view-role-permissions").on("click", function() {
|
||||
frappe.route_options = { doctype: me.get_doctype() || "" };
|
||||
frappe.set_route("permission-manager");
|
||||
})
|
||||
|
||||
return frappe.call({
|
||||
module:"frappe.core",
|
||||
page:"user_permissions",
|
||||
method: "get_users_and_links",
|
||||
callback: function(r) {
|
||||
me.options = r.message;
|
||||
|
||||
me.filters.user = me.wrapper.page.add_field({
|
||||
fieldname: "user",
|
||||
label: __("User"),
|
||||
fieldtype: "Select",
|
||||
options: ([__("Select User") + "..."].concat(r.message.users)).join("\n")
|
||||
});
|
||||
|
||||
me.filters.doctype = me.wrapper.page.add_field({
|
||||
fieldname: "doctype",
|
||||
label: __("DocType"),
|
||||
fieldtype: "Select",
|
||||
options: ([__("Select DocType") + "..."].concat(me.get_link_names())).join("\n")
|
||||
});
|
||||
|
||||
me.filters.user_permission = me.wrapper.page.add_field({
|
||||
fieldname: "user_permission",
|
||||
label: __("Name"),
|
||||
fieldtype: "Link",
|
||||
options: "[Select]"
|
||||
});
|
||||
|
||||
if(frappe.user_roles.includes("System Manager")) {
|
||||
me.download = me.wrapper.page.add_field({
|
||||
fieldname: "download",
|
||||
label: __("Download"),
|
||||
fieldtype: "Button",
|
||||
icon: "fa fa-download"
|
||||
});
|
||||
|
||||
me.upload = me.wrapper.page.add_field({
|
||||
fieldname: "upload",
|
||||
label: __("Upload"),
|
||||
fieldtype: "Button",
|
||||
icon: "fa fa-upload"
|
||||
});
|
||||
}
|
||||
|
||||
// bind change event
|
||||
$.each(me.filters, function(k, f) {
|
||||
f.$input.on("change", function() {
|
||||
me.refresh();
|
||||
});
|
||||
});
|
||||
|
||||
// change options in user_permission link
|
||||
me.filters.doctype.$input.on("change", function() {
|
||||
me.filters.user_permission.df.options = me.get_doctype();
|
||||
});
|
||||
|
||||
me.set_from_route();
|
||||
me.setup_download_upload();
|
||||
}
|
||||
});
|
||||
},
|
||||
setup_download_upload: function() {
|
||||
var me = this;
|
||||
me.download.$input.on("click", function() {
|
||||
window.location.href = frappe.urllib.get_base_url()
|
||||
+ "/api/method/frappe.core.page.user_permissions.user_permissions.get_user_permissions_csv";
|
||||
});
|
||||
|
||||
me.upload.$input.on("click", function() {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __("Upload User Permissions"),
|
||||
fields: [
|
||||
{
|
||||
fieldtype:"HTML",
|
||||
options: '<p class="text-muted"><ol>'+
|
||||
"<li>"+__("Upload CSV file containing all user permissions in the same format as Download.")+"</li>"+
|
||||
"<li><strong>"+__("Any existing permission will be deleted / overwritten.")+"</strong></li>"+
|
||||
'</p>'
|
||||
},
|
||||
{
|
||||
fieldtype:"Attach", fieldname:"attach",
|
||||
}
|
||||
],
|
||||
primary_action_label: __("Upload and Sync"),
|
||||
primary_action: function() {
|
||||
var filedata = d.fields_dict.attach.get_value();
|
||||
if(!filedata) {
|
||||
frappe.msgprint(__("Please attach a file"));
|
||||
return;
|
||||
}
|
||||
frappe.call({
|
||||
method:"frappe.core.page.user_permissions.user_permissions.import_user_permissions",
|
||||
args: {
|
||||
filedata: filedata
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
frappe.msgprint(__("Permissions Updated"));
|
||||
d.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
d.show();
|
||||
})
|
||||
},
|
||||
get_link_names: function() {
|
||||
return this.options.link_fields;
|
||||
},
|
||||
set_from_route: function() {
|
||||
var me = this;
|
||||
if(frappe.route_options && this.filters && !$.isEmptyObject(this.filters)) {
|
||||
$.each(frappe.route_options, function(key, value) {
|
||||
if(me.filters[key] && frappe.route_options[key]!=null)
|
||||
me.set_filter(key, value);
|
||||
});
|
||||
frappe.route_options = null;
|
||||
}
|
||||
this.refresh();
|
||||
},
|
||||
set_filter: function(key, value) {
|
||||
this.filters[key].$input.val(value);
|
||||
},
|
||||
get_user: function() {
|
||||
var user = this.filters.user.$input.val();
|
||||
return user== __("Select User") + "..." ? null : user;
|
||||
},
|
||||
get_doctype: function() {
|
||||
var doctype = this.filters.doctype.$input.val();
|
||||
return doctype== __("Select DocType") + "..." ? null : doctype;
|
||||
},
|
||||
get_user_permission: function() {
|
||||
// autosuggest hack!
|
||||
var user_permission = this.filters.user_permission.$input.val();
|
||||
return (user_permission === "%") ? null : user_permission;
|
||||
},
|
||||
render: function(prop_list) {
|
||||
var me = this;
|
||||
this.body.empty();
|
||||
this.prop_list = prop_list;
|
||||
if(!prop_list || !prop_list.length) {
|
||||
this.add_message(__("No User Restrictions found."));
|
||||
} else {
|
||||
this.show_user_permissions_table();
|
||||
}
|
||||
this.show_add_user_permission();
|
||||
if(this.get_user() && this.get_doctype()) {
|
||||
$('<button class="btn btn-default btn-sm" style="margin-left: 10px;">\
|
||||
Show Allowed Documents</button>').appendTo(this.body.find(".btn-area")).on("click", function() {
|
||||
frappe.route_options = {doctype: me.get_doctype(), user:me.get_user() };
|
||||
frappe.set_route("query-report/Permitted Documents For User");
|
||||
});
|
||||
}
|
||||
},
|
||||
add_message: function(txt) {
|
||||
$('<p class="text-muted">' + txt + '</p>').appendTo(this.body);
|
||||
},
|
||||
refresh: function() {
|
||||
var me = this;
|
||||
if(!me.filters.user) {
|
||||
this.body.html("<p class='text-muted'>"+__("Loading")+"...</p>");
|
||||
return;
|
||||
}
|
||||
if(!me.get_user() && !me.get_doctype()) {
|
||||
this.body.html("<p class='text-muted'>"+__("Select User or DocType to start.")+"</p>");
|
||||
return;
|
||||
}
|
||||
// get permissions
|
||||
return frappe.call({
|
||||
module: "frappe.core",
|
||||
page: "user_permissions",
|
||||
method: "get_permissions",
|
||||
args: {
|
||||
parent: me.get_user(),
|
||||
defkey: me.get_doctype(),
|
||||
defvalue: me.get_user_permission()
|
||||
},
|
||||
callback: function(r) {
|
||||
me.render(r.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
show_user_permissions_table: function() {
|
||||
var me = this;
|
||||
this.table = $("<table class='table table-bordered'>\
|
||||
<thead><tr></tr></thead>\
|
||||
<tbody></tbody>\
|
||||
</table>").appendTo(this.body);
|
||||
|
||||
$('<p class="text-muted small">'
|
||||
+__("These restrictions will apply for Document Types where 'Apply User Permissions' is checked for the permission rule and a field with this value is present.")
|
||||
+'</p>').appendTo(this.body);
|
||||
|
||||
$.each([[__("Allow User"), 150], [__("If Document Type"), 150], [__("Is"),150], ["", 50]],
|
||||
function(i, col) {
|
||||
$("<th>")
|
||||
.html(col[0])
|
||||
.css("width", col[1]+"px")
|
||||
.appendTo(me.table.find("thead tr"));
|
||||
});
|
||||
|
||||
|
||||
$.each(this.prop_list, function(i, d) {
|
||||
var row = $("<tr>").appendTo(me.table.find("tbody"));
|
||||
|
||||
$("<td>").html('<a class="grey" href="#Form/User/'+encodeURIComponent(d.parent)+'">'
|
||||
+d.parent+'</a>').appendTo(row);
|
||||
$("<td>").html(d.defkey).appendTo(row);
|
||||
$("<td>").html(d.defvalue).appendTo(row);
|
||||
|
||||
me.add_delete_button(row, d);
|
||||
});
|
||||
|
||||
},
|
||||
add_delete_button: function(row, d) {
|
||||
var me = this;
|
||||
$("<button class='btn btn-sm btn-default'><i class='fa fa-remove'></i></button>")
|
||||
.appendTo($("<td>").appendTo(row))
|
||||
.attr("data-name", d.name)
|
||||
.attr("data-user", d.parent)
|
||||
.attr("data-defkey", d.defkey)
|
||||
.attr("data-defvalue", d.defvalue)
|
||||
.click(function() {
|
||||
return frappe.call({
|
||||
module: "frappe.core",
|
||||
page: "user_permissions",
|
||||
method: "remove",
|
||||
args: {
|
||||
name: $(this).attr("data-name"),
|
||||
user: $(this).attr("data-user"),
|
||||
defkey: $(this).attr("data-defkey"),
|
||||
defvalue: $(this).attr("data-defvalue")
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.exc) {
|
||||
frappe.msgprint(__("Did not remove"));
|
||||
} else {
|
||||
me.refresh();
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
show_add_user_permission: function() {
|
||||
var me = this;
|
||||
$("<button class='btn btn-default btn-sm'>"+__("Add A User Restriction")+"</button>")
|
||||
.appendTo($('<p class="btn-area">').appendTo(this.body))
|
||||
.click(function() {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __("Add A New Restriction"),
|
||||
fields: [
|
||||
{fieldtype:"Select", label:__("Allow User"),
|
||||
options:me.options.users, reqd:1, fieldname:"user"},
|
||||
{fieldtype:"Select", label: __("If Document Type"), fieldname:"defkey",
|
||||
options:me.get_link_names(), reqd:1},
|
||||
{fieldtype:"Link", label:__("Is"), fieldname:"defvalue",
|
||||
options:'[Select]', reqd:1},
|
||||
{fieldtype:"Button", label: __("Add"), fieldname:"add"},
|
||||
]
|
||||
});
|
||||
if(me.get_user()) {
|
||||
d.set_value("user", me.get_user());
|
||||
d.get_input("user").prop("disabled", true);
|
||||
}
|
||||
if(me.get_doctype()) {
|
||||
d.set_value("defkey", me.get_doctype());
|
||||
d.get_input("defkey").prop("disabled", true);
|
||||
}
|
||||
if(me.get_user_permission()) {
|
||||
d.set_value("defvalue", me.get_user_permission());
|
||||
d.get_input("defvalue").prop("disabled", true);
|
||||
}
|
||||
|
||||
d.fields_dict["defvalue"].get_query = function(txt) {
|
||||
if(!d.get_value("defkey")) {
|
||||
frappe.throw(__("Please select Document Type"));
|
||||
}
|
||||
|
||||
return {
|
||||
doctype: d.get_value("defkey")
|
||||
}
|
||||
};
|
||||
|
||||
d.get_input("add").click(function() {
|
||||
var args = d.get_values();
|
||||
if(!args) {
|
||||
return;
|
||||
}
|
||||
frappe.call({
|
||||
module: "frappe.core",
|
||||
page: "user_permissions",
|
||||
method: "add",
|
||||
args: args,
|
||||
callback: function(r) {
|
||||
if(r.exc) {
|
||||
frappe.msgprint(__("Did not add"));
|
||||
} else {
|
||||
me.refresh();
|
||||
}
|
||||
}
|
||||
})
|
||||
d.hide();
|
||||
});
|
||||
d.show();
|
||||
});
|
||||
}
|
||||
})
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"content": null,
|
||||
"creation": "2013-01-01 18:50:55",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"icon": "fa fa-user",
|
||||
"idx": 1,
|
||||
"modified": "2014-05-28 16:53:43.103533",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "user-permissions",
|
||||
"owner": "Administrator",
|
||||
"page_name": "user-permissions",
|
||||
"roles": [],
|
||||
"script": null,
|
||||
"standard": "Yes",
|
||||
"style": null,
|
||||
"title": "User Permissions Manager"
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
import frappe.defaults
|
||||
from frappe.permissions import (can_set_user_permissions, add_user_permission,
|
||||
remove_user_permission, get_valid_perms)
|
||||
from frappe.core.doctype.user.user import get_system_users
|
||||
from frappe.utils.csvutils import UnicodeWriter, read_csv_content_from_uploaded_file
|
||||
from frappe.defaults import clear_default
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_users_and_links():
|
||||
return {
|
||||
"users": get_system_users(),
|
||||
"link_fields": get_doctypes_for_user_permissions()
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_permissions(parent=None, defkey=None, defvalue=None):
|
||||
if defkey and not can_set_user_permissions(defkey, defvalue):
|
||||
raise frappe.PermissionError
|
||||
|
||||
conditions, values = _build_conditions(locals())
|
||||
|
||||
permissions = frappe.db.sql("""select name, parent, defkey, defvalue
|
||||
from tabDefaultValue
|
||||
where parent not in ('__default', '__global')
|
||||
and substr(defkey,1,1)!='_'
|
||||
and parenttype='User Permission'
|
||||
{conditions}
|
||||
order by parent, defkey""".format(conditions=conditions), values, as_dict=True)
|
||||
|
||||
if not defkey:
|
||||
out = []
|
||||
doctypes = get_doctypes_for_user_permissions()
|
||||
for p in permissions:
|
||||
if p.defkey in doctypes:
|
||||
out.append(p)
|
||||
permissions = out
|
||||
|
||||
return permissions
|
||||
|
||||
def _build_conditions(filters):
|
||||
conditions = []
|
||||
values = {}
|
||||
for key, value in filters.items():
|
||||
if filters.get(key):
|
||||
conditions.append("and `{key}`=%({key})s".format(key=key))
|
||||
values[key] = value
|
||||
|
||||
return "\n".join(conditions), values
|
||||
|
||||
@frappe.whitelist()
|
||||
def remove(user, name, defkey, defvalue):
|
||||
if not can_set_user_permissions(defkey, defvalue):
|
||||
frappe.throw(_("Cannot remove permission for DocType: {0} and Name: {1}").format(
|
||||
defkey, defvalue), frappe.PermissionError)
|
||||
|
||||
remove_user_permission(defkey, defvalue, user, name)
|
||||
|
||||
@frappe.whitelist()
|
||||
def add(user, defkey, defvalue):
|
||||
if not can_set_user_permissions(defkey, defvalue):
|
||||
frappe.throw(_("Cannot set permission for DocType: {0} and Name: {1}").format(
|
||||
defkey, defvalue), frappe.PermissionError)
|
||||
|
||||
add_user_permission(defkey, defvalue, user, with_message=True)
|
||||
|
||||
def get_doctypes_for_user_permissions():
|
||||
'''Get doctypes for the current user where user permissions are applicable'''
|
||||
user_roles = frappe.get_roles()
|
||||
|
||||
if "System Manager" in user_roles:
|
||||
doctypes = set([p.parent for p in get_valid_perms()])
|
||||
else:
|
||||
doctypes = set([p.parent for p in get_valid_perms() if p.set_user_permissions])
|
||||
|
||||
single_doctypes = set([d.name for d in frappe.get_all("DocType", {"issingle": 1})])
|
||||
|
||||
return sorted(doctypes.difference(single_doctypes))
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_user_permissions_csv():
|
||||
out = [["User Permissions"], ["User", "Document Type", "Value"]]
|
||||
out += [[a.parent, a.defkey, a.defvalue] for a in get_permissions()]
|
||||
|
||||
csv = UnicodeWriter()
|
||||
for row in out:
|
||||
csv.writerow(row)
|
||||
|
||||
frappe.response['result'] = str(csv.getvalue())
|
||||
frappe.response['type'] = 'csv'
|
||||
frappe.response['doctype'] = "User Permissions"
|
||||
|
||||
@frappe.whitelist()
|
||||
def import_user_permissions():
|
||||
frappe.only_for("System Manager")
|
||||
rows = read_csv_content_from_uploaded_file(ignore_encoding=True)
|
||||
clear_default(parenttype="User Permission")
|
||||
|
||||
if rows[0][0]!="User Permissions" and rows[1][0] != "User":
|
||||
frappe.throw(frappe._("Please upload using the same template as download."))
|
||||
|
||||
for row in rows[2:]:
|
||||
add_user_permission(row[1], row[2], row[0])
|
||||
|
|
@ -48,25 +48,10 @@ def is_a_user_permission_key(key):
|
|||
return ":" not in key and key != frappe.scrub(key)
|
||||
|
||||
def get_user_permissions(user=None):
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
||||
return build_user_permissions(user)
|
||||
|
||||
def build_user_permissions(user):
|
||||
out = frappe.cache().hget("user_permissions", user)
|
||||
if out==None:
|
||||
out = {}
|
||||
for key, value in frappe.db.sql("""select defkey, ifnull(defvalue, '') as defvalue
|
||||
from tabDefaultValue where parent=%s and parenttype='User Permission'""", (user,)):
|
||||
out.setdefault(key, []).append(value)
|
||||
|
||||
# add profile match
|
||||
if user not in out.get("User", []):
|
||||
out.setdefault("User", []).append(user)
|
||||
|
||||
frappe.cache().hset("user_permissions", user, out)
|
||||
return out
|
||||
from frappe.core.doctype.user_permission.user_permission \
|
||||
import get_user_permissions as _get_user_permissions
|
||||
'''Return frappe.core.doctype.user_permissions.user_permissions._get_user_permissions (kept for backward compatibility)'''
|
||||
return _get_user_permissions(user)
|
||||
|
||||
def get_defaults(user=None):
|
||||
globald = get_defaults_for()
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ def getdoctype(doctype, with_parent=False, cached_timestamp=None):
|
|||
if not docs:
|
||||
docs = get_meta_bundle(doctype)
|
||||
|
||||
frappe.response['user_permissions'] = get_user_permissions(docs)
|
||||
frappe.response['user_settings'] = get_user_settings(parent_dt or doctype)
|
||||
|
||||
if cached_timestamp and docs[0].modified==cached_timestamp:
|
||||
|
|
@ -102,16 +101,6 @@ def get_docinfo(doc=None, doctype=None, name=None):
|
|||
"rating": get_feedback_rating(doc.doctype, doc.name)
|
||||
}
|
||||
|
||||
def get_user_permissions(meta):
|
||||
out = {}
|
||||
all_user_permissions = frappe.defaults.get_user_permissions()
|
||||
|
||||
for m in meta:
|
||||
for df in m.get_fields_to_check_permissions(all_user_permissions):
|
||||
out[df.options] = list(set(all_user_permissions[df.options]))
|
||||
|
||||
return out
|
||||
|
||||
def get_attachments(dt, dn):
|
||||
return frappe.get_all("File", fields=["name", "file_name", "file_url", "is_private"],
|
||||
filters = {"attached_to_name": dn, "attached_to_doctype": dt})
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from frappe.utils import nowdate, nowtime, now_datetime
|
|||
import frappe.defaults
|
||||
from frappe.model.db_schema import type_map
|
||||
import copy
|
||||
from frappe.core.doctype.user_permission.user_permission import get_user_permissions
|
||||
|
||||
def get_new_doc(doctype, parent_doc = None, parentfield = None, as_dict=False):
|
||||
if doctype not in frappe.local.new_doc_templates:
|
||||
|
|
@ -47,7 +48,7 @@ def make_new_doc(doctype):
|
|||
return doc
|
||||
|
||||
def set_user_and_static_default_values(doc):
|
||||
user_permissions = frappe.defaults.get_user_permissions()
|
||||
user_permissions = get_user_permissions()
|
||||
defaults = frappe.defaults.get_defaults()
|
||||
|
||||
for df in doc.meta.get("fields"):
|
||||
|
|
@ -103,7 +104,7 @@ def get_static_default_value(df, user_permissions):
|
|||
|
||||
def set_dynamic_default_values(doc, parent_doc, parentfield):
|
||||
# these values should not be cached
|
||||
user_permissions = frappe.defaults.get_user_permissions()
|
||||
user_permissions = get_user_permissions()
|
||||
|
||||
for df in frappe.get_meta(doc["doctype"]).get("fields"):
|
||||
if df.get("default"):
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ class DatabaseQuery(object):
|
|||
# apply user permissions?
|
||||
if role_permissions.get("apply_user_permissions", {}).get("read"):
|
||||
# get user permissions
|
||||
user_permissions = frappe.defaults.get_user_permissions(self.user)
|
||||
user_permissions = frappe.permissions.get_user_permissions(self.user)
|
||||
self.add_user_permissions(user_permissions,
|
||||
user_permission_doctypes=role_permissions.get("user_permission_doctypes").get("read"))
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from frappe.utils.file_manager import remove_all
|
|||
from frappe.utils.password import delete_all_passwords_for
|
||||
from frappe import _
|
||||
from frappe.model.naming import revert_series_if_last
|
||||
from frappe.utils.global_search import delete_for_document
|
||||
from frappe.utils.global_search import delete_for_document
|
||||
|
||||
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False,
|
||||
ignore_permissions=False, flags=None, ignore_on_trash=False):
|
||||
|
|
@ -158,8 +158,13 @@ def update_flags(doc, flags=None, ignore_permissions=False):
|
|||
|
||||
def check_permission_and_not_submitted(doc):
|
||||
# permission
|
||||
if not doc.flags.ignore_permissions and frappe.session.user!="Administrator" and (not doc.has_permission("delete") or (doc.doctype=="DocType" and not doc.custom)):
|
||||
frappe.msgprint(_("User not allowed to delete {0}: {1}").format(doc.doctype, doc.name), raise_exception=True)
|
||||
if (not doc.flags.ignore_permissions
|
||||
and frappe.session.user!="Administrator"
|
||||
and (
|
||||
not doc.has_permission("delete")
|
||||
or (doc.doctype=="DocType" and not doc.custom))):
|
||||
frappe.msgprint(_("User not allowed to delete {0}: {1}")
|
||||
.format(doc.doctype, doc.name), raise_exception=frappe.PermissionError)
|
||||
|
||||
# check if submitted
|
||||
if doc.docstatus == 1:
|
||||
|
|
|
|||
|
|
@ -189,3 +189,4 @@ frappe.patches.v8_1.enable_allow_error_traceback_in_system_settings
|
|||
frappe.patches.v8_1.update_format_options_in_auto_email_report
|
||||
frappe.patches.v8_1.delete_custom_docperm_if_doctype_not_exists
|
||||
frappe.patches.v8_5.delete_email_group_member_with_invalid_emails
|
||||
frappe.patches.v8_x.update_user_permission
|
||||
|
|
|
|||
0
frappe/patches/v8_x/__init__.py
Normal file
0
frappe/patches/v8_x/__init__.py
Normal file
25
frappe/patches/v8_x/update_user_permission.py
Normal file
25
frappe/patches/v8_x/update_user_permission.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc('core', 'doctype', 'user_permission')
|
||||
frappe.delete_doc('core', 'page', 'user-permissions')
|
||||
for perm in frappe.db.sql("""
|
||||
select
|
||||
name, parent, defkey, defvalue
|
||||
from
|
||||
tabDefaultValue
|
||||
where
|
||||
parent not in ('__default', '__global')
|
||||
and
|
||||
substr(defkey,1,1)!='_'
|
||||
and
|
||||
parenttype='User Permission'
|
||||
""", as_dict=True):
|
||||
frappe.get_doc(dict(
|
||||
doctype='User Permission',
|
||||
user=perm.parent,
|
||||
allow=perm.defkey,
|
||||
for_value=perm.defvalue
|
||||
)).insert(ignore_permissions = True)
|
||||
|
||||
frappe.db.sql('delete from tabDefaultValue where parenttype="User Permission"')
|
||||
|
|
@ -7,7 +7,6 @@ import frappe, copy, json
|
|||
from frappe import _, msgprint
|
||||
from frappe.utils import cint
|
||||
import frappe.share
|
||||
|
||||
rights = ("read", "write", "create", "delete", "submit", "cancel", "amend",
|
||||
"print", "email", "report", "import", "export", "set_user_permissions", "share")
|
||||
|
||||
|
|
@ -25,6 +24,9 @@ def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None):
|
|||
"""
|
||||
if not user: user = frappe.session.user
|
||||
|
||||
if verbose:
|
||||
print('--- Checking for {0} {1} ---'.format(doctype, doc.name if doc else '-'))
|
||||
|
||||
if frappe.is_table(doctype):
|
||||
if verbose: print("Table type, always true")
|
||||
return True
|
||||
|
|
@ -40,7 +42,7 @@ def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None):
|
|||
return False
|
||||
|
||||
if user=="Administrator":
|
||||
if verbose: print("Administrator")
|
||||
if verbose: print("Allowing Administrator")
|
||||
return True
|
||||
|
||||
def false_if_not_shared():
|
||||
|
|
@ -210,7 +212,10 @@ def get_role_permissions(meta, user=None, verbose=False):
|
|||
|
||||
if p.user_permission_doctypes:
|
||||
# set user_permission_doctypes in perms
|
||||
user_permission_doctypes = json.loads(p.user_permission_doctypes)
|
||||
try:
|
||||
user_permission_doctypes = json.loads(p.user_permission_doctypes)
|
||||
except ValueError:
|
||||
user_permission_doctypes = []
|
||||
else:
|
||||
user_permission_doctypes = get_linked_doctypes(meta.name)
|
||||
|
||||
|
|
@ -247,8 +252,12 @@ def get_role_permissions(meta, user=None, verbose=False):
|
|||
|
||||
return frappe.local.role_permissions[cache_key]
|
||||
|
||||
def get_user_permissions(user):
|
||||
from frappe.core.doctype.user_permission.user_permission import get_user_permissions
|
||||
return get_user_permissions(user)
|
||||
|
||||
def user_has_permission(doc, verbose=True, user=None, user_permission_doctypes=None):
|
||||
from frappe.defaults import get_user_permissions
|
||||
from frappe.core.doctype.user_permission.user_permission import get_user_permissions
|
||||
user_permissions = get_user_permissions(user)
|
||||
user_permission_doctypes = get_user_permission_doctypes(user_permission_doctypes, user_permissions)
|
||||
|
||||
|
|
@ -258,6 +267,10 @@ def user_has_permission(doc, verbose=True, user=None, user_permission_doctypes=N
|
|||
|
||||
messages = {}
|
||||
|
||||
if not user_permission_doctypes:
|
||||
# no doctypes restricted
|
||||
end_result = True
|
||||
|
||||
# check multiple sets of user_permission_doctypes using OR condition
|
||||
for doctypes in user_permission_doctypes:
|
||||
result = True
|
||||
|
|
@ -309,9 +322,9 @@ def has_controller_permissions(doc, ptype, user=None):
|
|||
def get_doctypes_with_read():
|
||||
return list(set([p.parent for p in get_valid_perms()]))
|
||||
|
||||
def get_valid_perms(doctype=None):
|
||||
def get_valid_perms(doctype=None, user=None):
|
||||
'''Get valid permissions for the current user from DocPerm and Custom DocPerm'''
|
||||
roles = get_roles()
|
||||
roles = get_roles(user)
|
||||
|
||||
perms = get_perms_for(roles)
|
||||
custom_perms = get_perms_for(roles, 'Custom DocPerm')
|
||||
|
|
@ -360,7 +373,8 @@ def get_roles(user=None, with_standard=True):
|
|||
|
||||
def get_perms_for(roles, perm_doctype='DocPerm'):
|
||||
'''Get perms for given roles'''
|
||||
return frappe.db.sql("""select * from `tab{doctype}` where docstatus=0
|
||||
return frappe.db.sql("""
|
||||
select * from `tab{doctype}` where docstatus=0
|
||||
and ifnull(permlevel,0)=0
|
||||
and role in ({roles})""".format(doctype = perm_doctype,
|
||||
roles=", ".join(["%s"]*len(roles))), tuple(roles), as_dict=1)
|
||||
|
|
@ -386,22 +400,28 @@ def set_user_permission_if_allowed(doctype, name, user, with_message=False):
|
|||
if get_role_permissions(frappe.get_meta(doctype), user).set_user_permissions!=1:
|
||||
add_user_permission(doctype, name, user, with_message)
|
||||
|
||||
def add_user_permission(doctype, name, user, with_message=False):
|
||||
'''Add user default'''
|
||||
if name not in frappe.defaults.get_user_permissions(user).get(doctype, []):
|
||||
def add_user_permission(doctype, name, user, apply=False):
|
||||
'''Add user permission'''
|
||||
from frappe.core.doctype.user_permission.user_permission import get_user_permissions
|
||||
if name not in get_user_permissions(user).get(doctype, []):
|
||||
if not frappe.db.exists(doctype, name):
|
||||
frappe.throw(_("{0} {1} not found").format(_(doctype), name), frappe.DoesNotExistError)
|
||||
|
||||
frappe.defaults.add_default(doctype, name, user, "User Permission")
|
||||
elif with_message:
|
||||
msgprint(_("Permission already set"))
|
||||
frappe.get_doc(dict(
|
||||
doctype='User Permission',
|
||||
user=user,
|
||||
allow=doctype,
|
||||
for_value=name,
|
||||
apply_for_all_roles=apply
|
||||
)).insert()
|
||||
|
||||
def remove_user_permission(doctype, name, user, default_value_name=None):
|
||||
frappe.defaults.clear_default(key=doctype, value=name, parent=user, parenttype="User Permission",
|
||||
name=default_value_name)
|
||||
def remove_user_permission(doctype, name, user):
|
||||
user_permission_name = frappe.db.get_value('User Permission',
|
||||
dict(user=user, allow=doctype, for_value=name))
|
||||
frappe.delete_doc('User Permission', user_permission_name)
|
||||
|
||||
def clear_user_permissions_for_doctype(doctype):
|
||||
frappe.defaults.clear_default(parenttype="User Permission", key=doctype)
|
||||
frappe.cache().delete_value('user_permissions')
|
||||
|
||||
def can_import(doctype, raise_exception=False):
|
||||
if not ("System Manager" in frappe.get_roles() or has_permission(doctype, "import")):
|
||||
|
|
@ -426,9 +446,10 @@ def apply_user_permissions(doctype, ptype, user=None):
|
|||
|
||||
def get_user_permission_doctypes(user_permission_doctypes, user_permissions):
|
||||
"""returns a list of list like [["User", "Blog Post"], ["User"]]"""
|
||||
if cint(frappe.db.get_single_value("System Settings", "ignore_user_permissions_if_missing")):
|
||||
if cint(frappe.get_system_settings('ignore_user_permissions_if_missing')):
|
||||
# select those user permission doctypes for which user permissions exist!
|
||||
user_permission_doctypes = [list(set(doctypes).intersection(set(user_permissions.keys())))
|
||||
user_permission_doctypes = [
|
||||
list(set(doctypes).intersection(set(user_permissions.keys())))
|
||||
for doctypes in user_permission_doctypes]
|
||||
|
||||
if len(user_permission_doctypes) > 1:
|
||||
|
|
@ -452,6 +473,22 @@ def get_user_permission_doctypes(user_permission_doctypes, user_permissions):
|
|||
|
||||
return user_permission_doctypes
|
||||
|
||||
def update_permission_property(doctype, role, permlevel, ptype, value=None, validate=True):
|
||||
'''Update a property in Custom Perm'''
|
||||
from frappe.core.doctype.doctype.doctype import validate_permissions_for_doctype
|
||||
out = setup_custom_perms(doctype)
|
||||
|
||||
name = frappe.get_value('Custom DocPerm', dict(parent=doctype, role=role,
|
||||
permlevel=permlevel))
|
||||
|
||||
frappe.db.sql("""
|
||||
update `tabCustom DocPerm`
|
||||
set `{0}`=%s where name=%s""".format(ptype), (value, name))
|
||||
if validate:
|
||||
validate_permissions_for_doctype(doctype)
|
||||
|
||||
return out
|
||||
|
||||
def setup_custom_perms(parent):
|
||||
'''if custom permssions are not setup for the current doctype, set them up'''
|
||||
if not frappe.db.exists('Custom DocPerm', dict(parent=parent)):
|
||||
|
|
|
|||
|
|
@ -77,10 +77,6 @@ frappe.defaults = {
|
|||
},
|
||||
|
||||
get_user_permissions: function() {
|
||||
return frappe.defaults.user_permissions;
|
||||
return frappe.boot.user_permissions;
|
||||
},
|
||||
set_user_permissions: function(user_permissions) {
|
||||
if(!user_permissions) return;
|
||||
frappe.defaults.user_permissions = $.extend(frappe.defaults.user_permissions || {}, user_permissions);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -599,9 +599,9 @@ frappe.views.ListView = frappe.ui.BaseList.extend({
|
|||
}, true);
|
||||
}
|
||||
if (frappe.model.can_set_user_permissions(this.doctype)) {
|
||||
this.page.add_menu_item(__('User Permissions Manager'), function () {
|
||||
frappe.set_route('user-permissions', {
|
||||
doctype: me.doctype
|
||||
this.page.add_menu_item(__('User Permissions'), function () {
|
||||
frappe.set_route('List', 'User Permission', {
|
||||
allow: me.doctype
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,8 +127,10 @@ $.extend(frappe.model, {
|
|||
var user_default = "";
|
||||
var user_permissions = frappe.defaults.get_user_permissions();
|
||||
var meta = frappe.get_meta(doc.doctype);
|
||||
var has_user_permissions = (df.fieldtype==="Link" && user_permissions
|
||||
&& df.ignore_user_permissions != 1 && user_permissions[df.options]);
|
||||
var has_user_permissions = (df.fieldtype==="Link"
|
||||
&& user_permissions
|
||||
&& df.ignore_user_permissions != 1
|
||||
&& user_permissions[df.options]);
|
||||
|
||||
// don't set defaults for "User" link field using User Permissions!
|
||||
if (df.fieldtype==="Link" && df.options!=="User") {
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ $.extend(frappe.model, {
|
|||
localStorage["_doctype:" + doctype] = JSON.stringify(r.docs);
|
||||
}
|
||||
frappe.model.init_doctype(doctype);
|
||||
frappe.defaults.set_user_permissions(r.user_permissions);
|
||||
|
||||
if(r.user_settings) {
|
||||
// remember filters and other settings from last view
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ frappe.views.QueryReport = Class.extend({
|
|||
doctype: "Report",
|
||||
name: me.report_name
|
||||
};
|
||||
frappe.set_route("user-permissions");
|
||||
frappe.set_route('List', 'User Permission');
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -821,12 +821,12 @@ frappe.views.ReportView = frappe.ui.BaseList.extend({
|
|||
make_user_permissions: function() {
|
||||
var me = this;
|
||||
if(this.docname && frappe.model.can_set_user_permissions("Report")) {
|
||||
this.page.add_menu_item(__("User Permissions Manager"), function() {
|
||||
this.page.add_menu_item(__("User Permissions"), function() {
|
||||
frappe.route_options = {
|
||||
doctype: "Report",
|
||||
name: me.docname
|
||||
};
|
||||
frappe.set_route("user-permissions");
|
||||
frappe.set_route('List', 'User Permission');
|
||||
}, true);
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -266,12 +266,12 @@ def make_test_records_for_doctype(doctype, verbose=0, force=False):
|
|||
frappe.local.test_objects[doctype] += test_module._make_test_records(verbose)
|
||||
|
||||
elif hasattr(test_module, "test_records"):
|
||||
frappe.local.test_objects[doctype] += make_test_objects(doctype, test_module.test_records, verbose)
|
||||
frappe.local.test_objects[doctype] += make_test_objects(doctype, test_module.test_records, verbose, force)
|
||||
|
||||
else:
|
||||
test_records = frappe.get_test_records(doctype)
|
||||
if test_records:
|
||||
frappe.local.test_objects[doctype] += make_test_objects(doctype, test_records, verbose)
|
||||
frappe.local.test_objects[doctype] += make_test_objects(doctype, test_records, verbose, force)
|
||||
|
||||
elif verbose:
|
||||
print_mandatory_fields(doctype)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ import frappe.defaults
|
|||
import unittest
|
||||
import json
|
||||
import frappe.model.meta
|
||||
from frappe.core.page.user_permissions.user_permissions import add, remove, get_permissions
|
||||
from frappe.permissions import clear_user_permissions_for_doctype, get_doc_permissions
|
||||
from frappe.permissions import (add_user_permission, remove_user_permission,
|
||||
clear_user_permissions_for_doctype, get_doc_permissions, add_permission,
|
||||
get_valid_perms)
|
||||
from frappe.core.page.permission_manager.permission_manager import update, reset
|
||||
from frappe.test_runner import make_test_records_for_doctype
|
||||
|
||||
test_records = frappe.get_test_records('Blog Post')
|
||||
|
||||
|
|
@ -24,6 +26,7 @@ class TestPermissions(unittest.TestCase):
|
|||
|
||||
user = frappe.get_doc("User", "test1@example.com")
|
||||
user.add_roles("Website Manager")
|
||||
user.add_roles("System Manager")
|
||||
|
||||
user = frappe.get_doc("User", "test2@example.com")
|
||||
user.add_roles("Blogger")
|
||||
|
|
@ -36,6 +39,8 @@ class TestPermissions(unittest.TestCase):
|
|||
reset('Contact')
|
||||
reset('Salutation')
|
||||
|
||||
frappe.db.sql('delete from `tabUser Permission`')
|
||||
|
||||
self.set_ignore_user_permissions_if_missing(0)
|
||||
|
||||
frappe.set_user("test1@example.com")
|
||||
|
|
@ -78,7 +83,7 @@ class TestPermissions(unittest.TestCase):
|
|||
def test_user_permissions_in_doc(self):
|
||||
self.set_user_permission_doctypes(["Blog Category"])
|
||||
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
|
@ -94,7 +99,7 @@ class TestPermissions(unittest.TestCase):
|
|||
def test_user_permissions_in_report(self):
|
||||
self.set_user_permission_doctypes(["Blog Category"])
|
||||
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com")
|
||||
add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
names = [d.name for d in frappe.get_list("Blog Post", fields=["name", "blog_category"])]
|
||||
|
|
@ -103,7 +108,7 @@ class TestPermissions(unittest.TestCase):
|
|||
self.assertFalse("-test-blog-post" in names)
|
||||
|
||||
def test_default_values(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com")
|
||||
add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.new_doc("Blog Post")
|
||||
|
|
@ -139,14 +144,14 @@ class TestPermissions(unittest.TestCase):
|
|||
|
||||
def test_set_user_permissions(self):
|
||||
frappe.set_user("test1@example.com")
|
||||
add("test2@example.com", "Blog Post", "-test-blog-post")
|
||||
add_user_permission("Blog Post", "-test-blog-post", "test2@example.com")
|
||||
|
||||
def test_not_allowed_to_set_user_permissions(self):
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
# this user can't add user permissions
|
||||
self.assertRaises(frappe.PermissionError, add,
|
||||
"test2@example.com", "Blog Post", "-test-blog-post")
|
||||
self.assertRaises(frappe.PermissionError, add_user_permission,
|
||||
"Blog Post", "-test-blog-post", "test2@example.com")
|
||||
|
||||
def test_read_if_explicit_user_permissions_are_set(self):
|
||||
self.set_user_permission_doctypes(["Blog Post"])
|
||||
|
|
@ -165,13 +170,12 @@ class TestPermissions(unittest.TestCase):
|
|||
|
||||
def test_not_allowed_to_remove_user_permissions(self):
|
||||
self.test_set_user_permissions()
|
||||
defname = get_permissions("test2@example.com", "Blog Post", "-test-blog-post")[0].name
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
# user cannot remove their own user permissions
|
||||
self.assertRaises(frappe.PermissionError, remove,
|
||||
"test2@example.com", defname, "Blog Post", "-test-blog-post")
|
||||
self.assertRaises(frappe.PermissionError, remove_user_permission,
|
||||
"Blog Post", "-test-blog-post", "test2@example.com")
|
||||
|
||||
def test_user_permissions_based_on_blogger(self):
|
||||
frappe.set_user("test2@example.com")
|
||||
|
|
@ -181,7 +185,7 @@ class TestPermissions(unittest.TestCase):
|
|||
self.set_user_permission_doctypes(["Blog Post"])
|
||||
|
||||
frappe.set_user("test1@example.com")
|
||||
add("test2@example.com", "Blog Post", "-test-blog-post")
|
||||
add_user_permission("Blog Post", "-test-blog-post", "test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.get_doc("Blog Post", "-test-blog-post-1")
|
||||
|
|
@ -199,9 +203,9 @@ class TestPermissions(unittest.TestCase):
|
|||
blog_post.get_field("title").set_only_once = 0
|
||||
|
||||
def test_user_permission_doctypes(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
"test2@example.com")
|
||||
frappe.permissions.add_user_permission("Blogger", "_Test Blogger 1",
|
||||
add_user_permission("Blogger", "_Test Blogger 1",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
|
@ -221,9 +225,9 @@ class TestPermissions(unittest.TestCase):
|
|||
def if_owner_setup(self):
|
||||
update('Blog Post', 'Blogger', 0, 'if_owner', 1)
|
||||
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
"test2@example.com")
|
||||
frappe.permissions.add_user_permission("Blogger", "_Test Blogger 1",
|
||||
add_user_permission("Blogger", "_Test Blogger 1",
|
||||
"test2@example.com")
|
||||
|
||||
update('Blog Post', 'Blogger', 0, 'user_permission_doctypes', json.dumps(["Blog Category"]))
|
||||
|
|
@ -231,11 +235,13 @@ class TestPermissions(unittest.TestCase):
|
|||
frappe.model.meta.clear_cache("Blog Post")
|
||||
|
||||
def set_user_permission_doctypes(self, user_permission_doctypes):
|
||||
set_user_permission_doctypes(doctype="Blog Post", role="Blogger",
|
||||
set_user_permission_doctypes(["Blog Post"], role="Blogger",
|
||||
apply_user_permissions=1, user_permission_doctypes=user_permission_doctypes)
|
||||
|
||||
def test_insert_if_owner_with_user_permissions(self):
|
||||
"""If `If Owner` is checked for a Role, check if that document is allowed to be read, updated, submitted, etc. except be created, even if the document is restricted based on User Permissions."""
|
||||
frappe.delete_doc('Blog Post', '-test-blog-post-title')
|
||||
|
||||
self.set_user_permission_doctypes(["Blog Category"])
|
||||
self.if_owner_setup()
|
||||
|
||||
|
|
@ -252,7 +258,7 @@ class TestPermissions(unittest.TestCase):
|
|||
self.assertRaises(frappe.PermissionError, doc.insert)
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category",
|
||||
add_user_permission("Blog Category", "_Test Blog Category",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
|
@ -273,8 +279,8 @@ class TestPermissions(unittest.TestCase):
|
|||
self.set_user_permission_doctypes(['Blog Category', 'Blog Post', 'Blogger'])
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category",
|
||||
"test2@example.com")
|
||||
# add_user_permission("Blog Category", "_Test Blog Category",
|
||||
# "test2@example.com")
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
doc = frappe.get_doc({
|
||||
|
|
@ -294,33 +300,73 @@ class TestPermissions(unittest.TestCase):
|
|||
self.assertTrue(doc.has_permission("write"))
|
||||
|
||||
def test_strict_user_permissions(self):
|
||||
"""If `Strict User Permissions` is checked in System Settings, show records even if User Permissions are missing for a linked doctype"""
|
||||
set_user_permission_doctypes(doctype="Contact", role="Sales User",
|
||||
apply_user_permissions=1, user_permission_doctypes=['Salutation'])
|
||||
set_user_permission_doctypes(doctype="Salutation", role="All",
|
||||
apply_user_permissions=1, user_permission_doctypes=['Salutation'])
|
||||
"""If `Strict User Permissions` is checked in System Settings,
|
||||
show records even if User Permissions are missing for a linked
|
||||
doctype"""
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
frappe.permissions.add_user_permission("Salutation", "Mr", "test3@example.com")
|
||||
frappe.db.sql('delete from tabContact')
|
||||
make_test_records_for_doctype('Contact', force=True)
|
||||
|
||||
set_user_permission_doctypes("Contact", role="Sales User",
|
||||
apply_user_permissions=1, user_permission_doctypes=['Salutation'])
|
||||
set_user_permission_doctypes("Salutation", role="All",
|
||||
apply_user_permissions=1, user_permission_doctypes=['Salutation'])
|
||||
|
||||
add_user_permission("Salutation", "Mr", "test3@example.com")
|
||||
self.set_strict_user_permissions(0)
|
||||
|
||||
frappe.set_user("test3@example.com")
|
||||
self.assertEquals(len(frappe.get_list("Contact")),2)
|
||||
self.assertEquals(len(frappe.get_list("Contact")), 2)
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
self.set_strict_user_permissions(1)
|
||||
|
||||
frappe.set_user("test3@example.com")
|
||||
self.assertTrue(len(frappe.get_list("Contact")),1)
|
||||
self.assertTrue(len(frappe.get_list("Contact")), 1)
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
self.set_strict_user_permissions(0)
|
||||
|
||||
def test_automatic_apply_user_permissions(self):
|
||||
'''Test user permissions are automatically applied when a user permission
|
||||
is created'''
|
||||
# create a user
|
||||
frappe.get_doc(dict(doctype='User', email='test_user_perm@example.com',
|
||||
first_name='tester')).insert(ignore_if_duplicate=True)
|
||||
frappe.get_doc(dict(doctype='Role', role_name='Test Role User Perm')
|
||||
).insert(ignore_if_duplicate=True)
|
||||
|
||||
def set_user_permission_doctypes(doctype, role, apply_user_permissions, user_permission_doctypes):
|
||||
# add a permission for event
|
||||
add_permission('DocType', 'Test Role User Perm')
|
||||
frappe.get_doc('User', 'test_user_perm@example.com').add_roles('Test Role User Perm')
|
||||
|
||||
|
||||
# add user permission
|
||||
add_user_permission('Module Def', 'Core', 'test_user_perm@example.com', True)
|
||||
|
||||
# check if user permission is applied in the new role
|
||||
_perm = None
|
||||
for perm in get_valid_perms('DocType', 'test_user_perm@example.com'):
|
||||
if perm.role == 'Test Role User Perm':
|
||||
_perm = perm
|
||||
|
||||
self.assertEqual(_perm.apply_user_permissions, 1)
|
||||
|
||||
# restrict by module
|
||||
self.assertTrue('Module Def' in json.loads(_perm.user_permission_doctypes))
|
||||
|
||||
|
||||
def set_user_permission_doctypes(doctypes, role, apply_user_permissions,
|
||||
user_permission_doctypes):
|
||||
user_permission_doctypes = None if not user_permission_doctypes else json.dumps(user_permission_doctypes)
|
||||
|
||||
update(doctype, role, 0, 'apply_user_permissions', 1)
|
||||
update(doctype, role, 0, 'user_permission_doctypes', user_permission_doctypes)
|
||||
if isinstance(doctypes, basestring):
|
||||
doctypes = [doctypes]
|
||||
|
||||
frappe.clear_cache(doctype=doctype)
|
||||
for doctype in doctypes:
|
||||
update(doctype, role, 0, 'apply_user_permissions', 1)
|
||||
update(doctype, role, 0, 'user_permission_doctypes',
|
||||
user_permission_doctypes)
|
||||
|
||||
frappe.clear_cache(doctype=doctype)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue