fix: added permission checks on various whitelisted functions (backport #56745) (#56945)

Co-authored-by: Diptanil Saha <diptanil@frappe.io>
This commit is contained in:
mergify[bot]
2026-07-09 16:00:19 +05:30
committed by GitHub
parent 2ed6f25d94
commit 55e0d106c9
3 changed files with 60 additions and 33 deletions

View File

@@ -115,7 +115,7 @@ def get_party_bank_account(party_type, party):
)
def get_default_company_bank_account(company, party_type, party):
def get_default_company_bank_account(company, party_type, party, ignore_permissions=True):
default_company_bank_account = frappe.db.get_value(party_type, party, "default_bank_account")
if default_company_bank_account:
if company != frappe.get_cached_value("Bank Account", default_company_bank_account, "company"):
@@ -126,6 +126,14 @@ def get_default_company_bank_account(company, party_type, party):
"Bank Account", {"company": company, "is_company_account": 1, "is_default": 1}
)
if not ignore_permissions:
default_company_bank_account = (
default_company_bank_account
if default_company_bank_account
and frappe.get_cached_doc("Bank Account", default_company_bank_account).has_permission("select")
else None
)
return default_company_bank_account

View File

@@ -2691,6 +2691,9 @@ def get_party_details(company, party_type, party, date, cost_center=None):
if not frappe.db.exists(party_type, party):
frappe.throw(_("{0} {1} does not exist").format(_(party_type), party))
ptype = "select" if frappe.only_has_select_perm(party_type) else "read"
frappe.has_permission(party_type, ptype, party, throw=True)
party_account = get_party_account(party_type, party, company)
account_currency = get_account_currency(party_account)
account_balance = (
@@ -2707,7 +2710,7 @@ def get_party_details(company, party_type, party, date, cost_center=None):
)
if party_type in ["Customer", "Supplier"]:
party_bank_account = get_party_bank_account(party_type, party)
bank_account = get_default_company_bank_account(company, party_type, party)
bank_account = get_default_company_bank_account(company, party_type, party, ignore_permissions=False)
return {
"party_account": party_account,

View File

@@ -431,6 +431,17 @@ def get_party_account(party_type, party=None, company=None, include_advance=Fals
Will first search in party (Customer / Supplier) record, if not found,
will search in group (Customer Group / Supplier Group),
finally will return default."""
def account_perm_check(account):
ptype = "select" if frappe.only_has_select_perm("Account") else "read"
if frappe.has_permission("Account", ptype, account):
return
# Using custom message to prevent data leak in case of `apply_strict_permission` is enabled.
frappe.throw(
_("User don't have permissions to select/read this account."), exc=frappe.PermissionError
)
if not party_type:
frappe.throw(_("Party Type is mandatory"))
if not company:
@@ -441,46 +452,51 @@ def get_party_account(party_type, party=None, company=None, include_advance=Fals
"default_receivable_account" if party_type == "Customer" else "default_payable_account"
)
return frappe.get_cached_value("Company", company, default_account_name)
account = frappe.db.get_value(
"Party Account", {"parenttype": party_type, "parent": party, "company": company}, "account"
)
if not account and party_type in ["Customer", "Supplier"]:
party_group_doctype = "Customer Group" if party_type == "Customer" else "Supplier Group"
group = frappe.get_cached_value(party_type, party, scrub(party_group_doctype))
account = frappe.get_cached_value("Company", company, default_account_name)
else:
account = frappe.db.get_value(
"Party Account",
{"parenttype": party_group_doctype, "parent": group, "company": company},
"account",
"Party Account", {"parenttype": party_type, "parent": party, "company": company}, "account"
)
if not account and party_type in ["Customer", "Supplier"]:
default_account_name = (
"default_receivable_account" if party_type == "Customer" else "default_payable_account"
)
account = frappe.get_cached_value("Company", company, default_account_name)
if not account and party_type in ["Customer", "Supplier"]:
party_group_doctype = "Customer Group" if party_type == "Customer" else "Supplier Group"
group = frappe.get_cached_value(party_type, party, scrub(party_group_doctype))
account = frappe.db.get_value(
"Party Account",
{"parenttype": party_group_doctype, "parent": group, "company": company},
"account",
)
existing_gle_currency = get_party_gle_currency(party_type, party, company)
if existing_gle_currency:
if account:
account_currency = frappe.get_cached_value("Account", account, "account_currency")
if (account and account_currency != existing_gle_currency) or not account:
account = get_party_gle_account(party_type, party, company)
if not account and party_type in ["Customer", "Supplier"]:
default_account_name = (
"default_receivable_account" if party_type == "Customer" else "default_payable_account"
)
account = frappe.get_cached_value("Company", company, default_account_name)
# get default account on the basis of party type
if not account:
account_type = frappe.get_cached_value("Party Type", party_type, "account_type")
default_account_name = "default_" + account_type.lower() + "_account"
account = frappe.get_cached_value("Company", company, default_account_name)
existing_gle_currency = get_party_gle_currency(party_type, party, company)
if existing_gle_currency:
if account:
account_currency = frappe.get_cached_value("Account", account, "account_currency")
if (account and account_currency != existing_gle_currency) or not account:
account = get_party_gle_account(party_type, party, company)
if include_advance and party_type in ["Customer", "Supplier", "Student"]:
# get default account on the basis of party type
if not account:
account_type = frappe.get_cached_value("Party Type", party_type, "account_type")
default_account_name = "default_" + account_type.lower() + "_account"
account = frappe.get_cached_value("Company", company, default_account_name)
if account:
account_perm_check(account)
if include_advance and party and party_type in ["Customer", "Supplier", "Student"]:
advance_account = get_party_advance_account(party_type, party, company)
if advance_account:
account_perm_check(advance_account)
return [account, advance_account]
else:
return [account]
return [account]
return account