diff --git a/financial-services-accelerator/accelerators/fs-is/repository/resources/apis/accelerator-extensions-v1.0.4.yaml b/financial-services-accelerator/accelerators/fs-is/repository/resources/apis/accelerator-extensions-v1.0.4.yaml
new file mode 100644
index 000000000..984676145
--- /dev/null
+++ b/financial-services-accelerator/accelerators/fs-is/repository/resources/apis/accelerator-extensions-v1.0.4.yaml
@@ -0,0 +1,2703 @@
+openapi: 3.0.1
+info:
+ title: API contract for financial accelerator extension points in WSO2 IS and APIM
+ description: This API defines the REST API contract for services that implements logic to extend the Open Data accelerator flow.
+ contact:
+ name: WSO2
+ url: https://wso2.com/solutions/financial-services/open-banking/
+ license:
+ name: Apache 2.0
+ url: https://www.apache.org/licenses/LICENSE-2.0.html
+ version: v1.0.3
+servers:
+ - url: https://virtserver.swaggerhub.com/wso2-f5b/OB4/1.0.0
+ description: SwaggerHub API Auto Mocking
+security:
+ - BasicAuth: []
+ - OAuth2: []
+tags:
+ - name: Client
+ description: APIs for dynamically registering/updating client related extensions
+ - name: Application
+ description: APIs for registering/updating applications through devportal related extensions
+ - name: Consent
+ description: APIs for consent flow extensions
+ - name: Token
+ description: APIs for token flow extensions
+ - name: Authorize
+ description: APIs for authorize flow extensions
+ - name: Error Handling
+ description: APIs for handling accelerator errors
+paths:
+ /map-accelerator-error-response:
+ post:
+ tags:
+ - Error Handling
+ summary: map accelerator level error formats to custom error formats
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMapperRequestBody'
+ example:
+ requestId: Ec1wMjmiG8
+ data:
+ error:
+ code: "401"
+ description: Invalid client ID provided.
+ operation: consent_create
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForErrorMapper'
+ example:
+ responseId: Ec1wMjmiG8
+ errorCode: 400
+ data:
+ customErrorCode: invalid
+ customErrorDescription: Invalid client ID provided.
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /pre-process-client-creation:
+ post:
+ tags:
+ - Client
+ summary: handle pre validations & obtain custom data to store in dynamic client registration step
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ClientProcessRequestBody'
+ examples:
+ ProcessClientCreation:
+ summary: ProcessClientCreation
+ value:
+ requestId: Ec1wMjmiG8
+ data:
+ clientData:
+ key: value
+ softwareStatement:
+ key: value
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForClientProcess'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ data:
+ clientData:
+ key: value
+ failedExample:
+ summary: Failed response
+ value:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorCode: 401
+ data:
+ error: invalid_client_metadata
+ errorDescription: Invalid scope values found
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Bad request
+ errorDescription: Request does not comply with the schema
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Internal server error
+ errorDescription: Error occurred while handling the request
+ /pre-process-client-update:
+ post:
+ tags:
+ - Client
+ summary: handle pre validations & obtain custom data to store in dynamic client update step
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ClientProcessRequestBody'
+ examples:
+ ProcessClientUpdate:
+ summary: ProcessClientUpdate
+ value:
+ requestId: Ec1wMjmiG8
+ data:
+ clientData:
+ key: value
+ softwareStatement:
+ key: value
+ existingClientData:
+ key: value
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForClientProcess'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ data:
+ clientData:
+ key: value
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 400
+ data:
+ error: invalid_client_metadata
+ errorDescription: Invalid scope values found
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Bad request
+ errorDescription: Request does not comply with the schema
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Internal server error
+ errorDescription: Error occurred while handling the request
+ /pre-process-client-retrieval:
+ post:
+ tags:
+ - Client
+ summary: handle post client retrieval response generation
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ClientProcessRequestBody'
+ examples:
+ ProcessClientRetrieval:
+ summary: ProcessClientRetrieval
+ value:
+ requestId: Ec1wMjmiG8
+ data:
+ existingClientData:
+ key: value
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForClientProcess'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ data:
+ clientData:
+ key: value
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 400
+ data:
+ error: invalid_client_metadata
+ errorDescription: Invalid scope values found
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Bad request
+ errorDescription: Request does not comply with the schema
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Internal server error
+ errorDescription: Error occurred while handling the request
+ /pre-process-application-creation:
+ post:
+ tags:
+ - Application
+ summary: handle pre validations & changes to the consumer application creation
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AppCreateProcessRequestBody'
+ examples:
+ ProcessApplicationCreation:
+ summary: ProcessApplicationCreation
+ value:
+ requestId: Ec1wMjmiG8
+ data:
+ appData:
+ key: value
+ additionalProperties:
+ key: value
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForApplicationCreation'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ data:
+ clientId: value
+ additionalAppData:
+ key: value
+ failedExample:
+ summary: Failed response
+ value:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: Invalid certificate found
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Bad request
+ errorDescription: Request does not comply with the schema
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Internal server error
+ errorDescription: Error occurred while handling the request
+ /pre-process-application-update:
+ post:
+ tags:
+ - Application
+ summary: handle pre validations & changes to the consumer application update
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AppUpdateProcessRequestBody'
+ examples:
+ ProcessApplicationUpdate:
+ summary: ProcessApplicationUpdate
+ value:
+ requestId: Ec1wMjmiG8
+ data:
+ appData:
+ key: value
+ additionalProperties:
+ key: value
+ existingAppData:
+ key: value
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForApplicationUpdate'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ data:
+ additionalAppData:
+ key: value
+ failedExample:
+ summary: Failed response
+ value:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: Invalid certificate found
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Bad request
+ errorDescription: Request does not comply with the schema
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Internal server error
+ errorDescription: Error occurred while handling the request
+ /pre-process-consent-creation:
+ post:
+ tags:
+ - Consent
+ summary: handle pre validations & obtain custom consent data to be stored
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PreProcessConsentCreationRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForPreProcessConsentCreation'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /enrich-consent-creation-response:
+ post:
+ tags:
+ - Consent
+ summary: "handle post-consent generation -response generation,validations"
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EnrichConsentCreationRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForResponseAlternation'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /pre-process-consent-update:
+ post:
+ tags:
+ - Consent
+ summary: handle pre validations & obtain custom consent data to be updated
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PreProcessConsentUpdateRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForPreProcessConsentUpdate'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /enrich-consent-update-response:
+ post:
+ tags:
+ - Consent
+ summary: "handle post-consent update - response generation,validations"
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EnrichConsentUpdateRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForResponseAlternation'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /pre-process-consent-file-upload:
+ post:
+ tags:
+ - Consent
+ summary: Handle pre validations related to file upload requests.
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PreProcessFileUploadRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForPreProcessFileUpload'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /enrich-consent-file-response:
+ post:
+ tags:
+ - Consent
+ summary: Modify the response sent in the file upload request after successfully storing the file.
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EnrichFileUploadResponseRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForResponseAlternation'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /pre-process-consent-retrieval:
+ post:
+ tags:
+ - Consent
+ summary: handle pre-consent retrieval validations
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PreProcessConsentRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForResponseAlternation'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /validate-consent-file-retrieval:
+ post:
+ tags:
+ - Consent
+ summary: Handle validations related to file retrieval and return a response
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PreProcessConsentRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /pre-process-consent-revoke:
+ post:
+ tags:
+ - Consent
+ summary: handle pre-consent revocation validations when a TPP calls consent /DELETE
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PreProcessConsentRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForConsentRevocation'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /enrich-consent-search-response:
+ post:
+ tags:
+ - Consent
+ summary: handle consent search required extension to fetch additional data
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EnrichConsentSearchRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForConsentSearch'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /populate-consent-authorize-screen:
+ post:
+ tags:
+ - Consent
+ summary: handle validations before consent authorization and consent data to load in consent authorization UI
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PopulateConsentAuthorizeScreenRequestBody'
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForPopulateConsentAuthorizeScreen'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Permissions are missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /persist-authorized-consent:
+ post:
+ tags:
+ - Consent
+ summary: handle consent persistence logic and enrich response with user authorization and account mapping data
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PersistAuthorizedConsentRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Successful response
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForPersistAuthorizedConsent'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Bad Request
+ errorDescription: Request does not comply with the schema
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: Internal server error
+ errorDescription: Error occurred while handling the request
+ /validate-consent-access:
+ post:
+ tags:
+ - Consent
+ summary: handle custom consent data validations before data access
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ValidateConsentAccessRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 401
+ data:
+ errorMessage: invalid_permissions
+ errorDescription: "The requested permissions are invalid, unknown"
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: invalid_request
+ errorDescription: Permissions are missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /issue-refresh-token:
+ post:
+ tags:
+ - Token
+ summary: Handles refresh token issuance and validations
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/IssueRefreshTokenRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Successful response
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForIssueRefreshToken'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Permissions are missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /validate-authorization-request:
+ post:
+ tags:
+ - Authorize
+ summary: Handles pre-user authorization requests
+ operationId: preUserAuthorization
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ValidateAuthorizationRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Successful response
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForValidateAuthorizationRequest'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 401
+ errorMessage: invalid_permissions
+ errorDescription: "The requested permissions are invalid, unknown"
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Permissions are missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /validate-event-subscription:
+ post:
+ tags:
+ - Event Subscription
+ summary: handle event subscription validations & storing data
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EventSubscriptionRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForEventSubscriptionValidation'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ successExampleWithDetails:
+ summary: Success response With Details
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ data:
+ callbackUrl: https://test.com
+ version: "3.1"
+ eventTypes:
+ - eventType
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 400
+ data:
+ error: Invalid Request
+ errorMessage: Invalid event subscription payload
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /enrich-event-subscription-response:
+ post:
+ tags:
+ - Event Subscription
+ summary: handle post event-subscription-creation response generation
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EventSubscriptionRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForEnrichEventSubscription'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ data:
+ eventSubscriptionResponse: {}
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 400
+ data:
+ error: Invalid Request
+ errorMessage: Invalid event subscription payload
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /validate-event-creation:
+ post:
+ tags:
+ - Event Creation
+ summary: handle event creation validations & storing data
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EventCreationRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForEventValidation'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 400
+ data:
+ error: Invalid Request
+ errorMessage: Invalid event creation payload
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /validate-event-polling:
+ post:
+ tags:
+ - Event Polling
+ summary: handle event polling validations & storing data
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EventPollingRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForEventValidation'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 400
+ data:
+ error: Invalid Request
+ errorMessage: Invalid event polling payload
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ data:
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+ /enrich-event-polling-response:
+ post:
+ tags:
+ - Event Polling
+ summary: handle post event-polling response generation
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EventPollingRequestBody'
+ required: true
+ responses:
+ "200":
+ description: Ok
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Response200ForEnrichEventPolling'
+ examples:
+ successExample:
+ summary: Success response
+ value:
+ responseId: Ec1wMjmiG8
+ status: SUCCESS
+ data:
+ eventPollingResponse: {}
+ failedExample:
+ summary: Failed response
+ value:
+ status: ERROR
+ errorCode: 400
+ data:
+ error: Invalid Request
+ errorMessage: Invalid event polling payload
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: invalid_request
+ errorDescription: Data is missing
+ "500":
+ description: Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ example:
+ responseId: Ec1wMjmiG8
+ status: ERROR
+ errorMessage: server_error
+ errorDescription: Failed to process the response
+components:
+ schemas:
+ Response200ForErrorMapper:
+ type: object
+ required:
+ - responseId
+ - data
+ properties:
+ responseId:
+ type: string
+ errorCode:
+ type: integer
+ data:
+ type: object
+ description: Defines the custom error response.
+ ErrorMapperRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/ErrorMapperData'
+ ErrorMapperData:
+ type: object
+ properties:
+ error:
+ $ref: '#/components/schemas/Error'
+ description: Defines the context data related to the errors.
+ Error:
+ type: object
+ properties:
+ code:
+ type: string
+ description: Error code identifying the specific issue.
+ description:
+ type: string
+ description: Detailed description of the error.
+ operation:
+ type: string
+ description: The operation where the error occurred.
+ description: Defines an error object with details.
+ Request:
+ type: object
+ properties:
+ consentInitiationData:
+ type: object
+ description: The initiation payload used by third parties which includes detailed information on data access request.
+ requestHeaders:
+ $ref: '#/components/schemas/RequestHeaders'
+ consentResourcePath:
+ type: string
+ description: To identify requested consent type
+ RequestForEnrichConsentCreationResponse:
+ type: object
+ properties:
+ consentId:
+ type: string
+ description: To identify requested
+ consentResource:
+ $ref: '#/components/schemas/StoredDetailedConsentResourceData'
+ consentResourcePath:
+ type: string
+ description: consent resource path
+ RequestForPreProcessConsentUpdate:
+ type: object
+ properties:
+ consentUpdateData:
+ type: object
+ description: The upload payload used by third parties which includes detailed information on data access request.
+ storedConsentResource:
+ $ref: '#/components/schemas/StoredBasicConsentResourceData'
+ requestHeaders:
+ $ref: '#/components/schemas/RequestHeaders'
+ consentResourcePath:
+ type: string
+ description: To identify requested consent type
+ RequestForEnrichConsentUpdateResponse:
+ type: object
+ properties:
+ consentId:
+ type: string
+ description: To identify requested
+ consentResource:
+ $ref: '#/components/schemas/StoredBasicConsentResourceData'
+ consentResourcePath:
+ type: string
+ description: consent resource path
+ RequestForPreProcessFileUpload:
+ type: object
+ properties:
+ consentId:
+ type: string
+ description: To identify requested
+ consentResource:
+ $ref: '#/components/schemas/StoredDetailedConsentResourceData'
+ fileContent:
+ type: string
+ description: content of the uploaded file
+ consentResourcePath:
+ type: string
+ description: consent resource path
+ requestHeaders:
+ $ref: '#/components/schemas/RequestHeaders'
+ RequestForEnrichFileUploadResponse:
+ type: object
+ properties:
+ consentId:
+ type: string
+ description: To identify consent.
+ fileUploadCreatedTime:
+ type: string
+ description: Timestamp which the file was stored in the database.
+ PreProcessConsentRetrievalData:
+ type: object
+ properties:
+ consentId:
+ type: string
+ description: The consent id
+ consentResource:
+ $ref: '#/components/schemas/StoredBasicConsentResourceData'
+ requestHeaders:
+ $ref: '#/components/schemas/RequestHeaders'
+ consentResourcePath:
+ type: string
+ description: Resource url
+ ConsentSearchData:
+ type: object
+ properties:
+ searchType:
+ type: string
+ enum:
+ - BULK_SEARCH
+ - AMENDMENT_HISTORY
+ searchResult:
+ type: object
+ description: payload
+ enrichmentParams:
+ type: object
+ description: query params
+ PopulateConsentAuthorizeScreenData:
+ type: object
+ properties:
+ consentId:
+ type: string
+ example: An UUID
+ userId:
+ type: string
+ example: Username
+ requestParameters:
+ type: object
+ description: Custom object with request parameters
+ consentResource:
+ $ref: '#/components/schemas/StoredDetailedConsentResourceData'
+ ValidateConsentAccessData:
+ type: object
+ properties:
+ consentId:
+ type: string
+ description: The consent id
+ consentResource:
+ $ref: '#/components/schemas/StoredDetailedConsentResourceData'
+ dataRequestPayload:
+ type: object
+ description: The receipt used by Third parties which includes detailed information on data access request
+ SuccessResponse:
+ type: object
+ required:
+ - responseId
+ - status
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ SuccessResponseConsentRevocation:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseConsentRevocationData'
+ SuccessResponsePopulateConsentAuthorizeScreen:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponsePopulateConsentAuthorizeScreenData'
+ SuccessResponseForResponseAlternation:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseForResponseAlternationData'
+ SuccessResponseForConsentSearch:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseForConsentSearchData'
+ SuccessResponsePreProcessConsentCreation:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseWithDetailedConsentData'
+ SuccessResponsePreProcessConsentUpdate:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseWithBasicConsentData'
+ SuccessResponsePreProcessFileUpload:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponsePreProcessFileUploadData'
+ FailedResponse:
+ required:
+ - responseId
+ - data
+ - errorCode
+ - status
+ type: object
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ description: "Indicates the outcome of the request. For a failed operation, this should be set to ERROR."
+ enum:
+ - ERROR
+ errorCode:
+ type: integer
+ description: If any HTTP error code to return.
+ data:
+ type: object
+ description: :"Custom error object to response back"
+ FailedResponseInConsentAuthorize:
+ type: object
+ required:
+ - responseId
+ - data
+ - status
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ description: "Indicates the outcome of the request. For a failed operation, this should be set to ERROR."
+ enum:
+ - ERROR
+ data:
+ $ref: '#/components/schemas/FailedResponseInConsentAuthorizeData'
+ FailedResponseInConsentAuthorizeData:
+ required:
+ - errorMessage
+ type: object
+ properties:
+ errorMessage:
+ type: string
+ description: Error message to be displayed in the URL
+ newConsentStatus:
+ type: string
+ description: New consent status to be set to the consent
+ ErrorResponse:
+ required:
+ - data
+ - status
+ type: object
+ properties:
+ status:
+ type: string
+ description: "Indicates the outcome of the request. For an error operation, this should be set to ERROR."
+ enum:
+ - ERROR
+ data:
+ type: object
+ description: :"Custom error object to response back"
+ PreProcessConsentCreationRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/Request'
+ EnrichConsentCreationRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/RequestForEnrichConsentCreationResponse'
+ PreProcessConsentUpdateRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/RequestForPreProcessConsentUpdate'
+ EnrichConsentUpdateRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/RequestForEnrichConsentUpdateResponse'
+ EnrichFileUploadResponseRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/RequestForEnrichFileUploadResponse'
+ PreProcessFileUploadRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/RequestForPreProcessFileUpload'
+ PreProcessConsentRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/PreProcessConsentRetrievalData'
+ EnrichConsentSearchRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/ConsentSearchData'
+ PopulateConsentAuthorizeScreenRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/PopulateConsentAuthorizeScreenData'
+ ValidateConsentAccessRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/ValidateConsentAccessData'
+ IssueRefreshTokenRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/IssueRefreshTokenRequestData'
+ IssueRefreshTokenRequestData:
+ type: object
+ properties:
+ grantType:
+ type: string
+ example: authorization_code
+ consentCreatedTime:
+ type: integer
+ format: int64
+ consentValidityPeriod:
+ type: integer
+ format: int64
+ defaultRefreshTokenValidityPeriod:
+ type: integer
+ format: int64
+ Response200ForPreProcessConsentCreation:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponsePreProcessConsentCreation'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForPreProcessConsentUpdate:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponsePreProcessConsentUpdate'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForPreProcessFileUpload:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponsePreProcessFileUpload'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForResponseAlternation:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseForResponseAlternation'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForConsentSearch:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseForConsentSearch'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponse'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForIssueRefreshToken:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseIssueRefreshToken'
+ - $ref: '#/components/schemas/FailedResponse'
+ SuccessResponseIssueRefreshToken:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseIssueRefreshTokenData'
+ SuccessResponseIssueRefreshTokenData:
+ type: object
+ properties:
+ issueRefreshToken:
+ type: boolean
+ refreshTokenValidityPeriod:
+ type: integer
+ format: int64
+ Response200ForValidateAuthorizationRequest:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponse'
+ - $ref: '#/components/schemas/FailedResponse'
+ ValidateAuthorizationRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/ValidateAuthorizationRequestBodyData'
+ ValidateAuthorizationRequestBodyData:
+ type: object
+ properties:
+ requestObject:
+ type: object
+ description: full request object
+ Response200ForConsentRevocation:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseConsentRevocation'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForPopulateConsentAuthorizeScreen:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponsePopulateConsentAuthorizeScreen'
+ - $ref: '#/components/schemas/FailedResponseInConsentAuthorize'
+ SuccessResponseConsentRevocationData:
+ type: object
+ properties:
+ revocationStatusName:
+ type: string
+ description: Name for the revoked status
+ requireTokenRevocation:
+ type: string
+ description: Require access token to be revoked
+ SuccessResponseForResponseAlternationData:
+ type: object
+ properties:
+ responseHeaders:
+ type: object
+ description: Headers to be included in the response.
+ modifiedResponse:
+ type: object
+ description: Generated custom response body
+ SuccessResponseForConsentSearchData:
+ type: object
+ properties:
+ enrichedSearchResult:
+ type: object
+ description: Enriched search result
+ SuccessResponseWithDetailedConsentData:
+ type: object
+ properties:
+ consentResource:
+ $ref: '#/components/schemas/DetailedConsentResourceData'
+ SuccessResponseWithBasicConsentData:
+ type: object
+ properties:
+ consentResource:
+ $ref: '#/components/schemas/BasicConsentResourceData'
+ SuccessResponsePreProcessFileUploadData:
+ type: object
+ properties:
+ consentStatus:
+ type: string
+ description: "New consent status after the file upload is successful."
+ userId:
+ type: string
+ description: "Id of the user doing the file upload. Used for auditing purposes."
+ PersistAuthorizedConsentRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/PersistAuthorizedConsent'
+ PersistAuthorizedConsent:
+ type: object
+ properties:
+ consentId:
+ type: string
+ isApproved:
+ type: boolean
+ userGrantedData:
+ $ref: '#/components/schemas/UserGrantedData'
+ consentResource:
+ $ref: '#/components/schemas/StoredDetailedConsentResourceData'
+ UserGrantedData:
+ type: object
+ properties:
+ requestParameters:
+ type: object
+ authorizedResources:
+ $ref: '#/components/schemas/AuthorizedResources'
+ userId:
+ type: string
+ Response200ForPersistAuthorizedConsent:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponsePersistAuthorizedConsent'
+ - $ref: '#/components/schemas/FailedResponseInConsentAuthorize'
+ SuccessResponsePersistAuthorizedConsent:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseWithDetailedConsentData'
+ - $ref: '#/components/schemas/SuccessResponseWithDetailedConsentDataAndAmendments'
+ SuccessResponseWithDetailedConsentDataAndAmendments:
+ type: object
+ properties:
+ consentResource:
+ $ref: '#/components/schemas/DetailedConsentResourceDataWithAmendments'
+ BasicConsentResourceData:
+ type: object
+ properties:
+ type:
+ type: string
+ status:
+ type: string
+ validityTime:
+ type: integer
+ format: int64
+ recurringIndicator:
+ type: boolean
+ frequency:
+ type: integer
+ receipt:
+ type: object
+ attributes:
+ type: object
+ DetailedConsentResourceData:
+ type: object
+ properties:
+ type:
+ type: string
+ status:
+ type: string
+ validityTime:
+ type: integer
+ format: int64
+ recurringIndicator:
+ type: boolean
+ frequency:
+ type: integer
+ receipt:
+ type: object
+ attributes:
+ type: object
+ authorizations:
+ type: array
+ items:
+ $ref: '#/components/schemas/Authorization'
+ DetailedConsentResourceDataWithAmendments:
+ type: object
+ properties:
+ type:
+ type: string
+ status:
+ type: string
+ validityTime:
+ type: integer
+ format: int64
+ recurringIndicator:
+ type: boolean
+ frequency:
+ type: integer
+ receipt:
+ type: object
+ attributes:
+ type: object
+ authorizations:
+ type: array
+ items:
+ $ref: '#/components/schemas/Authorization'
+ amendments:
+ type: array
+ items:
+ $ref: '#/components/schemas/AmendedAuthorization'
+ StoredBasicConsentResourceData:
+ type: object
+ properties:
+ id:
+ type: string
+ receipt:
+ type: object
+ createdTime:
+ type: integer
+ format: int32
+ updatedTime:
+ type: integer
+ format: int32
+ clientId:
+ type: string
+ type:
+ type: string
+ status:
+ type: string
+ frequency:
+ type: integer
+ validityTime:
+ type: integer
+ format: int32
+ recurringIndicator:
+ type: boolean
+ attributes:
+ type: object
+ StoredDetailedConsentResourceData:
+ type: object
+ properties:
+ id:
+ type: string
+ receipt:
+ type: object
+ createdTime:
+ type: integer
+ format: int32
+ updatedTime:
+ type: integer
+ format: int32
+ clientId:
+ type: string
+ type:
+ type: string
+ status:
+ type: string
+ frequency:
+ type: integer
+ validityTime:
+ type: integer
+ format: int32
+ recurringIndicator:
+ type: boolean
+ attributes:
+ type: object
+ authorizations:
+ type: array
+ items:
+ $ref: '#/components/schemas/StoredAuthorization'
+ fileContent:
+ type: string
+ Authorization:
+ type: object
+ properties:
+ userId:
+ type: string
+ type:
+ type: string
+ status:
+ type: string
+ resources:
+ type: array
+ items:
+ $ref: '#/components/schemas/Resource'
+ AmendedAuthorization:
+ type: object
+ properties:
+ id:
+ type: string
+ type:
+ type: string
+ status:
+ type: string
+ resources:
+ type: array
+ items:
+ $ref: '#/components/schemas/Resource'
+ amendedResources:
+ type: array
+ items:
+ $ref: '#/components/schemas/AmendedResource'
+ StoredAuthorization:
+ type: object
+ properties:
+ id:
+ type: string
+ userId:
+ type: string
+ type:
+ type: string
+ status:
+ type: string
+ resources:
+ type: array
+ items:
+ $ref: '#/components/schemas/StoredResource'
+ Resource:
+ type: object
+ properties:
+ accountId:
+ type: string
+ permission:
+ type: string
+ status:
+ type: string
+ AmendedResource:
+ type: object
+ properties:
+ id:
+ type: string
+ permission:
+ type: string
+ status:
+ type: string
+ StoredResource:
+ type: object
+ properties:
+ id:
+ type: string
+ accountId:
+ type: string
+ permission:
+ type: string
+ status:
+ type: string
+ Response200ForClientProcess:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseClientProcess'
+ - $ref: '#/components/schemas/FailedResponseClientProcess'
+ ClientProcessRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/ClientProcessData'
+ ClientProcessData:
+ type: object
+ properties:
+ clientData:
+ type: object
+ description: Client Registration Data. Mandatory for pre-process-client-creation and pre-process-client-update.
+ softwareStatement:
+ type: object
+ description: "Parameters of the decoded SSA. Mandatory for pre-process-client-creation, pre-process-client-update and pre-process-client-retrieval."
+ existingClientData:
+ type: object
+ description: properties of the existing client application. Mandatory for pre-process-client-update.
+ description: Defines the context data related to the client registration.
+ SuccessResponseClientProcess:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseClientProcess_data'
+ SuccessResponseClientProcess_data:
+ type: object
+ properties:
+ clientData:
+ type: object
+ description: Defines the success response.
+ FailedResponseClientProcess:
+ required:
+ - data
+ - status
+ type: object
+ properties:
+ status:
+ type: string
+ description: "Indicates the outcome of the request. For a failed operation, this should be set to ERROR."
+ enum:
+ - ERROR
+ errorCode:
+ type: integer
+ description: If any HTTP error code to return.
+ data:
+ $ref: '#/components/schemas/FailedResponseClientProcess_data'
+ FailedResponseClientProcess_data:
+ type: object
+ properties:
+ error:
+ type: string
+ description: Provides the error code for error.
+ enum:
+ - invalid_client_metadata
+ - invalid_redirect_uri
+ - invalid_software_statement
+ errorDescription:
+ type: string
+ description: Offers a detailed explanation of the error.
+ EventSubscriptionRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/EventSubscriptionRequest'
+ EventSubscriptionRequest:
+ type: object
+ properties:
+ eventType:
+ type: string
+ enum:
+ - SubscriptionCreation
+ - SingleSubscriptionRetrieval
+ - BulkSubscriptionRetrieval
+ - SubscriptionRetrievalForEventTypes
+ - SubscriptionUpdate
+ - SubscriptionDelete
+ eventSubscriptionData:
+ type: object
+ description: Event Subscription Payload
+ EventCreationRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/EventCreationRequest'
+ EventCreationRequest:
+ type: object
+ properties:
+ eventData:
+ type: object
+ description: Event creation Payload
+ EventPollingRequestBody:
+ type: object
+ required:
+ - requestId
+ - data
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/EventPollingRequest'
+ EventPollingRequest:
+ type: object
+ properties:
+ eventPollingData:
+ type: object
+ description: Event polling data
+ Response200ForEventSubscriptionValidation:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponse'
+ - $ref: '#/components/schemas/SuccessResponseForEventWithDetails'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForEventValidation:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponse'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForEnrichEventSubscription:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseForEnrichEventSubscription'
+ - $ref: '#/components/schemas/FailedResponse'
+ Response200ForEnrichEventPolling:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseForEnrichEventPolling'
+ - $ref: '#/components/schemas/FailedResponse'
+ SuccessResponseForEventWithDetails:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseForEventWithDetails_data'
+ SuccessResponseForEventWithDetails_data:
+ type: object
+ properties:
+ callbackUrl:
+ type: string
+ version:
+ type: string
+ eventTypes:
+ type: array
+ items:
+ type: string
+ SuccessResponseForEnrichEventSubscription:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseForEnrichEventSubscription_data'
+ SuccessResponseForEnrichEventSubscription_data:
+ type: object
+ properties:
+ eventSubscriptionResponse:
+ type: object
+ description: Event Subscription Response
+ SuccessResponseForEnrichEventPolling:
+ type: object
+ required:
+ - responseId
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseForEnrichEventPolling_data'
+ SuccessResponseForEnrichEventPolling_data:
+ type: object
+ properties:
+ eventPollingResponse:
+ type: object
+ description: Event Polling Response
+ RequestHeaders:
+ type: object
+ description: Request headers sent by the TPP. Filtered set of headers are sent to the external service.
+ SuccessResponsePopulateConsentAuthorizeScreenData:
+ type: object
+ properties:
+ consentData:
+ type: object
+ additionalProperties: true
+ properties:
+ type:
+ type: string
+ description: The type of consent
+ basicConsentData:
+ type: object
+ description: Structured descriptive text shown on the consent page, split into sections. Each key is a section title, and its value is a list of bullet points displayed under that section.
+ additionalProperties:
+ items:
+ type: string
+ permissions:
+ type: array
+ description: List of permissions for the consent (optional)
+ items:
+ type: object
+ required:
+ - uid
+ - displayValues
+ properties:
+ uid:
+ type: string
+ description: Unique ID for the permission
+ displayValues:
+ type: array
+ description: Permission display values
+ items:
+ type: string
+ initiatedAccounts:
+ type: array
+ description: Accounts initiated with this permission
+ items:
+ $ref: '#/components/schemas/Account'
+ initiatedAccountsForConsent:
+ type: array
+ description: Initialized accounts for the overall consent (optional)
+ items:
+ $ref: '#/components/schemas/Account'
+ allowMultipleAccounts:
+ type: boolean
+ description: Indicates if multiple consumer accounts can be selected per consent / permission
+ handleAccountSelectionSeparately:
+ type: boolean
+ description: Indicates if account selection must be handled separately in the UI
+ isReauthorization:
+ type: boolean
+ description: Indicates if this is a reauthorization flow (optional)
+ consentMetadata:
+ type: object
+ description: Hidden consent metadata to be forwarded to consent persistence.
+ consumerData:
+ type: object
+ additionalProperties: true
+ description: Consumer related data fetched from the banking backend.
+ properties:
+ accounts:
+ type: array
+ description: List of all user accounts/resources selectable in the UI
+ items:
+ type: object
+ required:
+ - displayName
+ - selected
+ allOf:
+ - $ref: '#/components/schemas/Account'
+ properties:
+ selected:
+ type: boolean
+ description: Whether the account is selected by default
+ AuthorizedResources:
+ type: object
+ additionalProperties: true
+ properties:
+ approval:
+ type: boolean
+ description: Whether the user approved the consent
+ isReauthorization:
+ type: boolean
+ description: Indicates if this was a reauthorization flow (optional)
+ type:
+ type: string
+ description: Type of consent granted (e.g., 'accounts', 'payments', etc.)
+ authorizedData:
+ type: array
+ description: List of granted permissions and corresponding user-selected account data
+ items:
+ type: object
+ required:
+ - accounts
+ properties:
+ permissions:
+ type: array
+ description: Granted permissions (optional if no permissions exist)
+ items:
+ type: string
+ accounts:
+ type: array
+ description: Accounts selected for the permissions
+ items:
+ $ref: '#/components/schemas/Account'
+ metadata:
+ type: object
+ description: Consent authorization related metadata.
+ Account:
+ type: object
+ description: A user account or resource representation
+ required:
+ - displayName
+ properties:
+ displayName:
+ type: string
+ description: Account display name
+ additionalProperties: true
+
+ AppCreateProcessRequestBody:
+ type: object
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/AppCreateProcessData'
+ AppCreateProcessData:
+ type: object
+ required:
+ - appData
+ - additionalProperties
+ properties:
+ appData:
+ type: object
+ description: OAuth Application Data. Mandatory for pre-process-application-creation.
+ additionalProperties:
+ type: object
+ description: Additional properties retrieved from devportal UI. Mandatory for pre-process-application-creation.
+ description: Defines the context data related to the application registration.
+ AppUpdateProcessRequestBody:
+ type: object
+ properties:
+ requestId:
+ type: string
+ description: A unique correlation identifier
+ example: Ec1wMjmiG8
+ data:
+ $ref: '#/components/schemas/AppUpdateProcessData'
+ AppUpdateProcessData:
+ type: object
+ required:
+ - appData
+ - additionalProperties
+ - existingAppData
+ properties:
+ appData:
+ type: object
+ description: OAuth Application Data. Mandatory for pre-process-application-update.
+ additionalProperties:
+ type: object
+ description: Additional properties retrieved from devportal UI. Mandatory for pre-process-application-update.
+ existingAppData:
+ type: object
+ description: Existing OAuth Application Data. Mandatory for pre-process-application-update.
+ description: Defines the context data related to the application update.
+ Response200ForApplicationCreation:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseApplicationCreation'
+ - $ref: '#/components/schemas/FailedResponseApplicationProcess'
+ SuccessResponseApplicationCreation:
+ type: object
+ required:
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseApplicationCreation_data'
+ SuccessResponseApplicationCreation_data:
+ type: object
+ properties:
+ clientId:
+ type: string
+ description: Unique id to be stored as the clientId
+ additionalAppData:
+ type: object
+ description: Defines the additional properties to store against the application.
+ Response200ForApplicationUpdate:
+ oneOf:
+ - $ref: '#/components/schemas/SuccessResponseApplicationUpdate'
+ - $ref: '#/components/schemas/FailedResponseApplicationProcess'
+ SuccessResponseApplicationUpdate:
+ type: object
+ required:
+ - status
+ - data
+ properties:
+ responseId:
+ type: string
+ status:
+ type: string
+ enum:
+ - SUCCESS
+ data:
+ $ref: '#/components/schemas/SuccessResponseApplicationUpdate_data'
+ SuccessResponseApplicationUpdate_data:
+ type: object
+ properties:
+ additionalAppData:
+ type: object
+ description: Defines the additional properties to store against the application.
+ FailedResponseApplicationProcess:
+ required:
+ - data
+ - status
+ type: object
+ properties:
+ status:
+ type: string
+ description: "Indicates the outcome of the request. For a failed operation, this should be set to ERROR."
+ enum:
+ - ERROR
+ errorMessage:
+ $ref: '#/components/schemas/FailedResponseApplicationProcessData'
+ FailedResponseApplicationProcessData:
+ required:
+ - errorMessage
+ type: object
+ properties:
+ errorMessage:
+ type: string
+ description: Error message to be returned
+ securitySchemes:
+ BasicAuth:
+ type: http
+ scheme: basic
+ OAuth2:
+ type: oauth2
+ flows:
+ clientCredentials:
+ tokenUrl: https://example.com/oauth/token
+ scopes:
+ process: process request generate response
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.common/src/main/java/org/wso2/financial/services/accelerator/common/extension/model/ServiceExtensionTypeEnum.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.common/src/main/java/org/wso2/financial/services/accelerator/common/extension/model/ServiceExtensionTypeEnum.java
index afba501c0..98fc24ab0 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.common/src/main/java/org/wso2/financial/services/accelerator/common/extension/model/ServiceExtensionTypeEnum.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.common/src/main/java/org/wso2/financial/services/accelerator/common/extension/model/ServiceExtensionTypeEnum.java
@@ -46,7 +46,9 @@ public enum ServiceExtensionTypeEnum {
ENRICH_EVENT_POLLING_RESPONSE("enrich_event_polling_response"),
MAP_ACCELERATOR_ERROR_RESPONSE("map_accelerator_error_response"),
PRE_PROCESS_APPLICATION_CREATION("pre_process_application_creation"),
- PRE_PROCESS_APPLICATION_UPDATE("pre_process_application_update");
+ PRE_PROCESS_APPLICATION_UPDATE("pre_process_application_update"),
+ PRE_PROCESS_CONSENT_UPDATE("pre_process_consent_update"),
+ ENRICH_CONSENT_UPDATE_RESPONSE("enrich_consent_update_response");
private final String type;
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.dao/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/dao/queries/ConsentMgtCommonDBQueries.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.dao/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/dao/queries/ConsentMgtCommonDBQueries.java
index 5c9574063..2310c56d6 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.dao/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/dao/queries/ConsentMgtCommonDBQueries.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.dao/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/dao/queries/ConsentMgtCommonDBQueries.java
@@ -41,7 +41,7 @@ public String getGetConsentWithConsentAttributesPreparedStatement() {
return "SELECT FS_CONSENT.CONSENT_ID, RECEIPT, CREATED_TIME, UPDATED_TIME, CLIENT_ID, CONSENT_TYPE, " +
"CURRENT_STATUS, CONSENT_FREQUENCY, VALIDITY_TIME, RECURRING_INDICATOR, " +
- "FS_CONSENT_ATTRIBUTE.ATT_KEY, FS_CONSENT_ATTRIBUTE.ATT_VALUE FROM FS_CONSENT RIGHT JOIN " +
+ "FS_CONSENT_ATTRIBUTE.ATT_KEY, FS_CONSENT_ATTRIBUTE.ATT_VALUE FROM FS_CONSENT LEFT JOIN " +
"FS_CONSENT_ATTRIBUTE ON FS_CONSENT.CONSENT_ID = FS_CONSENT_ATTRIBUTE.CONSENT_ID WHERE FS_CONSENT" +
".CONSENT_ID = ?";
}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/ConsentExtensionUtils.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/ConsentExtensionUtils.java
index 377b00aab..a8d1fc495 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/ConsentExtensionUtils.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/ConsentExtensionUtils.java
@@ -120,6 +120,34 @@ public static JSONObject getInitiationResponse(Object responseObj, DetailedConse
return response;
}
+ /**
+ * Method to construct Initiation response.
+ *
+ * @param responseObj Response of the request
+ * @param createdConsent Consent response received from service layer
+ * @return JSONObject Initiation Response
+ */
+ public static JSONObject getInitiationResponse(Object responseObj, ConsentResource createdConsent) {
+
+ JSONObject response = (JSONObject) responseObj;
+ JSONObject dataObject = response.getJSONObject(ConsentExtensionConstants.DATA);
+ dataObject.put(ConsentExtensionConstants.CONSENT_ID, createdConsent.getConsentID());
+ dataObject.put(ConsentExtensionConstants.CREATION_DATE_TIME, convertToISO8601(createdConsent.getCreatedTime()));
+ dataObject.put(ConsentExtensionConstants.STATUS_UPDATE_DATE_TIME,
+ convertToISO8601(createdConsent.getUpdatedTime()));
+ dataObject.put(ConsentExtensionConstants.STATUS, createdConsent.getCurrentStatus());
+
+ response.remove(ConsentExtensionConstants.DATA);
+ response.put(ConsentExtensionConstants.DATA, dataObject);
+
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Initiation response constructed for consent ID: %s with status: %s",
+ createdConsent.getConsentID().replaceAll("[\r\n]", ""),
+ createdConsent.getCurrentStatus().replaceAll("[\r\n]", "")));
+ }
+ return response;
+ }
+
/**
* Method to construct Retrieval Initiation response.
*
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/ExternalAPIUtil.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/ExternalAPIUtil.java
index ace9753c3..7ed8e96db 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/ExternalAPIUtil.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/ExternalAPIUtil.java
@@ -29,6 +29,7 @@
import org.wso2.financial.services.accelerator.consent.mgt.extensions.authorize.model.ConsentPersistData;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.authorize.model.ExternalAPIPreConsentPersistRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.authorize.model.ExternalAPIPreConsentPersistResponseDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIBasicConsentResourceResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIConsentResourceResponseDTO;
import java.util.ArrayList;
@@ -439,4 +440,24 @@ private static ConsentMappingResource constructAmendedMappingResource(
return resource;
}
+ /**
+ * Combines all resolved data into a final {@link ConsentResource}.
+ *
+ * @param basicConsentResource The consent resource received from the external API pre-consent-update step.
+ * @param consentID Consent ID.
+ * @param clientID Client ID.
+ * @param createTime Consent Created timestamp.
+ * @return A fully constructed {@link ConsentResource}.
+ */
+ public static ConsentResource buildConsentResource(ExternalAPIBasicConsentResourceResponseDTO basicConsentResource,
+ String consentID, String clientID, long createTime) {
+
+ String receipt = basicConsentResource.getReceipt() != null ?
+ new JSONObject(basicConsentResource.getReceipt()).toString() : "{}";
+ return new ConsentResource(consentID, clientID, receipt, basicConsentResource.getType(),
+ basicConsentResource.getFrequency(), basicConsentResource.getValidityTime(),
+ basicConsentResource.getRecurringIndicator(), basicConsentResource.getStatus(),
+ createTime, 0);
+ }
+
}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/model/ExternalAPIBasicConsentResourceRequestDTO.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/model/ExternalAPIBasicConsentResourceRequestDTO.java
new file mode 100644
index 000000000..099a0a8a6
--- /dev/null
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/model/ExternalAPIBasicConsentResourceRequestDTO.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model;
+
+import org.json.JSONObject;
+import org.wso2.financial.services.accelerator.consent.mgt.dao.models.ConsentResource;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Basic Consent resource model for the API extension consent management.
+ */
+public class ExternalAPIBasicConsentResourceRequestDTO {
+
+ private String id;
+ private String clientId;
+ private String type;
+ private String status;
+ private int frequency;
+ private long validityTime;
+ private long createdTime;
+ private long updatedTime;
+ private boolean recurringIndicator;
+ private Map receipt;
+ private Map attributes;
+
+ public ExternalAPIBasicConsentResourceRequestDTO(ConsentResource consentResource) {
+
+ this.id = consentResource.getConsentID();
+ this.clientId = consentResource.getClientID();
+ this.type = consentResource.getConsentType();
+ this.status = consentResource.getCurrentStatus();
+ this.frequency = consentResource.getConsentFrequency();
+ this.validityTime = consentResource.getValidityPeriod();
+ this.createdTime = consentResource.getCreatedTime();
+ this.updatedTime = consentResource.getUpdatedTime();
+ this.recurringIndicator = consentResource.isRecurringIndicator();
+
+ if (consentResource.getReceipt() != null && !consentResource.getReceipt().isEmpty()) {
+ JSONObject receiptJson = new JSONObject(consentResource.getReceipt());
+ this.receipt = receiptJson.toMap();
+ } else {
+ this.receipt = Collections.emptyMap();
+ }
+ this.attributes = consentResource.getConsentAttributes();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getClientId() {
+ return clientId;
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public int getFrequency() {
+ return frequency;
+ }
+
+ public void setFrequency(int frequency) {
+ this.frequency = frequency;
+ }
+
+ public long getValidityTime() {
+ return validityTime;
+ }
+
+ public void setValidityTime(long validityTime) {
+ this.validityTime = validityTime;
+ }
+
+ public long getCreatedTime() {
+ return createdTime;
+ }
+
+ public void setCreatedTime(long createdTime) {
+ this.createdTime = createdTime;
+ }
+
+ public long getUpdatedTime() {
+ return updatedTime;
+ }
+
+ public void setUpdatedTime(long updatedTime) {
+ this.updatedTime = updatedTime;
+ }
+
+ public boolean getRecurringIndicator() {
+ return recurringIndicator;
+ }
+
+ public void setRecurringIndicator(boolean recurringIndicator) {
+ this.recurringIndicator = recurringIndicator;
+ }
+
+ public Map getReceipt() {
+ return receipt;
+ }
+
+ public void setReceipt(Map receipt) {
+ this.receipt = receipt;
+ }
+
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map attributes) {
+ this.attributes = attributes;
+ }
+}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/model/ExternalAPIBasicConsentResourceResponseDTO.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/model/ExternalAPIBasicConsentResourceResponseDTO.java
new file mode 100644
index 000000000..da839d019
--- /dev/null
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/common/model/ExternalAPIBasicConsentResourceResponseDTO.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model;
+
+import java.util.Map;
+
+/**
+ * Basic Consent resource response model for the API extension consent management.
+ */
+public class ExternalAPIBasicConsentResourceResponseDTO {
+
+ private String type;
+ private String status;
+ private Integer frequency;
+ private Long validityTime;
+ private Boolean recurringIndicator;
+ private Map receipt;
+ private Map attributes;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public Integer getFrequency() {
+ return frequency;
+ }
+
+ public void setFrequency(Integer frequency) {
+ this.frequency = frequency;
+ }
+
+ public Long getValidityTime() {
+ return validityTime;
+ }
+
+ public void setValidityTime(Long validityTime) {
+ this.validityTime = validityTime;
+ }
+
+ public Boolean getRecurringIndicator() {
+ return recurringIndicator;
+ }
+
+ public void setRecurringIndicator(Boolean recurringIndicator) {
+ this.recurringIndicator = recurringIndicator;
+ }
+
+ public Map getReceipt() {
+ return receipt;
+ }
+
+ public void setReceipt(Map receipt) {
+ this.receipt = receipt;
+ }
+
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map attributes) {
+ this.attributes = attributes;
+ }
+}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/impl/DefaultConsentManageHandler.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/impl/DefaultConsentManageHandler.java
index b7ba55933..8631cbcda 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/impl/DefaultConsentManageHandler.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/impl/DefaultConsentManageHandler.java
@@ -38,10 +38,13 @@
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.ExternalAPIUtil;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.ResponseStatus;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.idempotency.IdempotencyValidator;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIBasicConsentResourceRequestDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIBasicConsentResourceResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIConsentResourceRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIConsentResourceResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.internal.ConsentExtensionsDataHolder;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.ConsentManageHandler;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ConsentManageAuthorizationUpdateDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ConsentManageData;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ConsentPayloadValidationResult;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIConsentRetrieveRequestDTO;
@@ -49,9 +52,12 @@
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIConsentRevokeResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIModifiedResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostConsentGenerateRequestDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostConsentUpdateRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostFileUploadRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentGenerateRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentGenerateResponseDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentUpdateRequestDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentUpdateResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreFileUploadRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreFileUploadResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.utils.ConsentManageConstants;
@@ -79,6 +85,8 @@ public class DefaultConsentManageHandler implements ConsentManageHandler {
boolean isExternalPreFileUploadEnabled;
boolean isExternalPostFileUploadEnabled;
boolean isExternalPreFileRetrievalEnabled;
+ boolean isExternalPreConsentUpdateEnabled;
+ boolean isExternalPostConsentUpdateEnabled;
String idempotencyHeaderName;
IdempotencyValidator idempotencyValidator;
@@ -101,6 +109,10 @@ public DefaultConsentManageHandler() {
.contains(ServiceExtensionTypeEnum.ENRICH_CONSENT_FILE_RESPONSE);
isExternalPreFileRetrievalEnabled = configParser.getServiceExtensionTypes()
.contains(ServiceExtensionTypeEnum.VALIDATE_CONSENT_FILE_RETRIEVAL);
+ isExternalPreConsentUpdateEnabled = configParser.getServiceExtensionTypes()
+ .contains(ServiceExtensionTypeEnum.PRE_PROCESS_CONSENT_UPDATE);
+ isExternalPostConsentUpdateEnabled = configParser.getServiceExtensionTypes()
+ .contains(ServiceExtensionTypeEnum.ENRICH_CONSENT_UPDATE_RESPONSE);
idempotencyHeaderName = configParser.getIdempotencyHeaderName();
idempotencyValidator = new IdempotencyValidator();
}
@@ -149,16 +161,28 @@ public void handleGet(ConsentManageData consentManageData) throws ConsentExcepti
ConsentOperationEnum.CONSENT_RETRIEVE);
try {
+
+ if (ConsentManageUtils.isInternalConsentRequest(consentManageData)) {
+ // Allowing consent retrieval for internal purpose. Retrieving the detailed consent and response back
+ // for internal consent retrieval requests
+ log.info(String.format("Processing internal consent retrieval request for consentId: %s",
+ consentId.replaceAll("[\r\n]+", " ")));
+ DetailedConsentResource detailedConsentResource = consentCoreService.getDetailedConsent(consentId);
+ consentManageData.setResponsePayload(new JSONObject(detailedConsentResource));
+ consentManageData.setResponseStatus(ResponseStatus.OK);
+ return;
+ }
+
ConsentResource consent = consentCoreService.getConsent(consentId, false);
if (consent == null) {
- log.error("Consent not found");
+ log.error(String.format("Consent not found for consent ID: %s", consentId.replaceAll("[\r\n]+", " ")));
throw new ConsentException(ResponseStatus.BAD_REQUEST, "Consent not found",
ConsentOperationEnum.CONSENT_RETRIEVE);
}
// Check whether the client id is matching
if (!consent.getClientID().equals(consentManageData.getClientId())) {
- log.error("Client ID mismatch");
- throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID mismatch",
+ log.error(ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR);
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR,
ConsentOperationEnum.CONSENT_RETRIEVE);
}
@@ -228,7 +252,7 @@ public void handlePost(ConsentManageData consentManageData) throws ConsentExcept
if (!FinancialServicesUtils.isValidClientId(consentManageData.getClientId())) {
log.error("Client ID does not exist in the system.");
throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID does not exist in the system.",
- ConsentOperationEnum.CONSENT_RETRIEVE);
+ ConsentOperationEnum.CONSENT_CREATE);
}
//Validate Initiation headers
@@ -352,7 +376,7 @@ public void handleDelete(ConsentManageData consentManageData) throws ConsentExce
if (!FinancialServicesUtils.isValidClientId(consentManageData.getClientId())) {
log.error("Client ID does not exist in the system.");
throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID does not exist in the system.",
- ConsentOperationEnum.CONSENT_RETRIEVE);
+ ConsentOperationEnum.CONSENT_DELETE);
}
//Validate Initiation headers
@@ -388,9 +412,9 @@ public void handleDelete(ConsentManageData consentManageData) throws ConsentExce
if (!consentResource.getClientID().equals(consentManageData.getClientId())) {
//Throwing this error in a generic manner since client will not be able to identify if consent
// exists if consent does not belong to them
- log.error(ConsentManageConstants.NO_CONSENT_FOR_CLIENT_ERROR);
- throw new ConsentException(ResponseStatus.BAD_REQUEST,
- ConsentManageConstants.NO_CONSENT_FOR_CLIENT_ERROR, ConsentOperationEnum.CONSENT_DELETE);
+ log.error(ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR);
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR,
+ ConsentOperationEnum.CONSENT_DELETE);
}
if (isExtensionsEnabled && isExternalPreConsentRevocationEnabled) {
@@ -446,9 +470,134 @@ public void handleDelete(ConsentManageData consentManageData) throws ConsentExce
@Override
public void handlePut(ConsentManageData consentManageData) throws ConsentException {
- log.error("Method PUT is not supported");
- throw new ConsentException(ResponseStatus.METHOD_NOT_ALLOWED, "Method PUT is not supported",
+ if (consentManageData.getHeaders().containsKey(ConsentExtensionConstants.INTERACTION_ID_HEADER)) {
+ consentManageData.setResponseHeader(ConsentExtensionConstants.INTERACTION_ID_HEADER,
+ consentManageData.getHeaders().get(ConsentExtensionConstants.INTERACTION_ID_HEADER));
+ } else {
+ consentManageData.setResponseHeader(ConsentExtensionConstants.INTERACTION_ID_HEADER,
+ UUID.randomUUID().toString());
+ }
+
+ //Check whether client ID exists
+ if (StringUtils.isEmpty(consentManageData.getClientId())) {
+ log.error("Client ID missing in the request.");
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID missing in the request.",
+ ConsentOperationEnum.CONSENT_UPDATE);
+ }
+
+ //Check whether client ID is valid
+ if (!FinancialServicesUtils.isValidClientId(consentManageData.getClientId())) {
+ log.error("Client ID does not exist in the system.");
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID does not exist in the system.",
+ ConsentOperationEnum.CONSENT_UPDATE);
+ }
+
+ if (consentManageData.getRequestPath() == null) {
+ log.error("Resource Path Not Found");
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, "Resource Path Not Found",
+ ConsentOperationEnum.CONSENT_UPDATE);
+ }
+
+ String consentId = ConsentManageUtils.extractConsentIdFromPath(consentManageData.getRequestPath(),
ConsentOperationEnum.CONSENT_UPDATE);
+
+ try {
+
+ // Allowing the developers to use /consent/{ConsentId}/authorisations/{authId} endpoint with
+ // wso2 internal header to update authorisation resources for a particular authorisation ID
+ if (ConsentManageUtils.isInternalConsentRequest(consentManageData) &&
+ consentManageData.getRequestPath().contains("authorisations")) {
+ // Allowing consent update for internal purpose.
+ ConsentManageAuthorizationUpdateDTO updatedAuthResource = ConsentManageUtils
+ .updateConsentAuthResource(consentManageData, consentId, consentCoreService);
+ consentManageData.setResponsePayload(new JSONObject(updatedAuthResource));
+ consentManageData.setResponseStatus(ResponseStatus.OK);
+ return;
+ }
+
+ ConsentResource storedConsentResource = consentCoreService.getConsent(consentId, true);
+
+ if (storedConsentResource == null) {
+ log.error("Consent not found");
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, "Consent not found",
+ ConsentOperationEnum.CONSENT_UPDATE);
+ }
+
+ if (!storedConsentResource.getClientID().equals(consentManageData.getClientId())) {
+ //Throwing this error in a generic manner since client will not be able to identify if consent
+ // exists if consent does not belong to them
+ log.error(ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR);
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR,
+ ConsentOperationEnum.CONSENT_UPDATE);
+ }
+
+ ConsentResource updatedConsent;
+ if (isExtensionsEnabled && isExternalPreConsentUpdateEnabled) {
+ // Call external service before updating consent
+ ExternalAPIBasicConsentResourceRequestDTO externalAPIConsentResource =
+ new ExternalAPIBasicConsentResourceRequestDTO(storedConsentResource);
+ ExternalAPIPreConsentUpdateRequestDTO preRequestDTO =
+ new ExternalAPIPreConsentUpdateRequestDTO(consentManageData, externalAPIConsentResource);
+ ExternalAPIPreConsentUpdateResponseDTO preResponseDTO = ExternalAPIConsentManageUtils.
+ callExternalService(preRequestDTO);
+ updatedConsent = constructUpdatingConsent(preResponseDTO, storedConsentResource);
+ } else {
+ String consentType = ConsentManageUtils.getConsentManageValidator().getConsentType(consentManageData);
+ //Validate Initiation request
+ ConsentPayloadValidationResult validationResponse = ConsentManageUtils.getConsentManageValidator()
+ .validateRequestPayload(consentManageData, consentType);
+ if (!validationResponse.isValid()) {
+ log.error(validationResponse.getErrorMessage().replaceAll("[\r\n]+", " "));
+ throw new ConsentException(validationResponse.getHttpCode(), validationResponse.getErrorCode(),
+ validationResponse.getErrorMessage());
+ }
+
+ ConsentResource updatingConsent = new ConsentResource(consentManageData.getClientId(),
+ consentManageData.getPayload().toString(), storedConsentResource.getConsentType(),
+ storedConsentResource.getCurrentStatus());
+ updatingConsent.setConsentID(consentId);
+ updatingConsent.setValidityPeriod(ConsentManageUtils.getValidityTime(consentManageData.getPayload(),
+ consentType));
+
+ updatedConsent = consentCoreService.updateConsent(updatingConsent);
+ }
+
+ if (isExtensionsEnabled && isExternalPostConsentUpdateEnabled) {
+ // Call external service after generating consent
+ ConsentResource createdConsentResource = consentCoreService.getConsent(
+ updatedConsent.getConsentID(), true);
+ ExternalAPIBasicConsentResourceRequestDTO externalAPIConsentResource =
+ new ExternalAPIBasicConsentResourceRequestDTO(createdConsentResource);
+ ExternalAPIPostConsentUpdateRequestDTO postRequestDTO = new ExternalAPIPostConsentUpdateRequestDTO(
+ externalAPIConsentResource, consentManageData.getRequestPath());
+ ExternalAPIModifiedResponseDTO postResponseDTO = ExternalAPIConsentManageUtils.
+ callExternalService(postRequestDTO);
+
+ if (postResponseDTO.getModifiedResponse() != null) {
+ consentManageData.setResponsePayload(postResponseDTO.getModifiedResponse());
+ } else {
+ consentManageData.setResponsePayload(new JSONObject());
+ }
+ if (postResponseDTO.getResponseHeaders() != null) {
+ consentManageData.setResponseHeaders(postResponseDTO.getResponseHeaders());
+ } else {
+ consentManageData.setResponseHeaders(new HashMap<>());
+ }
+ } else {
+ consentManageData.setResponsePayload(ConsentExtensionUtils
+ .getInitiationResponse(consentManageData.getPayload(), updatedConsent));
+ }
+ consentManageData.setResponseStatus(ResponseStatus.OK);
+
+ } catch (ConsentManagementException e) {
+ log.error("Error Occurred while creating the consent", e);
+ throw new ConsentException(ResponseStatus.INTERNAL_SERVER_ERROR,
+ "Error Occurred while updating the consent", ConsentOperationEnum.CONSENT_UPDATE);
+ } catch (FinancialServicesException e) {
+ log.error("Error Occurred while updating the consent", e);
+ throw new ConsentException(ResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage(),
+ ConsentOperationEnum.CONSENT_UPDATE);
+ }
}
@Override
@@ -473,7 +622,7 @@ public void handleFileUploadPost(ConsentManageData consentManageData) throws Con
//Check whether client ID exists
if (StringUtils.isEmpty(consentManageData.getClientId())) {
log.error("Client ID is missing in the request.");
- throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID id missing in the request.",
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID missing in the request.",
ConsentOperationEnum.CONSENT_FILE_UPLOAD);
}
@@ -590,7 +739,7 @@ public void handleFileGet(ConsentManageData consentManageData) throws ConsentExc
//Check whether client ID exists
if (StringUtils.isEmpty(consentManageData.getClientId())) {
log.error("Client ID is missing in the request.");
- throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID id missing in the request.",
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID missing in the request.",
ConsentOperationEnum.CONSENT_FILE_RETRIEVAL);
}
@@ -619,8 +768,8 @@ public void handleFileGet(ConsentManageData consentManageData) throws ConsentExc
}
// Check whether the client id is matching
if (!consent.getClientID().equals(consentManageData.getClientId())) {
- log.error("Client ID mismatch");
- throw new ConsentException(ResponseStatus.BAD_REQUEST, "Client ID mismatch",
+ log.error(ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR);
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR,
ConsentOperationEnum.CONSENT_FILE_RETRIEVAL);
}
ConsentFile consentFile = consentCoreService.getConsentFile(consentId);
@@ -672,4 +821,28 @@ private DetailedConsentResource generateConsent(ExternalAPIPreConsentGenerateRes
}
}
+ /**
+ * Constructs the consent resource to be updated based on the response from external service and updates the consent
+ *
+ * @param responseDTO Response from external service for pre consent update call
+ * @param storedConsentResource Consent resource stored in the system before update
+ * @return Consent resource to update
+ * @throws ConsentException If error occurs while constructing the consent resource or updating the consent
+ */
+ private ConsentResource constructUpdatingConsent(ExternalAPIPreConsentUpdateResponseDTO responseDTO,
+ ConsentResource storedConsentResource) throws ConsentException {
+
+ ExternalAPIBasicConsentResourceResponseDTO externalAPIConsentResource = responseDTO.getConsentResource();
+ try {
+ ConsentResource consentResource = ExternalAPIUtil.buildConsentResource(
+ externalAPIConsentResource, storedConsentResource.getConsentID(),
+ storedConsentResource.getClientID(), storedConsentResource.getCreatedTime());
+ return consentCoreService.updateConsent(consentResource);
+ } catch (ConsentManagementException e) {
+ log.error("Error persisting consent", e);
+ throw new ConsentException(ResponseStatus.INTERNAL_SERVER_ERROR, "Error persisting consent",
+ ConsentOperationEnum.CONSENT_UPDATE);
+ }
+ }
+
}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ConsentManageAuthorizationUpdateDTO.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ConsentManageAuthorizationUpdateDTO.java
new file mode 100644
index 000000000..70afbce60
--- /dev/null
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ConsentManageAuthorizationUpdateDTO.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model;
+
+import java.util.List;
+
+/**
+ * DTO for consent authorization update in consent management.
+ */
+public class ConsentManageAuthorizationUpdateDTO {
+
+ private String authorizationID;
+ private String consentID;
+ private String userID;
+ private String authorizationStatus;
+ private String authorizationType;
+ private long updatedTime;
+ List mappingResources;
+
+ public ConsentManageAuthorizationUpdateDTO() {
+
+ }
+
+ public ConsentManageAuthorizationUpdateDTO(String consentID, String userID, String authorizationStatus,
+ String authorizationType, long updatedTime) {
+ this.consentID = consentID;
+ this.userID = userID;
+ this.authorizationStatus = authorizationStatus;
+ this.authorizationType = authorizationType;
+ this.updatedTime = updatedTime;
+
+ }
+ public String getAuthorizationID() {
+
+ return authorizationID;
+ }
+
+ public String getAuthorizationType() {
+
+ return authorizationType;
+ }
+
+ public void setAuthorizationType(String authorizationType) {
+
+ this.authorizationType = authorizationType;
+ }
+
+ public void setAuthorizationID(String authorizationID) {
+
+ this.authorizationID = authorizationID;
+ }
+
+ public String getConsentID() {
+
+ return consentID;
+ }
+
+ public void setConsentID(String consentID) {
+
+ this.consentID = consentID;
+ }
+
+ public String getUserID() {
+
+ return userID;
+ }
+
+ public void setUserID(String userID) {
+
+ this.userID = userID;
+ }
+
+ public String getAuthorizationStatus() {
+
+ return authorizationStatus;
+ }
+
+ public void setAuthorizationStatus(String authorizationStatus) {
+
+ this.authorizationStatus = authorizationStatus;
+ }
+
+ public long getUpdatedTime() {
+
+ return updatedTime;
+ }
+
+ public void setUpdatedTime(long updatedTime) {
+
+ this.updatedTime = updatedTime;
+ }
+
+ public List getMappingResources() {
+
+ return mappingResources;
+ }
+
+ public void setMappingResources(List mappingResources) {
+
+ this.mappingResources = mappingResources;
+ }
+
+ /**
+ * Mapping resource class to hold the mapping information related to the authorization.
+ */
+ public static class MappingResource {
+
+ private String mappingID;
+ private String authorizationID;
+ private String accountID;
+ private String permission;
+ private String mappingStatus;
+
+ public MappingResource() {
+
+ }
+
+ public MappingResource(String authorizationID, String accountID, String permission,
+ String mappingStatus) {
+ this.authorizationID = authorizationID;
+ this.accountID = accountID;
+ this.permission = permission;
+ this.mappingStatus = mappingStatus;
+ }
+
+ public String getMappingID() {
+
+ return mappingID;
+ }
+
+ public void setMappingID(String mappingID) {
+
+ this.mappingID = mappingID;
+ }
+
+ public String getAuthorizationID() {
+
+ return authorizationID;
+ }
+
+ public void setAuthorizationID(String authorizationID) {
+
+ this.authorizationID = authorizationID;
+ }
+
+ public String getAccountID() {
+
+ return accountID;
+ }
+
+ public void setAccountID(String accountID) {
+
+ this.accountID = accountID;
+ }
+
+ public String getPermission() {
+
+ return permission;
+ }
+
+ public void setPermission(String permission) {
+
+ this.permission = permission;
+ }
+
+ public String getMappingStatus() {
+
+ return mappingStatus;
+ }
+
+ public void setMappingStatus(String mappingStatus) {
+
+ this.mappingStatus = mappingStatus;
+ }
+ }
+
+}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPostConsentUpdateRequestDTO.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPostConsentUpdateRequestDTO.java
new file mode 100644
index 000000000..69a7466fe
--- /dev/null
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPostConsentUpdateRequestDTO.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model;
+
+import org.json.JSONObject;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIBasicConsentResourceRequestDTO;
+
+/**
+ * ExternalAPIPostConsentUpdateRequestDTO.
+ */
+public class ExternalAPIPostConsentUpdateRequestDTO {
+
+ private String consentId;
+ private ExternalAPIBasicConsentResourceRequestDTO consentResource;
+ private String consentResourcePath;
+
+
+ public ExternalAPIPostConsentUpdateRequestDTO(ExternalAPIBasicConsentResourceRequestDTO consentResource,
+ String resourcePath) {
+
+ this.consentId = consentResource.getId();
+ this.consentResource = consentResource;
+ this.consentResourcePath = resourcePath;
+
+ }
+
+ public String getConsentId() {
+ return consentId;
+ }
+
+ public void setConsentId(String consentId) {
+ this.consentId = consentId;
+ }
+
+ public ExternalAPIBasicConsentResourceRequestDTO getConsentResource() {
+ return consentResource;
+ }
+
+ public void setConsentResource(ExternalAPIBasicConsentResourceRequestDTO consentResource) {
+ this.consentResource = consentResource;
+ }
+
+ public String getConsentResourcePath() {
+ return consentResourcePath;
+ }
+
+ public void setConsentResourcePath(String consentResourcePath) {
+ this.consentResourcePath = consentResourcePath;
+ }
+
+ /**
+ * Convert the dto to a JSON object with correct consent resource format.
+ *
+ * @return JSON object
+ */
+ public JSONObject toJson() {
+
+ JSONObject dtoJson = new JSONObject(this);
+ JSONObject consentResourceJson = new JSONObject(consentResource);
+ dtoJson.put("consentResource", consentResourceJson);
+ return dtoJson;
+ }
+}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPreConsentUpdateRequestDTO.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPreConsentUpdateRequestDTO.java
new file mode 100644
index 000000000..2383d6a23
--- /dev/null
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPreConsentUpdateRequestDTO.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model;
+
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIBasicConsentResourceRequestDTO;
+
+import java.util.Map;
+
+/**
+ * ExternalAPIPreConsentUpdateRequestDTO.
+ */
+public class ExternalAPIPreConsentUpdateRequestDTO {
+
+ //Payload can either be a JSONObject or a JSONArray
+ private ExternalAPIBasicConsentResourceRequestDTO consentResource;
+ private Object consentUpdateData;
+ private String consentResourcePath;
+ private Map requestHeaders;
+
+ public ExternalAPIPreConsentUpdateRequestDTO(ConsentManageData consentManageData,
+ ExternalAPIBasicConsentResourceRequestDTO consentResource) {
+
+ this.consentResource = consentResource;
+ this.consentUpdateData = consentManageData.getPayload();
+ this.consentResourcePath = consentManageData.getRequestPath();
+ this.requestHeaders = consentManageData.getAllowedExtensionHeaders();
+ }
+
+ public ExternalAPIBasicConsentResourceRequestDTO getConsentResource() {
+ return consentResource;
+ }
+
+ public void setConsentResource(ExternalAPIBasicConsentResourceRequestDTO consentResource) {
+ this.consentResource = consentResource;
+ }
+
+ public Object getConsentUpdateData() {
+ return consentUpdateData;
+ }
+
+ public void setConsentUpdateData(Object consentUpdateData) {
+ this.consentUpdateData = consentUpdateData;
+ }
+
+ public String getConsentResourcePath() {
+ return consentResourcePath;
+ }
+
+ public void setConsentResourcePath(String consentResourcePath) {
+ this.consentResourcePath = consentResourcePath;
+ }
+
+ public Map getRequestHeaders() {
+ return requestHeaders;
+ }
+
+ public void setRequestHeaders(Map requestHeaders) {
+ this.requestHeaders = requestHeaders;
+ }
+}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPreConsentUpdateResponseDTO.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPreConsentUpdateResponseDTO.java
new file mode 100644
index 000000000..8b1a01784
--- /dev/null
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/model/ExternalAPIPreConsentUpdateResponseDTO.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model;
+
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIBasicConsentResourceResponseDTO;
+
+/**
+ * ExternalAPIPreConsentUpdateResponseDTO.
+ */
+public class ExternalAPIPreConsentUpdateResponseDTO {
+
+ private ExternalAPIBasicConsentResourceResponseDTO consentResource;
+
+ public ExternalAPIBasicConsentResourceResponseDTO getConsentResource() {
+ return consentResource;
+ }
+
+ public void setConsentResource(ExternalAPIBasicConsentResourceResponseDTO consentResource) {
+ this.consentResource = consentResource;
+ }
+}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ConsentManageConstants.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ConsentManageConstants.java
index 83405d968..78c0179ac 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ConsentManageConstants.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ConsentManageConstants.java
@@ -25,4 +25,7 @@ public class ConsentManageConstants {
public static final String NO_CONSENT_FOR_CLIENT_ERROR = "No valid consent found for given information";
public static final String CONSENT_TYPE_MISMATCH_ERROR = "Consent Type mismatch";
+ public static final String INTERNAL_API_REQUEST_HEADER = "x-wso2-internal-request";
+ public static final String CLIENT_ID_MISMATCH_ERROR = "Client Id in the request does not match with the client Id" +
+ " associated to the consent";
}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ConsentManageUtils.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ConsentManageUtils.java
index 18a41c3f0..6ab112324 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ConsentManageUtils.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ConsentManageUtils.java
@@ -18,11 +18,19 @@
package org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.utils;
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import org.wso2.financial.services.accelerator.common.config.FinancialServicesConfigParser;
import org.wso2.financial.services.accelerator.common.constant.FinancialServicesConstants;
+import org.wso2.financial.services.accelerator.common.exception.ConsentManagementException;
+import org.wso2.financial.services.accelerator.consent.mgt.dao.models.AuthorizationResource;
+import org.wso2.financial.services.accelerator.consent.mgt.dao.models.ConsentMappingResource;
+import org.wso2.financial.services.accelerator.consent.mgt.dao.models.DetailedConsentResource;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.ConsentException;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.ConsentExtensionConstants;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.ConsentExtensionExporter;
@@ -30,6 +38,9 @@
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.ResponseStatus;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.ConsentManageValidator;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.builder.ConsentManageBuilder;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ConsentManageAuthorizationUpdateDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ConsentManageData;
+import org.wso2.financial.services.accelerator.consent.mgt.service.ConsentCoreService;
import java.time.Instant;
import java.time.OffsetDateTime;
@@ -37,10 +48,13 @@
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
/**
* Utility class for consent manage module.
@@ -50,6 +64,7 @@ public class ConsentManageUtils {
private static final Log log = LogFactory.getLog(ConsentManageUtils.class);
private static final FinancialServicesConfigParser parser = FinancialServicesConfigParser.getInstance();
private static final Pattern UUID_PATTERN = Pattern.compile(FinancialServicesConstants.UUID_REGEX);
+ private static final Gson gson = new Gson();
public static boolean isConsentExpirationTimeValid(String expDateVal) {
@@ -283,4 +298,211 @@ public static long getValidityTime(Object payload, String consentType) {
}
}
}
+
+ /**
+ * Method to get whether the request is an internal consent API request.
+ *
+ * @param consentManageData consentManageData
+ * @return boolean whether the request is an internal consent API request
+ */
+ public static boolean isInternalConsentRequest(ConsentManageData consentManageData) {
+ Map headers = consentManageData.getHeaders();
+ if (headers != null && headers.containsKey(ConsentManageConstants.INTERNAL_API_REQUEST_HEADER)) {
+ return Boolean.parseBoolean(headers.get(ConsentManageConstants.INTERNAL_API_REQUEST_HEADER));
+ }
+ return false;
+ }
+
+ /**
+ * Method to update the authorization resource of a consent based on the auth id and
+ * consent id in the request path and return the updated authorization resource.
+ * The payload of the /consent/{ConsentId}/authorisations/{authId} API should be in the format
+ * {@link ConsentManageAuthorizationUpdateDTO}.
+ *
+ * @param consentManageData data containing the request path and headers
+ * @param consentId consent id extracted from the request path
+ * @param consentCoreService service to retrieve and update the consent and authorization resource
+ * @return updated AuthorizationResource object
+ * @throws ConsentException in case of errors in retrieving/updating the consent or authorization resource
+ */
+ public static ConsentManageAuthorizationUpdateDTO updateConsentAuthResource(
+ ConsentManageData consentManageData, String consentId, ConsentCoreService consentCoreService)
+ throws ConsentException {
+
+ log.info(String.format("Updating authorization resource for consent: %s", consentId.replaceAll("[\r\n]", "")));
+ try {
+ ConsentManageAuthorizationUpdateDTO authDetails = gson.fromJson(consentManageData.getPayload().toString(),
+ ConsentManageAuthorizationUpdateDTO.class);
+
+ // Splitting resource path /consent/{ConsentId}/authorisations/{authId} from "/authorisations/"
+ // to get the auth Id
+ String authId = extractAuthIdFromPath(consentManageData.getRequestPath());
+
+ // Creating an AuthorizationResource object with the details from the request payload and the consent id.
+ // Setting updated time as 0 since the updating time will be set in the DAO layer
+ AuthorizationResource updatingAuthResource = new AuthorizationResource(consentId, authDetails.getUserID(),
+ authDetails.getAuthorizationStatus(), authDetails.getAuthorizationType(), 0);
+ updatingAuthResource.setAuthorizationID(authId);
+
+ DetailedConsentResource detailedConsentResource = consentCoreService.getDetailedConsent(consentId);
+ if (detailedConsentResource.getAuthorizationResources().isEmpty()) {
+ log.error(String.format("No authorization resource found for consent id: %s",
+ consentId.replaceAll("[\r\n]", "")));
+ throw new ConsentException(ResponseStatus.BAD_REQUEST,
+ "No authorization resource found for consent id: " + consentId,
+ ConsentOperationEnum.CONSENT_UPDATE);
+ }
+
+ Optional matchingAuthResource = detailedConsentResource.getAuthorizationResources()
+ .stream()
+ .filter(resource -> authId.equals(resource.getAuthorizationID()))
+ .findFirst();
+
+ if (matchingAuthResource.isPresent()) {
+ // Update the authorization resource if authId is found
+ consentCoreService.updateAuthorizationResources(Collections.singletonList(updatingAuthResource));
+ consentCoreService.updateAuthorizationUser(authId, updatingAuthResource.getUserID());
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Authorization resource updated successfully for auth id: %s",
+ authId.replaceAll("[\r\n]", "")));
+ }
+ AuthorizationResource updatedAuthResource = consentCoreService.getAuthorizationResource(authId);
+ List createdMappingResources = null;
+ if (CollectionUtils.isNotEmpty(authDetails.getMappingResources())) {
+ // Deactivate the current account mappings of the authorization resource if available
+ deactivateAccountMappings(detailedConsentResource, consentCoreService, authId);
+ // Create new account mappings based on the request payload
+ createdMappingResources = createConsentMappings(authDetails.getMappingResources(),
+ consentCoreService, authId);
+ }
+ return constructUpdateResponse(updatedAuthResource, createdMappingResources);
+ } else {
+ // Throw an error if authId is not found
+ String errorMsg = String.format("No matching authorization resource found for consent id: %s and" +
+ " auth id: %s", consentId.replaceAll("[\r\n]", ""),
+ authId.replaceAll("[\r\n]", ""));
+ log.error(errorMsg);
+ throw new ConsentManagementException(errorMsg);
+ }
+ } catch (JsonSyntaxException e) {
+ log.error("Payload is not in the correct format", e);
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, "Payload is not in the correct format",
+ ConsentOperationEnum.CONSENT_UPDATE);
+ } catch (ConsentManagementException e) {
+ log.error(String.format("Error occurred while updating consent authorization resource: %s",
+ e.getMessage().replaceAll("[\r\n]", "")));
+ throw new ConsentException(ResponseStatus.BAD_REQUEST, e.getMessage(), ConsentOperationEnum.CONSENT_UPDATE);
+ }
+
+ }
+
+ /**
+ * Method to extract auth id from the request path. The request path will be in the format
+ * /consent/{ConsentId}/authorisations/{authId}.
+ *
+ * @param requestPath request path of the API request
+ * @return auth id extracted from the request path
+ * @throws ConsentManagementException in case the auth id is not found in the request path
+ */
+ private static String extractAuthIdFromPath(String requestPath) throws ConsentManagementException {
+
+ String[] pathParts = requestPath.split("/authorisations/");
+ String authId = pathParts.length > 1 ? pathParts[1] : null;
+ if (StringUtils.isBlank(authId)) {
+ log.error("Auth id is missing in the request path.");
+ throw new ConsentManagementException("Invalid request path: Auth id is missing.");
+ }
+ return authId;
+ }
+
+ /**
+ * Method to deactivate all the account mappings of a consent.
+ *
+ * @param storedResource detailed consent resource containing the account mappings to be deactivated
+ * @param consentCoreService service to call the method to deactivate the account mappings
+ * @param authId auth id for which the mappings need to be deactivated (used for logging purposes)
+ * @throws ConsentManagementException in case of errors in deactivating the account mappings
+ */
+ private static void deactivateAccountMappings(DetailedConsentResource storedResource,
+ ConsentCoreService consentCoreService, String authId)
+ throws ConsentManagementException {
+
+ ArrayList mappingIdsToDeactivate = new ArrayList<>();
+ storedResource.getConsentMappingResources().stream()
+ .filter(consentMappingResource ->
+ consentMappingResource.getAuthorizationID().equals(authId))
+ .map(ConsentMappingResource::getMappingID)
+ .forEach(mappingIdsToDeactivate::add);
+ if (CollectionUtils.isNotEmpty(mappingIdsToDeactivate)) {
+ consentCoreService.deactivateAccountMappings(mappingIdsToDeactivate);
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Authorization resource mappings deactivate successfully for auth id: %s",
+ authId.replaceAll("[\r\n]", "")));
+ }
+ return;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Authorization resource mappings not available for auth id: %s hence skipping" +
+ " deactivation", authId.replaceAll("[\r\n]", "")));
+ }
+ }
+
+ /**
+ * Method to create new account mappings for an authorization resource based on the request payload.
+ *
+ * @param authMappingResources list of resources in the request payload for which the mappings need to be created
+ * @param consentCoreService service to call the method to create the account mappings
+ * @param authId auth id for which the mappings need to be created (used for logging purposes)
+ * @return list of created ConsentMappingResource objects
+ * @throws ConsentManagementException in case of errors in creating the account mappings
+ */
+ private static List createConsentMappings(
+ List authMappingResources,
+ ConsentCoreService consentCoreService, String authId)
+ throws ConsentManagementException {
+
+ List updatingMappingResources = authMappingResources.stream()
+ .map(resource -> new ConsentMappingResource(authId, resource.getAccountID(),
+ resource.getPermission(), resource.getMappingStatus()))
+ .collect(Collectors.toList());
+ List createdMappings = consentCoreService
+ .createConsentMappingResources(updatingMappingResources);
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Authorization resource mappings created successfully for auth id: %s",
+ authId.replaceAll("[\r\n]", "")));
+ }
+ return createdMappings;
+ }
+
+ /**
+ * Method to construct the response object of the /consent/{ConsentId}/authorisations/{authId} API after updating
+ * the authorization resource and creating the account mappings based on the request payload.
+ *
+ * @param updatedAuthResource updated AuthorizationResource object
+ * @param createdMappingResources list of created ConsentMappingResource objects for the authorization resource
+ * @return ConsentManageAuthorizationUpdateDTO object to be sent in the response of the API
+ */
+ private static ConsentManageAuthorizationUpdateDTO constructUpdateResponse(
+ AuthorizationResource updatedAuthResource, List createdMappingResources) {
+
+ ConsentManageAuthorizationUpdateDTO authorization = new ConsentManageAuthorizationUpdateDTO(
+ updatedAuthResource.getConsentID(), updatedAuthResource.getUserID(),
+ updatedAuthResource.getAuthorizationStatus(), updatedAuthResource.getAuthorizationType(),
+ updatedAuthResource.getUpdatedTime());
+ authorization.setAuthorizationID(updatedAuthResource.getAuthorizationID());
+
+ if (CollectionUtils.isNotEmpty(createdMappingResources)) {
+ List resources = createdMappingResources.stream()
+ .map(mapping -> {
+ ConsentManageAuthorizationUpdateDTO.MappingResource resource =
+ new ConsentManageAuthorizationUpdateDTO.MappingResource(mapping.getAuthorizationID(),
+ mapping.getAccountID(), mapping.getPermission(), mapping.getMappingStatus());
+ resource.setMappingID(mapping.getMappingID());
+ return resource;
+ })
+ .collect(Collectors.toList());
+ authorization.setMappingResources(resources);
+ }
+ return authorization;
+ }
}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ExternalAPIConsentManageUtils.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ExternalAPIConsentManageUtils.java
index 6ccfd0254..458231a19 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ExternalAPIConsentManageUtils.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/utils/ExternalAPIConsentManageUtils.java
@@ -33,9 +33,12 @@
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIConsentRevokeResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIModifiedResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostConsentGenerateRequestDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostConsentUpdateRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostFileUploadRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentGenerateRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentGenerateResponseDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentUpdateRequestDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentUpdateResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreFileUploadRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreFileUploadResponseDTO;
@@ -168,6 +171,39 @@ public static ExternalAPIModifiedResponseDTO callExternalServiceForFileRetrieval
return gson.fromJson(responseJson.toString(), ExternalAPIModifiedResponseDTO.class);
}
+ /**
+ * Method to call external service for pre consent update.
+ *
+ * @param requestDTO - Request DTO
+ * @return - Response DTO
+ * @throws FinancialServicesException - If there is an error while calling the external service
+ */
+ public static ExternalAPIPreConsentUpdateResponseDTO callExternalService(
+ ExternalAPIPreConsentUpdateRequestDTO requestDTO) throws FinancialServicesException {
+
+ log.debug("Calling external service for pre consent update");
+ JSONObject requestJson = new JSONObject(requestDTO);
+ JSONObject responseJson = callExternalService(requestJson, ServiceExtensionTypeEnum.PRE_PROCESS_CONSENT_UPDATE);
+ return gson.fromJson(responseJson.toString(), ExternalAPIPreConsentUpdateResponseDTO.class);
+ }
+
+ /**
+ * Method to call external service for post consent update.
+ *
+ * @param requestDTO - Request DTO
+ * @return - Response DTO
+ * @throws FinancialServicesException - If there is an error while calling the external service
+ */
+ public static ExternalAPIModifiedResponseDTO callExternalService(
+ ExternalAPIPostConsentUpdateRequestDTO requestDTO) throws FinancialServicesException {
+
+ log.debug("Calling external service for post consent update");
+ JSONObject requestJson = requestDTO.toJson();
+ JSONObject responseJson = callExternalService(requestJson,
+ ServiceExtensionTypeEnum.ENRICH_CONSENT_UPDATE_RESPONSE);
+ return gson.fromJson(responseJson.toString(), ExternalAPIModifiedResponseDTO.class);
+ }
+
/**
* Method to call external service using a Json.
*
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/DefaultConsentManageHandlerTest.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/DefaultConsentManageHandlerTest.java
index 54ded133f..6e8012b89 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/DefaultConsentManageHandlerTest.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/manage/DefaultConsentManageHandlerTest.java
@@ -22,10 +22,10 @@
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
+import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.financial.services.accelerator.common.config.FinancialServicesConfigParser;
import org.wso2.financial.services.accelerator.common.constant.FinancialServicesConstants;
import org.wso2.financial.services.accelerator.common.exception.ConsentManagementException;
@@ -45,11 +45,15 @@
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIConsentRevokeResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIModifiedResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostConsentGenerateRequestDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostConsentUpdateRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPostFileUploadRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentGenerateRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentGenerateResponseDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentUpdateRequestDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentUpdateResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreFileUploadRequestDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreFileUploadResponseDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.utils.ConsentManageConstants;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.utils.ExternalAPIConsentManageUtils;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.util.DataProviders;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.util.TestConstants;
@@ -57,6 +61,7 @@
import org.wso2.financial.services.accelerator.consent.mgt.service.impl.ConsentCoreServiceImpl;
import java.lang.reflect.Field;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -76,8 +81,6 @@ public class DefaultConsentManageHandlerTest {
DefaultConsentManageHandler defaultConsentManageHandler;
DefaultConsentManageHandler externalServiceConsentManageHandler;
@Mock
- ConsentManageData consentManageDataMock;
- @Mock
ConsentCoreServiceImpl consentCoreServiceMock;
private static Map headers;
private static Map configs;
@@ -86,9 +89,8 @@ public class DefaultConsentManageHandlerTest {
private MockedStatic financialServicesUtilsMockedStatic;
@BeforeClass
- public void initTest() throws ConsentManagementException, IdentityOAuth2Exception {
+ public void initTest() throws ConsentManagementException {
- consentManageDataMock = mock(ConsentManageData.class);
consentCoreServiceMock = mock(ConsentCoreServiceImpl.class);
consentExtensionsDataHolder = mockStatic(ConsentExtensionsDataHolder.class);
configParser = mockStatic(FinancialServicesConfigParser.class);
@@ -110,6 +112,14 @@ public void initTest() throws ConsentManagementException, IdentityOAuth2Exceptio
.getConsentAttributes(anyString());
doReturn(true).when(consentCoreServiceMock).revokeConsent(anyString(), any(), any(),
anyBoolean());
+ doReturn(TestUtil.getSampleConsentResource(TestConstants.AWAITING_AUTH_STATUS)).when(consentCoreServiceMock)
+ .updateConsent(any());
+ doReturn(true).when(consentCoreServiceMock).updateAuthorizationResources(any());
+ doReturn(TestUtil.getSampleAuthorizationResource(TestConstants.SAMPLE_CONSENT_ID,
+ TestConstants.SAMPLE_AUTH_ID)).when(consentCoreServiceMock).getAuthorizationResource(any());
+ doReturn(true).when(consentCoreServiceMock).deactivateAccountMappings(any());
+ doReturn(Collections.singletonList(TestUtil.getSampleConsentMappingResource(TestConstants.SAMPLE_AUTH_ID)))
+ .when(consentCoreServiceMock).createConsentMappingResources(any());
configs = new HashMap();
configs.put(FinancialServicesConstants.MAX_INSTRUCTED_AMOUNT, "1000");
@@ -137,6 +147,8 @@ public void initTest() throws ConsentManagementException, IdentityOAuth2Exceptio
setPrivateBoolean(externalServiceConsentManageHandler, "isExternalPreFileUploadEnabled", true);
setPrivateBoolean(externalServiceConsentManageHandler, "isExternalPostFileUploadEnabled", true);
setPrivateBoolean(externalServiceConsentManageHandler, "isExternalPreFileRetrievalEnabled", true);
+ setPrivateBoolean(externalServiceConsentManageHandler, "isExternalPreConsentUpdateEnabled", true);
+ setPrivateBoolean(externalServiceConsentManageHandler, "isExternalPostConsentUpdateEnabled", true);
financialServicesUtilsMockedStatic = Mockito.mockStatic(FinancialServicesUtils.class);
financialServicesUtilsMockedStatic.when(() -> FinancialServicesUtils.isValidClientId(anyString()))
@@ -151,79 +163,117 @@ public void tearDown() {
financialServicesUtilsMockedStatic.close();
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandlePostWithoutClientId() {
- setConsentManageBuilder();
- JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
- doReturn(payload).when(consentManageDataMock).getPayload();
-
- defaultConsentManageHandler.handlePost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(null).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handlePost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Client ID missing in the request.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandlePostWithInvalidHeaders() {
- setConsentManageBuilderForErrorScenario();
- JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
- doReturn(payload).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
-
- defaultConsentManageHandler.handlePost(consentManageDataMock);
+ try {
+ setConsentManageBuilderForErrorScenario();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handlePost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid headers");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandlePostWithoutRequestPath() {
- setConsentManageBuilder();
- JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
- doReturn(payload).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
-
- defaultConsentManageHandler.handlePost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(null).when(consentManageDataMock).getRequestPath();
+
+ defaultConsentManageHandler.handlePost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Resource Path Not Found");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandlePostWithInvalidRequestPath() {
- setConsentManageBuilder();
- JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
- doReturn(payload).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(headers).when(consentManageDataMock).getHeaders();
-
- defaultConsentManageHandler.handlePost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(headers).when(consentManageDataMock).getHeaders();
+
+ defaultConsentManageHandler.handlePost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid request path found.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandlePostWithInvalidPayload() {
- setConsentManageBuilder();
- doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(TestConstants.INVALID_INITIATION_OBJECT).when(consentManageDataMock)
- .getPayload();
- defaultConsentManageHandler.handlePost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(ConsentExtensionConstants.ACCOUNT_CONSENT_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(TestConstants.INVALID_INITIATION_OBJECT).when(consentManageDataMock)
+ .getPayload();
+
+ defaultConsentManageHandler.handlePost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Payload is not in the correct format");
+ }
}
- @Test(expectedExceptions = ConsentException.class, dataProvider = "AccountInitiationDataProvider",
- dataProviderClass = DataProviders.class)
- public void testHandlePostWithInvalidInitiation(String initiation) {
+ @Test(dataProvider = "AccountInitiationDataProvider", dataProviderClass = DataProviders.class)
+ public void testHandlePostWithInvalidInitiation(String initiation, String errorMessage) {
- setConsentManageBuilder();
- JSONObject payload = new JSONObject(initiation);
- doReturn(payload).when(consentManageDataMock).getPayload();
- doReturn(ConsentExtensionConstants.ACCOUNT_CONSENT_PATH).when(consentManageDataMock)
- .getRequestPath();
-
- defaultConsentManageHandler.handlePost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(initiation);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(ConsentExtensionConstants.ACCOUNT_CONSENT_PATH).when(consentManageDataMock)
+ .getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handlePost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ errorMessage);
+ }
}
@Test
public void testHandlePostForAccounts() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
doReturn(headers).when(consentManageDataMock).getHeaders();
doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
doReturn(ConsentExtensionConstants.ACCOUNT_CONSENT_PATH).when(consentManageDataMock)
@@ -232,12 +282,18 @@ public void testHandlePostForAccounts() {
doReturn(payload).when(consentManageDataMock).getPayload();
defaultConsentManageHandler.handlePost(consentManageDataMock);
+
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.CREATED);
}
@Test
public void testHandlePostForAccountsWithExtensionEnabled() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
doReturn(payload).when(consentManageDataMock).getPayload();
doReturn(TestConstants.ACCOUNT_CONSENT_GET_PATH).when(consentManageDataMock).getRequestPath();
@@ -259,6 +315,10 @@ public void testHandlePostForAccountsWithExtensionEnabled() {
.thenReturn(postConsentGenerateResponseDTO);
externalServiceConsentManageHandler.handlePost(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.CREATED);
}
}
@@ -266,6 +326,7 @@ public void testHandlePostForAccountsWithExtensionEnabled() {
public void testHandlePostForCOF() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
doReturn(headers).when(consentManageDataMock).getHeaders();
doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
doReturn(ConsentExtensionConstants.COF_CONSENT_PATH).when(consentManageDataMock)
@@ -274,12 +335,17 @@ public void testHandlePostForCOF() {
doReturn(payload).when(consentManageDataMock).getPayload();
defaultConsentManageHandler.handlePost(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.CREATED);
}
@Test
public void testHandlePostForPayments() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
doReturn(headers).when(consentManageDataMock).getHeaders();
doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
doReturn(ConsentExtensionConstants.PAYMENT_CONSENT_PATH).when(consentManageDataMock)
@@ -288,68 +354,101 @@ public void testHandlePostForPayments() {
doReturn(payload).when(consentManageDataMock).getPayload();
defaultConsentManageHandler.handlePost(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.CREATED);
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleFilePostWithoutClientId() {
- setConsentManageBuilder();
- consentManageDataMock = mock(ConsentManageData.class);
- doReturn(TestConstants.SAMPLE_CONSENT_FILE).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.PAYMENTS_FILE_UPLOAD_PATH).when(consentManageDataMock).getRequestPath();
- defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.SAMPLE_CONSENT_FILE).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.PAYMENTS_FILE_UPLOAD_PATH).when(consentManageDataMock).getRequestPath();
+
+ defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Client ID missing in the request.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleFilePostWithoutRequestPath() {
- setConsentManageBuilder();
- consentManageDataMock = mock(ConsentManageData.class);
- doReturn(TestConstants.SAMPLE_CONSENT_FILE).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.SAMPLE_CONSENT_FILE).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Resource path not found in the request");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleFilePostWithInvalidRequestPath() {
- setConsentManageBuilder();
- consentManageDataMock = mock(ConsentManageData.class);
- doReturn(TestConstants.SAMPLE_CONSENT_FILE).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(headers).when(consentManageDataMock).getHeaders();
-
- defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.SAMPLE_CONSENT_FILE).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(headers).when(consentManageDataMock).getHeaders();
+
+ defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid Request Path. Valid consent id not found.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleFilePostWithNullPayload() {
- setConsentManageBuilder();
- consentManageDataMock = mock(ConsentManageData.class);
- doReturn(TestConstants.PAYMENTS_FILE_UPLOAD_PATH).when(consentManageDataMock).getRequestPath();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(null).when(consentManageDataMock).getPayload();
- defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.PAYMENTS_FILE_UPLOAD_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(null).when(consentManageDataMock).getPayload();
+
+ defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid file content found in the request.");
+ }
}
@Test
public void testHandlePostForFilePayments() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
doReturn(headers).when(consentManageDataMock).getHeaders();
doReturn(TestConstants.SAMPLE_CONSENT_FILE).when(consentManageDataMock).getPayload();
doReturn(TestConstants.PAYMENTS_FILE_UPLOAD_PATH).when(consentManageDataMock).getRequestPath();
doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
defaultConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
}
@Test
public void testHandlePostForFilePaymentsWithExtensionEnabled() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
doReturn(TestConstants.SAMPLE_CONSENT_FILE).when(consentManageDataMock).getPayload();
doReturn(TestConstants.PAYMENTS_FILE_UPLOAD_PATH).when(consentManageDataMock).getRequestPath();
doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
@@ -362,82 +461,147 @@ public void testHandlePostForFilePaymentsWithExtensionEnabled() {
ExternalAPIPreFileUploadRequestDTO.class))).thenReturn(preFileUploadResponseDTO);
mockedStatic.when(() -> ExternalAPIConsentManageUtils.callExternalService(any(
ExternalAPIPostFileUploadRequestDTO.class))).thenReturn(modifiedResponseDTO);
+
externalServiceConsentManageHandler.handleFileUploadPost(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
}
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleGetWithoutClientId() {
- setConsentManageBuilder();
- doReturn(null).when(consentManageDataMock).getClientId();
- defaultConsentManageHandler.handleGet(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(null).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handleGet(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Client ID missing in the request.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleGetWithInvalidHeaders() {
- setConsentManageBuilderForErrorScenario();
+ try {
+ setConsentManageBuilderForErrorScenario();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handleGet(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid headers");
+ }
+ }
- JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
- doReturn(payload).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ @Test
+ public void testHandleGetWithoutRequestPath() {
- defaultConsentManageHandler.handleGet(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(null).when(consentManageDataMock).getRequestPath();
+
+ defaultConsentManageHandler.handleGet(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Resource path not found in the request");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
- public void testHandleGetWithoutRequestPath() {
+ @Test
+ public void testHandleGetWithInvalidRequestPath() {
- setConsentManageBuilder();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(null).when(consentManageDataMock).getRequestPath();
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(headers).when(consentManageDataMock).getHeaders();
+
+ defaultConsentManageHandler.handleGet(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid Request Path. Valid consent id not found.");
+ }
+ }
- defaultConsentManageHandler.handleGet(consentManageDataMock);
+ @Test
+ public void testHandleGetWithInvalidConsentId() {
+
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.REQUEST_PATH_WITH_INVALID_CONSENT_ID).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(TestConstants.INVALID_INITIATION_OBJECT).when(consentManageDataMock)
+ .getPayload();
+
+ defaultConsentManageHandler.handleGet(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid Request Path. Valid consent id not found.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
- public void testHandleGetWithInvalidRequestPath() {
+ @Test
+ public void testHandleGetForInternalRequests() {
setConsentManageBuilder();
- JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject();
doReturn(payload).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.ACCOUNT_CONSENT_GET_PATH).when(consentManageDataMock)
+ .getRequestPath();
doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+
+ Map headers = new HashMap<>();
+ headers.put(ConsentManageConstants.INTERNAL_API_REQUEST_HEADER, "true");
doReturn(headers).when(consentManageDataMock).getHeaders();
defaultConsentManageHandler.handleGet(consentManageDataMock);
- }
-
- @Test(expectedExceptions = ConsentException.class)
- public void testHandleGetWithInvalidConsentId() {
- setConsentManageBuilder();
- doReturn(TestConstants.REQUEST_PATH_WITH_INVALID_CONSENT_ID).when(consentManageDataMock).getRequestPath();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(TestConstants.INVALID_INITIATION_OBJECT).when(consentManageDataMock)
- .getPayload();
- defaultConsentManageHandler.handleGet(consentManageDataMock);
+ Mockito.verify(consentManageDataMock).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
}
@Test
public void testHandleGet() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
JSONObject payload = new JSONObject();
doReturn(payload).when(consentManageDataMock).getPayload();
doReturn(TestConstants.ACCOUNT_CONSENT_GET_PATH).when(consentManageDataMock)
.getRequestPath();
doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(new HashMap<>()).when(consentManageDataMock).getHeaders();
defaultConsentManageHandler.handleGet(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
}
@Test
public void testHandleGetWithExtensionEnabled() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
JSONObject payload = new JSONObject();
doReturn(payload).when(consentManageDataMock).getPayload();
doReturn(TestConstants.ACCOUNT_CONSENT_GET_PATH).when(consentManageDataMock).getRequestPath();
@@ -451,31 +615,49 @@ public void testHandleGetWithExtensionEnabled() {
).thenReturn(mockResponse);
externalServiceConsentManageHandler.handleGet(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
}
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleFileGetWithoutClientId() {
- setConsentManageBuilder();
- doReturn(null).when(consentManageDataMock).getClientId();
- defaultConsentManageHandler.handleFileGet(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(null).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handleFileGet(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Client ID missing in the request.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleFileGetWithoutRequestPath() {
- setConsentManageBuilder();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(null).when(consentManageDataMock).getRequestPath();
-
- defaultConsentManageHandler.handleFileGet(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(null).when(consentManageDataMock).getRequestPath();
+
+ defaultConsentManageHandler.handleFileGet(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Resource path not found in the request");
+ }
}
@Test
public void testHandleFileGet() throws ConsentManagementException {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
JSONObject payload = new JSONObject();
doReturn(payload).when(consentManageDataMock).getPayload();
doReturn(TestConstants.ACCOUNT_CONSENT_GET_PATH).when(consentManageDataMock)
@@ -485,12 +667,17 @@ public void testHandleFileGet() throws ConsentManagementException {
.getConsentFile(anyString());
defaultConsentManageHandler.handleFileGet(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
}
@Test
public void testHandleFileGetWithExtensionEnabled() throws ConsentManagementException {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
JSONObject payload = new JSONObject();
doReturn(payload).when(consentManageDataMock).getPayload();
doReturn(TestConstants.ACCOUNT_CONSENT_GET_PATH).when(consentManageDataMock).getRequestPath();
@@ -506,66 +693,103 @@ public void testHandleFileGetWithExtensionEnabled() throws ConsentManagementExce
).thenReturn(mockResponse);
externalServiceConsentManageHandler.handleFileGet(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
}
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleDeleteWithoutClientId() {
- setConsentManageBuilder();
- doReturn(null).when(consentManageDataMock).getClientId();
- defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(null).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Client ID missing in the request.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleDeleteWithInvalidHeaders() {
- setConsentManageBuilderForErrorScenario();
- JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
- doReturn(payload).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
-
- defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ try {
+ setConsentManageBuilderForErrorScenario();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+
+ defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid headers");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleDeleteWithoutRequestPath() {
- setConsentManageBuilder();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(null).when(consentManageDataMock).getRequestPath();
-
- defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(null).when(consentManageDataMock).getRequestPath();
+
+ defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Resource Path Not Found");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleDeleteWithInvalidRequestPath() {
- setConsentManageBuilder();
- JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
- doReturn(payload).when(consentManageDataMock).getPayload();
- doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(headers).when(consentManageDataMock).getHeaders();
-
- defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(headers).when(consentManageDataMock).getHeaders();
+
+ defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid Request Path. Valid consent id not found.");
+ }
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
public void testHandleDeleteWithInvalidConsentId() {
- setConsentManageBuilder();
- doReturn(TestConstants.REQUEST_PATH_WITH_INVALID_CONSENT_ID).when(consentManageDataMock).getRequestPath();
- doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
- doReturn(TestConstants.INVALID_INITIATION_OBJECT).when(consentManageDataMock)
- .getPayload();
- defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.REQUEST_PATH_WITH_INVALID_CONSENT_ID).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(TestConstants.INVALID_INITIATION_OBJECT).when(consentManageDataMock)
+ .getPayload();
+
+ defaultConsentManageHandler.handleDelete(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid Request Path. Valid consent id not found.");
+ }
}
@Test
public void testHandleDelete() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
JSONObject payload = new JSONObject();
doReturn(payload).when(consentManageDataMock).getPayload();
doReturn(TestConstants.ACCOUNT_CONSENT_GET_PATH).when(consentManageDataMock)
@@ -573,12 +797,17 @@ public void testHandleDelete() {
doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
defaultConsentManageHandler.handleDelete(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.NO_CONTENT);
}
@Test
public void testHandleDeleteWithExtensionEnabled() {
setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
JSONObject payload = new JSONObject();
doReturn(payload).when(consentManageDataMock).getPayload();
doReturn(TestConstants.ACCOUNT_CONSENT_GET_PATH).when(consentManageDataMock).getRequestPath();
@@ -593,19 +822,224 @@ public void testHandleDeleteWithExtensionEnabled() {
).thenReturn(mockResponse);
externalServiceConsentManageHandler.handleDelete(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.NO_CONTENT);
+ }
+ }
+
+ @Test
+ public void testHandlePutWithoutClientId() {
+
+ try {
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(null).when(consentManageDataMock).getClientId();
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Client ID missing in the request.");
+ }
+ }
+
+ @Test
+ public void testHandlePutWithoutRequestPath() {
+
+ try {
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(null).when(consentManageDataMock).getRequestPath();
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Resource Path Not Found");
+ }
+ }
+
+ @Test
+ public void testHandlePutWithInvalidConsentId() {
+
+ try {
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ setConsentManageBuilder();
+ doReturn(TestConstants.INVALID_REQUEST_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(TestConstants.INVALID_INITIATION_OBJECT).when(consentManageDataMock)
+ .getPayload();
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid Request Path. Valid consent id not found.");
+ }
+ }
+
+ @Test
+ public void testHandlePutWithUnMatchingClientID() {
+
+ try {
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn("test123").when(consentManageDataMock).getClientId();
+ doReturn(TestConstants.ACCOUNT_CONSENT_UPDATE_PATH).when(consentManageDataMock).getRequestPath();
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ ConsentManageConstants.CLIENT_ID_MISMATCH_ERROR);
+ }
+ }
+
+ @Test
+ public void testHandlePutWithInvalidRequestPath() {
+
+ try {
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.AUTHORISATION_UPDATE_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(headers).when(consentManageDataMock).getHeaders();
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Invalid request path found.");
}
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
+ public void testHandlePutWithInvalidRequestPayload() {
+
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.ACCOUNT_CONSENT_UPDATE_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ doReturn(TestConstants.INVALID_INITIATION_OBJECT).when(consentManageDataMock)
+ .getPayload();
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Payload is not in the correct format");
+ }
+ }
+
+ @Test
public void testHandlePut() {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ doReturn(TestConstants.ACCOUNT_CONSENT_UPDATE_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+
defaultConsentManageHandler.handlePut(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(4)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
}
- @Test(expectedExceptions = ConsentException.class)
+ @Test
+ public void testHandlePutWithExtensionEnabled() {
+
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ JSONObject payload = new JSONObject(TestConstants.VALID_INITIATION);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(TestConstants.ACCOUNT_CONSENT_UPDATE_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+
+ try (MockedStatic mockedStatic = mockStatic(
+ ExternalAPIConsentManageUtils.class)) {
+ ExternalAPIPreConsentUpdateResponseDTO preConsentGenerateResponseDTO =
+ TestUtil.getSampleExternalAPIPreConsentUpdateResponseDTO();
+ ExternalAPIModifiedResponseDTO postConsentGenerateResponseDTO =
+ TestUtil.getSampleExternalAPIModifiedResponseDTO();
+
+ mockedStatic.when(() -> ExternalAPIConsentManageUtils.callExternalService(any(
+ ExternalAPIPreConsentUpdateRequestDTO.class))).thenReturn(preConsentGenerateResponseDTO);
+
+ mockedStatic.when(() ->
+ ExternalAPIConsentManageUtils.callExternalService(
+ any(ExternalAPIPostConsentUpdateRequestDTO.class)))
+ .thenReturn(postConsentGenerateResponseDTO);
+
+ externalServiceConsentManageHandler.handlePut(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(4)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(3)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
+ }
+ }
+
+ @Test
+ public void testHandlePutAuthorisationWithoutAuthID() {
+
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ Map internalHeaders = Map.of(ConsentManageConstants.INTERNAL_API_REQUEST_HEADER, "true");
+ doReturn(TestConstants.AUTHORISATION_UPDATE_PATH_WITHOUT_AUTH_ID).when(consentManageDataMock)
+ .getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ JSONObject payload = new JSONObject(TestConstants.CONSENT_AUTHORISATION_UPDATE_PAYLOAD);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(internalHeaders).when(consentManageDataMock).getHeaders();
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+ doReturn(headers).when(consentManageDataMock).getHeaders();
+ } catch (ConsentException e) {
+ Assert.assertTrue(e.getPayload().getJSONObject("error").getString("description")
+ .contains("Invalid request path: Auth id is missing."));
+ }
+ }
+
+ @Test
+ public void testHandlePutAuthorisationWithInvalidAuthID() {
+
+ try {
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ Map internalHeaders = Map.of(ConsentManageConstants.INTERNAL_API_REQUEST_HEADER, "true");
+ doReturn(TestConstants.AUTHORISATION_UPDATE_PATH_WITH_INVALID_AUTH_ID).when(consentManageDataMock)
+ .getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ JSONObject payload = new JSONObject(TestConstants.CONSENT_AUTHORISATION_UPDATE_PAYLOAD);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(internalHeaders).when(consentManageDataMock).getHeaders();
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+ doReturn(headers).when(consentManageDataMock).getHeaders();
+ } catch (ConsentException e) {
+ Assert.assertTrue(e.getPayload().getJSONObject("error").getString("description")
+ .contains("No matching authorization resource found for consent id"));
+ }
+ }
+
+ @Test
+ public void testHandlePutAuthorisation() {
+
+ setConsentManageBuilder();
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ Map internalHeaders = Map.of(ConsentManageConstants.INTERNAL_API_REQUEST_HEADER, "true");
+ doReturn(TestConstants.AUTHORISATION_UPDATE_PATH).when(consentManageDataMock).getRequestPath();
+ doReturn(TestConstants.SAMPLE_CLIENT_ID).when(consentManageDataMock).getClientId();
+ JSONObject payload = new JSONObject(TestConstants.CONSENT_AUTHORISATION_UPDATE_PAYLOAD);
+ doReturn(payload).when(consentManageDataMock).getPayload();
+ doReturn(internalHeaders).when(consentManageDataMock).getHeaders();
+
+ defaultConsentManageHandler.handlePut(consentManageDataMock);
+
+ Mockito.verify(consentManageDataMock, Mockito.times(4)).getRequestPath();
+ Mockito.verify(consentManageDataMock, Mockito.times(2)).getClientId();
+ Mockito.verify(consentManageDataMock).setResponseStatus(ResponseStatus.OK);
+ }
+
+ @Test
public void testHandlePatch() {
- defaultConsentManageHandler.handlePatch(consentManageDataMock);
+ try {
+ ConsentManageData consentManageDataMock = mock(ConsentManageData.class);
+ defaultConsentManageHandler.handlePatch(consentManageDataMock);
+ } catch (ConsentException e) {
+ Assert.assertEquals(e.getPayload().getJSONObject("error").getString("description"),
+ "Method PATCH is not supported");
+ }
}
private static void setConsentManageBuilder() {
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/DataProviders.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/DataProviders.java
index b8cc89d75..581e09e10 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/DataProviders.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/DataProviders.java
@@ -29,18 +29,18 @@ public class DataProviders {
Object[][] getAccountInitiationDataProvider() {
return new Object[][]{
- {"{}"},
- {INITIATION_WITHOUT_ACCOUNT_PERMISSION},
- {INITIATION_WITH_UNACCEPTABLE_PERMISSION},
- {INITIATION_WITHOUT_EXPIRATION_DATES},
- {INITIATION_NON_STRING_EXPIRATION_DATES},
- {INITIATION_WITH_INVALID_EXPIRATION_DATES},
- {INITIATION_WITH_PAST_EXPIRATION_DATES},
- {INITIATION_NON_STRING_TRANS_FROM_DATES},
- {INITIATION_WITH_INVALID_TRANS_FROM_DATES},
- {INITIATION_NON_STRING_TRANS_TO_DATES},
- {INITIATION_WITH_INVALID_TRANS_TO_DATES},
- {INITIATION_WITH_PAST_TRANS_TO_DATES}
+ {"{}", "Invalid request payload"},
+ {INITIATION_WITHOUT_ACCOUNT_PERMISSION, "Permissions are invalid"},
+ {INITIATION_WITH_UNACCEPTABLE_PERMISSION, "Permissions are invalid"},
+ {INITIATION_WITHOUT_EXPIRATION_DATES, "ExpirationDateTime is invalid"},
+ {INITIATION_NON_STRING_EXPIRATION_DATES, "ExpirationDateTime is invalid"},
+ {INITIATION_WITH_INVALID_EXPIRATION_DATES, "ExpirationDateTime is invalid"},
+ {INITIATION_WITH_PAST_EXPIRATION_DATES, "ExpirationDateTime should be a future date"},
+ {INITIATION_NON_STRING_TRANS_FROM_DATES, "TransactionFromDateTime is invalid"},
+ {INITIATION_WITH_INVALID_TRANS_FROM_DATES, "TransactionFromDateTime is invalid"},
+ {INITIATION_NON_STRING_TRANS_TO_DATES, "TransactionToDateTime is invalid"},
+ {INITIATION_WITH_INVALID_TRANS_TO_DATES, "TransactionToDateTime is invalid"},
+ {INITIATION_WITH_PAST_TRANS_TO_DATES, "TransactionToDateTime should be after TransactionFromDateTime"}
};
}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/TestConstants.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/TestConstants.java
index f5d431269..680807bc1 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/TestConstants.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/TestConstants.java
@@ -39,6 +39,7 @@ public class TestConstants {
public static final String INVALID_REQUEST_PATH = "accounts";
public static final String REQUEST_PATH_WITH_INVALID_CONSENT_ID = "accounts/1234";
public static final String ACCOUNT_CONSENT_GET_PATH = "account-access-consents/" + SAMPLE_CONSENT_ID;
+ public static final String ACCOUNT_CONSENT_UPDATE_PATH = "account-access-consents/" + SAMPLE_CONSENT_ID;
public static final String PAYMENTS_FILE_UPLOAD_PATH = "fileUpload/" + SAMPLE_CONSENT_ID;
public static final String INVALID_INITIATION_OBJECT = "Invalid Object";
public static final int SAMPLE_CONSENT_FREQUENCY = 1;
@@ -70,6 +71,12 @@ public class TestConstants {
public static final String SAMPLE_PREVIOUS_STATUS = "Received";
public static final String SAMPLE_CONSENT_FILE = "sample file content";
public static final long CREATED_TIME = Instant.now().toEpochMilli();
+ public static final String AUTHORISATION_UPDATE_PATH = "/consent/" + SAMPLE_CONSENT_ID + "/authorisations/"
+ + SAMPLE_AUTH_ID;
+ public static final String AUTHORISATION_UPDATE_PATH_WITHOUT_AUTH_ID = "/consent/" + SAMPLE_CONSENT_ID +
+ "/authorisations/";
+ public static final String AUTHORISATION_UPDATE_PATH_WITH_INVALID_AUTH_ID = "/consent/" + SAMPLE_CONSENT_ID +
+ "/authorisations/" + SAMPLE_CONSENT_ID;
public static final Map SAMPLE_CONSENT_ATTRIBUTES_MAP = new HashMap() {
{
put("x-request-id", UUID.randomUUID().toString());
@@ -617,4 +624,17 @@ public class TestConstants {
" ]\n" +
"}";
+ public static final String CONSENT_AUTHORISATION_UPDATE_PAYLOAD = "{\n" +
+ " \"userID\": \"test@wso2.com\",\n" +
+ " \"authorizationType\": \"authorisation\",\n" +
+ " \"authorizationStatus\": \"Created\",\n" +
+ " \"mappingResources\": [\n" +
+ " {\n" +
+ " \"accountID\": \"1234\",\n" +
+ " \"permission\": \"auth\",\n" +
+ " \"mappingStatus\": \"active\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }";
+
}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/TestUtil.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/TestUtil.java
index 7c542a802..b0f7995a8 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/TestUtil.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.extensions/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/extensions/util/TestUtil.java
@@ -18,6 +18,7 @@
package org.wso2.financial.services.accelerator.consent.mgt.extensions.util;
+import com.google.gson.JsonParser;
import org.wso2.financial.services.accelerator.consent.mgt.dao.models.AuthorizationResource;
import org.wso2.financial.services.accelerator.consent.mgt.dao.models.ConsentAttributes;
import org.wso2.financial.services.accelerator.consent.mgt.dao.models.ConsentFile;
@@ -26,8 +27,11 @@
import org.wso2.financial.services.accelerator.consent.mgt.dao.models.ConsentResource;
import org.wso2.financial.services.accelerator.consent.mgt.dao.models.ConsentStatusAuditRecord;
import org.wso2.financial.services.accelerator.consent.mgt.dao.models.DetailedConsentResource;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIBasicConsentResourceResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.common.model.ExternalAPIConsentResourceResponseDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIModifiedResponseDTO;
import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentGenerateResponseDTO;
+import org.wso2.financial.services.accelerator.consent.mgt.extensions.manage.model.ExternalAPIPreConsentUpdateResponseDTO;
import java.util.ArrayList;
import java.util.Collections;
@@ -257,4 +261,37 @@ public static ExternalAPIPreConsentGenerateResponseDTO getSampleExternalAPIPreCo
responseDTO.setConsentResource(resource);
return responseDTO;
}
+
+ public static ExternalAPIPreConsentUpdateResponseDTO getSampleExternalAPIPreConsentUpdateResponseDTO() {
+
+ ExternalAPIPreConsentUpdateResponseDTO responseDTO = new ExternalAPIPreConsentUpdateResponseDTO();
+
+ ExternalAPIBasicConsentResourceResponseDTO resource = new ExternalAPIBasicConsentResourceResponseDTO();
+ resource.setType("ACCOUNT");
+ resource.setStatus("AWAITING_AUTHORIZATION");
+ resource.setFrequency(3);
+ resource.setValidityTime(3600L);
+ resource.setRecurringIndicator(true);
+
+ // Sample receipt
+ Map receipt = new HashMap<>();
+ receipt.put("confirmationCode", "ABC123");
+ resource.setReceipt(receipt);
+
+ // Sample attributes
+ Map attributes = new HashMap<>();
+ attributes.put("channel", "MOBILE");
+ resource.setAttributes(attributes);
+
+ responseDTO.setConsentResource(resource);
+ return responseDTO;
+ }
+
+ public static ExternalAPIModifiedResponseDTO getSampleExternalAPIModifiedResponseDTO() {
+
+ ExternalAPIModifiedResponseDTO responseDTO = new ExternalAPIModifiedResponseDTO();
+ responseDTO.setModifiedResponse(JsonParser.parseString("{}"));
+ responseDTO.setResponseHeaders(new HashMap<>());
+ return responseDTO;
+ }
}
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/ConsentCoreService.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/ConsentCoreService.java
index 6496d28b1..bef704615 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/ConsentCoreService.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/ConsentCoreService.java
@@ -120,6 +120,17 @@ ConsentResource getConsent(String consentID, boolean withConsentAttributes)
DetailedConsentResource storeDetailedConsentResource(DetailedConsentResource detailedConsentResource)
throws ConsentManagementException;
+ /**
+ * This method is used to update an existing consent (excluding client ID and CreatedTime)
+ * based on the given consent.
+ * An audit record will be created.
+ *
+ * @param consentResource the consent resource with updated values and new associations
+ * @return the updated consent resource
+ * @throws ConsentManagementException thrown if an error occurs during the operation
+ */
+ ConsentResource updateConsent(ConsentResource consentResource) throws ConsentManagementException;
+
/**
* This method is used to update an existing consent (excluding client ID and CreatedTime) and create
* new authorization and mapping records based on the given detailed consent.
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/constants/ConsentCoreServiceConstants.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/constants/ConsentCoreServiceConstants.java
index 4a4ce7d84..9ed195c57 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/constants/ConsentCoreServiceConstants.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/constants/ConsentCoreServiceConstants.java
@@ -45,6 +45,7 @@ public class ConsentCoreServiceConstants {
public static final String USER_ACCOUNTS_BINDING_REASON = "Bind user accounts to consent";
public static final String CONSENT_REVOKE_REASON = "Revoke the consent";
public static final String CONSENT_REAUTHORIZE_REASON = "Reauthorize consent";
+ public static final String BASIC_CONSENT_UPDATE_REASON = "Update Basic consent";
public static final String CONSENT_AMEND_REASON = "Amend consent";
public static final String DEFAULT_PERMISSION_VALUE = "n/a";
public static final String ADDITIONAL_AUTHORIZATION_RESOURCES = "AdditionalAuthorizationResources";
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/impl/ConsentCoreServiceImpl.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/impl/ConsentCoreServiceImpl.java
index 1e28ca041..e471a809f 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/impl/ConsentCoreServiceImpl.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/main/java/org/wso2/financial/services/accelerator/consent/mgt/service/impl/ConsentCoreServiceImpl.java
@@ -280,6 +280,49 @@ public DetailedConsentResource storeDetailedConsentResource(DetailedConsentResou
}
}
+ @Override
+ public ConsentResource updateConsent(ConsentResource consentResource) throws ConsentManagementException {
+
+ if (consentResource == null || StringUtils.isBlank(consentResource.getConsentID())) {
+ log.error("Consent or consentId is missing");
+ throw new ConsentManagementException("Consent or consentId is missing");
+ }
+
+ Connection connection = DatabaseUtils.getDBConnection();
+ try {
+ ConsentCoreDAO consentCoreDAO = ConsentStoreInitializer.getInitializedConsentCoreDAOImpl();
+
+ try {
+ ConsentResource previousConsent = getConsent(consentResource.getConsentID(), false);
+ /* Update the base consent using updated values from ConsentResource.
+ Immutable parameters are ignored in the update (i.e. clientId, createdTime) at DAO level.*/
+ consentCoreDAO.updateConsentResource(connection, consentResource);
+
+ // Add audit record
+ HashMap consentDataMap = new HashMap<>();
+ consentDataMap.put(ConsentCoreServiceConstants.CONSENT_RESOURCE, consentResource);
+
+ ConsentCoreServiceUtil.postStateChange(connection, consentCoreDAO, consentResource.getConsentID(),
+ null, consentResource.getCurrentStatus(), previousConsent.getCurrentStatus(),
+ ConsentCoreServiceConstants.BASIC_CONSENT_UPDATE_REASON, consentResource.getClientID(),
+ consentDataMap
+ );
+
+ DatabaseUtils.commitTransaction(connection);
+ log.debug("Updated consent successfully.");
+ return consentResource;
+
+ } catch (ConsentDataInsertionException | ConsentDataUpdationException e) {
+ log.error("Error during updating consent, rolling back", e);
+ DatabaseUtils.rollbackTransaction(connection);
+ throw new ConsentManagementException("Failed to update consent and create related records", e);
+ }
+ } finally {
+ log.debug(ConsentCoreServiceConstants.DATABASE_CONNECTION_CLOSE_LOG_MSG);
+ DatabaseUtils.closeConnection(connection);
+ }
+ }
+
@Override
public DetailedConsentResource updateConsentAndCreateAuthResources(DetailedConsentResource detailedConsentResource,
String primaryUserId) throws ConsentManagementException {
diff --git a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/service/impl/ConsentMgtCoreServiceTests.java b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/service/impl/ConsentMgtCoreServiceTests.java
index 781425cea..d9d72c39a 100644
--- a/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/service/impl/ConsentMgtCoreServiceTests.java
+++ b/financial-services-accelerator/components/org.wso2.financial.services.accelerator.consent.mgt.service/src/test/java/org/wso2/financial/services/accelerator/consent/mgt/service/impl/ConsentMgtCoreServiceTests.java
@@ -536,6 +536,40 @@ public void testStoreDetailedConsentResourceWithMissingConsentID() throws Consen
consentCoreServiceImpl.storeDetailedConsentResource(detailedConsentResource);
}
+ @Test
+ public void testUpdateConsent() throws ConsentManagementException,
+ ConsentDataRetrievalException, ConsentDataUpdationException {
+
+ doReturn(ConsentMgtServiceTestData.getSampleStoredConsentResource()).when(mockedConsentCoreDAO)
+ .getConsentResource(any(), anyString());
+ doNothing().when(mockedConsentCoreDAO).updateConsentResource(any(), any());
+
+ ConsentResource result = consentCoreServiceImpl.updateConsent(
+ ConsentMgtServiceTestData.getSampleStoredConsentResource());
+ Assert.assertNotNull(result);
+ }
+
+ @Test(expectedExceptions = ConsentManagementException.class)
+ public void testUpdateConsentWithoutConsentId() throws ConsentManagementException {
+
+ ConsentResource consentResource = new ConsentResource();
+ consentResource.setConsentID(null);
+
+ consentCoreServiceImpl.updateConsent(consentResource);
+ }
+
+ @Test(expectedExceptions = ConsentManagementException.class)
+ public void testUpdateConsentWithConsentUpdateError() throws ConsentManagementException,
+ ConsentDataUpdationException, ConsentDataRetrievalException {
+
+ doReturn(ConsentMgtServiceTestData.getSampleStoredConsentResource()).when(mockedConsentCoreDAO)
+ .getConsentResource(any(), anyString());
+ doThrow(ConsentDataUpdationException.class).when(mockedConsentCoreDAO).updateConsentResource(any(), any());
+
+ ConsentResource result = consentCoreServiceImpl.updateConsent(
+ ConsentMgtServiceTestData.getSampleStoredConsentResource());
+ }
+
@Test
public void testUpdateConsentAndCreateAuthResources() throws ConsentManagementException,
ConsentDataRetrievalException, ConsentDataInsertionException {