This is an automated email from the ASF dual-hosted git repository. mridulpathak pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
commit 3b5423b760753cf7bf49c471e93bffe8c985c258 Author: Mridul Pathak <[email protected]> AuthorDate: Mon Oct 12 17:16:11 2026 +0530 Elevate createAccountAndCredit's internal FinAccount writes to the system user createAccountAndCredit (shared by createServiceCredit and createFinAccountAndCredit) was the one caller in this change not elevated to the system user, so a caller without accounting permission now gets rejected by createFinAccount/createFinAccountRole/createFinAccountTrans. --- .../accounting/finaccount/FinAccountServices.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/applications/accounting/src/main/java/org/apache/ofbiz/accounting/finaccount/FinAccountServices.java b/applications/accounting/src/main/java/org/apache/ofbiz/accounting/finaccount/FinAccountServices.java index 86795f19ff..b3d4616671 100644 --- a/applications/accounting/src/main/java/org/apache/ofbiz/accounting/finaccount/FinAccountServices.java +++ b/applications/accounting/src/main/java/org/apache/ofbiz/accounting/finaccount/FinAccountServices.java @@ -121,7 +121,11 @@ public class FinAccountServices { createAccountContext.put("finAccountTypeId", finAccountTypeId); createAccountContext.put("finAccountName", accountName); createAccountContext.put("ownerPartyId", partyId); - createAccountContext.put("userLogin", userLogin); + // createFinAccount requires accounting permission; run as the "system" user since this is a trusted + // side effect of an already-validated service-credit/financial-account operation + GenericValue createAccountPermUserLogin = EntityQuery.use(delegator).from("UserLogin") + .where("userLoginId", "system").cache().queryOne(); + createAccountContext.put("userLogin", createAccountPermUserLogin); Map<String, Object> createAccountResult = dispatcher.runSync(createAccountServiceName, createAccountContext); if (ServiceUtil.isError(createAccountResult) || ServiceUtil.isFailure(createAccountResult)) { @@ -139,7 +143,11 @@ public class FinAccountServices { roleCtx.put("partyId", partyId); roleCtx.put("roleTypeId", "OWNER"); roleCtx.put("finAccountId", creditAccountId); - roleCtx.put("userLogin", userLogin); + // createFinAccountRole requires accounting permission; run as the "system" user since this is + // a trusted side effect of an already-validated service-credit/financial-account operation + GenericValue rolePermUserLogin = EntityQuery.use(delegator).from("UserLogin") + .where("userLoginId", "system").cache().queryOne(); + roleCtx.put("userLogin", rolePermUserLogin); roleCtx.put("fromDate", UtilDateTime.nowTimestamp()); Map<String, Object> roleResp; try { @@ -167,7 +175,12 @@ public class FinAccountServices { transactionMap.put("amount", context.get("amount")); transactionMap.put("reasonEnumId", context.get("reasonEnumId")); transactionMap.put("comments", context.get("comments")); - transactionMap.put("userLogin", userLogin); + // createFinAccountTrans requires accounting permission; run as the "system" user since this transaction + // is a trusted side effect of an already-validated service-credit/financial-account operation (the + // partyId above still records the real party the transaction is with) + GenericValue transPermUserLogin = EntityQuery.use(delegator).from("UserLogin") + .where("userLoginId", "system").cache().queryOne(); + transactionMap.put("userLogin", transPermUserLogin); Map<String, Object> creditTransResult = dispatcher.runSync("createFinAccountTrans", transactionMap); if (ServiceUtil.isError(creditTransResult) || ServiceUtil.isFailure(creditTransResult)) {

