From 82d2a2fda1018dc7fdcacf3d550bbd564aea41c0 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 27 May 2014 13:46:46 +0530 Subject: [PATCH] Permission relogication continued --- frappe/config/setup.py | 6 +- .../doctype/communication/communication.json | 11 +- frappe/core/doctype/doctype/doctype.py | 1 + frappe/core/doctype/event/event.json | 7 +- frappe/core/doctype/event/test_event.py | 2 +- .../core/doctype/letter_head/letter_head.json | 4 +- frappe/core/doctype/page/page.json | 9 +- frappe/core/doctype/report/report.json | 7 +- frappe/core/doctype/role/role.json | 5 +- frappe/core/doctype/todo/todo.json | 327 +++++++++--------- frappe/core/doctype/user/user.json | 4 +- .../permission_manager/permission_manager.js | 35 +- .../page/user_permissions/user_permissions.js | 2 +- .../user_permissions/user_permissions.json | 2 +- .../page/user_permissions/user_permissions.py | 14 +- frappe/defaults.py | 32 +- frappe/permissions.py | 19 +- frappe/public/js/frappe/form/infobar.js | 2 +- frappe/public/js/frappe/model/meta.js | 12 +- frappe/public/js/frappe/model/perm.js | 82 ++--- frappe/public/js/frappe/print/print_table.js | 2 +- frappe/public/js/frappe/views/doclistview.js | 5 +- frappe/public/js/frappe/views/reportview.js | 2 +- frappe/public/js/legacy/clientscriptAPI.js | 2 +- frappe/public/js/legacy/form.js | 3 +- .../doctype/blog_category/blog_category.json | 12 +- .../website/doctype/blog_post/blog_post.json | 214 ++++++------ .../doctype/blog_post/test_blog_post.py | 9 +- frappe/website/doctype/blogger/blogger.json | 5 +- 29 files changed, 408 insertions(+), 429 deletions(-) diff --git a/frappe/config/setup.py b/frappe/config/setup.py index 787d0d1662..d6fd0d34f2 100644 --- a/frappe/config/setup.py +++ b/frappe/config/setup.py @@ -26,10 +26,10 @@ def get_data(): }, { "type": "page", - "name": "user-properties", - "label": _("User Permission Restrictions"), + "name": "user-permissions", + "label": _("User Permissions"), "icon": "icon-user", - "description": _("Set Defaults and Restrictions for Users") + "description": _("Set Permissions per User") }, ] }, diff --git a/frappe/core/doctype/communication/communication.json b/frappe/core/doctype/communication/communication.json index 508d44c62a..2410353975 100644 --- a/frappe/core/doctype/communication/communication.json +++ b/frappe/core/doctype/communication/communication.json @@ -2,7 +2,7 @@ "allow_attach": 1, "allow_import": 1, "autoname": "naming_series:", - "creation": "2013-01-29 10:47:14.000000", + "creation": "2013-01-29 10:47:14", "description": "Keep a track of all communications", "docstatus": 0, "doctype": "DocType", @@ -154,7 +154,7 @@ "idx": 1, "in_dialog": 0, "issingle": 0, - "modified": "2014-01-24 13:01:25.000000", + "modified": "2014-05-27 03:49:08.475911", "modified_by": "Administrator", "module": "Core", "name": "Communication", @@ -162,7 +162,7 @@ "permissions": [ { "amend": 0, - "cancel": 0, + "apply_user_permissions": 1, "create": 1, "delete": 1, "email": 1, @@ -176,7 +176,6 @@ }, { "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -190,7 +189,7 @@ }, { "amend": 0, - "cancel": 0, + "apply_user_permissions": 1, "create": 1, "delete": 1, "email": 1, @@ -203,7 +202,6 @@ "write": 1 }, { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -216,7 +214,6 @@ "write": 1 }, { - "cancel": 0, "create": 1, "delete": 1, "email": 1, diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index db5971d411..aa7b609c0d 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -70,6 +70,7 @@ class DocType(Document): and (not autoname.startswith('eval:')) \ and (not autoname in ('Prompt', 'hash')) \ and (not autoname.startswith('naming_series:')): + prefix = autoname.split('.')[0] used_in = frappe.db.sql('select name from tabDocType where substring_index(autoname, ".", 1) = %s and name!=%s', (prefix, name)) if used_in: diff --git a/frappe/core/doctype/event/event.json b/frappe/core/doctype/event/event.json index 7c32762656..ec5e6ca3ad 100644 --- a/frappe/core/doctype/event/event.json +++ b/frappe/core/doctype/event/event.json @@ -1,6 +1,6 @@ { "autoname": "EV.#####", - "creation": "2013-06-10 13:17:47.000000", + "creation": "2013-06-10 13:17:47", "docstatus": 0, "doctype": "DocType", "fields": [ @@ -244,14 +244,14 @@ "icon": "icon-calendar", "idx": 1, "in_create": 1, - "modified": "2014-01-24 13:00:01.000000", + "modified": "2014-05-27 03:49:10.612463", "modified_by": "Administrator", "module": "Core", "name": "Event", "owner": "Administrator", "permissions": [ { - "cancel": 0, + "apply_user_permissions": 1, "create": 1, "delete": 0, "email": 1, @@ -264,7 +264,6 @@ "write": 1 }, { - "cancel": 0, "create": 1, "delete": 1, "email": 1, diff --git a/frappe/core/doctype/event/test_event.py b/frappe/core/doctype/event/test_event.py index 7bed6eb843..fb7877ebcb 100644 --- a/frappe/core/doctype/event/test_event.py +++ b/frappe/core/doctype/event/test_event.py @@ -1,7 +1,7 @@ # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt -"""Use blog post test to test permission restriction logic""" +"""Use blog post test to test user permissions logic""" import frappe import frappe.defaults diff --git a/frappe/core/doctype/letter_head/letter_head.json b/frappe/core/doctype/letter_head/letter_head.json index 115570898b..5da7ffc4dd 100644 --- a/frappe/core/doctype/letter_head/letter_head.json +++ b/frappe/core/doctype/letter_head/letter_head.json @@ -52,14 +52,13 @@ "icon": "icon-font", "idx": 1, "max_attachments": 3, - "modified": "2014-05-07 06:03:07.760995", + "modified": "2014-05-27 03:49:13.372430", "modified_by": "Administrator", "module": "Core", "name": "Letter Head", "owner": "Administrator", "permissions": [ { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -72,6 +71,7 @@ "write": 1 }, { + "apply_user_permissions": 1, "delete": 0, "email": 0, "permlevel": 0, diff --git a/frappe/core/doctype/page/page.json b/frappe/core/doctype/page/page.json index 1ea08691f7..b8aab04f73 100644 --- a/frappe/core/doctype/page/page.json +++ b/frappe/core/doctype/page/page.json @@ -2,7 +2,7 @@ "allow_copy": 0, "allow_rename": 1, "autoname": "field:page_name", - "creation": "2012-12-20 17:16:49.000000", + "creation": "2012-12-20 17:16:49", "docstatus": 0, "doctype": "DocType", "fields": [ @@ -16,6 +16,7 @@ { "fieldname": "page_name", "fieldtype": "Data", + "in_list_view": 1, "label": "Page Name", "oldfieldname": "page_name", "oldfieldtype": "Data", @@ -25,12 +26,14 @@ { "fieldname": "title", "fieldtype": "Data", + "in_list_view": 1, "label": "Title", "permlevel": 0 }, { "fieldname": "icon", "fieldtype": "Data", + "in_list_view": 1, "label": "icon", "permlevel": 0 }, @@ -84,14 +87,13 @@ "idx": 1, "issingle": 0, "istable": 0, - "modified": "2013-12-30 13:48:02.000000", + "modified": "2014-05-27 03:49:14.476843", "modified_by": "Administrator", "module": "Core", "name": "Page", "owner": "Administrator", "permissions": [ { - "cancel": 0, "create": 1, "email": 1, "permlevel": 0, @@ -102,6 +104,7 @@ "write": 1 }, { + "apply_user_permissions": 1, "email": 1, "permlevel": 0, "print": 1, diff --git a/frappe/core/doctype/report/report.json b/frappe/core/doctype/report/report.json index 62e81b08b9..26ed9ef6e9 100644 --- a/frappe/core/doctype/report/report.json +++ b/frappe/core/doctype/report/report.json @@ -101,14 +101,13 @@ ], "icon": "icon-table", "idx": 1, - "modified": "2014-05-12 17:08:04.185601", + "modified": "2014-05-27 03:49:17.001234", "modified_by": "Administrator", "module": "Core", "name": "Report", "owner": "Administrator", "permissions": [ { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -121,7 +120,6 @@ "write": 1 }, { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -134,7 +132,6 @@ "write": 1 }, { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -147,7 +144,7 @@ "write": 1 }, { - "cancel": 0, + "apply_user_permissions": 1, "delete": 0, "email": 1, "permlevel": 0, diff --git a/frappe/core/doctype/role/role.json b/frappe/core/doctype/role/role.json index 78a76096d0..7c3f02dd39 100644 --- a/frappe/core/doctype/role/role.json +++ b/frappe/core/doctype/role/role.json @@ -23,7 +23,7 @@ "idx": 1, "issingle": 0, "istable": 0, - "modified": "2014-05-23 01:29:48.468901", + "modified": "2014-05-27 03:49:17.110223", "modified_by": "Administrator", "module": "Core", "name": "Role", @@ -31,7 +31,6 @@ "permissions": [ { "amend": 0, - "cancel": 0, "create": 1, "email": 1, "permlevel": 0, @@ -43,7 +42,6 @@ "write": 1 }, { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -56,6 +54,7 @@ "write": 1 }, { + "apply_user_permissions": 1, "permlevel": 0, "read": 1, "role": "All" diff --git a/frappe/core/doctype/todo/todo.json b/frappe/core/doctype/todo/todo.json index 23d85a649d..1139bf07bb 100644 --- a/frappe/core/doctype/todo/todo.json +++ b/frappe/core/doctype/todo/todo.json @@ -1,198 +1,197 @@ { - "allow_attach": 0, - "allow_copy": 0, - "allow_rename": 0, - "autoname": "TDI.########", - "creation": "2012-07-03 13:30:35.000000", - "docstatus": 0, - "doctype": "DocType", + "allow_attach": 0, + "allow_copy": 0, + "allow_rename": 0, + "autoname": "TDI.########", + "creation": "2012-07-03 13:30:35", + "docstatus": 0, + "doctype": "DocType", "fields": [ { - "fieldname": "description_and_status", - "fieldtype": "Section Break", - "label": "Description and Status", + "fieldname": "description_and_status", + "fieldtype": "Section Break", + "label": "Description and Status", "permlevel": 0 - }, + }, { - "allow_on_submit": 0, - "fieldname": "description", - "fieldtype": "Text", - "hidden": 0, - "in_filter": 0, - "in_list_view": 1, - "label": "Description", - "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Text", - "permlevel": 0, - "print_hide": 0, - "print_width": "300px", - "report_hide": 0, - "reqd": 1, - "search_index": 0, + "allow_on_submit": 0, + "fieldname": "description", + "fieldtype": "Text", + "hidden": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Description", + "no_copy": 0, + "oldfieldname": "description", + "oldfieldtype": "Text", + "permlevel": 0, + "print_hide": 0, + "print_width": "300px", + "report_hide": 0, + "reqd": 1, + "search_index": 0, "width": "300px" - }, + }, { - "fieldname": "column_break_2", - "fieldtype": "Column Break", + "fieldname": "column_break_2", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "default": "Open", - "fieldname": "status", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Status", - "options": "Open\nClosed", + "default": "Open", + "fieldname": "status", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Status", + "options": "Open\nClosed", "permlevel": 0 - }, + }, { - "allow_on_submit": 0, - "default": "Medium", - "fieldname": "priority", - "fieldtype": "Select", - "hidden": 0, - "in_filter": 0, - "in_list_view": 1, - "label": "Priority", - "no_copy": 0, - "oldfieldname": "priority", - "oldfieldtype": "Data", - "options": "High\nMedium\nLow", - "permlevel": 0, - "print_hide": 0, - "report_hide": 0, - "reqd": 0, + "allow_on_submit": 0, + "default": "Medium", + "fieldname": "priority", + "fieldtype": "Select", + "hidden": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Priority", + "no_copy": 0, + "oldfieldname": "priority", + "oldfieldtype": "Data", + "options": "High\nMedium\nLow", + "permlevel": 0, + "print_hide": 0, + "report_hide": 0, + "reqd": 0, "search_index": 0 - }, + }, { - "allow_on_submit": 0, - "fieldname": "date", - "fieldtype": "Date", - "hidden": 0, - "in_filter": 0, - "in_list_view": 1, - "label": "Due Date", - "no_copy": 0, - "oldfieldname": "date", - "oldfieldtype": "Date", - "permlevel": 0, - "print_hide": 0, - "report_hide": 0, - "reqd": 0, + "allow_on_submit": 0, + "fieldname": "date", + "fieldtype": "Date", + "hidden": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Due Date", + "no_copy": 0, + "oldfieldname": "date", + "oldfieldtype": "Date", + "permlevel": 0, + "print_hide": 0, + "report_hide": 0, + "reqd": 0, "search_index": 0 - }, + }, { - "fieldname": "section_break_6", - "fieldtype": "Section Break", - "label": "Reference", + "fieldname": "section_break_6", + "fieldtype": "Section Break", + "label": "Reference", "permlevel": 0 - }, + }, { - "allow_on_submit": 0, - "fieldname": "reference_type", - "fieldtype": "Data", - "hidden": 0, - "in_filter": 0, - "label": "Reference Type", - "no_copy": 0, - "oldfieldname": "reference_type", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "report_hide": 0, - "reqd": 0, + "allow_on_submit": 0, + "fieldname": "reference_type", + "fieldtype": "Data", + "hidden": 0, + "in_filter": 0, + "label": "Reference Type", + "no_copy": 0, + "oldfieldname": "reference_type", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "report_hide": 0, + "reqd": 0, "search_index": 0 - }, + }, { - "allow_on_submit": 0, - "fieldname": "reference_name", - "fieldtype": "Data", - "hidden": 0, - "in_filter": 0, - "label": "Reference Name", - "no_copy": 0, - "oldfieldname": "reference_name", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 0, - "report_hide": 0, - "reqd": 0, + "allow_on_submit": 0, + "fieldname": "reference_name", + "fieldtype": "Data", + "hidden": 0, + "in_filter": 0, + "label": "Reference Name", + "no_copy": 0, + "oldfieldname": "reference_name", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 0, + "report_hide": 0, + "reqd": 0, "search_index": 0 - }, + }, { - "fieldname": "column_break_10", - "fieldtype": "Column Break", + "fieldname": "column_break_10", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "allow_on_submit": 0, - "fieldname": "role", - "fieldtype": "Link", - "hidden": 0, - "in_filter": 0, - "label": "Role", - "no_copy": 0, - "oldfieldname": "role", - "oldfieldtype": "Link", - "options": "Role", - "permlevel": 0, - "print_hide": 0, - "report_hide": 0, - "reqd": 0, + "allow_on_submit": 0, + "fieldname": "role", + "fieldtype": "Link", + "hidden": 0, + "in_filter": 0, + "label": "Role", + "no_copy": 0, + "oldfieldname": "role", + "oldfieldtype": "Link", + "options": "Role", + "permlevel": 0, + "print_hide": 0, + "report_hide": 0, + "reqd": 0, "search_index": 0 - }, + }, { - "fieldname": "assigned_by", - "fieldtype": "Link", - "label": "Assigned By", - "options": "User", + "fieldname": "assigned_by", + "fieldtype": "Link", + "label": "Assigned By", + "options": "User", "permlevel": 0 } - ], - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "icon-check", - "idx": 1, - "in_create": 0, - "in_dialog": 0, - "issingle": 0, - "max_attachments": 0, - "modified": "2014-03-12 17:06:46.000000", - "modified_by": "Administrator", - "module": "Core", - "name": "ToDo", - "owner": "Administrator", + ], + "hide_heading": 0, + "hide_toolbar": 0, + "icon": "icon-check", + "idx": 1, + "in_create": 0, + "in_dialog": 0, + "issingle": 0, + "max_attachments": 0, + "modified": "2014-05-27 03:49:21.667888", + "modified_by": "Administrator", + "module": "Core", + "name": "ToDo", + "owner": "Administrator", "permissions": [ { - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "apply_user_permissions": 1, - "role": "All", - "submit": 0, + "apply_user_permissions": 1, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "All", + "submit": 0, "write": 1 - }, + }, { - "create": 1, - "delete": 0, - "email": 1, - "export": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", + "create": 1, + "delete": 0, + "email": 1, + "export": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", "write": 1 } - ], - "read_only": 0, - "read_only_onload": 0, + ], + "read_only": 0, + "read_only_onload": 0, "title_field": "description" -} +} \ No newline at end of file diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json index 3a67a0236f..6b2b33504c 100644 --- a/frappe/core/doctype/user/user.json +++ b/frappe/core/doctype/user/user.json @@ -435,7 +435,6 @@ "owner": "Administrator", "permissions": [ { - "cancel": 0, "create": 1, "delete": 0, "email": 1, @@ -448,7 +447,7 @@ "write": 1 }, { - "cancel": 0, + "apply_user_permissions": 1, "create": 0, "delete": 0, "email": 1, @@ -456,7 +455,6 @@ "print": 1, "read": 1, "report": 1, - "apply_user_permissions": 1, "role": "All", "submit": 0, "write": 0 diff --git a/frappe/core/page/permission_manager/permission_manager.js b/frappe/core/page/permission_manager/permission_manager.js index 070de96495..0b091c4dd6 100644 --- a/frappe/core/page/permission_manager/permission_manager.js +++ b/frappe/core/page/permission_manager/permission_manager.js @@ -108,13 +108,7 @@ frappe.PermissionEngine = Class.extend({ d.rights = []; $.each(me.rights, function(i, r) { if(d[r]===1) { - if(r==="restrict") { - d.rights.push(__("Can Restrict Others")); - } else if(r==="restricted") { - d.rights.push(__("Only Restricted Documents")); - } else { - d.rights.push(__(toTitle(r))); - } + d.rights.push(__(toTitle(r.replace("_", " ")))); } }); d.rights = d.rights.join(", "); @@ -185,14 +179,14 @@ frappe.PermissionEngine = Class.extend({ .appendTo(me.table.find("thead tr")); }); - var add_cell = function(row, d, fieldname, is_check) { + var add_cell = function(row, d, fieldname) { return $("").appendTo(row) .attr("data-fieldname", fieldname) .html(d[fieldname]); }; - var add_check = function(cell, d, fieldname, label) { - if(!label) label = fieldname; + var add_check = function(cell, d, fieldname, label, without_grid) { + if(!label) label = fieldname.replace(/_/g, " "); if(d.permlevel > 0 && ["read", "write"].indexOf(fieldname)==-1) { return; } @@ -208,13 +202,20 @@ frappe.PermissionEngine = Class.extend({ .attr("data-ptype", fieldname) .attr("data-name", d.name) .attr("data-doctype", d.parent) + + return checkbox; }; $.each(perm_list, function(i, d) { if(!d.permlevel) d.permlevel = 0; var row = $("").appendTo(me.table.find("tbody")); add_cell(row, d, "parent"); - me.set_show_users(add_cell(row, d, "role"), d.role); + var role_cell = add_cell(row, d, "role"); + me.set_show_users(role_cell, d.role); + + if (d.permlevel===0) { + add_check(role_cell, d, "apply_user_permissions").removeClass("col-md-4"); + } var cell = add_cell(row, d, "permlevel"); if(d.permlevel==0) { @@ -226,14 +227,8 @@ frappe.PermissionEngine = Class.extend({ var perm_container = $("
").appendTo(perm_cell); $.each(me.rights, function(i, r) { - if(r==="restrict") { - add_check(perm_container, d, "restrict", "Can Restrict Others"); - } else if(r==="restricted") { - add_check(perm_container, d, "restricted", "Only Restricted Documents"); - } else { - add_check(perm_container, d, r); - } - }) + add_check(perm_container, d, r); + }); // buttons me.add_delete_button(row, d); @@ -260,7 +255,7 @@ frappe.PermissionEngine = Class.extend({ return $.format('{1}', [p, p]); }) msgprint(__("Users with role {0}:", [role]) - + r.message.join("
")); + + "
" + r.message.join("
")); } }) return false; diff --git a/frappe/core/page/user_permissions/user_permissions.js b/frappe/core/page/user_permissions/user_permissions.js index d68bff341c..b19e20c5c4 100644 --- a/frappe/core/page/user_permissions/user_permissions.js +++ b/frappe/core/page/user_permissions/user_permissions.js @@ -1,7 +1,7 @@ frappe.pages['user-permissions'].onload = function(wrapper) { frappe.ui.make_app_page({ parent: wrapper, - title: 'User Permissions', + title: "User Permissions Manager", single_column: true }); $(wrapper).find(".layout-main").html("
\ diff --git a/frappe/core/page/user_permissions/user_permissions.json b/frappe/core/page/user_permissions/user_permissions.json index 1b849e5245..cdb74628d2 100644 --- a/frappe/core/page/user_permissions/user_permissions.json +++ b/frappe/core/page/user_permissions/user_permissions.json @@ -12,5 +12,5 @@ "page_name": "user-permissions", "roles": [], "standard": "Yes", - "title": "User Permissions" + "title": "User Permissions Manager" } diff --git a/frappe/core/page/user_permissions/user_permissions.py b/frappe/core/page/user_permissions/user_permissions.py index 28249c1546..a30a5d9ea0 100644 --- a/frappe/core/page/user_permissions/user_permissions.py +++ b/frappe/core/page/user_permissions/user_permissions.py @@ -55,23 +55,15 @@ def remove(user, name, defkey, defvalue): raise frappe.PermissionError("Cannot Remove Permission for User: {user} on DocType: {doctype} and Name: {name}".format( user=user, doctype=defkey, name=defvalue)) - frappe.defaults.clear_default(key=defkey, value=defvalue, parent=user, name=name) - -def clear_user_permissions(doctype): - frappe.defaults.clear_default(parenttype="User Permission", key=doctype) + frappe.permissions.remove_user_permission(defkey, defvalue, user, name) @frappe.whitelist() def add(user, defkey, defvalue): if not frappe.permissions.can_set_user_permissions_for_user(user, defkey, defvalue): - raise frappe.PermissionError("Cannot Restrict User: {user} for DocType: {doctype} and Name: {name}".format( + raise frappe.PermissionError("Cannot Set Permission for User: {user} on DocType: {doctype} and Name: {name}".format( user=user, doctype=defkey, name=defvalue)) - # check if already exists - d = frappe.db.sql("""select name from tabDefaultValue - where parent=%s and parenttype='User Permission' and defkey=%s and defvalue=%s""", (user, defkey, defvalue)) - - if not d: - frappe.defaults.add_default(defkey, defvalue, user, "User Permission") + frappe.permissions.add_user_permission(defkey, defvalue, user) def get_doctypes_for_user_permissions(): user_roles = frappe.get_roles() diff --git a/frappe/defaults.py b/frappe/defaults.py index 544933edfa..1825ca8bfb 100644 --- a/frappe/defaults.py +++ b/frappe/defaults.py @@ -91,35 +91,39 @@ def clear_default(key=None, value=None, parent=None, name=None, parenttype=None) conditions = [] values = [] - if key: - conditions.append("defkey=%s") - values.append(key) - - if value: - conditions.append("defvalue=%s") - values.append(value) - if name: conditions.append("name=%s") values.append(name) + else: + if key: + conditions.append("defkey=%s") + values.append(key) + + if value: + conditions.append("defvalue=%s") + values.append(value) + + if parent: + conditions.append("parent=%s") + values.append(parent) + + if parenttype: + conditions.append("parenttype=%s") + values.append(parenttype) + if parent: - conditions.append("parent=%s") clear_cache(parent) - values.append(parent) else: clear_cache("__default") clear_cache("__global") - if parenttype: - conditions.append("parenttype=%s") - values.append(parenttype) - if not conditions: raise Exception, "[clear_default] No key specified." frappe.db.sql("""delete from tabDefaultValue where {0}""".format(" and ".join(conditions)), tuple(values)) + _clear_cache(parent) def get_defaults_for(parent="__default"): diff --git a/frappe/permissions.py b/frappe/permissions.py index 990b51ea3d..53a4ec5ca8 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -113,14 +113,14 @@ def can_set_user_permissions_for_user(user, doctype, docname=None): if not can_set_user_permissions(doctype, docname): return False - # check if target user does not have restrict permission + # check if target user does not have permission to set user permissions if get_role_permissions(frappe.get_meta(doctype), user).set_user_permissions==1: return False return True def can_set_user_permissions(doctype, docname=None): - # System Manager can always restrict + # System Manager can always set user permissions if "System Manager" in frappe.get_roles(): return True @@ -136,6 +136,21 @@ def can_set_user_permissions(doctype, docname=None): return True +def set_user_permission_if_allowed(doctype, name, user): + if get_role_permissions(frappe.get_meta(doctype), user).set_user_permissions!=1: + add_user_permission(doctype, name, user) + +def add_user_permission(doctype, name, user): + if name not in frappe.defaults.get_user_permissions(user).get(doctype, []): + frappe.defaults.add_default(doctype, name, user, "User Permission") + +def remove_user_permission(doctype, name, user, default_value_name=None): + frappe.defaults.clear_default(key=doctype, value=name, parent=user, parenttype="User Permission", + name=default_value_name) + +def clear_user_permissions_for_doctype(doctype): + frappe.defaults.clear_default(parenttype="User Permission", key=doctype) + def can_import(doctype, raise_exception=False): if not ("System Manager" in frappe.get_roles() or has_permission(doctype, "import")): if raise_exception: diff --git a/frappe/public/js/frappe/form/infobar.js b/frappe/public/js/frappe/form/infobar.js index 26f30133c6..05178af4a7 100644 --- a/frappe/public/js/frappe/form/infobar.js +++ b/frappe/public/js/frappe/form/infobar.js @@ -42,7 +42,7 @@ frappe.ui.form.InfoBar = Class.extend({ // link to user permissions if(!me.frm.meta.issingle && frappe.model.can_set_user_permissions(me.frm.doctype, me.frm)) { this.$user_properties = this.appframe.add_icon_btn("2", "icon-shield", - __("User Permission Restrictions"), function() { + __("User Permissions Manager"), function() { frappe.route_options = { property: me.frm.doctype, restriction: me.frm.docname diff --git a/frappe/public/js/frappe/model/meta.js b/frappe/public/js/frappe/model/meta.js index 658b0a479c..e54e7436d7 100644 --- a/frappe/public/js/frappe/model/meta.js +++ b/frappe/public/js/frappe/model/meta.js @@ -62,11 +62,17 @@ $.extend(frappe.meta, { return docfields; }, - get_fields_to_check_permissions: function(doctype, name, restricted_types) { - return $.map(frappe.meta.get_docfields(doctype, name), function(df) { + get_fields_to_check_permissions: function(doctype, name, user_permissions_doctypes) { + var fields = $.map(frappe.meta.get_docfields(doctype, name), function(df) { return (df.fieldtype==="Link" && df.ignore_user_permissions!==1 && - restricted_types.indexOf(df.options)!==-1) ? df : null; + user_permissions_doctypes.indexOf(df.options)!==-1) ? df : null; }); + + if (user_permissions_doctypes.indexOf(doctype)!==-1) { + fields = fields.concat({label: "Name", fieldname: name, options: doctype}); + } + + return fields; }, sort_docfields: function(docs) { diff --git a/frappe/public/js/frappe/model/perm.js b/frappe/public/js/frappe/model/perm.js index d37878f0e8..bc276c40d9 100644 --- a/frappe/public/js/frappe/model/perm.js +++ b/frappe/public/js/frappe/model/perm.js @@ -14,30 +14,30 @@ $.extend(frappe.perm, { doctype_perm: {}, has_perm: function(doctype, permlevel, ptype) { - if(!permlevel) permlevel = 0; - if(!frappe.perm.doctype_perm[doctype]) { + if (!permlevel) permlevel = 0; + if (!frappe.perm.doctype_perm[doctype]) { frappe.perm.doctype_perm[doctype] = frappe.perm.get_perm(doctype); } var perms = frappe.perm.doctype_perm[doctype]; - if(!perms) + if (!perms) return false; - if(!perms[permlevel]) + if (!perms[permlevel]) return false; return !!perms[permlevel][ptype]; }, get_perm: function(doctype) { - var perm = [{read: 0}]; + var perm = [{ read: 0, apply_user_permissions: {} }]; var meta = frappe.get_doc("DocType", doctype); - if(!meta) { + if (!meta) { return perm; } - if(user==="Administrator" || user_roles.indexOf("Administrator")!==-1) { + if (user==="Administrator" || user_roles.indexOf("Administrator")!==-1) { perm[0].read = 1; } @@ -47,8 +47,7 @@ $.extend(frappe.perm, { }, build_role_permissions: function(perm, meta) { - var permissions = meta.permissions || []; - $.each(permissions, function(i, p) { + $.each(meta.permissions || [], function(i, p) { // if user has this role if(user_roles.indexOf(p.role)!==-1) { var permlevel = cint(p.permlevel); @@ -56,64 +55,39 @@ $.extend(frappe.perm, { perm[permlevel] = {}; } $.each(frappe.perm.rights, function(i, key) { - if(key=="restricted") { - perm[permlevel][key] = (perm[permlevel][key] || 1) && (p[key] || 0); - } else { - perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0); + perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0); + + if (permlevel===0) { + var apply_user_permissions = perm[permlevel].apply_user_permissions; + var previous_value = Object.keys(apply_user_permissions).indexOf(key)===-1 ? 1 : apply_user_permissions[key]; + apply_user_permissions[key] = previous_value && p.apply_user_permissions; } }); } }); - }, - has_unrestricted_access: function(doctype, docname, restricted) { - var user_permissions = frappe.defaults.get_user_permissions(); - var doc = frappe.get_doc(doctype, docname); - - if(restricted) { - if(doc.owner==user) return true; - if(!user_permissions || $.isEmptyObject(user_permissions)) { - return false; - } - } else { - if(!user_permissions || $.isEmptyObject(user_permissions)) { - return true; - } - } - - // prepare restricted fields - var fields_to_check = frappe.perm.get_fields_to_check_permissions(doctype, docname, user_permissions); - - // loop and find if has restricted data - var has_restricted_data = false; - var doc = frappe.get_doc(doctype, docname); - $.each(fields_to_check, function(i, df) { - if(doc[df.fieldname] && user_permissions[df.options].indexOf(doc[df.fieldname])===-1) { - has_restricted_data = true; - return false; + // remove values with 0 + $.each(perm[0], function(key, val) { + if (!val) { + delete perm[0][key]; } }); - - return !has_restricted_data; }, - get_fields_to_check_permissions: function(doctype, docname, user_permissions) { - var fields_to_check = frappe.meta.get_fields_to_check_permissions(doctype, docname, - Object.keys(user_permissions)); - if(Object.keys(user_permissions).indexOf(doctype)!==-1) { - fields_to_check = fields_to_check.concat( - {label: "Name", fieldname: name, options: doctype}); + get_match_rules: function(doctype, ptype) { + if (!ptype) ptype = "read"; + + var perm = frappe.perm.get_perm(doctype); + var apply_user_permissions = perm[0].apply_user_permissions; + if (!apply_user_permissions[ptype]) { + return {}; } - return fields_to_check; - }, - get_match_rules: function(doctype) { var match_rules = {}; - - // Rule for user_permissions var user_permissions = frappe.defaults.get_user_permissions(); if(user_permissions && !$.isEmptyObject(user_permissions)) { - $.each(frappe.perm.get_fields_to_check_permissions(doctype, null, user_permissions), function(i, df) { + var fields_to_check = frappe.meta.get_fields_to_check_permissions(doctype, null, user_permissions); + $.each(fields_to_check, function(i, df) { match_rules[df.label] = user_permissions[df.options]; }); } @@ -124,7 +98,7 @@ $.extend(frappe.perm, { get_field_display_status: function(df, doc, perm, explain) { if(!doc) return "Write"; - perm = perm || frappe.perm.get_perm(doc.doctype, doc.name); + perm = perm || frappe.perm.get_perm(doc.doctype); if(!df.permlevel) df.permlevel = 0; var p = perm[df.permlevel]; var status = "None"; diff --git a/frappe/public/js/frappe/print/print_table.js b/frappe/public/js/frappe/print/print_table.js index bae8bdffa7..ccc88c3b47 100644 --- a/frappe/public/js/frappe/print/print_table.js +++ b/frappe/public/js/frappe/print/print_table.js @@ -21,7 +21,7 @@ frappe.print.Table = Class.extend({ this.make(); }, get_columns: function() { - var perms = frappe.perm.get_perm(this.doctype, this.docname); + var perms = frappe.perm.get_perm(this.doctype); return ['Sr'].concat($.map(frappe.meta.docfield_list[this.tabletype], function(df) { return (cint(df.print_hide) || !(perms[df.permlevel] && perms[df.permlevel].read)) ? null : df.fieldname; diff --git a/frappe/public/js/frappe/views/doclistview.js b/frappe/public/js/frappe/views/doclistview.js index 7835cba1f4..442e37936e 100644 --- a/frappe/public/js/frappe/views/doclistview.js +++ b/frappe/public/js/frappe/views/doclistview.js @@ -114,9 +114,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ } }); - if(perm[0].restricted) { - match_text.push(__("Or Created By") + " = " + user); - } frappe.utils.set_footnote(this, this.$page.find(".layout-main-section"), "

" + __("Showing only for (if not empty)") + ":

"; @@ -258,7 +255,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ } if(frappe.model.can_set_user_permissions(this.doctype)) { this.appframe.add_icon_btn("2", "icon-shield", - __("User Permission Restrictions"), function() { + __("User Permissions Manager"), function() { frappe.route_options = { property: me.doctype }; diff --git a/frappe/public/js/frappe/views/reportview.js b/frappe/public/js/frappe/views/reportview.js index 7f04c94d16..b076e44a4f 100644 --- a/frappe/public/js/frappe/views/reportview.js +++ b/frappe/public/js/frappe/views/reportview.js @@ -556,7 +556,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({ make_user_permissions: function() { var me = this; if(this.docname && frappe.model.can_set_user_permissions("Report")) { - this.page.appframe.add_button(__("User Permission Restrictions"), function() { + this.page.appframe.add_button(__("User Permissions Manager"), function() { frappe.route_options = { property: "Report", restriction: me.docname diff --git a/frappe/public/js/legacy/clientscriptAPI.js b/frappe/public/js/legacy/clientscriptAPI.js index 39c034d0a4..0e63ba01b3 100644 --- a/frappe/public/js/legacy/clientscriptAPI.js +++ b/frappe/public/js/legacy/clientscriptAPI.js @@ -263,7 +263,7 @@ _f.Frm.prototype.new_doc = function(doctype, field) { _f.Frm.prototype.set_read_only = function() { var perm = []; - $.each(frappe.perm.get_perm(cur_frm.doc.doctype, cur_frm.doc.name), function(i, permlevel) { + $.each(frappe.perm.get_perm(cur_frm.doc.doctype), function(i, permlevel) { if(permlevel!=null) perm[permlevel] = {read:1}; }); cur_frm.perm = perm; diff --git a/frappe/public/js/legacy/form.js b/frappe/public/js/legacy/form.js index d11da18448..ad3e38f6b9 100644 --- a/frappe/public/js/legacy/form.js +++ b/frappe/public/js/legacy/form.js @@ -335,8 +335,7 @@ _f.Frm.prototype.refresh_header = function() { _f.Frm.prototype.check_doc_perm = function() { // get perm var dt = this.parent_doctype?this.parent_doctype : this.doctype; - var dn = this.parent_docname?this.parent_docname : this.docname; - this.perm = frappe.perm.get_perm(dt, dn); + this.perm = frappe.perm.get_perm(dt); if(!this.perm[0].read) { return 0; diff --git a/frappe/website/doctype/blog_category/blog_category.json b/frappe/website/doctype/blog_category/blog_category.json index 5d57f4efed..035e34c27a 100644 --- a/frappe/website/doctype/blog_category/blog_category.json +++ b/frappe/website/doctype/blog_category/blog_category.json @@ -1,7 +1,7 @@ { "allow_import": 1, "autoname": "field:category_name", - "creation": "2013-03-08 09:41:11.000000", + "creation": "2013-03-08 09:41:11", "docstatus": 0, "doctype": "DocType", "document_type": "Master", @@ -9,6 +9,7 @@ { "fieldname": "category_name", "fieldtype": "Data", + "in_list_view": 1, "label": "Category Name", "permlevel": 0, "reqd": 1 @@ -16,6 +17,7 @@ { "fieldname": "title", "fieldtype": "Data", + "in_list_view": 1, "label": "Title", "permlevel": 0, "reqd": 1 @@ -23,6 +25,7 @@ { "fieldname": "published", "fieldtype": "Check", + "in_list_view": 1, "label": "Published", "permlevel": 0 }, @@ -30,6 +33,7 @@ "default": "blog", "fieldname": "parent_website_route", "fieldtype": "Link", + "in_list_view": 1, "label": "Parent Website Route", "options": "Website Route", "permlevel": 0, @@ -38,20 +42,20 @@ { "fieldname": "page_name", "fieldtype": "Data", + "in_list_view": 1, "label": "Page Name", "permlevel": 0 } ], "icon": "icon-tag", "idx": 1, - "modified": "2014-02-18 15:25:05.000000", + "modified": "2014-05-27 03:49:07.806255", "modified_by": "Administrator", "module": "Website", "name": "Blog Category", "owner": "Administrator", "permissions": [ { - "cancel": 0, "create": 1, "delete": 1, "email": 1, @@ -63,7 +67,7 @@ "write": 1 }, { - "cancel": 0, + "apply_user_permissions": 1, "delete": 0, "email": 1, "permlevel": 0, diff --git a/frappe/website/doctype/blog_post/blog_post.json b/frappe/website/doctype/blog_post/blog_post.json index 19bf7070d2..7e4de36b20 100644 --- a/frappe/website/doctype/blog_post/blog_post.json +++ b/frappe/website/doctype/blog_post/blog_post.json @@ -1,144 +1,142 @@ { - "allow_attach": 1, - "allow_import": 1, - "creation": "2013-03-28 10:35:30", - "docstatus": 0, - "doctype": "DocType", + "allow_attach": 1, + "allow_import": 1, + "creation": "2013-03-28 10:35:30", + "docstatus": 0, + "doctype": "DocType", "fields": [ { - "fieldname": "title", - "fieldtype": "Data", - "label": "Title", - "permlevel": 0, + "fieldname": "title", + "fieldtype": "Data", + "label": "Title", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "published_on", - "fieldtype": "Date", - "label": "Published On", + "fieldname": "published_on", + "fieldtype": "Date", + "label": "Published On", "permlevel": 0 - }, + }, { - "fieldname": "published", - "fieldtype": "Check", - "label": "Published", + "fieldname": "published", + "fieldtype": "Check", + "label": "Published", "permlevel": 0 - }, + }, { - "fieldname": "column_break_3", - "fieldtype": "Column Break", + "fieldname": "column_break_3", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "blogger", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Blogger", - "options": "Blogger", - "permlevel": 0, + "fieldname": "blogger", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Blogger", + "options": "Blogger", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "blog_category", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Blog Category", - "options": "Blog Category", + "fieldname": "blog_category", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Blog Category", + "options": "Blog Category", "permlevel": 0 - }, + }, { - "fieldname": "parent_website_route", - "fieldtype": "Link", - "hidden": 1, - "label": "Parent Website Route", - "options": "Website Route", - "permlevel": 0, + "fieldname": "parent_website_route", + "fieldtype": "Link", + "hidden": 1, + "label": "Parent Website Route", + "options": "Website Route", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "section_break_5", - "fieldtype": "Section Break", + "fieldname": "section_break_5", + "fieldtype": "Section Break", "permlevel": 0 - }, + }, { - "description": "Description for listing page, in plain text, only a couple of lines. (max 140 characters)", - "fieldname": "blog_intro", - "fieldtype": "Small Text", - "in_list_view": 1, - "label": "Blog Intro", - "permlevel": 0, + "description": "Description for listing page, in plain text, only a couple of lines. (max 140 characters)", + "fieldname": "blog_intro", + "fieldtype": "Small Text", + "in_list_view": 1, + "label": "Blog Intro", + "permlevel": 0, "reqd": 0 - }, + }, { - "fieldname": "content", - "fieldtype": "Text Editor", - "label": "Content", - "permlevel": 0, + "fieldname": "content", + "fieldtype": "Text Editor", + "label": "Content", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "page_name", - "fieldtype": "Data", - "hidden": 1, - "label": "Page Name", - "permlevel": 0, + "fieldname": "page_name", + "fieldtype": "Data", + "hidden": 1, + "label": "Page Name", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "email_sent", - "fieldtype": "Check", - "hidden": 1, - "label": "Email Sent", + "fieldname": "email_sent", + "fieldtype": "Check", + "hidden": 1, + "label": "Email Sent", "permlevel": 0 } - ], - "icon": "icon-quote-left", - "idx": 1, - "max_attachments": 5, - "modified": "2014-05-26 04:00:24.210166", - "modified_by": "Administrator", - "module": "Website", - "name": "Blog Post", - "owner": "Administrator", + ], + "icon": "icon-quote-left", + "idx": 1, + "max_attachments": 5, + "modified": "2014-05-27 03:49:07.888408", + "modified_by": "Administrator", + "module": "Website", + "name": "Blog Post", + "owner": "Administrator", "permissions": [ { - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "set_user_permissions": 1, - "role": "Website Manager", - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Website Manager", + "set_user_permissions": 1, + "submit": 0, "write": 1 - }, + }, { - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Blogger", - "submit": 0, + "apply_user_permissions": 1, + "create": 1, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Blogger", + "submit": 0, "write": 1 - }, + }, { - "cancel": 0, - "delete": 0, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Guest", - "submit": 0, + "delete": 0, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Guest", + "submit": 0, "write": 0 } ] -} +} \ No newline at end of file diff --git a/frappe/website/doctype/blog_post/test_blog_post.py b/frappe/website/doctype/blog_post/test_blog_post.py index 09fc6c09e7..4cbd186a07 100644 --- a/frappe/website/doctype/blog_post/test_blog_post.py +++ b/frappe/website/doctype/blog_post/test_blog_post.py @@ -6,7 +6,8 @@ import frappe import frappe.defaults import unittest -from frappe.core.page.user_permissions.user_permissions import add, remove, get_properties, clear_user_permissions +from frappe.core.page.user_permissions.user_permissions import add, remove, get_permissions +from frappe.permissions import clear_user_permissions_for_doctype test_records = frappe.get_test_records('Blog Post') @@ -30,8 +31,8 @@ class TestBlogPost(unittest.TestCase): def tearDown(self): frappe.set_user("Administrator") - clear_user_permissions("Blog Category") - clear_user_permissions("Blog Post") + clear_user_permissions_for_doctype("Blog Category") + clear_user_permissions_for_doctype("Blog Post") def test_basic_permission(self): post = frappe.get_doc("Blog Post", "_test-blog-post") @@ -120,7 +121,7 @@ class TestBlogPost(unittest.TestCase): def test_not_allowed_to_remove_self(self): self.add_restriction_to_user2() - defname = get_properties("test2@example.com", "Blog Post", "_test-blog-post")[0].name + defname = get_permissions("test2@example.com", "Blog Post", "_test-blog-post")[0].name frappe.set_user("test2@example.com") diff --git a/frappe/website/doctype/blogger/blogger.json b/frappe/website/doctype/blogger/blogger.json index 1cec8d7bd5..323588ea37 100644 --- a/frappe/website/doctype/blogger/blogger.json +++ b/frappe/website/doctype/blogger/blogger.json @@ -2,7 +2,7 @@ "allow_attach": 1, "allow_import": 1, "autoname": "field:short_name", - "creation": "2013-03-25 16:00:51.000000", + "creation": "2013-03-25 16:00:51", "description": "User ID of a Blogger", "docstatus": 0, "doctype": "DocType", @@ -62,7 +62,7 @@ "icon": "icon-user", "idx": 1, "max_attachments": 1, - "modified": "2013-12-20 19:23:58.000000", + "modified": "2014-05-27 03:49:07.960305", "modified_by": "Administrator", "module": "Website", "name": "Blogger", @@ -78,6 +78,7 @@ "write": 1 }, { + "apply_user_permissions": 1, "email": 1, "permlevel": 0, "print": 1,