Role and User Permissions

This commit is contained in:
Anand Doshi 2014-05-28 18:49:13 +05:30
parent 69eec9e344
commit 4985691617
10 changed files with 116 additions and 385 deletions

View File

@ -48,6 +48,7 @@ doc_events = {
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_qty"
},
"User": {
"validate": "erpnext.hr.doctype.employee.employee.validate_employee_role",
"on_update": "erpnext.hr.doctype.employee.employee.update_user_permissions"
}
}

View File

@ -55,7 +55,7 @@ class Employee(Document):
frappe.permissions.set_user_permission_if_allowed("Company", self.company, self.user_id)
def update_leave_approver_user_permissions(self):
"""restrict to this employee for leave approver"""
"""add employee user permission for leave approver"""
employee_leave_approvers = [d.leave_approver for d in self.get("employee_leave_approvers")]
if self.reports_to and self.reports_to not in employee_leave_approvers:
employee_leave_approvers.append(frappe.db.get_value("Employee", self.reports_to, "user_id"))
@ -204,13 +204,15 @@ def make_salary_structure(source_name, target=None):
target.make_earn_ded_table()
return target
def update_user_permissions(doc, method):
def validate_employee_role(doc, method):
# called via User hook
if "Employee" in [d.role for d in doc.get("user_roles")]:
try:
employee = frappe.get_doc("Employee", {"user_id": doc.name})
employee.update_user_permissions()
except frappe.DoesNotExistError:
if not frappe.db.get_value("Employee", {"user_id": doc.name}):
frappe.msgprint("Please set User ID field in an Employee record to set Employee Role")
doc.get("user_roles").remove(doc.get("user_roles", {"role": "Employee"})[0])
def update_user_permissions(doc, method):
# called via User hook
if "Employee" in [d.role for d in doc.get("user_roles")]:
employee = frappe.get_doc("Employee", {"user_id": doc.name})
employee.update_user_permissions()

View File

@ -2,10 +2,10 @@ execute:import unidecode # new requirement
erpnext.patches.v4_0.validate_v3_patch
erpnext.patches.v4_0.fix_employee_user_id
erpnext.patches.v4_0.remove_employee_role_if_no_employee
erpnext.patches.v4_0.update_user_properties
erpnext.patches.v4_0.apply_user_permissions
erpnext.patches.v4_0.move_warehouse_user_to_restrictions
execute:frappe.delete_doc_if_exists("DocType", "Warehouse User")
erpnext.patches.v4_0.new_permissions
erpnext.patches.v4_0.global_defaults_to_system_settings
erpnext.patches.v4_0.update_incharge_name_to_sales_person_in_maintenance_schedule
execute:frappe.reload_doc('accounts', 'doctype', 'sales_invoice') # 2014-01-29

View File

@ -0,0 +1,45 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
update_hr_permissions()
update_permissions()
remove_duplicate_user_permissions()
frappe.clear_cache()
def update_hr_permissions():
from frappe.core.page.user_permissions import user_permissions
# add set user permissions rights to HR Manager
frappe.db.sql("""update `tabDocPerm` set `set_user_permissions`=1 where parent in ('Employee', 'Leave Application')
and role='HR Manager' and permlevel=0 and `read`=1""")
# apply user permissions on Employee and Leave Application
frappe.db.sql("""update `tabDocPerm` set `apply_user_permissions`=1 where parent in ('Employee', 'Leave Application')
and role in ('Employee', 'Leave Approver') and permlevel=0 and `read`=1""")
frappe.clear_cache()
# save employees to run on_update events
for employee in frappe.db.sql_list("""select name from `tabEmployee`"""):
frappe.get_doc("Employee", employee).save()
def update_permissions():
# clear match conditions other than owner
frappe.db.sql("""update tabDocPerm set `match`=''
where ifnull(`match`,'') not in ('', 'owner')""")
def remove_duplicate_user_permissions():
# remove duplicate user_permissions (if they exist)
for d in frappe.db.sql("""select parent, defkey, defvalue,
count(*) as cnt from tabDefaultValue
where parent not in ('__global', '__default')
group by parent, defkey, defvalue""", as_dict=1):
if d.cnt > 1:
# order by parenttype so that user permission does not get removed!
frappe.db.sql("""delete from tabDefaultValue where `parent`=%s and `defkey`=%s and
`defvalue`=%s order by parenttype limit %s""", (d.parent, d.defkey, d.defvalue, d.cnt-1))

