Repository navigation
sec(api): apply allowed_accounts scope to RI exchange listing endpoints (closes #1030) - #1042
Conversation
…ilization, getReshapeRecommendations Three RI-exchange listing handlers gated on view:purchases but did not apply the caller's allowed_accounts filter, so a restricted user could see the full convertible-RI inventory and utilization for accounts outside their scope. getRIExchangeHistory already filtered by allowed_accounts; these three siblings now match that behaviour exactly (closes #1030). - Extract session from requirePermission in all three handlers. - Gate on getAllowedAccounts + auth.IsUnrestrictedAccess before any AWS SDK call; resolve the deployment CloudAccount UUID via resolveAWSCloudAccountID (test-injectable via reshapeAccountResolver). - Return an empty typed response when the deployment account is outside the session's allowed_accounts, identical to the getRIExchangeHistory pattern. - Add six regression tests in handler_per_account_perms_test.go covering the out-of-scope (returns empty) and admin/in-scope (passes gate) paths for all three handlers.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughHandlers listConvertibleRIs, getRIUtilization, and getReshapeRecommendations now fetch the session’s allowed_accounts and, for restricted sessions, resolve the deployment/reshape cloud account and return empty typed responses when out-of-scope. Exchange flows now require/resolve region explicitly and remove us-east-1 fallbacks; tests were added/updated for both scoping and region behaviors. ChangesRI-exchange Scope Enforcement & Region Validation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
…te (closes #1060) getExchangeQuote now resolves the region from the AWS SDK configuration chain when the caller omits it, matching getReshapeRecommendations instead of hardcoding us-east-1. executeExchange now returns 400 when region is absent. RI exchanges are financially irreversible; silently defaulting to us-east-1 would execute the exchange in the wrong region for deployments elsewhere. executeApprovedExchange now fails the exchange via failExchange when record.Region is empty instead of silently defaulting to us-east-1. A stored record without a region stamp should not proceed; the region must have been captured at record-creation time. Three regression tests pin each path: - TestExecuteExchange_EmptyRegionReturns400 - TestGetExchangeQuote_EmptyRegionResolvesFromSDK - TestExecuteApprovedExchange_EmptyRecordRegionFails Finding: 01-L4 from report 01-api-handlers (FOLD-1042).
FOLD-1042 additionsAdded commits for the two findings in the FOLD-1042 bucket ( 01-L4 -- region hardcoded to
|
|
Triggering a review to cover the new commits. 🧠 Learnings used✅ Action performedReview finished.
|
Extract reshapeCloudAccountInScope, resolveReshapeCloudAccountID, checkListRIsAccountIDParam, and parseReshapeParams helpers to bring getReshapeRecommendations (15->10) and listConvertibleRIs (13->7) within the gocyclo-10 threshold enforced by pre-commit. Also apply gofmt to pkg/exchange/reshape_crossfamily_test.go which the CI hook auto-fixed in-place but whose correction was not committed.
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai full review |
✅ Action performedFull review finished. |
Summary
listConvertibleRIs,getRIUtilization, andgetReshapeRecommendationsgated onview:purchasesbut never applied the session'sallowed_accountsfilter, so a restricted user could see the full convertible-RI inventory and utilization for accounts outside their scope.getRIExchangeHistory(the sibling handler) already applied this filter; the three listing handlers now match that behaviour exactly.resolveAWSCloudAccountID(test-injectable via the existingreshapeAccountResolverfield) and returns an empty typed response when the deployment account is outside the session'sallowed_accounts.handler_per_account_perms_test.gocover the out-of-scope (returns empty) and admin/in-scope (bypasses gate) paths for all three handlers.Closes #1030
Test plan
go test ./internal/api/... -count=1passes (1501 tests, no regressions)TestPerAccountPerms_ListConvertibleRIs_ScopedOutsideAllowedReturnsEmptyconfirms empty list returned for scoped user outside allowed accountsTestPerAccountPerms_GetRIUtilization_ScopedOutsideAllowedReturnsEmptyconfirms same for utilization endpointTestPerAccountPerms_GetReshapeRecommendations_ScopedOutsideAllowedReturnsEmptyconfirms same for reshape recommendationsIsUnrestrictedAccessbypasses the scope check for adminsgo vet ./internal/api/...cleanScope expanded
Additional findings from FOLD-1042 (
docs/code-review/16-remaining-findings-plan.md):01-L4 -- region defaults to hardcoded
us-east-1in quote/execute (finding 01-L4)getExchangeQuoteandexecuteExchangesilently defaulted an absentregiontothe hardcoded string
us-east-1, whilegetReshapeRecommendationscarefullyresolved the region from the AWS SDK configuration chain. On
executeExchange(a financially irreversible mutation), a wrong-region default could exchange RIs
in a region where none of the deployment's RIs live.
Fixes:
getExchangeQuote: resolves region from the AWS SDK chain vialoadAWSConfigWithRegionwhen the caller omits it (matchesgetReshapeRecommendations).executeExchange: returns 400 whenregionis absent from the body.executeApprovedExchange: fails the exchange viafailExchangewhenrecord.Regionis empty; the region must be captured at record-creation time.Three regression tests pin each path. 04-D4 (nit: unify
config.RIExchangeRecordand
exchange.ExchangeRecord) is skipped -- the two types must remain separatebecause
pkg/exchangeis a distinct Go module and cannot importinternal/config(see
pkg/exchange/auto.go:13-15). Documented indocs/code-review/open-questions/fold-1042.md.Also closes #1060
Summary by CodeRabbit
New Features
Bug Fixes