diff --git a/frappe/__init__.py b/frappe/__init__.py
index 575de13595..256683aea2 100644
--- a/frappe/__init__.py
+++ b/frappe/__init__.py
@@ -355,8 +355,8 @@ def get_roles(username=None):
return ["Guest"]
if username:
- import frappe.utils.user
- return frappe.utils.user.get_roles(username)
+ import frappe.permissions
+ return frappe.permissions.get_roles(username)
else:
return get_user().get_roles()
@@ -447,6 +447,9 @@ def only_for(roles):
"""Raise `frappe.PermissionError` if the user does not have any of the given **Roles**.
:param roles: List of roles to check."""
+ if local.flags.in_test:
+ return
+
if not isinstance(roles, (tuple, list)):
roles = (roles,)
roles = set(roles)
diff --git a/frappe/core/doctype/custom_docperm/__init__.py b/frappe/core/doctype/custom_docperm/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frappe/core/doctype/custom_docperm/custom_docperm.js b/frappe/core/doctype/custom_docperm/custom_docperm.js
new file mode 100644
index 0000000000..1f04a638a1
--- /dev/null
+++ b/frappe/core/doctype/custom_docperm/custom_docperm.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2016, Frappe Technologies and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Custom DocPerm', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/frappe/core/doctype/custom_docperm/custom_docperm.json b/frappe/core/doctype/custom_docperm/custom_docperm.json
new file mode 100644
index 0000000000..dd2cfb6248
--- /dev/null
+++ b/frappe/core/doctype/custom_docperm/custom_docperm.json
@@ -0,0 +1,809 @@
+{
+ "allow_copy": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "hash",
+ "beta": 0,
+ "creation": "2017-01-11 04:21:35.217943",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "role_and_level",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Role and Level",
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "role",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Role",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "role",
+ "oldfieldtype": "Link",
+ "options": "Role",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "150px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Filter records based on User Permissions defined for a user",
+ "fieldname": "apply_user_permissions",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Apply 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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Apply this rule if the User is the Owner",
+ "fieldname": "if_owner",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "If user is the owner",
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fieldname": "permlevel",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Level",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "permlevel",
+ "oldfieldtype": "Int",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "40px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "40px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "description": "JSON list of DocTypes used to apply User Permissions. If empty, all linked DocTypes will be used to apply User Permissions.",
+ "fieldname": "user_permission_doctypes",
+ "fieldtype": "Code",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "User Permission DocTypes",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_4",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "read",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Read",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "read",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "32px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "32px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "write",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Write",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "write",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "32px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "32px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "create",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Create",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "create",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "32px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "32px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "delete",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Delete",
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_8",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "submit",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Submit",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "submit",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "32px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "32px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cancel",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Cancel",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "cancel",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "32px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "32px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amend",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amend",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "amend",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "32px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "32px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "additional_permissions",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Additional 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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "report",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Report",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "32px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "32px"
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "export",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Export",
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "import",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Import",
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "This role update User Permissions for a user",
+ "fieldname": "set_user_permissions",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Set 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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_19",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "share",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Share",
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "print",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Print",
+ "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_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "email",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Email",
+ "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
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-01-11 04:21:35.217943",
+ "modified_by": "Administrator",
+ "module": "Core",
+ "name": "Custom DocPerm",
+ "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,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 1,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 0,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/frappe/core/doctype/custom_docperm/custom_docperm.py b/frappe/core/doctype/custom_docperm/custom_docperm.py
new file mode 100644
index 0000000000..3d2f2334d7
--- /dev/null
+++ b/frappe/core/doctype/custom_docperm/custom_docperm.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class CustomDocPerm(Document):
+ pass
diff --git a/frappe/core/doctype/custom_docperm/test_custom_docperm.py b/frappe/core/doctype/custom_docperm/test_custom_docperm.py
new file mode 100644
index 0000000000..bd6e17ccc9
--- /dev/null
+++ b/frappe/core/doctype/custom_docperm/test_custom_docperm.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+# test_records = frappe.get_test_records('Custom DocPerm')
+
+class TestCustomDocPerm(unittest.TestCase):
+ pass
diff --git a/frappe/core/doctype/docperm/docperm.json b/frappe/core/doctype/docperm/docperm.json
index be205b2fb7..8e9273118e 100644
--- a/frappe/core/doctype/docperm/docperm.json
+++ b/frappe/core/doctype/docperm/docperm.json
@@ -22,6 +22,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Role and Level",
"length": 0,
"no_copy": 0,
@@ -29,6 +30,7 @@
"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,
@@ -47,6 +49,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Role",
"length": 0,
"no_copy": 0,
@@ -58,6 +61,7 @@
"print_hide_if_no_value": 0,
"print_width": "150px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@@ -78,6 +82,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Apply User Permissions",
"length": 0,
"no_copy": 0,
@@ -85,6 +90,7 @@
"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,
@@ -104,6 +110,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "If user is the owner",
"length": 0,
"no_copy": 0,
@@ -112,33 +119,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "is_custom",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Is Custom",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -157,12 +138,14 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"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,
@@ -182,6 +165,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Level",
"length": 0,
"no_copy": 0,
@@ -192,6 +176,7 @@
"print_hide_if_no_value": 0,
"print_width": "40px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -213,6 +198,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "User Permission DocTypes",
"length": 0,
"no_copy": 0,
@@ -220,6 +206,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -238,6 +225,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Permissions",
"length": 0,
"no_copy": 0,
@@ -245,6 +233,7 @@
"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,
@@ -264,6 +253,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Read",
"length": 0,
"no_copy": 0,
@@ -274,6 +264,7 @@
"print_hide_if_no_value": 0,
"print_width": "32px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -294,6 +285,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Write",
"length": 0,
"no_copy": 0,
@@ -304,6 +296,7 @@
"print_hide_if_no_value": 0,
"print_width": "32px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -324,6 +317,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Create",
"length": 0,
"no_copy": 0,
@@ -334,6 +328,7 @@
"print_hide_if_no_value": 0,
"print_width": "32px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -354,6 +349,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Delete",
"length": 0,
"no_copy": 0,
@@ -361,6 +357,7 @@
"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,
@@ -379,12 +376,14 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"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,
@@ -403,6 +402,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Submit",
"length": 0,
"no_copy": 0,
@@ -413,6 +413,7 @@
"print_hide_if_no_value": 0,
"print_width": "32px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -432,6 +433,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Cancel",
"length": 0,
"no_copy": 0,
@@ -442,6 +444,7 @@
"print_hide_if_no_value": 0,
"print_width": "32px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -461,6 +464,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Amend",
"length": 0,
"no_copy": 0,
@@ -471,6 +475,7 @@
"print_hide_if_no_value": 0,
"print_width": "32px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -490,6 +495,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Additional Permissions",
"length": 0,
"no_copy": 0,
@@ -497,6 +503,7 @@
"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,
@@ -516,6 +523,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Report",
"length": 0,
"no_copy": 0,
@@ -524,6 +532,7 @@
"print_hide_if_no_value": 0,
"print_width": "32px",
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -544,6 +553,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Export",
"length": 0,
"no_copy": 0,
@@ -551,6 +561,7 @@
"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,
@@ -569,6 +580,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Import",
"length": 0,
"no_copy": 0,
@@ -576,6 +588,7 @@
"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,
@@ -595,6 +608,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Set User Permissions",
"length": 0,
"no_copy": 0,
@@ -602,6 +616,7 @@
"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,
@@ -620,12 +635,14 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"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,
@@ -645,6 +662,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Share",
"length": 0,
"no_copy": 0,
@@ -653,6 +671,7 @@
"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,
@@ -672,6 +691,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Print",
"length": 0,
"no_copy": 0,
@@ -679,6 +699,7 @@
"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,
@@ -698,6 +719,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Email",
"length": 0,
"no_copy": 0,
@@ -705,6 +727,7 @@
"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,
@@ -722,7 +745,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-09-29 08:07:20.450064",
+ "modified": "2017-01-11 04:21:44.249780",
"modified_by": "Administrator",
"module": "Core",
"name": "DocPerm",
@@ -732,5 +755,6 @@
"read_only": 0,
"read_only_onload": 0,
"sort_order": "ASC",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py
index 7aa56ee015..2701bcbb57 100644
--- a/frappe/core/doctype/user/user.py
+++ b/frappe/core/doctype/user/user.py
@@ -495,10 +495,10 @@ def get_user_roles(arg=None):
return frappe.get_roles(frappe.form_dict['uid'])
@frappe.whitelist()
-def get_perm_info(arg=None):
+def get_perm_info(role):
"""get permission info"""
- return frappe.db.sql("""select * from tabDocPerm where role=%s
- and docstatus<2 order by parent, permlevel""", (frappe.form_dict['role'],), as_dict=1)
+ from frappe.permissions import get_all_perms
+ return get_all_perms(role)
@frappe.whitelist(allow_guest=True)
def update_password(new_password, key=None, old_password=None):
diff --git a/frappe/core/page/permission_manager/permission_manager.js b/frappe/core/page/permission_manager/permission_manager.js
index 7d13d3a3a1..3b96e73e93 100644
--- a/frappe/core/page/permission_manager/permission_manager.js
+++ b/frappe/core/page/permission_manager/permission_manager.js
@@ -234,7 +234,8 @@ frappe.PermissionEngine = Class.extend({
checkbox.find("input")
.prop("checked", d[fieldname] ? true: false)
.attr("data-ptype", fieldname)
- .attr("data-name", d.name)
+ .attr("data-role", d.role)
+ .attr("data-permlevel", d.permlevel)
.attr("data-doctype", d.parent)
checkbox.find("label")
@@ -307,16 +308,18 @@ frappe.PermissionEngine = Class.extend({
var me = this;
$("")
.appendTo($("
").appendTo(row))
- .attr("data-name", d.name)
.attr("data-doctype", d.parent)
+ .attr("data-role", d.role)
+ .attr("data-permlevel", d.permlevel)
.click(function() {
return frappe.call({
module: "frappe.core",
page: "permission_manager",
method: "remove",
args: {
- name: $(this).attr("data-name"),
- doctype: $(this).attr("data-doctype")
+ doctype: $(this).attr("data-doctype"),
+ role: $(this).attr("data-role"),
+ permlevel: $(this).attr("data-permlevel")
},
callback: function(r) {
if(r.exc) {
@@ -339,7 +342,8 @@ frappe.PermissionEngine = Class.extend({
this.body.on("click", "input[type='checkbox']", function() {
var chk = $(this);
var args = {
- name: chk.attr("data-name"),
+ role: chk.attr("data-role"),
+ permlevel: chk.attr("data-permlevel"),
doctype: chk.attr("data-doctype"),
ptype: chk.attr("data-ptype"),
value: chk.prop("checked") ? 1 : 0
@@ -465,7 +469,8 @@ frappe.PermissionEngine = Class.extend({
method: "update",
args: {
doctype: d.parent,
- name: d.name,
+ role: d.role,
+ permlevel: d.permlevel,
ptype: "user_permission_doctypes",
value: user_permission_doctypes
},
@@ -477,6 +482,9 @@ frappe.PermissionEngine = Class.extend({
setTimeout(function() { msg.hide(); }, 3000);
d.user_permission_doctypes = user_permission_doctypes;
dialog.hide();
+ if(r.message==='refresh') {
+ me.refresh();
+ }
}
}
});
diff --git a/frappe/core/page/permission_manager/permission_manager.py b/frappe/core/page/permission_manager/permission_manager.py
index b223352e77..14385f8fe2 100644
--- a/frappe/core/page/permission_manager/permission_manager.py
+++ b/frappe/core/page/permission_manager/permission_manager.py
@@ -7,7 +7,8 @@ import frappe.defaults
from frappe.modules.import_file import get_file_path, read_doc_from_file
from frappe.translate import send_translations
from frappe.desk.notifications import delete_notification_count_for
-from frappe.permissions import reset_perms, get_linked_doctypes
+from frappe.permissions import reset_perms, get_linked_doctypes, get_all_perms, setup_custom_perms
+from frappe import _
@frappe.whitelist()
def get_roles_and_doctypes():
@@ -17,7 +18,6 @@ def get_roles_and_doctypes():
"doctypes": [d[0] for d in frappe.db.sql("""select name from `tabDocType` dt where
istable=0 and
name not in ('DocType') and
- exists(select * from `tabDocField` where parent=dt.name) and
exists(select * from `tabDocPerm` dp,`tabRole` role where dp.role = role.name and dp.parent=dt.name and not role.disabled)""")],
"roles": [d[0] for d in frappe.db.sql("""select name from tabRole where
name != 'Administrator' and disabled=0""")]
@@ -26,29 +26,30 @@ def get_roles_and_doctypes():
@frappe.whitelist()
def get_permissions(doctype=None, role=None):
frappe.only_for("System Manager")
- out = frappe.db.sql("""select * from tabDocPerm
- where %s%s order by parent, permlevel, role""" %
- (doctype and (" parent='%s'" % frappe.db.escape(doctype)) or "",
- role and ((doctype and " and " or "") + " role='%s'" % frappe.db.escape(role)) or ""),
- as_dict=True)
+ if role:
+ out = get_all_perms(role)
+ if doctype:
+ out = [p for p in out if p.parent == doctype]
+ else:
+ out = frappe.get_all('Custom DocPerm', fields='*', filters=dict(parent = doctype))
+ if not out:
+ out = frappe.get_all('DocPerm', fields='*', filters=dict(parent = doctype))
linked_doctypes = {}
for d in out:
- d.linked_doctypes = linked_doctypes.setdefault(d.parent, get_linked_doctypes(d.parent))
+ if not d.parent in linked_doctypes:
+ linked_doctypes[d.parent] = get_linked_doctypes(d.parent)
+ d.linked_doctypes = linked_doctypes[d.parent]
return out
-@frappe.whitelist()
-def remove(doctype, name):
- frappe.only_for("System Manager")
- frappe.db.sql("""delete from tabDocPerm where name=%s""", name)
- validate_and_reset(doctype, for_remove=True)
-
@frappe.whitelist()
def add(parent, role, permlevel):
frappe.only_for("System Manager")
+ setup_custom_perms(parent)
+
frappe.get_doc({
- "doctype":"DocPerm",
+ "doctype":"Custom DocPerm",
"__islocal": 1,
"parent": parent,
"parenttype": "DocType",
@@ -61,12 +62,34 @@ def add(parent, role, permlevel):
validate_and_reset(parent)
@frappe.whitelist()
-def update(name, doctype, ptype, value=None):
+def update(doctype, role, permlevel, ptype, value=None):
frappe.only_for("System Manager")
- frappe.db.sql("""update tabDocPerm set `%s`=%s where name=%s"""\
+
+ 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_and_reset(doctype)
+ return out
+
+@frappe.whitelist()
+def remove(doctype, role, permlevel):
+ frappe.only_for("System Manager")
+ setup_custom_perms(doctype)
+
+ name = frappe.get_value('Custom DocPerm', dict(parent=doctype, role=role, permlevel=permlevel))
+
+ frappe.db.sql('delete from `tabCustom DocPerm` where name=%s', name)
+ if not frappe.get_all('Custom DocPerm', dict(parent=doctype)):
+ frappe.throw(_('There must be atleast one permission rule.'), title=_('Cannot Remove'))
+
+ validate_and_reset(doctype, for_remove=True)
+
def validate_and_reset(doctype, for_remove=False):
from frappe.core.doctype.doctype.doctype import validate_permissions_for_doctype
validate_permissions_for_doctype(doctype, for_remove)
@@ -81,9 +104,10 @@ def reset(doctype):
def clear_doctype_cache(doctype):
frappe.clear_cache(doctype=doctype)
delete_notification_count_for(doctype)
- for user in frappe.db.sql_list("""select distinct tabUserRole.parent from tabUserRole, tabDocPerm
- where tabDocPerm.parent = %s
- and tabDocPerm.role = tabUserRole.role""", doctype):
+ for user in frappe.db.sql_list("""select distinct tabUserRole.parent from tabUserRole,
+ tabDocPerm
+ where tabDocPerm.parent = %s
+ and tabDocPerm.role = tabUserRole.role""", doctype):
frappe.clear_cache(user=user)
@frappe.whitelist()
diff --git a/frappe/core/page/user_permissions/user_permissions.py b/frappe/core/page/user_permissions/user_permissions.py
index a06a8c0c41..a9b34ca009 100644
--- a/frappe/core/page/user_permissions/user_permissions.py
+++ b/frappe/core/page/user_permissions/user_permissions.py
@@ -5,7 +5,8 @@ from __future__ import unicode_literals
import frappe
from frappe import _
import frappe.defaults
-import frappe.permissions
+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
@@ -19,7 +20,7 @@ def get_users_and_links():
@frappe.whitelist()
def get_permissions(parent=None, defkey=None, defvalue=None):
- if defkey and not frappe.permissions.can_set_user_permissions(defkey, defvalue):
+ if defkey and not can_set_user_permissions(defkey, defvalue):
raise frappe.PermissionError
conditions, values = _build_conditions(locals())
@@ -54,33 +55,23 @@ def _build_conditions(filters):
@frappe.whitelist()
def remove(user, name, defkey, defvalue):
- if not frappe.permissions.can_set_user_permissions(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)
- frappe.permissions.remove_user_permission(defkey, defvalue, user, name)
+ remove_user_permission(defkey, defvalue, user, name)
@frappe.whitelist()
def add(user, defkey, defvalue):
- if not frappe.permissions.can_set_user_permissions(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)
- frappe.permissions.add_user_permission(defkey, defvalue, user, with_message=True)
+ add_user_permission(defkey, defvalue, user, with_message=True)
def get_doctypes_for_user_permissions():
- user_roles = frappe.get_roles()
- condition = ""
- values = []
- if "System Manager" not in user_roles:
- condition = """and exists(select `tabDocPerm`.name from `tabDocPerm`
- where `tabDocPerm`.parent=`tabDocType`.name and `tabDocPerm`.`set_user_permissions`=1
- and `tabDocPerm`.role in ({roles}))""".format(roles=", ".join(["%s"]*len(user_roles)))
- values = user_roles
-
- return frappe.db.sql_list("""select name from tabDocType
- where issingle=0 and istable=0 {condition}""".format(condition=condition),
- tuple(values))
+ '''Get doctypes for the current user where user permissions are applicable'''
+ return list(set([p.parent for p in get_valid_perms() if p.set_user_permissions]))
@frappe.whitelist()
def get_user_permissions_csv():
@@ -105,4 +96,4 @@ def import_user_permissions():
frappe.throw(frappe._("Please upload using the same template as download."))
for row in rows[2:]:
- frappe.permissions.add_user_permission(row[1], row[2], row[0])
+ add_user_permission(row[1], row[2], row[0])
diff --git a/frappe/custom/doctype/customize_form/customize_form.js b/frappe/custom/doctype/customize_form/customize_form.js
index 91a323ade2..3b9b90da5e 100644
--- a/frappe/custom/doctype/customize_form/customize_form.js
+++ b/frappe/custom/doctype/customize_form/customize_form.js
@@ -76,6 +76,10 @@ frappe.ui.form.on("Customize Form", {
frappe.customize_form.confirm(__('Remove all customizations?'), frm);
}, "fa fa-eraser", "btn-default");
+ frm.add_custom_button(__('Set Permissions'), function() {
+ frappe.set_route('permission-manager', frm.doc.doc_type);
+ }, "fa fa-lock", "btn-default");
+
if(frappe.boot.developer_mode) {
frm.add_custom_button(__('Export Customizations'), function() {
frappe.prompt(
@@ -84,6 +88,8 @@ frappe.ui.form.on("Customize Form", {
label: __('Module to Export')},
{fieldtype:'Check', fieldname:'sync_on_migrate',
label: __('Sync on Migrate'), 'default': 1},
+ {fieldtype:'Check', fieldname:'with_permissions',
+ label: __('Export Custom Permissions'), 'default': 1},
],
function(data) {
frappe.call({
@@ -91,7 +97,8 @@ frappe.ui.form.on("Customize Form", {
args: {
doctype: frm.doc.doc_type,
module: data.module,
- sync_on_migrate: data.sync_on_migrate
+ sync_on_migrate: data.sync_on_migrate,
+ with_permissions: data.with_permissions
}
});
},
diff --git a/frappe/data/Framework.sql b/frappe/data/Framework.sql
index b0307a13c4..cbfaf485a3 100644
--- a/frappe/data/Framework.sql
+++ b/frappe/data/Framework.sql
@@ -78,7 +78,6 @@ CREATE TABLE `tabDocPerm` (
`permlevel` int(11) DEFAULT '0',
`role` varchar(255) DEFAULT NULL,
`match` varchar(255) DEFAULT NULL,
- `is_custom` int(1) NOT NULL DEFAULT 0,
`read` int(1) NOT NULL DEFAULT 1,
`write` int(1) NOT NULL DEFAULT 1,
`create` int(1) NOT NULL DEFAULT 1,
diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py
index 8d96a3b1a1..3e7af7ed8b 100644
--- a/frappe/model/base_document.py
+++ b/frappe/model/base_document.py
@@ -544,7 +544,7 @@ class BaseDocument(object):
for fieldname in constants:
df = self.meta.get_field(fieldname)
- # This conversion to string only when fieldtype is Date
+ # This conversion to string only when fieldtype is Date
if df.fieldtype == 'Date':
value = str(values.get(fieldname))
diff --git a/frappe/model/meta.py b/frappe/model/meta.py
index 5b7fa083ed..ae653e1a50 100644
--- a/frappe/model/meta.py
+++ b/frappe/model/meta.py
@@ -207,6 +207,7 @@ class Meta(Document):
self.apply_property_setters()
self.sort_fields()
self.get_valid_columns()
+ self.set_custom_permissions()
def add_custom_fields(self):
try:
@@ -278,6 +279,22 @@ class Meta(Document):
self.fields = newlist
+ def set_custom_permissions(self):
+ '''Reset `permissions` with Custom DocPerm if exists'''
+ if frappe.flags.in_patch or frappe.flags.in_import:
+ return
+
+ if not self.istable and self.name not in ('DocType', 'DocField', 'DocPerm',
+ 'Custom DocPerm'):
+ custom_perms = frappe.get_all('Custom DocPerm', fields='*',
+ filters=dict(parent=self.name), update=dict(doctype='Custom DocPerm'))
+ if custom_perms:
+ self.permissions = [Document(d) for d in custom_perms]
+
+ def get_fieldnames_with_value(self):
+ return [df.fieldname for df in self.fields if df.fieldtype not in no_value_fields]
+
+
def get_fields_to_check_permissions(self, user_permission_doctypes):
fields = self.get("fields", {
"fieldtype":"Link",
@@ -430,7 +447,7 @@ def trim_tables():
for doctype in frappe.db.get_all("DocType", filters={"issingle": 0}):
doctype = doctype.name
columns = frappe.db.get_table_columns(doctype)
- fields = [df.fieldname for df in frappe.get_meta(doctype).fields if df.fieldtype not in no_value_fields]
+ fields = frappe.get_meta(doctype).get_fieldnames_with_value()
columns_to_remove = [f for f in list(set(columns) - set(fields)) if f not in ignore_fields
and not f.startswith("_")]
if columns_to_remove:
diff --git a/frappe/modules/import_file.py b/frappe/modules/import_file.py
index 13fc5d6def..3c27fca86e 100644
--- a/frappe/modules/import_file.py
+++ b/frappe/modules/import_file.py
@@ -11,11 +11,11 @@ def import_files(module, dt=None, dn=None, force=False, pre_process=None, reset_
if type(module) is list:
out = []
for m in module:
- out.append(import_file(m[0], m[1], m[2], force=force, pre_process=pre_process,
+ out.append(import_file(m[0], m[1], m[2], force=force, pre_process=pre_process,
reset_permissions=reset_permissions))
return out
else:
- return import_file(module, dt, dn, force=force, pre_process=pre_process,
+ return import_file(module, dt, dn, force=force, pre_process=pre_process,
reset_permissions=reset_permissions)
def import_file(module, dt, dn, force=False, pre_process=None, reset_permissions=False):
@@ -32,7 +32,7 @@ def get_file_path(module, dt, dn):
return path
-def import_file_by_path(path, force=False, data_import=False, pre_process=None, ignore_version=None,
+def import_file_by_path(path, force=False, data_import=False, pre_process=None, ignore_version=None,
reset_permissions=False):
frappe.flags.in_import = True
try:
@@ -89,9 +89,9 @@ ignore_values = {
"Print Format": ["disabled"]
}
-ignore_doctypes = ["Page Role", "DocPerm"]
+ignore_doctypes = ["Page Role"]
-def import_doc(docdict, force=False, data_import=False, pre_process=None,
+def import_doc(docdict, force=False, data_import=False, pre_process=None,
ignore_version=None, reset_permissions=False):
frappe.flags.in_import = True
diff --git a/frappe/modules/utils.py b/frappe/modules/utils.py
index 980e0b418c..3e18350efa 100644
--- a/frappe/modules/utils.py
+++ b/frappe/modules/utils.py
@@ -40,13 +40,13 @@ def get_doc_module(module, doctype, name):
return frappe.get_module(module_name)
@frappe.whitelist()
-def export_customizations(module, doctype, sync_on_migrate=0):
+def export_customizations(module, doctype, sync_on_migrate=0, with_permissions=0):
"""Export Custom Field and Property Setter for the current document to the app folder.
This will be synced with bench migrate"""
if not frappe.get_conf().developer_mode:
raise 'Not developer mode'
- custom = {'custom_fields': [], 'property_setters': [],
+ custom = {'custom_fields': [], 'property_setters': [], 'custom_perms': [],
'doctype': doctype, 'sync_on_migrate': 1}
def add(_doctype):
@@ -57,6 +57,10 @@ def export_customizations(module, doctype, sync_on_migrate=0):
add(doctype)
+ if with_permissions:
+ custom['custom_perms'] = frappe.get_all('Custom DocPerm',
+ fields='*', filters={'parent': doctype})
+
# add custom fields and property setters for all child tables
for d in frappe.get_meta(doctype).get_table_fields():
add(d.options)
@@ -97,26 +101,28 @@ def sync_customizations_for_doctype(data):
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype
doctype = data['doctype']
- if data['custom_fields']:
- frappe.db.sql('delete from `tabCustom Field` where dt=%s', doctype)
- for d in data['custom_fields']:
- d['doctype'] = 'Custom Field'
+ def sync(key, custom_doctype, doctype_fieldname):
+ frappe.db.sql('delete from `tab{0}` where `{1}`=%s'.format(custom_doctype, doctype_fieldname),
+ doctype)
+
+ for d in data[key]:
+ d['doctype'] = custom_doctype
doc = frappe.get_doc(d)
doc.db_insert()
+ if data['custom_fields']:
+ sync('custom_fields', 'Custom Field', 'dt')
+
if data['property_setters']:
- frappe.db.sql('delete from `tabProperty Setter` where doc_type=%s', doctype)
+ sync('property_setters', 'Property Setter', 'doc_type')
- for d in data['property_setters']:
- d['doctype'] = 'Property Setter'
- doc = frappe.get_doc(d)
- doc.db_insert()
+ if data.get('custom_perms'):
+ sync('custom_perms', 'Custom DocPerm', 'parent')
print 'Updating customizations for {0}'.format(doctype)
validate_fields_for_doctype(doctype)
-
def scrub(txt):
return frappe.scrub(txt)
diff --git a/frappe/patches.txt b/frappe/patches.txt
index 925ff5fdae..1082156867 100644
--- a/frappe/patches.txt
+++ b/frappe/patches.txt
@@ -7,6 +7,8 @@ frappe.patches.v7_0.re_route #2016-06-27
execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2016-10-17
execute:frappe.reload_doc('core', 'doctype', 'docfield', force=True) #2017-01-06
execute:frappe.reload_doc('core', 'doctype', 'docperm') #2014-06-24
+execute:frappe.reload_doc('core', 'doctype', 'custom_docperm')
+frappe.patches.v7_2.setup_custom_perms
execute:frappe.reload_doc('core', 'doctype', 'role')
execute:frappe.reload_doc('core', 'doctype', 'user')
execute:frappe.reload_doc('core', 'doctype', 'deleted_document')
@@ -152,4 +154,4 @@ frappe.patches.v7_2.set_doctype_engine
frappe.patches.v7_2.merge_knowledge_base
frappe.patches.v7_0.update_report_builder_json
frappe.patches.v7_2.set_in_standard_filter_property #1
-execute:frappe.db.sql("update tabCommunication set communication_date = creation where time(communication_date) = 0")
\ No newline at end of file
+execute:frappe.db.sql("update tabCommunication set communication_date = creation where time(communication_date) = 0")
diff --git a/frappe/patches/v7_2/setup_custom_perms.py b/frappe/patches/v7_2/setup_custom_perms.py
new file mode 100644
index 0000000000..b543523106
--- /dev/null
+++ b/frappe/patches/v7_2/setup_custom_perms.py
@@ -0,0 +1,34 @@
+import frappe
+from frappe.permissions import setup_custom_perms
+from frappe.core.page.permission_manager.permission_manager import get_standard_permissions
+
+'''
+Copy DocPerm to Custom DocPerm where permissions are set differently
+'''
+
+def execute():
+ docperm_meta = frappe.get_meta('DocPerm')
+ for d in frappe.db.get_all('DocType', dict(istable=0, issingle=0, custom=0)):
+ perms = frappe.get_all('DocPerm', fields='*', filters=dict(parent=d.name), order_by='idx asc')
+
+ # get default perms
+ standard_perms = get_standard_permissions(d.name)
+
+ same = True
+ if len(standard_perms) != len(perms):
+ same = False
+
+ else:
+ for i, p in enumerate(perms):
+ standard = standard_perms[i]
+ for fieldname in docperm_meta.get_fieldnames_with_value():
+ if p.get(fieldname) != standard.get(fieldname):
+ print d.name, fieldname, p.get(fieldname), standard.get(fieldname)
+ same = False
+ break
+
+ if not same:
+ break
+
+ if not same:
+ setup_custom_perms(d.name)
diff --git a/frappe/permissions.py b/frappe/permissions.py
index e76603193b..35339384d1 100644
--- a/frappe/permissions.py
+++ b/frappe/permissions.py
@@ -177,7 +177,11 @@ def get_role_permissions(meta, user=None, verbose=False):
cache_key = (meta.name, user)
if not frappe.local.role_permissions.get(cache_key):
- perms = frappe._dict({ "apply_user_permissions": {}, "user_permission_doctypes": {}, "if_owner": {} })
+ perms = frappe._dict(
+ apply_user_permissions={},
+ user_permission_doctypes={},
+ if_owner={}
+ )
user_roles = frappe.get_roles(user)
dont_match = []
has_a_role_with_apply_user_permissions = False
@@ -301,6 +305,65 @@ def has_controller_permissions(doc, ptype, user=None):
# controller permissions could not decide on True or False
return None
+def get_doctypes_with_read():
+ return list(set([p.parent for p in get_valid_perms()]))
+
+def get_valid_perms(doctype=None):
+ '''Get valid permissions for the current user from DocPerm and Custom DocPerm'''
+ roles = get_roles()
+
+ perms = get_perms_for(roles)
+ custom_perms = get_perms_for(roles, 'Custom DocPerm')
+
+ doctypes_with_custom_perms = list(set([d.parent for d in custom_perms]))
+ for p in perms:
+ if not p.parent in doctypes_with_custom_perms:
+ custom_perms.append(p)
+
+ if doctype:
+ return [p for p in custom_perms if p.parent == doctype]
+ else:
+ return custom_perms
+
+def get_all_perms(role):
+ '''Returns valid permissions for a given role'''
+ perms = frappe.get_all('DocPerm', fields='*', filters=dict(role=role))
+ custom_perms = frappe.get_all('Custom DocPerm', fields='*', filters=dict(role=role))
+ doctypes_with_custom_perms = list(set(p.parent for p in custom_perms))
+
+ for p in perms:
+ if p.parent not in doctypes_with_custom_perms:
+ custom_perms.append(p)
+
+ return p
+
+def get_roles(user=None, with_standard=True):
+ """get roles of current user"""
+ if not user:
+ user = frappe.session.user
+
+ if user=='Guest':
+ return ['Guest']
+
+ def get():
+ return [r[0] for r in frappe.db.sql("""select role from tabUserRole
+ where parent=%s and role not in ('All', 'Guest')""", (user,))] + ['All', 'Guest']
+
+ roles = frappe.cache().hget("roles", user, get)
+
+ # filter standard if required
+ if not with_standard:
+ roles = filter(lambda x: x not in ['All', 'Guest', 'Administrator'], roles)
+
+ return roles
+
+def get_perms_for(roles, perm_doctype='DocPerm'):
+ '''Get perms for given roles'''
+ 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)
+
def can_set_user_permissions(doctype, docname=None):
# System Manager can always set user permissions
if frappe.session.user == "Administrator" or "System Manager" in frappe.get_roles():
@@ -323,6 +386,7 @@ def set_user_permission_if_allowed(doctype, name, user, with_message=False):
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, []):
if not frappe.db.exists(doctype, name):
frappe.throw(_("{0} {1} not found").format(_(doctype), name), frappe.DoesNotExistError)
@@ -387,14 +451,25 @@ def get_user_permission_doctypes(user_permission_doctypes, user_permissions):
return user_permission_doctypes
+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)):
+ copy_perms(parent)
+ return True
+
+def copy_perms(parent):
+ '''Copy all DocPerm in to Custom DocPerm for the given document'''
+ for d in frappe.get_all('DocPerm', fields='*', filters=dict(parent=parent)):
+ custom_perm = frappe.new_doc('Custom DocPerm')
+ custom_perm.update(d)
+ custom_perm.insert(ignore_permissions=True)
+
def reset_perms(doctype):
"""Reset permissions for given doctype."""
from frappe.desk.notifications import delete_notification_count_for
delete_notification_count_for(doctype)
- frappe.db.sql("""delete from tabDocPerm where parent=%s""", doctype)
- frappe.reload_doc(frappe.db.get_value("DocType", doctype, "module"),
- "DocType", doctype, force=True)
+ frappe.db.sql("""delete from `tabCustom DocPerm` where parent=%s""", doctype)
def get_linked_doctypes(dt):
return list(set([dt] + [d.options for d in
diff --git a/frappe/tests/test_form_load.py b/frappe/tests/test_form_load.py
index 95ea03b688..bab8b1c4ee 100644
--- a/frappe/tests/test_form_load.py
+++ b/frappe/tests/test_form_load.py
@@ -4,6 +4,8 @@ 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.permissions import get_valid_perms
class TestFormLoad(unittest.TestCase):
def test_load(self):
@@ -21,10 +23,16 @@ class TestFormLoad(unittest.TestCase):
user = frappe.get_doc('User', 'test@example.com')
user.remove_roles('Website Manager')
user.add_roles('Blogger')
- frappe.set_user(user.name)
+ reset('Blog Post')
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"')
+
+ update('Blog Post', 'Website Manager', 0, 'permlevel', 1)
+
+ frappe.set_user(user.name)
+
+ # print frappe.as_json(get_valid_perms('Blog Post'))
+
frappe.clear_cache(doctype='Blog Post')
blog = frappe.db.get_value('Blog Post', {'title': '_Test Blog Post'})
@@ -41,7 +49,7 @@ class TestFormLoad(unittest.TestCase):
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"')
+ reset('Blog Post')
frappe.clear_cache(doctype='Blog Post')
diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py
index dd022ec74d..bde6a808e2 100644
--- a/frappe/tests/test_permissions.py
+++ b/frappe/tests/test_permissions.py
@@ -11,6 +11,7 @@ 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.core.page.permission_manager.permission_manager import update, reset
test_records = frappe.get_test_records('Blog Post')
@@ -26,8 +27,8 @@ class TestPermissions(unittest.TestCase):
user = frappe.get_doc("User", "test2@example.com")
user.add_roles("Blogger")
- frappe.db.sql("""update `tabDocPerm` set if_owner=0
- where parent='Blog Post' and permlevel=0 and permlevel=0 and role='Blogger'""")
+ reset('Blogger')
+ reset('Blog Post')
self.set_ignore_user_permissions_if_missing(0)
@@ -41,12 +42,8 @@ class TestPermissions(unittest.TestCase):
clear_user_permissions_for_doctype("Blog Post")
clear_user_permissions_for_doctype("Blogger")
- frappe.db.sql("""update `tabDocPerm` set user_permission_doctypes=null, apply_user_permissions=0
- where parent='Blog Post' and permlevel=0 and apply_user_permissions=1
- and `read`=1""")
-
- frappe.db.sql("""update `tabDocPerm` set if_owner=0
- where parent='Blog Post' and permlevel=0 and permlevel=0 and role='Blogger'""")
+ reset('Blogger')
+ reset('Blog Post')
self.set_ignore_user_permissions_if_missing(0)
@@ -204,17 +201,14 @@ class TestPermissions(unittest.TestCase):
frappe.model.meta.clear_cache("Blog Post")
def if_owner_setup(self):
- frappe.db.sql("""update `tabDocPerm` set if_owner=1
- where parent='Blog Post' and permlevel=0 and permlevel=0 and role='Blogger'""")
+ update('Blog Post', 'Blogger', 0, 'if_owner', 1)
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
"test2@example.com")
frappe.permissions.add_user_permission("Blogger", "_Test Blogger 1",
"test2@example.com")
- frappe.db.sql("""update `tabDocPerm` set user_permission_doctypes=%s
- where parent='Blog Post' and permlevel=0 and apply_user_permissions=1
- and `read`=1""", json.dumps(["Blog Category"]))
+ update('Blog Post', 'Blogger', 0, 'user_permission_doctypes', json.dumps(["Blog Category"]))
frappe.model.meta.clear_cache("Blog Post")
@@ -283,14 +277,8 @@ class TestPermissions(unittest.TestCase):
def set_user_permission_doctypes(doctype, role, apply_user_permissions, user_permission_doctypes):
user_permission_doctypes = None if not user_permission_doctypes else json.dumps(user_permission_doctypes)
- frappe.db.sql("""update `tabDocPerm` set apply_user_permissions=%(apply_user_permissions)s,
- user_permission_doctypes=%(user_permission_doctypes)s
- where parent=%(doctype)s and permlevel=0
- and `read`=1 and role=%(role)s""", {
- "apply_user_permissions": apply_user_permissions,
- "user_permission_doctypes": user_permission_doctypes,
- "doctype": doctype,
- "role": role
- })
+
+ update(doctype, role, 0, 'apply_user_permissions', 1)
+ update(doctype, role, 0, 'user_permission_doctypes', user_permission_doctypes)
frappe.clear_cache(doctype=doctype)
diff --git a/frappe/utils/bot.py b/frappe/utils/bot.py
index 08a8721dbb..9be8a93a62 100644
--- a/frappe/utils/bot.py
+++ b/frappe/utils/bot.py
@@ -7,6 +7,10 @@ import frappe, re, frappe.utils
from frappe.desk.notifications import get_notifications
from frappe import _
+@frappe.whitelist()
+def get_bot_reply(question):
+ return BotReply().get_reply(question)
+
class BotParser(object):
'''Base class for bot parser'''
def __init__(self, reply, query):
diff --git a/frappe/utils/user.py b/frappe/utils/user.py
index 58f197c1d2..3be4295dfe 100755
--- a/frappe/utils/user.py
+++ b/frappe/utils/user.py
@@ -7,6 +7,7 @@ import frappe, json
from frappe import _dict
import frappe.share
from frappe.utils import cint
+from frappe.permissions import get_roles, get_valid_perms
class UserPermissions:
"""
@@ -69,10 +70,7 @@ class UserPermissions:
def build_perm_map(self):
"""build map of permissions at level 0"""
self.perm_map = {}
- roles = self.get_roles()
- for r in frappe.db.sql("""select * from tabDocPerm where docstatus=0
- and ifnull(permlevel,0)=0
- and role in ({roles})""".format(roles=", ".join(["%s"]*len(roles))), tuple(roles), as_dict=1):
+ for r in get_valid_perms():
dt = r['parent']
if not dt in self.perm_map:
@@ -272,26 +270,6 @@ def add_system_manager(email, first_name=None, last_name=None, send_welcome_emai
where name not in ("Administrator", "Guest", "All")""")
user.add_roles(*roles)
-def get_roles(user=None, with_standard=True):
- """get roles of current user"""
- if not user:
- user = frappe.session.user
-
- if user=='Guest':
- return ['Guest']
-
- def get():
- return [r[0] for r in frappe.db.sql("""select role from tabUserRole
- where parent=%s and role not in ('All', 'Guest')""", (user,))] + ['All', 'Guest']
-
- roles = frappe.cache().hget("roles", user, get)
-
- # filter standard if required
- if not with_standard:
- roles = filter(lambda x: x not in ['All', 'Guest', 'Administrator'], roles)
-
- return roles
-
def get_enabled_system_users():
return frappe.db.sql("""select * from tabUser where
user_type='System User' and enabled=1 and name not in ('Administrator', 'Guest')""", as_dict=1)
@@ -344,7 +322,7 @@ def disable_users(limits=None):
frappe.db.set_value("User", user, 'enabled', 0)
from frappe.core.doctype.user.user import get_total_users
-
+
if get_total_users() > cint(limits.get('users')):
reset_simultaneous_sessions(cint(limits.get('users')))
|