Repository navigation
feat: atomic cascades, SCA challenge recipients, exact rate limits and card fixes - #2963
Merged
Merged
Conversation
DeleteAccountCascade now removes the MapperAccountHolders rows of the deleted bank_id/account_id, and DeleteBankCascade removes them for every account of the bank through it. A holder row that outlived its account was read back by AuthUser.refreshUser (for example when the former holder created another account) and the five system views were granted on the deleted account again.
A consent's OBP_CONSENT_CHALLENGE rows are deleted when the PSU answers one correctly on POST .../consents/CONSENT_ID/authorise (the answered challenge and any other one started on the consent), and when the consent becomes REVOKED, REJECTED or EXPIRED through updateConsentStatus, revoke or the UK expiry sweep. A wrong answer keeps its row so the attempt counter still applies. Berlin Group consent challenges and transaction request challenges are left as they are, since they are read after answering.
…de_delete is true
…s bound to it
DELETE /obp/v4.0.0/management/cascading/banks/{BANK_ID}/accounts/{ACCOUNT_ID}
now also removes the SCA challenges of every consent whose JWT views name the
account. The consents are read from the users who hold or can see the account,
before their account access rows are deleted. The bank cascade deletes each
account through the same code.
…llenge table The account cascade looked for consents through the users who hold or can see the account, which misses a Berlin Group consent whose first challenge is still unanswered: no PSU is bound to it yet. The consents are now read from the challenges that carry a consent id and kept when their JWT names the account. The test now uses such a Berlin Group consent instead of an authorised UK consent, whose challenge is deleted once answered.
…points The Dynamic Entity cascade deletes back up to a ZZ_BAK_ entity before deleting and are used by API Manager, so they stay available whatever the prop says. The tests check that they are still routed with the prop off.
…hout SCA PUT /banks/BANK_ID/consents/CONSENT_ID changed nothing while consents.sca.enabled was on, yet answered 200, so Portal's Deny on a Berlin Group consent showed the consent as denied while it stayed received. Setting REJECTED on a consent that is INITIATED, received or AWAITINGAUTHORISATION now stores the refusal, as rejected for a Berlin Group consent; other changes keep their behaviour.
…Status's description
…sca' into develop-combined
CascadeDeleteEndpoints.gated now also reads Implementations4_0_0.routesInOrder, so a route left in the chain without its doc is caught: the middleware never runs such a route, and the 404 requests alone cannot see it. The 404 check also goes through the v5.0.0, v5.1.0 and v6.0.0 prefixes, and the enabled suite says which prop is missing when it fails.
The five ResourceDocs are registered as before and removed again by cascadeDeleteRoutes when allow_cascade_delete is false, the same set that leaves their routes out of routesInOrder, so a cascade endpoint added later needs one entry. The prop is read once per JVM.
The Resource Docs responses are cached in Redis, so after the prop changes the catalog can show the old list until the cache TTL passes or the rd_static and rd_all namespaces are invalidated.
With allow_cascade_delete on, the five CanDelete*Cascade roles are in ApiRole.availableRoles; with it off they are not.
…te is false The five CanDelete*Cascade roles are checked only by the /management/cascading endpoints, so while those are left out ApiRole.availableRoles leaves the roles out too: GET /roles, the glossary, the role check of v3.0.0 entitlement creation and of consents. ApiRole.valueOf still resolves them, so entitlements granted earlier keep working.
feat: hide the /management/cascading endpoints unless allow_cascade_delete is true
Trivy reports a CRITICAL vulnerability with a fix available in each: CVE-2026-69204 in http4s-ember-core 0.23.30 (fixed in 0.23.35) and CVE-2026-8763 in bcprov-jdk18on 1.84, which bcpg and bcpkix pull in (fixed in 1.85).
…link The new scenarios fail on the current code: the holder gets no InitiatePaymentsBerlinGroup access on refresh, and scaRedirect repeats the payment id and is built from the missing-prop error text.
…caRedirect once The mapped connector now generates the payment initiation view with the other Berlin Group views, so a holder can initiate a payment after a refresh. The scaRedirect link carries the payment id once and is left out when psu_make_payment_sca_redirect_url is not set. Closes #110
… link behaviour A blank psu_make_payment_sca_redirect_url no longer yields a relative link. The Boot comment and sample props now say that the mapped connector creates the payment initiation view on refresh and that the link is optional. Tests cover a second refresh and a user who holds no account.
…de and a new endpoint The scenarios fail on the current code: a deleted card and a cascaded account leave their MappedCardAttribute rows, and there is no endpoint that deletes one attribute.
Within a request the connection ignores rollback and is committed when the request ends, whatever the response, so a cascade that failed part way kept what it had deleted. DeletionUtil.databaseAtomicTask now takes a savepoint and rolls back to it when the cascade throws, the request connection passes rollback(Savepoint) through to the real connection, and the DB.rollback calls the cascades made, which did nothing there, are gone.
The savepoint handling of databaseAtomicTask moves into withSavepoint, which takes the connection, so it can be tested on its own; behaviour is unchanged.
…connection A savepoint is released on success and rolled back to on failure, a database that cannot release a savepoint does not fail a cascade that succeeded, a failed rollback keeps the cascade's exception, and rollback(Savepoint) on the request connection reaches the real one.
The Oracle and SQL Server drivers do not support releaseSavepoint; releasing it is now best effort, and the savepoint ends with the transaction.
…avepoint that cannot be set
… limits With several rate limits the legacy PUT must change none of them, its change must apply at once, the consumer's only rate limit is still changed or created, and v4.0.0 refuses a scope field and takes an empty one as not set.
…te limits, and apply its change at once PUT /management/consumers/CONSUMER_ID/consumer/call-limits (v3.1.0 and v4.0.0) changes the consumer's rate limit or creates it; with more than one rate limit, which v6.0.0 allows and sums, it now answers 400 OBP-30583 instead of overwriting the most recent one. Its change clears the rate limit cache as the other writes do, so it applies at once, and v4.0.0 refuses api_name, api_version and bank_id like v6.0.0. The existing rate limit tests expected the old cached behaviour and an endpoint scope nothing enforced; they now set the limit from another consumer and expect 429 on the call that goes over it.
A row an older v4.0.0 stored with "" for api_name, api_version and bank_id is the consumer's only rate limit and must be the one the PUT changes.
The legacy PUT finds and counts the consumer's rate limits through the getters, which take an empty bank_id, api_version or api_name as not set, so a row an older version stored with "" is changed instead of getting a second row next to it. The scaladoc of rateLimitScopeFields is no longer stacked on another function's.
… to tell Redis rounds the counter's TTL to whole seconds, so a one-second window reads as expired about half a second after the first call; a run slower than that cannot show the limit applied.
… doc The middleware enforces a resource doc's roles before the handler runs, so listing CanCreateCardsForBank made deleting a card need both roles.
fix: hold a rate limit to its exact dates and refuse unenforced scope fields
fix: delete a bank's dynamic entities and records in the bank cascade
fix: make the cascading deletes atomic
Create and update passed the failed validation to unboxFullOrFail with a message lacking an OBP code, so every invalid rule answered OBP-50005.
…imits-put # Conflicts: # scripts/resource_doc_baseline/parity_allowlist.json
fix: send challenge passcodes to the user when no customer is linked and report a failed send
…ctor fix: delete a card attribute through the connector
fix: grant the payment initiation view on accounts already held and keep existing opt-in views current
fix(cards): declare CanDeleteCardsForBank on the delete card resource doc
fix: keep the legacy Set Rate Limits from overwriting one of several rate limits
The create and update scenarios now check that validate reports OBP-38005 for a field reference, OBP-38002 for an incomplete expression (the compiler reports it as a failed compilation) and OBP-38010 for a tautology, before checking that create and update answer the same; the update scenarios carry the updateAbacRule tag.
fix(abac): answer rejected rule code with the error validate reports
Upstream now gives OBP-30582 and OBP-30583 to assets, so the rate limit errors RateLimitScopeNotSupported and RateLimitNotUnique move to OBP-30624 and OBP-30625.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



This brings the develop branch of hongwei1/OBP-API into develop. The
/management/cascadingdeletes are registered only when the new propallow_cascade_deleteis true (default false) and run atomically, rolling back to a savepoint when a step fails; the account and bank cascades also remove account holders, the SCA challenges of consents bound to the account and card attributes, and the bank cascade removes the bank's dynamic entities with their records while leaving the system space alone. A consent'sOBP_CONSENT_CHALLENGErows are deleted once they can no longer be used, and a PSU can refuse a consent it has not authorised without SCA. EMAIL and SMS challenge passcodes go to the linked customers' addresses, or else to the user's own confirmed address; a challenge is saved only once its passcode is sent, a transaction request that cannot get enough challenges is marked FAILED (OBP-35059,OBP-35060), and the error does not reveal a phone number.Account holders get
InitiatePaymentsBerlinGroupon refresh, also on accounts they already hold, andscaRedirectis omitted whenpsu_make_payment_sca_redirect_urlis not set. Consumer rate limits apply exactly fromfrom_datetoto_date,api_name,api_versionandbank_idare refused (OBP-30624), and the v3.1.0/v4.0.0 Set Rate Limits refuses a consumer with several rate limits (OBP-30625) and takes effect at once. Creating or updating an ABAC rule with invalid code answers the error validate reports (OBP-38002,OBP-38005,OBP-38010). Delete Card Attribute (v7.0.0) is new and goes through the connector, Delete Card (v3.1.0) declaresCanDeleteCardsForBank, and http4s and BouncyCastle are at 0.23.35 and 1.85. Each change has its own tests and came through hongwei1#108 to hongwei1#127. Not covered yet: two first Set Rate Limits calls racing on a consumer with no rate limit can each create one.