Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The goal is a full http4s migration — replace Lift Web across all version file

**Key files**: `Http4s700.scala` (v7.0.0 endpoints), `Http4s200.scala` (v2.0.0 endpoints — 37 own + path-rewriting bridge to Http4s140), `Http4s140.scala` (v1.4.0 endpoints — 11 own + path-rewriting bridge to Http4s130), `Http4s130.scala` (v1.3.0 endpoints — 3 own + path-rewriting bridge to Http4s121), `Http4s121.scala` (v1.2.1 endpoints — all 323 API1_2_1Test scenarios), `Http4sSupport.scala` (EndpointHelpers + recordMetric), `ResourceDocMiddleware.scala` (auth, entity resolution, transaction wrapper), `IdempotencyMiddleware.scala` (Redis-backed idempotency, opt-in via `Idempotency-Key` header, nested inside ResourceDocMiddleware), `RequestScopeConnection.scala` (DB transaction propagation to Futures).

**v7.0.0 native endpoints** (46 ResourceDocs): root, corePrivateAccountsAllBanks, deleteEntitlement, addEntitlement, getAccountAccessTrace, getConsentsConfig, getErrorMessages, getUserByUserId, createTradingOffer, getTradingOffer, getTradingOffers, cancelTradingOffer, createMarketOrder, getMarketOrder, cancelMarketOrder, createMarketMatch, getMarketTrade, requestSettlement, notifyDeposit, requestWithdrawal, createPaymentAuth, capturePaymentAuth, releasePaymentAuth, getPaymentAuth, createTestEmail, createValidationEmail, createOrganisation, getOrganisations, getOrganisation, updateOrganisation, deleteOrganisation, createRoutingScheme, getRoutingSchemes, getRoutingScheme, updateRoutingScheme, deleteRoutingScheme, getBankSupportedRoutingSchemes, putBankSupportedRoutingScheme, createPayeeLookup, createTransactionRequestMobileWallet, createTransactionRequestUtility, createTransactionRequestOpenCorridor, createTransactionRequestBulk, factoryResetSystemView. These carry genuinely v7-specific signatures/behaviour. The 20 duplicate "POC" endpoints originally added as migration scaffolding (getBanks, getBank, getCurrentUser, getCoreAccountById, getPrivateAccountByIdFull, getExplicitCounterpartyById, getFeatures, getScannedApiVersions, getConnectors, getProviders, getUsers, getCustomersAtOneBank, getCustomerByCustomerId, getAccountsAtBank, getCacheConfig, getCacheInfo, getDatabasePoolInfo, getStoredProcedureConnectorHealth, getMigrations, getCacheNamespaces) were **removed** — they cascade to their v6 twin via `v700ToV600Bridge` (getExplicitCounterpartyById → v4, no v6/v5 twin), `X-OBP-Version-Served: v6.0.0`. Kept deliberately in v7: `deleteEntitlement` (204), `addEntitlement` (409), `getUserByUserId` (404) — intentional RESTful response-code improvements over the older v6 200/400 convention.
**v7.0.0 native endpoints** (48 ResourceDocs): root, corePrivateAccountsAllBanks, createMyBank, getMyBanks, deleteEntitlement, addEntitlement, getAccountAccessTrace, getConsentsConfig, getErrorMessages, getUserByUserId, createTradingOffer, getTradingOffer, getTradingOffers, cancelTradingOffer, createMarketOrder, getMarketOrder, cancelMarketOrder, createMarketMatch, getMarketTrade, requestSettlement, notifyDeposit, requestWithdrawal, createPaymentAuth, capturePaymentAuth, releasePaymentAuth, getPaymentAuth, createTestEmail, createValidationEmail, createOrganisation, getOrganisations, getOrganisation, updateOrganisation, deleteOrganisation, createRoutingScheme, getRoutingSchemes, getRoutingScheme, updateRoutingScheme, deleteRoutingScheme, getBankSupportedRoutingSchemes, putBankSupportedRoutingScheme, createPayeeLookup, createTransactionRequestMobileWallet, createTransactionRequestUtility, createTransactionRequestOpenCorridor, createTransactionRequestBulk, factoryResetSystemView. These carry genuinely v7-specific signatures/behaviour. The 20 duplicate "POC" endpoints originally added as migration scaffolding (getBanks, getBank, getCurrentUser, getCoreAccountById, getPrivateAccountByIdFull, getExplicitCounterpartyById, getFeatures, getScannedApiVersions, getConnectors, getProviders, getUsers, getCustomersAtOneBank, getCustomerByCustomerId, getAccountsAtBank, getCacheConfig, getCacheInfo, getDatabasePoolInfo, getStoredProcedureConnectorHealth, getMigrations, getCacheNamespaces) were **removed** — they cascade to their v6 twin via `v700ToV600Bridge` (getExplicitCounterpartyById → v4, no v6/v5 twin), `X-OBP-Version-Served: v6.0.0`. Kept deliberately in v7: `deleteEntitlement` (204), `addEntitlement` (409), `getUserByUserId` (404) — intentional RESTful response-code improvements over the older v6 200/400 convention.

