Skip to content

FINERACT-2982: Add office-hierarchy check for deposit account activation - #6777

Open
danhandev wants to merge 1 commit into
apache:developfrom
danhandev:FINERACT-2982
Open

danhandev wants to merge 1 commit into
apache:developfrom
danhandev:FINERACT-2982

Conversation

@danhandev

Copy link
Copy Markdown

Description

Follow-up to FINERACT-2639 (#6698), covering the deposit-account activation part of FINERACT-2982.

Original issue
Activating a savings, fixed deposit or recurring deposit account can post an initial deposit (minimum opening balance, FD deposit amount, or a transfer from the linked savings account). Activation loaded the account with assembleFrom(...) and never checked the user's office, so a user from a sibling office could activate another office's account and post that deposit.

What changed
SavingsAccountWritePlatformServiceJpaRepositoryImpl.activate, DepositAccountWritePlatformServiceJpaRepositoryImpl.activateFDAccount and activateRDAccount now load the account with the assembleFromInUserScope(...) loaders from FINERACT-2639. No other logic changes.

Paths that reach these methods and are therefore covered:

  • POST /savingsaccounts/{id}?command=activate, /fixeddepositaccounts/..., /recurringdepositaccounts/...
  • GSIM activation (gsimActivate calls activate for each child account). Group members must share the group's office, so a user in scope of the group is in scope of every child.
  • Bulk import (SavingsImportHandler, FixedDepositImportHandler, RecurringDepositImportHandler submit the same activation commands).
  • With maker-checker enabled, the check runs for the maker on submission and for the checker on approval.

The transfer from a linked savings account during FD/RD activation is not checked separately: the linked account must belong to the same client, and SavingsAccount.office() derives the office from the client, so both accounts are always in the same office.

Side effect (behaviour change)
A non-head-office user can no longer activate an account outside their office hierarchy; they now get 403 and the account stays approved. Users in the account's office or a parent office, including head-office users, are unaffected. This may be worth a line in the release notes.

How it is covered

  • Unit: SavingsAccountWritePlatformServiceJpaRepositoryImplTest.activate_shouldRejectUserOutsideAccountOfficeHierarchy
  • Integration: activation cases in SavingsOfficeHierarchyAccessIntegrationTest and RecurringDepositOfficeHierarchyAccessIntegrationTest, and a new FixedDepositOfficeHierarchyAccessIntegrationTest. The sibling-office user is given the ACTIVATE_* permission, so the 403 comes from the office check, and the test asserts the hierarchy error message. Each test also checks that a user from the account's office can still activate and that the initial deposit is posted.
  • Verified against the code without the fix: the unit test and the three activation integration tests fail ("Expected call to fail, but it succeeded"); with the fix they pass, along with the existing FINERACT-2639 tests (PostgreSQL).

Out of scope, found while tracing (not changed here)

  • Client activation with a default savings product (ClientWritePlatformServiceJpaRepositoryImpl.activateClient → SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.createActiveApplication) creates an active savings account and posts the minimum opening balance. Client activation loads the client without an office check (ClientRepositoryWrapper.findOneWithNotFoundDetection), so this path is still open. Fixing it would change client activation for all clients, so I left it out and noted it on the Jira ticket.

Checklist

  • Write the commit message as per our guidelines
  • Acknowledge that we will not review PRs that are not passing the build ("green") - it is your responsibility to get a proposed PR to pass the build, not primarily the project's maintainers.
  • Create/update unit or integration tests for verifying the changes made.
  • Follow our coding conventions.
  • Add required Swagger annotation and update API documentation at fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm with details of any API changes (no API changes)
  • This PR must not be a "code dump". Large changes can be made in a branch, with assistance. Ask for help on the developer mailing list.
  • If merging this PR resolves a JIRA issue, I will mark that issue as resolved and set "Fix Version/s" appropriately. (only part of FINERACT-2982; the ticket stays open for the remaining operations)
  • I followed the AI Policy.

@adamsaghy

Copy link
Copy Markdown
Contributor

@danhandev Please rebase

Activating a savings, fixed deposit or recurring deposit account can post
an initial deposit, but activation loaded the account without checking the
user's office hierarchy, so a user from an unrelated office could activate
it. Load the account through the in-user-scope assemblers added in
FINERACT-2639, so such a user gets 403 and the account stays approved.

GSIM activation and bulk import go through the same methods and are
covered as well.

Assisted-By: claude-opus-5-5
@danhandev

Copy link
Copy Markdown
Author

Rebased on develop, thanks. The earlier build-core failure was the SavingsAccountRepositoryWrapperLockOrderTest compile error, fixed on develop by FINERACT-2968.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants