diff --git a/src/main/java/io/kontur/disasterninja/client/UserProfileClient.java b/src/main/java/io/kontur/disasterninja/client/UserProfileClient.java index be62f6da..68a61b68 100644 --- a/src/main/java/io/kontur/disasterninja/client/UserProfileClient.java +++ b/src/main/java/io/kontur/disasterninja/client/UserProfileClient.java @@ -16,6 +16,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; import java.util.List; import java.util.UUID; @@ -30,6 +31,7 @@ public class UserProfileClient extends RestClientWithBearerAuth { private static final String FEATURES_URL = "/features"; private static final String APP_URL = "/apps"; private static final String APP_URL_WITH_ID = "/apps/{id}"; + private static final String APP_CONFIG_URL = "/apps/configuration"; private static final String DEFAULT_APP_ID_URL = "/apps/default_id"; private static final String CURRENT_USER_URL = "/users/current_user"; private final RestTemplate userProfileRestTemplate; @@ -117,6 +119,19 @@ public AppDto getApp(UUID id) { return sendAppRequest(APP_URL_WITH_ID, id, GET, null).getBody(); } + public AppDto getApp(String domain) { + UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(APP_CONFIG_URL) + .queryParam("domain", domain); + LOG.info("Requester domain: {}", domain); + ResponseEntity response = userProfileRestTemplate + .exchange(builder.build().toString(), GET, + httpEntityWithUserBearerAuthIfPresentAndNoCacheHeader(null), + new ParameterizedTypeReference<>() { + }); + + return response.getBody(); + } + public AppDto createApp(AppDto input) { return sendAppRequest(APP_URL, null, POST, input).getBody(); } diff --git a/src/main/java/io/kontur/disasterninja/controller/AppsController.java b/src/main/java/io/kontur/disasterninja/controller/AppsController.java index 6dce69f7..a0b1bc26 100644 --- a/src/main/java/io/kontur/disasterninja/controller/AppsController.java +++ b/src/main/java/io/kontur/disasterninja/controller/AppsController.java @@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.*; import javax.validation.Valid; +import java.net.URI; import java.util.List; import java.util.ListIterator; import java.util.UUID; @@ -121,18 +122,25 @@ public List getListOfLayers(@PathVariable("id") UUID appId) { array = @ArraySchema(schema = @Schema(implementation = LayerDetailsDto.class)))) @PutMapping("/{id}/layers") public List updateListOfLayers(@PathVariable("id") UUID appId, - @RequestBody List layers) { + @RequestBody List layers) { List updatedLayers = layersApiService.updateApplicationLayers(appId, layers); return updatedLayers.stream().map(LayerDetailsDto::fromLayer).toList(); } - @Operation(summary = "Get application config with features and user settings by id. Returns default app if no " + - "appId is provided", tags = {"Applications"}) + @Operation(summary = "Get application config with features and user settings by id. Returns default app if " + + "no appId is provided and requester domain is unknown", tags = {"Applications"}) @ApiResponse(responseCode = "200", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = AppDto.class))) @GetMapping(path = "/configuration") - public AppDto getAppConfig(@RequestParam(name = "appId", required = false) UUID appId) { - return applicationService.getAppConfig(appId); + public AppDto getAppConfig(@RequestParam(name = "appId", required = false) UUID appId, + @RequestHeader(name = "X-Forwarded-Host", required = false) String xForwardedHost) { + String domain = null; + try { + domain = new URI(xForwardedHost).getHost(); + } catch (Exception ignored) { + } + + return applicationService.getAppConfig(appId, domain); } } diff --git a/src/main/java/io/kontur/disasterninja/service/AnalyticsService.java b/src/main/java/io/kontur/disasterninja/service/AnalyticsService.java index 7e82a605..86cbcaea 100644 --- a/src/main/java/io/kontur/disasterninja/service/AnalyticsService.java +++ b/src/main/java/io/kontur/disasterninja/service/AnalyticsService.java @@ -101,7 +101,7 @@ private List organizeResponse(List functions, Li private List getAnalyticsConfigurationForApplication(UUID appUuid) { try { - return Arrays.asList(objectMapper.treeToValue(applicationService.getAppConfig(appUuid) + return Arrays.asList(objectMapper.treeToValue(applicationService.getAppConfig(appUuid, null) .getFeatures() .stream() .map(FeatureDto::getConfiguration) diff --git a/src/main/java/io/kontur/disasterninja/service/ApplicationService.java b/src/main/java/io/kontur/disasterninja/service/ApplicationService.java index 572640f6..adfe67fc 100644 --- a/src/main/java/io/kontur/disasterninja/service/ApplicationService.java +++ b/src/main/java/io/kontur/disasterninja/service/ApplicationService.java @@ -17,18 +17,30 @@ public class ApplicationService { private final UserProfileClient userProfileClient; - public AppDto getAppConfig(UUID appId) { - if (appId == null) { - appId = UUID.fromString(Objects.requireNonNull(userProfileClient.getDefaultAppId().getBody())); + public AppDto getAppConfig(UUID appId, String domain) { + AppDto appDto = null; + if (appId != null) { + appDto = userProfileClient.getApp(appId); + } else { + // TODO: one UPS call can be made instead of three in case requester domain is unknown. + // Corresponding UPS changes required + if (domain != null) { + appDto = userProfileClient.getApp(domain); + } + if (appDto == null) { // requester domain is unknown + appId = UUID.fromString(Objects.requireNonNull(userProfileClient.getDefaultAppId().getBody())); + appDto = userProfileClient.getApp(appId); + } } - AppDto appDto = userProfileClient.getApp(appId); + if (AuthenticationUtil.isUserAuthenticated()) { appDto.setUser(userProfileClient.getCurrentUser()); } // TODO: remove this logic when feature configs from UPS are received within List features parameter List features = userProfileClient.getUserAppFeatures(appId); - features.forEach(feature -> feature.setConfiguration(appDto.getFeaturesConfig().get(feature.getName()))); + AppDto finalAppDto = appDto; + features.forEach(feature -> feature.setConfiguration(finalAppDto.getFeaturesConfig().get(feature.getName()))); appDto.setFeatures(features); appDto.setFeaturesConfig(null); diff --git a/src/test/java/io/kontur/disasterninja/controller/AppControllerTest.java b/src/test/java/io/kontur/disasterninja/controller/AppControllerTest.java index 58cb9310..88965849 100644 --- a/src/test/java/io/kontur/disasterninja/controller/AppControllerTest.java +++ b/src/test/java/io/kontur/disasterninja/controller/AppControllerTest.java @@ -354,7 +354,7 @@ public void getAppConfigUnauthenticated() throws IOException { MediaType.APPLICATION_JSON)); //WHEN - AppDto result = appsController.getAppConfig(appID); + AppDto result = appsController.getAppConfig(appID, null); //THEN assertNotNull(result.getDescription()); @@ -385,7 +385,7 @@ public void getAppConfigAuthenticated() throws IOException { MediaType.APPLICATION_JSON)); //WHEN - AppDto result = appsController.getAppConfig(appID); + AppDto result = appsController.getAppConfig(appID, null); //THEN assertNotNull(result.getDescription()); diff --git a/src/test/java/io/kontur/disasterninja/service/AnalyticsServiceTest.java b/src/test/java/io/kontur/disasterninja/service/AnalyticsServiceTest.java index 95f91ac7..46cac92a 100644 --- a/src/test/java/io/kontur/disasterninja/service/AnalyticsServiceTest.java +++ b/src/test/java/io/kontur/disasterninja/service/AnalyticsServiceTest.java @@ -161,7 +161,7 @@ public void calculateAnalyticsUsingAppConfigTest() throws JsonProcessingExceptio array[1] = new AnalyticsStatisticsConfigurationDto("sumXWhereNoY", "population", "count"); array[2] = new AnalyticsStatisticsConfigurationDto("sumX", "population", null); - when(applicationService.getAppConfig(any(UUID.class))).thenReturn(appDto); + when(applicationService.getAppConfig(any(UUID.class), any())).thenReturn(appDto); when(objectMapperMock.treeToValue(any(JsonNode.class), same(AnalyticsStatisticsConfigurationDto[].class))).thenReturn(array); when(insightsApiGraphqlClient.analyticsTabQuery(geoJSONArgumentCaptor.capture(), functionArgsArgumentCaptor.capture())).thenReturn(completableFuture); @@ -228,7 +228,7 @@ public void calculateAnalyticsUsingAppConfigTestException() throws ExecutionExce CompletableFuture> completableFuture = mock(CompletableFuture.class); - when(applicationService.getAppConfig(any(UUID.class))).thenReturn(appDto); + when(applicationService.getAppConfig(any(UUID.class), any())).thenReturn(appDto); when(objectMapperMock.treeToValue(any(JsonNode.class), same(AnalyticsStatisticsConfigurationDto[].class))).thenReturn(array); when(insightsApiGraphqlClient.analyticsTabQuery(any(GeoJSON.class), anyList())).thenReturn(completableFuture);