diff --git a/src/main/java/app/coronawarn/quicktest/config/QuickTestConfig.java b/src/main/java/app/coronawarn/quicktest/config/QuickTestConfig.java index b9094359..9c9f05ac 100644 --- a/src/main/java/app/coronawarn/quicktest/config/QuickTestConfig.java +++ b/src/main/java/app/coronawarn/quicktest/config/QuickTestConfig.java @@ -20,6 +20,8 @@ package app.coronawarn.quicktest.config; +import java.util.ArrayList; +import java.util.List; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -44,6 +46,8 @@ public class QuickTestConfig { private String labId; private String pcrEnabledKey; + private List sharedRealms = new ArrayList<>(); + private FrontendContextConfig frontendContextConfig = new FrontendContextConfig(); private CancellationConfig cancellation = new CancellationConfig(); diff --git a/src/main/java/app/coronawarn/quicktest/controller/ConfigController.java b/src/main/java/app/coronawarn/quicktest/controller/ConfigController.java index f3a1a499..ec24c7f8 100644 --- a/src/main/java/app/coronawarn/quicktest/controller/ConfigController.java +++ b/src/main/java/app/coronawarn/quicktest/controller/ConfigController.java @@ -60,7 +60,8 @@ public ResponseEntity getQuickTestContextFile() { new QuickTestContextFile( quickTestConfig.getFrontendContextConfig().getRulesServerUrl(), quickTestConfig.getFrontendContextConfig().getEnvironmentName(), - quickTestConfig.getCancellation().getCompletePendingTestsHours() + quickTestConfig.getCancellation().getCompletePendingTestsHours(), + quickTestConfig.getSharedRealms() )); } } diff --git a/src/main/java/app/coronawarn/quicktest/model/quicktest/QuickTestContextFile.java b/src/main/java/app/coronawarn/quicktest/model/quicktest/QuickTestContextFile.java index ff32b461..87fc00bc 100644 --- a/src/main/java/app/coronawarn/quicktest/model/quicktest/QuickTestContextFile.java +++ b/src/main/java/app/coronawarn/quicktest/model/quicktest/QuickTestContextFile.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; import lombok.Data; import lombok.RequiredArgsConstructor; @@ -41,4 +42,7 @@ public class QuickTestContextFile { @JsonProperty("cancellation-complete-pending-tests") private final int cancellationCompletePendingTests; + @JsonProperty("disable-user-management") + private final List disableUserManagement; + } diff --git a/src/main/java/app/coronawarn/quicktest/utils/Utilities.java b/src/main/java/app/coronawarn/quicktest/utils/Utilities.java index 5869f199..b7597372 100644 --- a/src/main/java/app/coronawarn/quicktest/utils/Utilities.java +++ b/src/main/java/app/coronawarn/quicktest/utils/Utilities.java @@ -94,7 +94,7 @@ public Map getIdsFromToken() throws ResponseStatusException { KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) principal; String realmName = keycloakPrincipal.getKeycloakSecurityContext().getRealm(); - if (realmName != null && realmName.equals(keycloakAdminProperties.getRealm())) { + if (isSharedRealm(realmName)) { String rootGroupNames = getRootGroupsFromToken(); ids.put(quickTestConfig.getTenantIdKey(), rootGroupNames); } else { @@ -118,6 +118,17 @@ public Map getIdsFromToken() throws ResponseStatusException { return ids; } + /** + * Check if Realm is Realm with User Management via QT-Portal or is another shared realm. + * + * @param realmName Name of the Realm to check + * @return if realm is shared. + */ + private boolean isSharedRealm(String realmName) { + return realmName != null && (quickTestConfig.getSharedRealms().contains(realmName) + || keycloakAdminProperties.getRealm().equals(realmName)); + } + /** * Get root group from Token. * diff --git a/src/main/resources/application-cloud.yml b/src/main/resources/application-cloud.yml index 509d3ca8..3abc4c70 100644 --- a/src/main/resources/application-cloud.yml +++ b/src/main/resources/application-cloud.yml @@ -139,6 +139,7 @@ quicktest: environment-name: ${QUICK_TEST_ENVIRONMENT_NAME:unknown} cancellation: final-deletion-days: ${QUICK_TEST_CANCELLATION_FINAL_DELETION_DAYS:28} + sharedRealms: ${QUICK_TEST_SHARED_REALMS} archive: excluded-partners: ${QT_ARCHIVE_EXCLUDED_PARTNERS:} diff --git a/src/test/java/app/coronawarn/quicktest/utils/UtilitiesTest.java b/src/test/java/app/coronawarn/quicktest/utils/UtilitiesTest.java index faf8acd7..19da3b3c 100644 --- a/src/test/java/app/coronawarn/quicktest/utils/UtilitiesTest.java +++ b/src/test/java/app/coronawarn/quicktest/utils/UtilitiesTest.java @@ -147,6 +147,47 @@ public void testGetIdsFromTokenForSelfServiceRealm() { } + @Test + @WithMockUser(username = "myUser", roles = {"myAuthority"}) + public void testGetIdsFromTokenForNonAdminSelfServiceRealm() { + final String pocId = "testPOC"; + final String userId = "userId"; + final String tokenGroupString = "[" + + "/rootGroup/NRW/Wuppertal/Barmen," + + "/rootGroup" + + "]"; + GroupRepresentation rootGroup = new GroupRepresentation(); + rootGroup.setName("rootGroup"); + + when(keycloakServiceMock.getRootGroupsOfUser(userId)).thenReturn(List.of(rootGroup)); + + SecurityContext springSecurityContext = SecurityContextHolder.createEmptyContext(); + SecurityContextHolder.setContext(springSecurityContext); + Set roles = Sets.newSet("user"); + + KeycloakPrincipal principal = mock(KeycloakPrincipal.class); + RefreshableKeycloakSecurityContext keycloakSecurityContext = mock(RefreshableKeycloakSecurityContext.class); + when(principal.getKeycloakSecurityContext()).thenReturn(keycloakSecurityContext); + when(principal.getKeycloakSecurityContext().getRealm()).thenReturn("qt-alt"); + + AccessToken idToken = mock(AccessToken.class); + when(idToken.getSubject()).thenReturn(userId); + when(principal.getKeycloakSecurityContext().getToken()).thenReturn(idToken); + Map mockTokens = new HashMap<>(); + mockTokens.put(quickTestConfig.getPointOfCareIdName(), pocId); + mockTokens.put(quickTestConfig.getGroupKey(), tokenGroupString); + when(idToken.getOtherClaims()).thenReturn(mockTokens); + + KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, keycloakSecurityContext); + KeycloakAuthenticationToken token = new KeycloakAuthenticationToken(account, false); + springSecurityContext.setAuthentication(token); + + Map expectedTokens = new HashMap<>(); + expectedTokens.put(quickTestConfig.getTenantPointOfCareIdKey(), pocId); + expectedTokens.put(quickTestConfig.getTenantIdKey(), rootGroup.getName()); + assertEquals(expectedTokens, utilities.getIdsFromToken()); + } + @Test @WithMockUser(username = "myUser", roles = {"myAuthority"}) public void testGetIdsFromTokenFailed() { diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index d752faf1..0b3dcf11 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -77,6 +77,8 @@ quicktest: dbEncryptionKey: abcdefghjklmnopq pointOfCareInformationName: poc_details pointOfCareInformationDelimiter: \, + sharedRealms: + - qt-alt clean-up-settings: cron: "0 0 0 29 2 ?" max-age-in-minutes: 2