View File

@ -3,11 +3,11 @@
from __future__ import unicode_literals
import frappe
import frappe.permissions
def execute():
from frappe.core.page.user_permissions import user_permissions
for warehouse, user in frappe.db.sql("""select parent, user from `tabWarehouse User`"""):
user_permissions.add(user, "Warehouse", warehouse)
frappe.delete_doc("DocType", "Warehouse User")
frappe.reload_doc("stock", "doctype", "warehouse")
frappe.permissions.add_user_permission("Warehouse", warehouse, user)
frappe.delete_doc_if_exists("DocType", "Warehouse User")
frappe.reload_doc("stock", "doctype", "warehouse")

View File

@ -1,24 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
# reset Page perms
from frappe.core.page.permission_manager.permission_manager import reset
reset("Page")
reset("Report")
# patch to move print, email into DocPerm
for doctype, hide_print, hide_email in frappe.db.sql("""select name, ifnull(allow_print, 0), ifnull(allow_email, 0)
from `tabDocType` where ifnull(issingle, 0)=0 and ifnull(istable, 0)=0 and
(ifnull(allow_print, 0)=0 or ifnull(allow_email, 0)=0)"""):
if not hide_print:
frappe.db.sql("""update `tabDocPerm` set `print`=1
where permlevel=0 and `read`=1 and parent=%s""", doctype)
if not hide_email:
frappe.db.sql("""update `tabDocPerm` set `email`=1
where permlevel=0 and `read`=1 and parent=%s""", doctype)

View File

@ -0,0 +1,15 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
import frappe.permissions
def execute():
for user in frappe.db.sql_list("select distinct parent from `tabUserRole` where role='Employee'"):
# if employee record does not exists, remove employee role!
if not frappe.db.get_value("Employee", {"user_id": user}):
user = frappe.get_doc("User", user)
for role in user.get("user_roles", {"role": "Employee"}):
user.get("user_roles").remove(role)
user.save()

View File

