diff --git a/goofy-client/apps/goofy-e2e/docker-compose.yml b/goofy-client/apps/goofy-e2e/docker-compose.yml index 8442b95916f581ba49c1302d76215b1994e2bd74..26654de47c4d989400b740de163fee969ef650ca 100644 --- a/goofy-client/apps/goofy-e2e/docker-compose.yml +++ b/goofy-client/apps/goofy-e2e/docker-compose.yml @@ -28,10 +28,6 @@ services: environment: - GRPC_CLIENT_PLUTO_ADDRESS=static://ozg-pluto:9090 - SPRING_PROFILES_ACTIVE=remotekc, e2e - - KOP_USER_MANAGER_URL=http://localhost:9092 - - KOP_USER_MANAGER_PROFILE_TEMPLATE=/api/userProfiles/%s - - KOP_USER_MANAGER_USER_URL_TEMPLATE=http://localhost:9092/api/userProfiles/%s - - KOP_USER_MANAGER_SEARCH_URL_TEMPLATE=http://localhost:9092/api/userProfiles/?searchBy={searchBy} ports: - 8080:8080 depends_on: diff --git a/goofy-server/src/main/java/de/itvsh/goofy/RootController.java b/goofy-server/src/main/java/de/itvsh/goofy/RootController.java index 3b32e7ad96338ad3fb53ff9ba366ad0dd50cfbbd..c702d42ded3940baf7d9d0b341b68ed4bd520eff 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/RootController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/RootController.java @@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.RestController; import de.itvsh.goofy.common.ModelBuilder; import de.itvsh.goofy.common.downloadtoken.DownloadTokenController; import de.itvsh.goofy.common.user.CurrentUserService; +import de.itvsh.goofy.common.user.InternalUserIdService; import de.itvsh.goofy.common.user.UserId; import de.itvsh.goofy.common.user.UserRole; import de.itvsh.goofy.system.SystemStatusService; @@ -41,6 +42,8 @@ public class RootController { private CurrentUserService currentUserService; @Autowired private SystemStatusService systemStatusService; + @Autowired + private InternalUserIdService internalUserIdService; @Value("${kop.user-manager.url:}") private String userManagerUrl; @@ -54,20 +57,24 @@ public class RootController { @GetMapping public EntityModel<RootResource> getRootResource() { var userManagerSearchUrl = userManagerUrl + userSearchTemplate; - var model = ModelBuilder.fromEntity(new RootResource()) + var internalUserId = internalUserIdService.getUserId(currentUserService.getUserId()); + + var modelBuilder = ModelBuilder.fromEntity(new RootResource()) .ifMatch(this::hasRole).addLinks( linkTo(RootController.class).withSelfRel(), linkTo(VorgangController.class).withRel(REL_VORGAENGE), Link.of(userManagerSearchUrl, REL_SEARCH_USER), linkTo(DownloadTokenController.class).withRel(REL_DOWNLOAD_TOKEN)) .ifMatch(this::hasRoleAndSearchServerAvailable).addLinks( - buildVorgangListByPageLink(REL_SEARCH, Optional.empty())) + buildVorgangListByPageLink(REL_SEARCH, Optional.empty())); + + internalUserId.ifPresent(userId -> modelBuilder .ifMatch(this::hasVerwaltungRole).addLink( - buildVorgangListByPageLink(REL_MY_VORGAENGE, Optional.of(currentUserService.getUserId()))) + buildVorgangListByPageLink(REL_MY_VORGAENGE, Optional.of(userId))) .ifMatch(this::hasVerwaltungRoleAndSearchServerAvailable).addLink( - buildVorgangListByPageLink(REL_SEARCH_MY_VORGAENGE, Optional.of(currentUserService.getUserId()))) - .buildModel(); + buildVorgangListByPageLink(REL_SEARCH_MY_VORGAENGE, Optional.of(userId)))); + var model = modelBuilder.buildModel(); getUserProfilesUrl() .ifPresent(urlTemplate -> model.add(Link.of(String.format(urlTemplate, currentUserService.getUserId()), REL_CURRENT_USER))); diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/user/InternalUserIdService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/user/InternalUserIdService.java new file mode 100644 index 0000000000000000000000000000000000000000..603e51a5c4d5660fb6b56dc66d756c89bb02a4b0 --- /dev/null +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/user/InternalUserIdService.java @@ -0,0 +1,33 @@ +package de.itvsh.goofy.common.user; + +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@Component +public class InternalUserIdService { + + private static final String PATH = "/migration/user/{externalUserId}"; // NOSONAR + + @Value("${kop.user-manager.url}") + private String userManagerUrl; + + private RestTemplate restTemplate = new RestTemplate(); + + public Optional<UserId> getUserId(UserId externalUserId) { + try { + var internalId = restTemplate.getForObject(userManagerUrl + PATH, String.class, externalUserId.toString()); + return StringUtils.isNotEmpty(internalId) ? Optional.of(UserId.from(internalId)) : Optional.empty(); + } catch (RestClientException e) { + LOG.warn("Error loading internal Userid.", e); + return Optional.empty(); + } + } +} diff --git a/goofy-server/src/main/resources/application-local.yml b/goofy-server/src/main/resources/application-local.yml index d16bb9cf2e4739e5b86a7acd8abd4b74107bb493..5cddb11cd66f7f3c659059c076d70c3fe511b8fb 100644 --- a/goofy-server/src/main/resources/application-local.yml +++ b/goofy-server/src/main/resources/application-local.yml @@ -17,7 +17,6 @@ server: kop: user-manager: - url: http://localhost:9091 + url: http://localhost:9092 profile-template: /api/userProfiles/%s - user-url-template: http://localhost:9091/api/userProfiles/%s - search-url-template: http://localhost:9091/api/userProfiles/?searchBy={searchBy} \ No newline at end of file + search-template: /api/userProfiles/?searchBy={searchBy} \ No newline at end of file diff --git a/goofy-server/src/main/resources/application.yml b/goofy-server/src/main/resources/application.yml index 6ef2af58fbbf0e02e5770a1458657a5402f86bf9..dd6db3af8b0d9e7ae616277a31cb78b5c15a114d 100644 --- a/goofy-server/src/main/resources/application.yml +++ b/goofy-server/src/main/resources/application.yml @@ -74,5 +74,5 @@ kop: postfachNachrichtAttachment: 3MB wiedervorlageAttachment: 40MB user-manager: - search-template: /api/userProfiles/?searchBy={searchBy} - profile-template: /api/userProfiles/%s \ No newline at end of file + profile-template: /api/userProfiles/%s + search-template: /api/userProfiles/?searchBy={searchBy} \ No newline at end of file diff --git a/goofy-server/src/test/java/de/itvsh/goofy/RootControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/RootControllerTest.java index a0155101eb49b51885a9b213699ce9af0ddd3933..04699e4914dc796f27c3c57570ada758855e5259 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/RootControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/RootControllerTest.java @@ -27,6 +27,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import de.itvsh.goofy.common.user.CurrentUserService; import de.itvsh.goofy.common.user.GoofyUserTestFactory; +import de.itvsh.goofy.common.user.InternalUserIdService; import de.itvsh.goofy.common.user.UserRole; import de.itvsh.goofy.common.user.UserTestFactory; import de.itvsh.goofy.system.SystemStatusService; @@ -34,6 +35,8 @@ import de.itvsh.goofy.system.SystemStatusService; class RootControllerTest { private static final String SEARCH_BY = "/test?searchBy={searchBy}"; + private static final String API_USER_PROFILES_TEMLPATE = "/api/userProfiles/%s"; + private static final String API_USER_PROFILES = "/api/userProfiles/"; private static final String USERMANAGER_URL = "http://localhost:8080"; private final String PATH = "/api"; @@ -47,6 +50,8 @@ class RootControllerTest { private CurrentUserService currentUserService; @Mock private SystemStatusService systemStatusService; + @Mock + private InternalUserIdService internalUserIdService; private MockMvc mockMvc; @@ -55,6 +60,7 @@ class RootControllerTest { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); when(currentUserService.getUserId()).thenReturn(UserTestFactory.ID); + when(internalUserIdService.getUserId(any())).thenReturn(Optional.of(UserTestFactory.ID)); ReflectionTestUtils.setField(controller, "userSearchTemplate", SEARCH_BY); ReflectionTestUtils.setField(controller, "userManagerUrl", USERMANAGER_URL); @@ -106,7 +112,7 @@ class RootControllerTest { } @Test - void shoulHaveMyVorgaengeLink() { + void shouldHaveMyVorgaengeLink() { var model = controller.getRootResource(); assertThat(model.getLink(RootController.REL_MY_VORGAENGE)).isPresent().get().extracting(Link::getHref) @@ -114,7 +120,7 @@ class RootControllerTest { } @Test - void shoulHaveSearchMyVorgaengeLink() { + void shouldHaveSearchMyVorgaengeLink() { var model = controller.getRootResource(); assertThat(model.getLink(RootController.REL_SEARCH_MY_VORGAENGE)).isPresent().get().extracting(Link::getHref) @@ -122,7 +128,7 @@ class RootControllerTest { } @Test - void shoulHaveDownloadTokenLink() { + void shouldHaveDownloadTokenLink() { var model = controller.getRootResource(); assertThat(model.getLink(RootController.REL_DOWNLOAD_TOKEN)).isPresent().get().extracting(Link::getHref) @@ -227,13 +233,13 @@ class RootControllerTest { class UsermanagerUrlConfigured { @Test void shouldHaveCurrentUserLink() { - when(controller.getUserProfilesUrl()).thenReturn(Optional.of("http://localhost:9092/api/userProfiles/%s")); + when(controller.getUserProfilesUrl()).thenReturn(Optional.of(USERMANAGER_URL + API_USER_PROFILES_TEMLPATE)); when(currentUserService.getUserId()).thenReturn(GoofyUserTestFactory.ID); var model = controller.getRootResource(); assertThat(model.getLink(RootController.REL_CURRENT_USER)).isPresent().get().extracting(Link::getHref) - .isEqualTo(Link.of("http://localhost:9092/api/userProfiles/" + GoofyUserTestFactory.ID, RootController.REL_CURRENT_USER) + .isEqualTo(Link.of(USERMANAGER_URL + API_USER_PROFILES + GoofyUserTestFactory.ID, RootController.REL_CURRENT_USER) .getHref()); } } @@ -250,6 +256,32 @@ class RootControllerTest { } } + @DisplayName("when external Id cannot resolved to internal id") + @Nested + class NoInternalUserId { + + @BeforeEach + void init() { + doReturn(true).when(controller).hasVerwaltungRole(); + when(controller.getUserProfilesUrl()).thenReturn(Optional.of(USERMANAGER_URL + API_USER_PROFILES)); + when(internalUserIdService.getUserId(any())).thenReturn(Optional.empty()); + } + + @Test + void shouldNotHaveMyVorgaengeLink() { + + var model = controller.getRootResource(); + + assertThat(model.getLink(RootController.REL_MY_VORGAENGE)).isNotPresent(); + } + + @Test + void shouldNotHaveSearchMyVorgaengeLink() { + var model = controller.getRootResource(); + + assertThat(model.getLink(RootController.REL_SEARCH_MY_VORGAENGE)).isNotPresent(); + } + } } } diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/user/InternalUserIdServiceTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/user/InternalUserIdServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a87c3940397a51d2deaf8ff493b906dc66548995 --- /dev/null +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/user/InternalUserIdServiceTest.java @@ -0,0 +1,57 @@ +package de.itvsh.goofy.common.user; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +class InternalUserIdServiceTest { + + @Spy + @InjectMocks + private InternalUserIdService internalUserIdService; + + @Mock + private RestTemplate restTemplate; + + @Nested + class TestSuccess { + @Test + void shouldReturnUserId() { + when(restTemplate.getForObject(anyString(), eq(String.class), anyString())).thenReturn(UserTestFactory.ID.toString()); + + var res = internalUserIdService.getUserId(UserTestFactory.ID); + + assertThat(res).isPresent().hasValue(UserTestFactory.ID); + } + } + + @Nested + class TestErrorCases { + + @Test + void shouldHandleEmptyValue() { + when(restTemplate.getForObject(anyString(), eq(String.class), anyString())).thenReturn(""); + + var res = internalUserIdService.getUserId(UserTestFactory.ID); + + assertThat(res).isNotPresent(); + } + + @Test + void shouldHandleError() { + when(restTemplate.getForObject(anyString(), eq(String.class), anyString())).thenThrow(new RestClientException("Test error")); + + var res = internalUserIdService.getUserId(UserTestFactory.ID); + + assertThat(res).isNotPresent(); + } + } +} diff --git a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/VorgangControllerITCase.java b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/VorgangControllerITCase.java index ce3246826396900b9e116ed93500f6beb8e52e14..fa0cf7bd41a3a27a224bb63ee3aebffd3fbcb512 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/vorgang/VorgangControllerITCase.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/vorgang/VorgangControllerITCase.java @@ -123,7 +123,7 @@ class VorgangControllerITCase { void shouldBePresentIfAssigned() throws Exception { when(remoteService.findVorgangWithEingang(anyString())).thenReturn(VorgangWithEingangTestFactory.create()); - doRequest().andExpect(jsonPath("$._links.assignedTo.href").value("http://localhost:9091/api/userProfiles/" + UserTestFactory.ID)); + doRequest().andExpect(jsonPath("$._links.assignedTo.href").value("http://localhost:9092/api/userProfiles/" + UserTestFactory.ID)); } @Test