Sfoglia il codice sorgente

[enhance] custom perms

version-14
Rushabh Mehta 8 anni fa
parent
commit
3f91c9455f
19 ha cambiato i file con 1093 aggiunte e 138 eliminazioni
  1. +5
    -2
      frappe/__init__.py
  2. +0
    -0
      frappe/core/doctype/custom_docperm/__init__.py
  3. +8
    -0
      frappe/core/doctype/custom_docperm/custom_docperm.js
  4. +809
    -0
      frappe/core/doctype/custom_docperm/custom_docperm.json
  5. +10
    -0
      frappe/core/doctype/custom_docperm/custom_docperm.py
  6. +12
    -0
      frappe/core/doctype/custom_docperm/test_custom_docperm.py
  7. +52
    -28
      frappe/core/doctype/docperm/docperm.json
  8. +3
    -3
      frappe/core/doctype/user/user.py
  9. +14
    -6
      frappe/core/page/permission_manager/permission_manager.js
  10. +65
    -20
      frappe/core/page/permission_manager/permission_manager.py
  11. +10
    -19
      frappe/core/page/user_permissions/user_permissions.py
  12. +0
    -1
      frappe/data/Framework.sql
  13. +9
    -0
      frappe/model/meta.py
  14. +5
    -5
      frappe/modules/import_file.py
  15. +1
    -0
      frappe/patches.txt
  16. +66
    -4
      frappe/permissions.py
  17. +11
    -3
      frappe/tests/test_form_load.py
  18. +10
    -22
      frappe/tests/test_permissions.py
  19. +3
    -25
      frappe/utils/user.py

+ 5
- 2
frappe/__init__.py Vedi File

@@ -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)


+ 0
- 0
frappe/core/doctype/custom_docperm/__init__.py Vedi File


+ 8
- 0
frappe/core/doctype/custom_docperm/custom_docperm.js Vedi File

@@ -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) {

}
});

+ 809
- 0
frappe/core/doctype/custom_docperm/custom_docperm.json Vedi File

@@ -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
}

+ 10
- 0
frappe/core/doctype/custom_docperm/custom_docperm.py Vedi File

@@ -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

+ 12
- 0
frappe/core/doctype/custom_docperm/test_custom_docperm.py Vedi File

@@ -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

+ 52
- 28
frappe/core/doctype/docperm/docperm.json Vedi File

@@ -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
}

+ 3
- 3
frappe/core/doctype/user/user.py Vedi File

@@ -499,10 +499,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):


+ 14
- 6
frappe/core/page/permission_manager/permission_manager.js Vedi File

@@ -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;
$("<button class='btn btn-default btn-sm'><i class='fa fa-remove'></i></button>")
.appendTo($("<td>").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();
}
}
}
});


+ 65
- 20
frappe/core/page/permission_manager/permission_manager.py Vedi File

@@ -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.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

@frappe.whitelist()
def get_roles_and_doctypes():
@@ -17,7 +17,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 +25,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 +61,56 @@ 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)
validate_and_reset(doctype, for_remove=True)

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 get_custom_perm_name(name):
'''Get the custom permission name for this DocPerm'''
if frappe.db.exists('Custom DocPerm', name):
return name
else:
original_perm = frappe.get_doc('DocPerm', name)
copy_perms(original_perm.parent)
name = frappe.db.get_value('Custom DocPerm', dict(parent=original_perm.parent,
role=original_perm.role, permlevel=original_perm.permlevel))

return name

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 +125,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()


+ 10
- 19
frappe/core/page/user_permissions/user_permissions.py Vedi File

@@ -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])

+ 0
- 1
frappe/data/Framework.sql Vedi File

@@ -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,


+ 9
- 0
frappe/model/meta.py Vedi File

@@ -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,14 @@ class Meta(Document):

self.fields = newlist

def set_custom_permissions(self):
'''Reset `permissions` with Custom DocPerm if exists'''
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))
if custom_perms:
self.permissions = custom_perms

def get_fields_to_check_permissions(self, user_permission_doctypes):
fields = self.get("fields", {
"fieldtype":"Link",


+ 5
- 5
frappe/modules/import_file.py Vedi File

@@ -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


+ 1
- 0
frappe/patches.txt Vedi File

@@ -7,6 +7,7 @@ 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') #2014-06-24
execute:frappe.reload_doc('core', 'doctype', 'role')
execute:frappe.reload_doc('core', 'doctype', 'user')
execute:frappe.reload_doc('core', 'doctype', 'deleted_document')


+ 66
- 4
frappe/permissions.py Vedi File

@@ -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)
@@ -392,9 +456,7 @@ def reset_perms(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


+ 11
- 3
frappe/tests/test_form_load.py Vedi File

@@ -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')



+ 10
- 22
frappe/tests/test_permissions.py Vedi File

@@ -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)

+ 3
- 25
frappe/utils/user.py Vedi File

@@ -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')))



Caricamento…
Annulla
Salva