@ -7,100 +7,45 @@ import frappe.permissions
import frappe.defaults
def execute():
frappe.reload_doc("core", "doctype", "docperm")
frappe.reload_doc("core", "doctype", "docfield")
frappe.reload_doc("hr", "doctype", "employee")
update_user_permissions()
update_user_match()
add_employee_user_permissions_to_leave_approver()
update_permissions()
remove_duplicate_user_permissions()
frappe.defaults.clear_cache()
set_print_email_permissions()
migrate_user_properties_to_user_permissions()
frappe.clear_cache()
def update_user_permissions():
frappe.reload_doc("core", "doctype", "docfield")
def migrate_user_properties_to_user_permissions():
for d in frappe.db.sql("""select parent, defkey, defvalue from tabDefaultValue
where parent not in ('__global', '__default')""", as_dict=True):
df = frappe.db.sql("""select options from tabDocField
where fieldname=%s and fieldtype='Link'""", d.defkey, as_dict=True)
if df:
frappe.db.sql("""update tabDefaultValue
set defkey=%s, parenttype='User Permission'
where defkey=%s and
parent not in ('__global', '__default')""", (df[0].options, d.defkey))
def update_user_match():
import frappe.defaults
doctype_matches = {}
for doctype, match in frappe.db.sql("""select parent, `match` from `tabDocPerm`
where `match` like %s and ifnull(`match`, '')!="leave_approver:user" """, "%:user"):
doctype_matches.setdefault(doctype, []).append(match)
for doctype, user_matches in doctype_matches.items():
meta = frappe.get_meta(doctype)
# for each user with roles of this doctype, check if match condition applies
for user in frappe.db.sql_list("""select name from `tabUser`
where enabled=1 and user_type='System User'"""):
user_roles = frappe.get_roles(user)
perms = meta.get({"doctype": "DocPerm", "permlevel": 0,
"role": ["in", [["All"] + user_roles]], "read": 1})
def set_print_email_permissions():
# reset Page perms
from frappe.core.page.permission_manager.permission_manager import reset
reset("Page")
reset("Report")
# user does not have required roles
if not perms:
continue
# assume match
user_match = True
for perm in perms:
if not perm.match:
# aha! non match found
user_match = False
break
if not user_match:
continue
# if match condition applies, restrict that user
# add that doc's restriction to that user
for match in user_matches:
for name in frappe.db.sql_list("""select name from `tab{doctype}`
where `{field}`=%s""".format(doctype=doctype, field=match.split(":")[0]), user):
frappe.defaults.add_default(doctype, name, user, "User Permission")
def add_employee_user_permissions_to_leave_approver():
from frappe.core.page.user_permissions import user_permissions
# add restrict rights to HR User and HR Manager
frappe.db.sql("""update `tabDocPerm` set `restrict`=1 where parent in ('Employee', 'Leave Application')
and role in ('HR User', 'HR Manager') and permlevel=0 and `read`=1""")
frappe.clear_cache()
# add Employee user_permissions (in on_update method)
for employee in frappe.db.sql_list("""select name from `tabEmployee`
where (exists(select leave_approver from `tabEmployee Leave Approver`
where `tabEmployee Leave Approver`.parent=`tabEmployee`.name)
or ifnull(`reports_to`, '')!='') and docstatus<2 and status='Active'"""):
frappe.get_doc("Employee", employee).save()
if "allow_print" not in frappe.db.get_table_columns("DocType"):
return
def update_permissions():
# clear match conditions other than owner
frappe.db.sql("""update tabDocPerm set `match`=''
where ifnull(`match`,'') not in ('', 'owner')""")
# patch to move print, email into DocPerm
# NOTE: allow_print and allow_email are misnamed. They were used to hide print / hide email
for doctype, hide_print, hide_email in frappe.db.sql("""select name, ifnull(allow_print, 0), ifnull(allow_email, 0)
from `tabDocType` where ifnull(issingle, 0)=0 and ifnull(istable, 0)=0 and
(ifnull(allow_print, 0)=0 or ifnull(allow_email, 0)=0)"""):
def remove_duplicate_user_permissions():
# remove duplicate user_permissions (if they exist)
for d in frappe.db.sql("""select parent, defkey, defvalue,
count(*) as cnt from tabDefaultValue
where parent not in ('__global', '__default')
group by parent, defkey, defvalue""", as_dict=1):
if d.cnt > 1:
# order by parenttype so that restriction does not get removed!
frappe.db.sql("""delete from tabDefaultValue where `parent`=%s and `defkey`=%s and
`defvalue`=%s order by parenttype limit %s""", (d.parent, d.defkey, d.defvalue, d.cnt-1))
if not hide_print:
frappe.db.sql("""update `tabDocPerm` set `print`=1
where permlevel=0 and `read`=1 and parent=%s""", doctype)
if not hide_email:
frappe.db.sql("""update `tabDocPerm` set `email`=1
where permlevel=0 and `read`=1 and parent=%s""", doctype)

View File

