Manage user roles and permissions - create roles, assign permissions, manage access
Manage user roles and permissions in Frappe applications. Create roles, assign permissions, and test access control for your ERPNext system.
/plugin marketplace add Venkateshvenki404224/frappe-apps-manager/plugin install frappe-apps-manager@frappe-marketplaceComprehensive role and permission management for Frappe applications including role creation, permission assignment, and access control.
Ask user what they want to do:
A. Create New Role
B. Manage Permissions
C. Assign Roles to Users
D. Test Permissions
Create New Role:
bench --site [site-name] console
# Create role
role = frappe.get_doc({
'doctype': 'Role',
'role_name': 'Custom Role',
'desk_access': 1, # Can access desk
'disabled': 0
})
role.insert()
frappe.db.commit()
Role Properties:
role_name: Unique role identifierdesk_access: 1 = Can access desk, 0 = Portal onlytwo_factor_auth: Require 2FA for this roledisabled: 1 = Role disabledAdd Permissions to DocType:
# Via console
from frappe.permissions import add_permission
add_permission('Customer', 'Custom Role', perm_level=0)
# Set specific permissions
add_permission('Customer', 'Custom Role',
read=1, write=1, create=1, delete=0,
submit=0, cancel=0, amend=0)
frappe.db.commit()
View Permission Matrix:
# Get all permissions for DocType
permissions = frappe.get_all('Custom DocPerm',
filters={'parent': 'Customer'},
fields=['role', 'read', 'write', 'create', 'delete', 'submit']
)
print(permissions)
Remove Permissions:
from frappe.permissions import remove_permission
remove_permission('Customer', 'Custom Role')
frappe.db.commit()
Add Roles to User:
bench --site [site-name] add-user-role user@example.com "Custom Role"
Or via console:
user = frappe.get_doc('User', 'user@example.com')
user.add_roles('Custom Role', 'Sales User')
frappe.db.commit()
Remove Roles:
user = frappe.get_doc('User', 'user@example.com')
user.remove_roles('Custom Role')
frappe.db.commit()
View User Roles:
user = frappe.get_doc('User', 'user@example.com')
roles = [r.role for r in user.roles]
print(roles)
Test User Access:
# Set user context
frappe.set_user('user@example.com')
# Test read permission
can_read = frappe.has_permission('Customer', 'read')
print(f"Can read: {can_read}")
# Test write permission
can_write = frappe.has_permission('Customer', 'write')
print(f"Can write: {can_write}")
# Test specific document
can_access = frappe.has_permission('Customer', 'read', 'CUST-001')
print(f"Can access CUST-001: {can_access}")
Debug Permission Issues:
# Get permission log
frappe.set_user('user@example.com')
try:
doc = frappe.get_doc('Customer', 'CUST-001')
except frappe.PermissionError as e:
print(f"Permission denied: {e}")
print(frappe.get_traceback())
User Permissions (Restrict Access):
# Limit user to specific customer
from frappe.permissions import add_user_permission
add_user_permission('Customer', 'CUST-001', 'user@example.com')
frappe.db.commit()
# User can only access CUST-001
Remove User Permission:
from frappe.permissions import remove_user_permission
remove_user_permission('Customer', 'CUST-001', 'user@example.com')
frappe.db.commit()
View User Permissions:
perms = frappe.get_all('User Permission',
filters={'user': 'user@example.com'},
fields=['allow', 'for_value', 'applicable_for']
)
print(perms)
Set Field-Level Permissions:
# Make field read-only for specific role
# Edit DocType JSON or use Property Setter
frappe.make_property_setter({
'doctype': 'Customer',
'fieldname': 'credit_limit',
'property': 'permlevel',
'value': 1
})
# Set permission for level 1
add_permission('Customer', 'Sales Manager',
perm_level=1, read=1, write=1)
If Condition Permissions:
# Add permission with condition
# Via DocType permission editor or console
perm = frappe.get_doc({
'doctype': 'Custom DocPerm',
'parent': 'Sales Invoice',
'parenttype': 'DocType',
'role': 'Sales User',
'if_owner': 1, # Only if user created the doc
'read': 1,
'write': 1
})
perm.insert()
frappe.db.commit()
Standard Frappe Roles:
System Manager (highest)
├── Administrator
├── All (all logged-in users)
├── Guest (not logged in)
└── Custom Roles
├── Sales Manager
├── Sales User
├── Purchase Manager
├── Purchase User
├── Stock Manager
└── Stock User
Check Role Hierarchy:
# Get roles for user including inherited
user_roles = frappe.get_roles('user@example.com')
print(user_roles)
Generate Permission Matrix:
# All permissions for DocType
matrix = frappe.db.sql("""
SELECT
role, read, write, create, delete,
submit, cancel, amend
FROM `tabCustom DocPerm`
WHERE parent = %s
ORDER BY permlevel, role
""", ('Customer',), as_dict=True)
for row in matrix:
print(f"{row.role}: R={row.read} W={row.write} C={row.create}")
User Access Report:
# All DocTypes accessible by user
frappe.set_user('user@example.com')
accessible = []
for doctype in frappe.get_all('DocType', pluck='name'):
if frappe.has_permission(doctype, 'read'):
accessible.append(doctype)
print(f"Accessible DocTypes: {accessible}")
Frappe Permission Module:
ERPNext Permission Patterns:
Real Permission Patterns:
{
"permissions": [
{
"role": "Sales User",
"read": 1,
"write": 1,
"create": 1
},
{
"role": "Sales Manager",
"read": 1,
"write": 1,
"create": 1,
"delete": 1,
"submit": 1,
"cancel": 1
},
{
"role": "Accounts User",
"read": 1,
"submit": 1
}
]
}
{
"role": "Sales User",
"if_owner": 1,
"read": 1,
"write": 1,
"delete": 1
}
# See: erpnext/accounts/doctype/sales_invoice/sales_invoice.py
def has_permission(doc, ptype, user):
if ptype == 'write' and doc.docstatus == 1:
return False # Cannot edit submitted docs
return True
Sales Team:
Inventory Team:
Accounts Team:
Support Team:
has_permission method