access_control: return True for pass-through in has_permission
Frappe's has_controller_permissions treats any falsy return as denial, so returning None was blocking every non-admin user on every doctype. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
692dbb2b52
commit
94b6f4f75e
|
|
@ -111,21 +111,25 @@ def before_request():
|
||||||
|
|
||||||
|
|
||||||
def has_permission(doc=None, ptype=None, user=None, debug=False):
|
def has_permission(doc=None, ptype=None, user=None, debug=False):
|
||||||
"""Per-doc hook. Applies to non-Administrator users that might otherwise have role access."""
|
"""Per-doc hook. Applies to non-Administrator users that might otherwise have role access.
|
||||||
|
|
||||||
|
IMPORTANT: Frappe treats a falsy return (None/False/0) as a denial — see
|
||||||
|
`has_controller_permissions` in frappe/permissions.py. Controllers can only
|
||||||
|
*deny*, never grant — so for the pass-through case we MUST return True."""
|
||||||
doctype = None
|
doctype = None
|
||||||
if doc is not None:
|
if doc is not None:
|
||||||
doctype = getattr(doc, "doctype", None)
|
doctype = getattr(doc, "doctype", None)
|
||||||
if doctype is None and isinstance(doc, str):
|
if doctype is None and isinstance(doc, str):
|
||||||
doctype = doc
|
doctype = doc
|
||||||
if not doctype:
|
if not doctype:
|
||||||
return None
|
return True
|
||||||
if is_blocked_doctype(doctype):
|
if is_blocked_doctype(doctype):
|
||||||
return False
|
return False
|
||||||
if doctype == "Workspace":
|
if doctype == "Workspace":
|
||||||
module = getattr(doc, "module", None)
|
module = getattr(doc, "module", None)
|
||||||
if module and module in BLOCKED_MODULES:
|
if module and module in BLOCKED_MODULES:
|
||||||
return False
|
return False
|
||||||
return None
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _filter_list(container, key, predicate):
|
def _filter_list(container, key, predicate):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue