Aman-Mittal opened a new issue, #777:
URL: https://github.com/apache/fineract-backoffice-ui/issues/777

   ## Summary
   
   Fineract authorises each Working Capital loan command with its own 
permission code (for example `APPROVE_WORKINGCAPITALLOAN` or 
`DISBURSE_WORKINGCAPITALLOAN`). This UI instead guards every action route with 
the single code `UPDATE_WORKINGCAPITALLOAN`, and renders the action buttons on 
the loan screen with no permission check at all. That produces two failures:
   
   - **Locked out wrongly.** An approver who holds `APPROVE_WORKINGCAPITALLOAN` 
but not `UPDATE_WORKINGCAPITALLOAN` is sent to `/forbidden`, although Fineract 
would accept the approval.
   - **Offered an action the server refuses.** A user who holds 
`UPDATE_WORKINGCAPITALLOAN` (or only read access) still sees Approve, Disburse, 
Reject, Undo, Mark as fraud, Waive charge, Delete, Detach originator and the 
rest. Fineract then answers 403.
   
   Regular loans had the same problem and fixed it with a per-command map 
(#691). Working Capital needs the equivalent.
   
   ## Evidence (`main` @ `8da1086f`)
   
   - `src/app/features/working-capital/working-capital.routes.ts` guards all of 
these with `data: { permissions: 'UPDATE_WORKINGCAPITALLOAN' }`: 
`loans/:id/action/:command`, `loans/:id/charge`, `loans/:id/breach-action`, 
`loans/:id/near-breach-action` and `loans/:id/delinquency-action`.
   - `src/app/features/working-capital/loans/wc-loan-view.component.ts` 
contains no `hasPermission` or `[appRequiresPermission]` reference.
     - Its action buttons are always rendered, gated only on loan status: 
`onRepayment`, `onAction('approve' | 'disburse' | 'reject' | 'undoapproval' | 
'undodisbursal' | 'markasfraud' | 'discount' | 'paymentrate')`, `onDelete`, 
`onAddCharge`, `onWaiveCharge`, the New delinquency / breach / near-breach 
action buttons, `onAttachOriginator` and `onDetachOriginator`.
     - Delete, Waive and Detach call the API directly from this screen, so no 
route guard applies to them.
   - `src/app/core/guards/command-permissions.ts` has 
`LOAN_COMMAND_PERMISSIONS` and `SAVINGS_COMMAND_PERMISSIONS`, but no Working 
Capital map.
   
   ## Permissions Fineract enforces
   
   All codes below are present in `scripts/permission-codes.json`.
   
   | UI action | Required code |
   |---|---|
   | View loan / tabs | `READ_WORKINGCAPITALLOAN` (or `ALL_FUNCTIONS_READ`) |
   | Create / modify / delete application | `CREATE_` / `UPDATE_` / 
`DELETE_WORKINGCAPITALLOAN` |
   | Approve / Reject / Undo approval | `APPROVE_` / `REJECT_` / 
`APPROVALUNDO_WORKINGCAPITALLOAN` |
   | Disburse / Undo disbursal | `DISBURSE_` / 
`DISBURSALUNDO_WORKINGCAPITALLOAN` |
   | Repayment | `REPAYMENT_WORKINGCAPITALLOAN` |
   | Mark as fraud | `SETFRAUD_WORKINGCAPITALLOAN` |
   | Update discount | `UPDATEDISCOUNT_WORKINGCAPITALLOAN` |
   | Change payment rate | `UPDATERATE_WORKINGCAPITALLOAN` |
   | Add / waive / adjust charge | `CREATE_` / `WAIVE_` / 
`ADJUSTMENT_WORKINGCAPITALLOANCHARGE` |
   | Delinquency action (pause/resume/reschedule) | 
`CREATE_WC_DELINQUENCY_ACTION` |
   | Delinquency reset / undo reset | `CREATE_WC_DELINQUENCY_RESET` |
   | Delinquency disable / enable | `CREATE_WC_DELINQUENCY_DISABLE` |
   | Breach action / reset / disable | `CREATE_WC_BREACH_ACTION` / 
`CREATE_WC_BREACH_RESET` / `CREATE_WC_BREACH_DISABLE` |
   | Near-breach action | `CREATE_WC_NEAR_BREACH_ACTION` |
   | Attach / detach originator | `ATTACH_` / 
`DETACH_WORKING_CAPITAL_LOAN_ORIGINATOR` |
   
   The reset and disable variants are resolved separately in 
`WorkingCapitalLoanDelinquencyActionApiResource` / 
`WorkingCapitalLoanBreachActionApiResource` 
(`*_RESOURCE_NAME_FOR_PERMISSIONS`). One "New action" form therefore needs a 
different code depending on the action type the user picks.
   
   Every write also passes with `ALL_FUNCTIONS`. With maker-checker on, the 
command is queued for the matching `_CHECKER` code, and the UI should say 
"submitted for approval".
   
   ## Suggested role allowances
   
   These are typical separations of duty, not prescriptive:
   
   | Role | Allowed |
   |---|---|
   | Loan officer | READ, CREATE/UPDATE application, REPAYMENT, CREATE charge, 
ATTACH originator |
   | Credit approver / branch manager | APPROVE, REJECT, APPROVALUNDO, 
DISBURSE, DISBURSALUNDO, WAIVE/ADJUSTMENT charge, delinquency/breach actions |
   | Risk / collections | SETFRAUD, UPDATERATE, delinquency reset/disable, 
breach reset/disable |
   | Auditor | READ only (`ALL_FUNCTIONS_READ`), with no enabled controls |
   
   ## Proposed fix
   
   1. Add `WORKING_CAPITAL_COMMAND_PERMISSIONS` to `command-permissions.ts`, 
plus a `wcCommandPermission` resolver. Use it on `loans/:id/action/:command`, 
as `loanCommandPermission` is used for regular loans.
   2. Guard the charge, breach, near-breach and delinquency routes with their 
own codes. Inside the delinquency and breach forms, disable action types whose 
reset or disable code the user lacks.
   3. Wrap every action button and menu item in `wc-loan-view` with 
`[appRequiresPermission]` using the same code. This includes Delete, Waive 
charge and Detach originator, which call the API directly.
   4. Add unit tests for each mapping, for a user with only 
`APPROVE_WORKINGCAPITALLOAN` (can approve), and for one with only 
`UPDATE_WORKINGCAPITALLOAN` (cannot approve). Extend the RBAC e2e spec with a 
read-only user on a Working Capital loan.
   
   ## Acceptance criteria
   
   - [ ] Each Working Capital action is offered only when the user holds the 
code Fineract checks for it.
   - [ ] A user holding a specific code but not `UPDATE_WORKINGCAPITALLOAN` can 
perform that action.
   - [ ] A read-only user sees no enabled write controls on a Working Capital 
loan.
   - [ ] `scripts/check-route-permissions.mjs` and 
`scripts/check-permission-codes.mjs` pass.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to