@ -1,355 +1,102 @@
{
"_last_update": null,
"_user_tags": null,
"allow_attach": null,
"allow_copy": null,
"allow_email": null,
"allow_import": null,
"allow_print": null,
"allow_rename": null,
"allow_trash": null,
"autoname": null,
"change_log": null,
"client_script": null,
"client_script_core": null,
"client_string": null,
"colour": null,
"creation": "2013-06-25 10:25:16",
"custom": null,
"default_print_format": null,
"description": "Settings for Selling Module",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Other",
"dt_template": null,
"fields": [
{
"allow_on_submit": null,
"default": "Customer Name",
"depends_on": null,
"description": null,
"fieldname": "cust_master_name",
"fieldtype": "Select",
"hidden": null,
"in_filter": null,
"in_list_view": 1,
"label": "Customer Naming By",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "Customer Name\nNaming Series",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "campaign_naming_by",
"fieldtype": "Select",
"hidden": null,
"in_filter": null,
"in_list_view": 1,
"label": "Campaign Naming By",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "Campaign Name\nNaming Series",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": "<a href=\"#Sales Browser/Customer Group\">Add / Edit</a>",
"fieldname": "customer_group",
"fieldtype": "Link",
"hidden": null,
"in_filter": null,
"in_list_view": 1,
"label": "Default Customer Group",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "Customer Group",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": "<a href=\"#Sales Browser/Territory\">Add / Edit</a>",
"fieldname": "territory",
"fieldtype": "Link",
"hidden": null,
"in_filter": null,
"in_list_view": 1,
"label": "Default Territory",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "Territory",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "selling_price_list",
"fieldtype": "Link",
"hidden": null,
"in_filter": null,
"in_list_view": 1,
"label": "Default Price List",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "Price List",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "column_break_5",
"fieldtype": "Column Break",
"hidden": null,
"in_filter": null,
"in_list_view": null,
"label": null,
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "so_required",
"fieldtype": "Select",
"hidden": null,
"in_filter": null,
"in_list_view": null,
"label": "Sales Order Required",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "No\nYes",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "dn_required",
"fieldtype": "Select",
"hidden": null,
"in_filter": null,
"in_list_view": null,
"label": "Delivery Note Required",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "No\nYes",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "maintain_same_sales_rate",
"fieldtype": "Check",
"hidden": null,
"in_filter": null,
"in_list_view": null,
"label": "Maintain Same Rate Throughout Sales Cycle",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "editable_price_list_rate",
"fieldtype": "Check",
"hidden": null,
"in_filter": null,
"in_list_view": null,
"label": "Allow user to edit Price List Rate in transactions",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
"permlevel": 0
}
],
"hide_heading": null,
"hide_toolbar": null,
"icon": "icon-cog",
"idx": 1,
"in_create": null,
"in_dialog": null,
"is_submittable": null,
"is_transaction_doc": null,
"issingle": 1,
"istable": null,
"max_attachments": null,
"menu_index": null,
"modified": "2014-04-16 12:21:36.117261",
"modified": "2014-05-28 18:12:55.898953",
"modified_by": "Administrator",
"module": "Selling",
"name": "Selling Settings",
"name_case": null,
"owner": "Administrator",
"parent": null,
"parent_node": null,
"parentfield": null,
"parenttype": null,
"permissions": [
{
"amend": null,
"cancel": null,
"create": 1,
"delete": null,
"email": 1,
"export": null,
"import": null,
"match": null,
"permlevel": 0,
"print": 1,
"read": 1,
"report": null,
"restrict": null,
"role": "System Manager",
"submit": null,
"write": 1
}
],
"plugin": null,
"print_outline": null,
"read_only": null,
"read_only_onload": null,
"search_fields": null,
"server_code": null,
"server_code_compiled": null,
"server_code_core": null,
"server_code_error": null,
"show_in_menu": null,
"smallicon": null,
"subject": null,
"tag_fields": null,
"title_field": null,
"use_template": null,
"version": null
]
}

View File

@ -392,7 +392,7 @@ def create_logo(args):
def add_all_roles_to(name):
user = frappe.get_doc("User", name)
for role in frappe.db.sql("""select name from tabRole"""):
if role[0] not in ["Administrator", "Guest", "All", "Customer", "Supplier", "Partner"]:
if role[0] not in ["Administrator", "Guest", "All", "Customer", "Supplier", "Partner", "Employee"]:
d = user.append("user_roles")
d.role = role[0]
user.save()