diff --git a/app/src/main/resources/swagger/api-docs.json b/app/src/main/resources/swagger/api-docs.json index e7581b0b..2fc830bd 100644 --- a/app/src/main/resources/swagger/api-docs.json +++ b/app/src/main/resources/swagger/api-docs.json @@ -2832,6 +2832,91 @@ } ] } }, + "/v1/users/onboarding/aggregator" : { + "post" : { + "tags" : [ "user" ], + "summary" : "onboardingAggregator", + "description" : "The service allows the onboarding of Users for aggregators", + "operationId" : "onboardingAggregatorUsingPOST", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OnboardingUserDto" + } + } + } + }, + "responses" : { + "201" : { + "description" : "Created" + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "403" : { + "description" : "Forbidden", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "404" : { + "description" : "Not Found", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "409" : { + "description" : "Conflict", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + } + }, "/v1/users/validate" : { "post" : { "tags" : [ "user" ], @@ -3038,6 +3123,9 @@ "originId" : { "type" : "string" }, + "parentDescription" : { + "type" : "string" + }, "recipientCode" : { "type" : "string" }, diff --git a/connector-api/src/main/java/it/pagopa/selfcare/onboarding/connector/api/OnboardingMsConnector.java b/connector-api/src/main/java/it/pagopa/selfcare/onboarding/connector/api/OnboardingMsConnector.java index 04651176..f88352e5 100644 --- a/connector-api/src/main/java/it/pagopa/selfcare/onboarding/connector/api/OnboardingMsConnector.java +++ b/connector-api/src/main/java/it/pagopa/selfcare/onboarding/connector/api/OnboardingMsConnector.java @@ -14,6 +14,8 @@ public interface OnboardingMsConnector { void onboardingUsers(OnboardingData onboardingData); + void onboardingUsersAggregator(OnboardingData onboardingData); + void onboardingCompany(OnboardingData onboardingData); void onboardingTokenComplete(String onboardingId, MultipartFile contract); diff --git a/connector/rest/docs/openapi/api-selfcare-onboarding-docs.json b/connector/rest/docs/openapi/api-selfcare-onboarding-docs.json index 21e2b4b8..f8e247ce 100644 --- a/connector/rest/docs/openapi/api-selfcare-onboarding-docs.json +++ b/connector/rest/docs/openapi/api-selfcare-onboarding-docs.json @@ -21,6 +21,8 @@ "name" : "Onboarding Controller" }, { "name" : "billing-portal" + }, { + "name" : "internal-pnpg" }, { "name" : "internal-v1" }, { @@ -788,7 +790,7 @@ }, "/v1/onboarding/pg/completion" : { "post" : { - "tags" : [ "Onboarding Controller" ], + "tags" : [ "Onboarding Controller", "internal-pnpg" ], "summary" : "Complete PG onboarding request on PNPG domain and set status to COMPLETED.", "description" : "Perform onboarding as /onboarding/psp but completing the onboarding request to COMPLETED phase.", "operationId" : "onboardingPgCompletion", @@ -900,6 +902,44 @@ } ] } }, + "/v1/onboarding/psp/import" : { + "post" : { + "tags" : [ "Onboarding Controller" ], + "summary" : "Import PSP onboarding with token creation and complete to COMPLETED.", + "description" : "Perform onboarding as /onboarding/psp but create token and completing the onboarding request to COMPLETED phase.", + "operationId" : "onboardingPspImport", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OnboardingImportPspRequest" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OnboardingResponse" + } + } + } + }, + "401" : { + "description" : "Not Authorized" + }, + "403" : { + "description" : "Not Allowed" + } + }, + "security" : [ { + "SecurityScheme" : [ ] + } ] + } + }, "/v1/onboarding/users" : { "post" : { "tags" : [ "Onboarding Controller" ], @@ -938,6 +978,44 @@ } ] } }, + "/v1/onboarding/users/aggregator" : { + "post" : { + "tags" : [ "Onboarding Controller" ], + "summary" : "Onboard users for aggregators, save user data, and trigger async onboarding activities.", + "description" : "Perform onboarding users request, it is used for aggregators.Users data will be saved on personal data vault if it doesn't already exist.At the end, function triggers async activities related to onboarding based on institution type.", + "operationId" : "onboardingUsersAggregator", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OnboardingUserRequest" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OnboardingResponse" + } + } + } + }, + "401" : { + "description" : "Not Authorized" + }, + "403" : { + "description" : "Not Allowed" + } + }, + "security" : [ { + "SecurityScheme" : [ ] + } ] + } + }, "/v1/onboarding/users/pg" : { "post" : { "tags" : [ "Onboarding Controller" ], @@ -2269,11 +2347,10 @@ } }, "OnboardingImportContract" : { - "required" : [ "fileName", "filePath", "createdAt" ], + "required" : [ "filePath", "createdAt" ], "type" : "object", "properties" : { "fileName" : { - "minLength" : 1, "type" : "string" }, "filePath" : { @@ -2285,6 +2362,28 @@ }, "createdAt" : { "$ref" : "#/components/schemas/LocalDateTime" + }, + "activatedAt" : { + "$ref" : "#/components/schemas/LocalDateTime" + } + } + }, + "OnboardingImportPspRequest" : { + "required" : [ "institution", "productId", "contractImported" ], + "type" : "object", + "properties" : { + "institution" : { + "$ref" : "#/components/schemas/InstitutionPspRequest" + }, + "billing" : { + "$ref" : "#/components/schemas/BillingRequest" + }, + "productId" : { + "minLength" : 1, + "type" : "string" + }, + "contractImported" : { + "$ref" : "#/components/schemas/OnboardingImportContract" } } }, diff --git a/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImpl.java b/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImpl.java index a2fc1916..d9243471 100644 --- a/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImpl.java +++ b/connector/rest/src/main/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImpl.java @@ -13,7 +13,10 @@ import it.pagopa.selfcare.onboarding.connector.rest.client.MsOnboardingSupportApiClient; import it.pagopa.selfcare.onboarding.connector.rest.client.MsOnboardingTokenApiClient; import it.pagopa.selfcare.onboarding.connector.rest.mapper.OnboardingMapper; -import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.*; +import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.OnboardingGet; +import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.OnboardingResponse; +import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.OnboardingStatus; +import it.pagopa.selfcare.onboarding.generated.openapi.v1.dto.ReasonRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.Resource; import org.springframework.http.HttpStatus; @@ -88,6 +91,12 @@ public void onboardingUsers(OnboardingData onboardingData) { msOnboardingApiClient._onboardingUsers(onboardingMapper.toOnboardingUsersRequest(onboardingData)); } + @Override + @Retry(name = "retryTimeout") + public void onboardingUsersAggregator(OnboardingData onboardingData) { + msOnboardingApiClient._onboardingUsersAggregator(onboardingMapper.toOnboardingUsersRequest(onboardingData)); + } + @Override @Retry(name = "retryTimeout") diff --git a/connector/rest/src/test/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImplTest.java b/connector/rest/src/test/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImplTest.java index 4140f186..b7e172ca 100644 --- a/connector/rest/src/test/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImplTest.java +++ b/connector/rest/src/test/java/it/pagopa/selfcare/onboarding/connector/OnboardingMsConnectorImplTest.java @@ -384,6 +384,30 @@ void onboardingUsers() { verifyNoMoreInteractions(msOnboardingApiClient); } + + @Test + void onboardingUsersAggregator() { + // given + final String origin = "origin"; + final String originId = "originId"; + OnboardingData onboardingData = new OnboardingData(); + onboardingData.setOrigin(origin); + onboardingData.setOriginId(originId); + OnboardingUserRequest request = new OnboardingUserRequest(); + request.setOrigin(origin); + request.setOriginId(originId); + OnboardingResponse resource = Mockito.mock(OnboardingResponse.class); + when(msOnboardingApiClient._onboardingUsersAggregator(request)) + .thenReturn(ResponseEntity.of(Optional.of(resource))); + // when + final Executable executable = () -> onboardingMsConnector.onboardingUsersAggregator(onboardingData); + // then + assertDoesNotThrow(executable); + verify(msOnboardingApiClient, times(1)) + ._onboardingUsersAggregator(request); + verifyNoMoreInteractions(msOnboardingApiClient); + } + @Test void onboardingPaAggregation() { // given diff --git a/core/src/main/java/it/pagopa/selfcare/onboarding/core/UserService.java b/core/src/main/java/it/pagopa/selfcare/onboarding/core/UserService.java index a5a9e689..ecb02007 100644 --- a/core/src/main/java/it/pagopa/selfcare/onboarding/core/UserService.java +++ b/core/src/main/java/it/pagopa/selfcare/onboarding/core/UserService.java @@ -6,5 +6,6 @@ public interface UserService { void validate(User user); void onboardingUsers(OnboardingData onboardingData); + void onboardingUsersAggregator(OnboardingData onboardingData); boolean checkManager(OnboardingData onboardingData); } diff --git a/core/src/main/java/it/pagopa/selfcare/onboarding/core/UserServiceImpl.java b/core/src/main/java/it/pagopa/selfcare/onboarding/core/UserServiceImpl.java index 7b38ab4c..3ff65991 100644 --- a/core/src/main/java/it/pagopa/selfcare/onboarding/core/UserServiceImpl.java +++ b/core/src/main/java/it/pagopa/selfcare/onboarding/core/UserServiceImpl.java @@ -66,6 +66,14 @@ public void onboardingUsers(OnboardingData onboardingData) { log.trace("onboardingUsers end"); } + @Override + public void onboardingUsersAggregator(OnboardingData onboardingData) { + log.trace("onboardingUsersAggregator start"); + log.debug("onboardingUsersAggregator onboardingData = {}", onboardingData); + onboardingMsConnector.onboardingUsersAggregator(onboardingData); + log.trace("onboardingUsersAggregator end"); + } + @Override public boolean checkManager(OnboardingData onboardingData) { log.trace("checkManager start"); diff --git a/core/src/test/java/it/pagopa/selfcare/onboarding/core/UserServiceImplTest.java b/core/src/test/java/it/pagopa/selfcare/onboarding/core/UserServiceImplTest.java index 190f9355..c1d6482d 100644 --- a/core/src/test/java/it/pagopa/selfcare/onboarding/core/UserServiceImplTest.java +++ b/core/src/test/java/it/pagopa/selfcare/onboarding/core/UserServiceImplTest.java @@ -154,6 +154,19 @@ void onboardingUsers() { verifyNoMoreInteractions(onboardingMsConnector); } + @Test + void onboardingUsersAggregator() { + // given + OnboardingData onboardingData = new OnboardingData(); + doNothing().when(onboardingMsConnector).onboardingUsersAggregator(any()); + // when + userService.onboardingUsersAggregator(onboardingData); + // then + verify(onboardingMsConnector, times(1)) + .onboardingUsersAggregator(onboardingData); + verifyNoMoreInteractions(onboardingMsConnector); + } + @Test void checkManager() { // given diff --git a/web/src/main/java/it/pagopa/selfcare/onboarding/web/controller/UserController.java b/web/src/main/java/it/pagopa/selfcare/onboarding/web/controller/UserController.java index 69be48dc..2dadf44f 100644 --- a/web/src/main/java/it/pagopa/selfcare/onboarding/web/controller/UserController.java +++ b/web/src/main/java/it/pagopa/selfcare/onboarding/web/controller/UserController.java @@ -13,6 +13,7 @@ import it.pagopa.selfcare.onboarding.web.model.mapper.OnboardingResourceMapper; import it.pagopa.selfcare.onboarding.web.model.mapper.UserMapper; import lombok.extern.slf4j.Slf4j; +import org.owasp.encoder.Encode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -73,6 +74,23 @@ public void onboarding(@RequestBody @Valid OnboardingUserDto request) { log.trace("onboarding end"); } + + @ApiResponse(responseCode = "403", + description = "Forbidden", + content = { + @Content(mediaType = APPLICATION_PROBLEM_JSON_VALUE, + schema = @Schema(implementation = Problem.class)) + }) + @PostMapping(value = "/onboarding/aggregator") + @ResponseStatus(HttpStatus.CREATED) + @ApiOperation(value = "", notes = "${swagger.onboarding.users.api.onboarding-aggregator}") + public void onboardingAggregator(@RequestBody @Valid OnboardingUserDto request) { + log.trace("onboardingAggregator start"); + log.debug("onboardingAggregator request = {}", Encode.forJava(request.toString())); + userService.onboardingUsersAggregator(onboardingResourceMapper.toEntity(request)); + log.trace("onboardingAggregator end"); + } + @ApiResponse(responseCode = "403", description = "Forbidden", content = { diff --git a/web/src/main/resources/swagger/swagger_en.properties b/web/src/main/resources/swagger/swagger_en.properties index 1358f3d4..80af26ba 100644 --- a/web/src/main/resources/swagger/swagger_en.properties +++ b/web/src/main/resources/swagger/swagger_en.properties @@ -91,6 +91,7 @@ swagger.onboarding.model.expiringDate=Onboarding request expiring date swagger.onboarding.model.admins=Administrators specific data swagger.onboarding.user.api.validate=Check if requested user data are valid swagger.onboarding.users.api.onboarding=The service allows the onboarding of Users +swagger.onboarding.users.api.onboarding-aggregator=The service allows the onboarding of Users for aggregators swagger.onboarding.users.api.check-manager=Returns true if current manager and previous one are the same swagger.onboarding.user.model.id=User's unique identifier swagger.onboarding.user.model.surname=User's surname diff --git a/web/src/test/java/it/pagopa/selfcare/onboarding/web/controller/UserControllerTest.java b/web/src/test/java/it/pagopa/selfcare/onboarding/web/controller/UserControllerTest.java index 7d5a1bc6..1beab646 100644 --- a/web/src/test/java/it/pagopa/selfcare/onboarding/web/controller/UserControllerTest.java +++ b/web/src/test/java/it/pagopa/selfcare/onboarding/web/controller/UserControllerTest.java @@ -101,6 +101,23 @@ void onboardingUsers(@Value("classpath:stubs/onboardingUsers.json") Resource onb verifyNoMoreInteractions(userServiceMock); } + + @Test + void onboardingUsersAggregator(@Value("classpath:stubs/onboardingUsers.json") Resource onboardinUserDto) throws Exception { + // when + mvc.perform(MockMvcRequestBuilders + .post(BASE_URL + "/onboarding/aggregator") + .content(onboardinUserDto.getInputStream().readAllBytes()) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()) + .andExpect(content().string(emptyString())); + // then + verify(userServiceMock, times(1)) + .onboardingUsersAggregator(any(OnboardingData.class)); + verifyNoMoreInteractions(userServiceMock); + } + /** * Method under test: {@link UserController#checkManager(OnboardingUserDto)} */