**Tests**: `Http4s700RoutesTest` (91 scenarios, port 8087). `makeHttpRequest` returns `(Int, JValue, Map[String, String])`. `makeHttpRequestWithBody(method, path, body, headers)` for POST/PUT.
## Migrating a Lift Endpoint to http4s
Expand Down
7 changes: 7 additions & 0 deletions obp-api/src/main/resources/props/sample.props.template
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,13 @@ allow_sandbox_data_import=true
# Secret key that allows access to the "data import" api. You should change this to your own secret key
sandbox_data_import_secret=change_me

## Self-service bank creation (POST /my/banks): the maximum number of banks each registered
## User may create without holding the role CanCreateBank. The bank identity (bank_id, short
## name, full name) is auto-generated by the server — the caller cannot choose it.
## 0 disables the endpoint (default). Users holding CanCreateBank are unaffected by this
## limit — they use POST /banks as usual.
# self_service_bank_creation.limit=0



### API features
Expand Down
31 changes: 31 additions & 0 deletions obp-api/src/main/scala/code/api/util/ApiSession.scala
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,37 @@ case class CallContext(

// for endpoint body convenient get userId
def userId: String = user.map(_.userId).openOrThrowException(AuthenticatedUserIsRequired)

/**
* The human User this request is really about.
*
* The authenticated `user` may be the human themselves, or an agent user minted by a
* Consent the human granted (e.g. Opey / MCP acting under a consent). Resolution order:
* 1. `onBehalfOfUser` or `consenter`, when a middleware populated them (free);
* 2. otherwise resolve via the delegation registry: the caller's ResourceUser row's
* CreatedByConsentId names the Consent that minted it, and that Consent's userId
* names the granting human;
* 3. otherwise the caller IS the human.
*
* IMPORTANT: this reads only the authenticated user and server-written columns
* (ResourceUser.CreatedByConsentId, MappedConsent.mUserId). It deliberately takes no
* parameters so nothing caller-asserted (body/header/query values) can ever influence
* the resolution — identity-sensitive queries (e.g. /my/banks) depend on that.
*/
def effectiveHumanUserId: String = {
val delegatedHumanUserId = onBehalfOfUser.or(consenter).map(_.userId).filter(_.nonEmpty)
delegatedHumanUserId.openOr {
val authenticatedUserId = user.map(_.userId).openOr("")
val grantingHumanUserId = for {
callerResourceUser <- code.model.dataAccess.ResourceUser.find(
net.liftweb.mapper.By(code.model.dataAccess.ResourceUser.userId_, authenticatedUserId))
consentId <- net.liftweb.common.Full(callerResourceUser.CreatedByConsentId.get)
.filter(id => id != null && id.nonEmpty)
consent <- code.consent.Consents.consentProvider.vend.getConsentByConsentId(consentId)
} yield consent.userId
grantingHumanUserId.filter(_.nonEmpty).openOr(authenticatedUserId)
}
}
def userPrimaryKey: UserPrimaryKey = user.map(_.userPrimaryKey).openOrThrowException(AuthenticatedUserIsRequired)
def loggedInUser: User = user.openOrThrowException(AuthenticatedUserIsRequired)
// for endpoint body convenient get cc.callContext
Expand Down
2 changes: 2 additions & 0 deletions obp-api/src/main/scala/code/api/util/ErrorMessages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ object ErrorMessages {
val UpdateCustomerAccountLinkError = "OBP-30227: Could not update the customer account link."
val DeleteCustomerAccountLinkError = "OBP-30228: Could not delete the customer account link."
val GetConsentImplicitSCAError = "OBP-30229: Could not get the implicit SCA consent."
val SelfServiceBankCreationDisabled = "OBP-30230: Self-service bank creation is disabled on this instance."
val SelfServiceBankLimitReached = "OBP-30231: Self-service bank creation limit reached. To create more banks you require the role CanCreateBank."

val CreateSystemViewError = "OBP-30250: Could not create the system view"
val DeleteSystemViewError = "OBP-30251: Could not delete the system view"
Expand Down
Loading
Loading