311 lines
9.1 KiB
Python
311 lines
9.1 KiB
Python
import frappe
|
|
from frappe import _
|
|
|
|
# ============================================================================
|
|
# CONFIGURATION: Define field mappings for each doctype
|
|
# Add new doctypes here as needed - this is the ONLY place you need to update
|
|
# ============================================================================
|
|
|
|
DOCTYPE_PERMISSION_MAPPINGS = {
|
|
"Asset": {
|
|
"Company": "company",
|
|
"Location": "location",
|
|
"Department": "department",
|
|
"Manufacturer": "custom_manufacturer",
|
|
"Supplier": "supplier",
|
|
"Modality": "custom_modality",
|
|
"Cost Center": "cost_center",
|
|
"Asset Type":"custom_asset_type",
|
|
"Asset Category": "asset_category"
|
|
},
|
|
"Work_Order": {
|
|
"Company": "company",
|
|
"Location": "location",
|
|
"Department": "department",
|
|
"Issue Type": "work_order_type"
|
|
|
|
},
|
|
"Asset Maintenance": {
|
|
"Company": "company",
|
|
"Asset": "asset_name",
|
|
"Supplier": "supplier"
|
|
},
|
|
"Asset Maintenance Log": {
|
|
"Company": "company",
|
|
"Asset": "asset_name"
|
|
}
|
|
# Add more doctypes as needed - just add them here!
|
|
}
|
|
|
|
|
|
# ============================================================================
|
|
# HELPER FUNCTION
|
|
# ============================================================================
|
|
|
|
def is_system_user(user):
|
|
"""Check if user is Administrator or has System Manager role."""
|
|
if user == "Administrator":
|
|
return True
|
|
|
|
roles = frappe.get_roles(user)
|
|
return "System Manager" in roles
|
|
|
|
|
|
# ============================================================================
|
|
# CORE API FUNCTIONS - These 4 functions handle everything
|
|
# ============================================================================
|
|
|
|
@frappe.whitelist(allow_guest = True)
|
|
def get_user_permissions(user=None):
|
|
"""
|
|
Get all user permissions for the logged-in user.
|
|
|
|
Returns:
|
|
dict: User permissions grouped by 'allow' doctype
|
|
"""
|
|
if not user:
|
|
user = frappe.session.user
|
|
|
|
if is_system_user(user):
|
|
return {
|
|
"is_admin": True,
|
|
"permissions": {},
|
|
"user": user,
|
|
"total_permissions": 0
|
|
}
|
|
|
|
permissions = frappe.get_all(
|
|
"User Permission",
|
|
filters={"user": user},
|
|
fields=["name", "allow", "for_value", "is_default", "apply_to_all_doctypes", "applicable_for"],
|
|
order_by="allow asc"
|
|
)
|
|
|
|
# Group by 'allow' doctype
|
|
grouped = {}
|
|
for perm in permissions:
|
|
allow_doctype = perm.get("allow")
|
|
if allow_doctype not in grouped:
|
|
grouped[allow_doctype] = []
|
|
grouped[allow_doctype].append({
|
|
"for_value": perm.get("for_value"),
|
|
"is_default": perm.get("is_default"),
|
|
"apply_to_all_doctypes": perm.get("apply_to_all_doctypes"),
|
|
"applicable_for": perm.get("applicable_for")
|
|
})
|
|
|
|
return {
|
|
"is_admin": False,
|
|
"permissions": grouped,
|
|
"user": user,
|
|
"total_permissions": len(permissions),
|
|
"permission_types": list(grouped.keys())
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest = True)
|
|
def get_permission_filters(target_doctype, user=None):
|
|
"""
|
|
Get permission filters for ANY doctype.
|
|
This is the MAIN function - use this for all doctypes.
|
|
|
|
Args:
|
|
target_doctype: The doctype (e.g., "Asset", "Work Order", "Project")
|
|
user: Optional user email
|
|
|
|
Returns:
|
|
dict: Filters to apply for queries
|
|
"""
|
|
if not user:
|
|
user = frappe.session.user
|
|
|
|
# System users have full access
|
|
if is_system_user(user):
|
|
return {
|
|
"is_admin": True,
|
|
"filters": {},
|
|
"restrictions": {},
|
|
"target_doctype": target_doctype,
|
|
"user": user
|
|
}
|
|
|
|
# Get field mapping for this doctype
|
|
field_mapping = DOCTYPE_PERMISSION_MAPPINGS.get(target_doctype, {})
|
|
|
|
if not field_mapping:
|
|
return {
|
|
"is_admin": False,
|
|
"filters": {},
|
|
"restrictions": {},
|
|
"target_doctype": target_doctype,
|
|
"user": user,
|
|
"warning": f"No permission mapping defined for {target_doctype}"
|
|
}
|
|
|
|
filters = {}
|
|
restrictions = {}
|
|
|
|
for allow_doctype, target_field in field_mapping.items():
|
|
permissions = frappe.get_all(
|
|
"User Permission",
|
|
filters={
|
|
"user": user,
|
|
"allow": allow_doctype
|
|
},
|
|
fields=["for_value", "applicable_for", "apply_to_all_doctypes"]
|
|
)
|
|
|
|
if permissions:
|
|
# Filter permissions that apply to this doctype
|
|
applicable = [
|
|
p for p in permissions
|
|
if p.get("apply_to_all_doctypes") == 1
|
|
or not p.get("applicable_for")
|
|
or p.get("applicable_for") == target_doctype
|
|
]
|
|
|
|
if applicable:
|
|
allowed_values = list(set([p.get("for_value") for p in applicable]))
|
|
filters[target_field] = ["in", allowed_values]
|
|
restrictions[allow_doctype] = {
|
|
"field": target_field,
|
|
"values": allowed_values,
|
|
"count": len(allowed_values)
|
|
}
|
|
|
|
return {
|
|
"is_admin": False,
|
|
"filters": filters,
|
|
"restrictions": restrictions,
|
|
"target_doctype": target_doctype,
|
|
"user": user,
|
|
"total_restrictions": len(restrictions)
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest = True)
|
|
def get_allowed_values(allow_doctype, user=None):
|
|
"""
|
|
Get allowed values for a specific permission type.
|
|
|
|
Args:
|
|
allow_doctype: e.g., "Company", "Location", "Department"
|
|
user: Optional user email
|
|
|
|
Returns:
|
|
dict: List of allowed values
|
|
"""
|
|
if not user:
|
|
user = frappe.session.user
|
|
|
|
if is_system_user(user):
|
|
return {
|
|
"is_admin": True,
|
|
"allowed_values": [],
|
|
"has_restriction": False
|
|
}
|
|
|
|
permissions = frappe.get_all(
|
|
"User Permission",
|
|
filters={"user": user, "allow": allow_doctype},
|
|
fields=["for_value", "is_default"]
|
|
)
|
|
|
|
allowed_values = list(set([p.get("for_value") for p in permissions]))
|
|
default_value = next((p.get("for_value") for p in permissions if p.get("is_default")), None)
|
|
|
|
return {
|
|
"is_admin": False,
|
|
"allowed_values": sorted(allowed_values),
|
|
"default_value": default_value,
|
|
"has_restriction": len(allowed_values) > 0,
|
|
"allow_doctype": allow_doctype
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest = True)
|
|
def check_document_access(doctype, docname, user=None):
|
|
"""
|
|
Check if user has access to a specific document.
|
|
|
|
Args:
|
|
doctype: e.g., "Asset", "Work Order"
|
|
docname: The document name/ID
|
|
user: Optional user email
|
|
|
|
Returns:
|
|
dict: Access status
|
|
"""
|
|
if not user:
|
|
user = frappe.session.user
|
|
|
|
if is_system_user(user):
|
|
return {"has_access": True, "is_admin": True}
|
|
|
|
try:
|
|
doc = frappe.get_doc(doctype, docname)
|
|
except frappe.DoesNotExistError:
|
|
return {"has_access": False, "error": f"{doctype} '{docname}' not found"}
|
|
except frappe.PermissionError:
|
|
return {"has_access": False, "error": "Permission denied"}
|
|
|
|
# Get permission filters
|
|
perm_result = get_permission_filters(doctype, user)
|
|
|
|
if perm_result.get("is_admin"):
|
|
return {"has_access": True, "is_admin": True}
|
|
|
|
restrictions = perm_result.get("restrictions", {})
|
|
|
|
if not restrictions:
|
|
return {"has_access": True, "no_restrictions": True}
|
|
|
|
# Check each restriction
|
|
for allow_doctype, info in restrictions.items():
|
|
field = info.get("field")
|
|
allowed_values = info.get("values", [])
|
|
doc_value = getattr(doc, field, None)
|
|
|
|
if doc_value and doc_value not in allowed_values:
|
|
return {
|
|
"has_access": False,
|
|
"denied_by": allow_doctype,
|
|
"field": field,
|
|
"document_value": doc_value,
|
|
"allowed_values": allowed_values
|
|
}
|
|
|
|
return {"has_access": True}
|
|
|
|
|
|
@frappe.whitelist(allow_guest = True)
|
|
def get_configured_doctypes():
|
|
"""Get list of doctypes that have permission mappings configured."""
|
|
return {
|
|
"doctypes": list(DOCTYPE_PERMISSION_MAPPINGS.keys()),
|
|
"mappings": {
|
|
dt: list(mapping.keys())
|
|
for dt, mapping in DOCTYPE_PERMISSION_MAPPINGS.items()
|
|
}
|
|
}
|
|
|
|
|
|
@frappe.whitelist(allow_guest = True)
|
|
def get_user_defaults(user=None):
|
|
"""Get default values from user permissions (where is_default=1)."""
|
|
if not user:
|
|
user = frappe.session.user
|
|
|
|
if is_system_user(user):
|
|
return {"is_admin": True, "defaults": {}}
|
|
|
|
permissions = frappe.get_all(
|
|
"User Permission",
|
|
filters={"user": user, "is_default": 1},
|
|
fields=["allow", "for_value"]
|
|
)
|
|
|
|
defaults = {p.get("allow"): p.get("for_value") for p in permissions}
|
|
|
|
return {"is_admin": False, "defaults": defaults}
|