diff --git a/.env b/.env index 5e5dc00f2..12cdb7593 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ # Used in docker-compose # shellcheck disable=SC2034 -KEYCLOAK_VERSION=22.0.4 +KEYCLOAK_VERSION=23.0.1 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c6e8d8a91..3962d46bd 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -33,6 +33,7 @@ jobs: - KEYCLOAK_VERSION: 20.0.5 - KEYCLOAK_VERSION: 21.1.1 - KEYCLOAK_VERSION: 22.0.4 + - KEYCLOAK_VERSION: 23.0.1 steps: - uses: actions/checkout@v3 with: @@ -50,6 +51,11 @@ jobs: key: ${{ runner.os }}-maven-${{ matrix.env.KEYCLOAK_VERSION }}-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-maven-${{ matrix.env.KEYCLOAK_VERSION }} + - name: Adapt sources for Keycloak versions < 23.0.0 (UPConfig -> String) + if: ${{ matrix.env.KEYCLOAK_VERSION < '23.0.0' }} + run: | + echo "JAVAX_PROFILE=-Ppre-keycloak23" >> $GITHUB_ENV + - name: Adapt sources for Keycloak versions < 22.0.0 (jakarta -> javax) if: ${{ matrix.env.KEYCLOAK_VERSION < '22.0.0' }} run: | @@ -159,6 +165,11 @@ jobs: key: ${{ runner.os }}-${{ matrix.java }}-maven-build-pom-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-${{ matrix.java }}-maven-build-pom + - name: Adapt sources for Keycloak versions < 23.0.0 (UPConfig -> String) + if: ${{ matrix.env.KEYCLOAK_VERSION < '23.0.0' }} + run: | + echo "JAVAX_PROFILE=-Ppre-keycloak23" >> $GITHUB_ENV + - name: Adapt sources for Keycloak versions < 22.0.0 (jakarta -> javax) if: ${{ matrix.env.KEYCLOAK_VERSION < '22.0.0' }} run: | @@ -192,6 +203,11 @@ jobs: restore-keys: | ${{ runner.os }}-maven-keycloak-legacy + - name: Adapt sources for Keycloak versions < 23.0.0 (UPConfig -> String) + if: ${{ matrix.env.KEYCLOAK_VERSION < '23.0.0' }} + run: | + echo "JAVAX_PROFILE=-Ppre-keycloak23" >> $GITHUB_ENV + - name: Adapt sources for Keycloak versions < 22.0.0 (jakarta -> javax) if: ${{ matrix.env.KEYCLOAK_VERSION < '22.0.0' }} run: | diff --git a/Dockerfile b/Dockerfile index 848c3f18b..be02aac5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ FROM ${BUILDER_IMAGE} AS BUILDER WORKDIR /app/ -ARG KEYCLOAK_VERSION=22.0.4 +ARG KEYCLOAK_VERSION=23.0.1 ARG MAVEN_CLI_OPTS="-ntp -B" COPY .mvn .mvn diff --git a/README.md b/README.md index b188bef0b..76c9ad924 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ Additionally, the tag `maven` contains the source code and compile keycloak-conf Keycloak versions, that not official supported., e.g.: ```bash -docker run --rm -ti -v $PWD:/config/ -eKEYCLOAK_VERSION=22.0.4 -eMAVEN_CLI_OPTS="-B -ntp -q" adorsys/keycloak-config-cli:edge-build +docker run --rm -ti -v $PWD:/config/ -eKEYCLOAK_VERSION=23.0.1 -eMAVEN_CLI_OPTS="-B -ntp -q" adorsys/keycloak-config-cli:edge-build ``` ### Docker run diff --git a/pom.xml b/pom.xml index dee390cf6..65ae22e1f 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ UTF-8 UTF-8 - 22.0.4 + 23.0.1 3.2.0 10.0 @@ -727,6 +727,61 @@ import jakarta import javax + + import org.keycloak.representations.userprofile.config.UPConfig; + ; + + + return JsonUtil.toJson\(userProfileResource.getConfiguration\(\)\); + return userProfileResource.getConfiguration(); + + + userProfileResource.update\(JsonUtil.readValue\(newUserProfileConfiguration, UPConfig.class\)\); + userProfileResource.update(newUserProfileConfiguration); + + + + + + + + + pre-keycloak23 + + + + com.google.code.maven-replacer-plugin + replacer + ${maven-replacer.version} + + + replace-upconfig-with-string + generate-sources + + replace + + + + + + ${project.basedir}/src + + + main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java + + + + import org.keycloak.representations.userprofile.config.UPConfig; + ; + + + return JsonUtil.toJson\(userProfileResource.getConfiguration\(\)\); + return userProfileResource.getConfiguration(); + + + userProfileResource.update\(JsonUtil.readValue\(newUserProfileConfiguration, UPConfig.class\)\); + userProfileResource.update(newUserProfileConfiguration); + diff --git a/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java index 7ce265ee1..32eaf0490 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/GroupRepository.java @@ -111,13 +111,12 @@ public void addSubGroup(String realmName, String parentGroupId, GroupRepresentat } public GroupRepresentation getSubGroupByName(String realmName, String parentGroupId, String name) { - GroupRepresentation existingGroup = getResourceById(realmName, parentGroupId).toRepresentation(); - - return existingGroup.getSubGroups() + GroupRepresentation subGroup = getSubGroups(realmName, parentGroupId) .stream() .filter(subgroup -> Objects.equals(subgroup.getName(), name)) .findFirst() .orElse(null); + return subGroup; } public void addRealmRoles(String realmName, String groupId, List roleNames) { @@ -239,4 +238,12 @@ private GroupResource getResourceById(String realmName, String groupId) { .groups() .group(groupId); } + + public List getSubGroups(String realmName, String parentGroupId) { + // TODO make max size configurable + // note this is currently the only way to populate the subgroup information + // The meaning of the briefRepresentation was apprently inverted by mistake in Keycloak 23.0.0 + // see: https://github.com/keycloak/keycloak/issues/25096 + return getResourceById(realmName, parentGroupId).getSubGroups(0, 100, true); + } } diff --git a/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java index 1e16a64ce..7685ff0c9 100644 --- a/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java +++ b/src/main/java/de/adorsys/keycloak/config/repository/UserProfileRepository.java @@ -23,16 +23,13 @@ import de.adorsys.keycloak.config.exception.KeycloakRepositoryException; import de.adorsys.keycloak.config.util.JsonUtil; import org.keycloak.admin.client.resource.UserProfileResource; +import org.keycloak.representations.userprofile.config.UPConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; -import java.util.Optional; - -import jakarta.ws.rs.core.Response; - @Component public class UserProfileRepository { @@ -57,35 +54,36 @@ public void updateUserProfile(String realm, boolean newUserProfileEnabled, Strin if (!newUserProfileEnabled) { logger.trace("UserProfile is explicitly disabled, removing configuration."); - try (var response = userProfileResource.update(null)) { - logger.trace("UserProfile configuration removed."); - } - return; + userProfileResource.update(null); + logger.trace("UserProfile configuration removed."); } var realmAttributes = realmRepository.get(realm).getAttributesOrEmpty(); - var currentUserProfileConfiguration = Optional.ofNullable(userProfileResource.getConfiguration()).orElse(""); + var currentUserProfileConfiguration = getUserProfileConfiguration(userProfileResource); if (!StringUtils.hasText(currentUserProfileConfiguration)) { logger.warn("UserProfile is enabled, but no configuration string provided."); return; } - var currentUserProfileEnabled = Boolean.parseBoolean(realmAttributes.getOrDefault(REALM_ATTRIBUTES_USER_PROFILE_ENABLED_STRING, "false")); + var currentUserProfileEnabled = + Boolean.parseBoolean(realmAttributes.getOrDefault(REALM_ATTRIBUTES_USER_PROFILE_ENABLED_STRING, "false")); + if (!currentUserProfileEnabled) { logger.warn("UserProfile enabled attribute in realm differs from configuration. " + "This is strange, because the attribute import should have done that already."); } var userProfileConfigChanged = hasUserProfileConfigurationChanged(newUserProfileConfiguration, currentUserProfileConfiguration); + if (!userProfileConfigChanged) { logger.trace("UserProfile did not change, skipping update."); return; } - try (var updateUserProfileResponse = userProfileResource.update(newUserProfileConfiguration)) { - if (!updateUserProfileResponse.getStatusInfo().equals(Response.Status.OK)) { - throw new KeycloakRepositoryException("Could not update UserProfile Definition"); - } + try { + resolveUserProfileUpdate(userProfileResource, newUserProfileConfiguration); + } catch (Exception ex) { + throw new KeycloakRepositoryException("Could not update UserProfile Definition", ex); } logger.trace("UserProfile updated."); @@ -97,6 +95,14 @@ private boolean hasUserProfileConfigurationChanged(String newUserProfileConfigur return !currentValue.equals(newValue); } + private String getUserProfileConfiguration(UserProfileResource userProfileResource) { + return JsonUtil.toJson(userProfileResource.getConfiguration()); + } + + private void resolveUserProfileUpdate(UserProfileResource userProfileResource, String newUserProfileConfiguration) { + userProfileResource.update(JsonUtil.readValue(newUserProfileConfiguration, UPConfig.class)); + } + private UserProfileResource getResource(String realmName) { return this.realmRepository.getResource(realmName).users().userProfile(); } diff --git a/src/main/java/de/adorsys/keycloak/config/service/GroupImportService.java b/src/main/java/de/adorsys/keycloak/config/service/GroupImportService.java index c8334e8f8..5045a3b73 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/GroupImportService.java +++ b/src/main/java/de/adorsys/keycloak/config/service/GroupImportService.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.util.*; import java.util.function.Consumer; @@ -77,18 +78,44 @@ private void deleteGroupsMissingInImport( List importedGroups, List existingGroups ) { - Set importedGroupNames = importedGroups.stream() - .map(GroupRepresentation::getName) - .collect(Collectors.toSet()); + Map groupPathMap = new HashMap<>(); + for (GroupRepresentation groupRep : importedGroups) { + buildGroupPathLookupMap(groupPathMap, groupRep, "/"); + } for (GroupRepresentation existingGroup : existingGroups) { - if (importedGroupNames.contains(existingGroup.getName())) continue; + if (groupPathMap.containsKey("/" + existingGroup.getName())) { + if (existingGroup.getSubGroupCount() > 0) { + tryRecursivelyDeletingDanglingSubGroups(groupPathMap, realmName, existingGroup.getId()); + } + continue; + } logger.debug("Delete group '{}' in realm '{}'", existingGroup.getName(), realmName); groupRepository.deleteGroup(realmName, existingGroup.getId()); } } + private void tryRecursivelyDeletingDanglingSubGroups(Map groupPathMap, String realmName, String parentGroupId) { + List subGroups = groupRepository.getSubGroups(realmName, parentGroupId); + for (GroupRepresentation subGroup : subGroups) { + String path = subGroup.getPath(); + if (!groupPathMap.containsKey(path)) { + groupRepository.deleteGroup(realmName, subGroup.getId()); + } else { + tryRecursivelyDeletingDanglingSubGroups(groupPathMap, realmName, subGroup.getId()); + } + } + } + + private void buildGroupPathLookupMap(Map map, GroupRepresentation currentGroup, String prefix) { + String groupPath = prefix + currentGroup.getName(); + map.put(groupPath, currentGroup); + for (GroupRepresentation subGroup : currentGroup.getSubGroups()) { + buildGroupPathLookupMap(map, subGroup, groupPath + "/"); + } + } + private void createOrUpdateRealmGroup(String realmName, GroupRepresentation group) { String groupName = group.getName(); @@ -114,6 +141,10 @@ private void createGroup(String realmName, GroupRepresentation group) { } private void addRealmRoles(String realmName, GroupRepresentation existingGroup) { + if (existingGroup == null) { + return; + } + List realmRoles = existingGroup.getRealmRoles(); if (realmRoles != null && !realmRoles.isEmpty()) { @@ -122,6 +153,10 @@ private void addRealmRoles(String realmName, GroupRepresentation existingGroup) } private void addClientRoles(String realmName, GroupRepresentation existingGroup) { + if (existingGroup == null) { + return; + } + Map> existingClientRoles = existingGroup.getClientRoles(); String groupId = existingGroup.getId(); @@ -136,6 +171,10 @@ private void addClientRoles(String realmName, GroupRepresentation existingGroup) } private void addSubGroups(String realmName, GroupRepresentation existingGroup) { + if (existingGroup == null) { + return; + } + List subGroups = existingGroup.getSubGroups(); String groupId = existingGroup.getId(); @@ -243,26 +282,32 @@ private void updateGroupRealmRoles(String realmName, String groupId, List estimateRealmRolesToRemove(List realmRoles, List existingRealmRolesNames) { - List realmRoleNamesToRemove = new ArrayList<>(); + if (existingRealmRolesNames == null) { + return Collections.emptyList(); + } + + List realmRoleNamesToRemove = new ArrayList<>(); for (String existingRealmRolesName : existingRealmRolesNames) { if (!realmRoles.contains(existingRealmRolesName)) { realmRoleNamesToRemove.add(existingRealmRolesName); } } - return realmRoleNamesToRemove; } private List estimateRealmRolesToAdd(List realmRoles, List existingRealmRolesNames) { - List realmRoleNamesToAdd = new ArrayList<>(); + if (existingRealmRolesNames == null) { + return realmRoles; + } + + List realmRoleNamesToAdd = new ArrayList<>(); for (String realmRoleName : realmRoles) { if (!existingRealmRolesNames.contains(realmRoleName)) { realmRoleNamesToAdd.add(realmRoleName); } } - return realmRoleNamesToAdd; } @@ -285,10 +330,17 @@ private void updateClientRoles( String clientId = clientRole.getKey(); List clientRoleNames = clientRole.getValue(); - List existingClientRoleNamesForClient = existingClientRoleNames.get(clientId); + List clientRoleNamesToAdd; + List clientRoleNamesToRemove; - List clientRoleNamesToAdd = estimateClientRolesToAdd(existingClientRoleNamesForClient, clientRoleNames); - List clientRoleNamesToRemove = estimateClientRolesToRemove(existingClientRoleNamesForClient, clientRoleNames); + if (existingClientRoleNames != null) { + List existingClientRoleNamesForClient = existingClientRoleNames.get(clientId); + clientRoleNamesToAdd = estimateClientRolesToAdd(existingClientRoleNamesForClient, clientRoleNames); + clientRoleNamesToRemove = estimateClientRolesToRemove(existingClientRoleNamesForClient, clientRoleNames); + } else { + clientRoleNamesToAdd = clientRoleNames; + clientRoleNamesToRemove = Collections.emptyList(); + } groupRepository.addClientRoles(realmName, groupId, clientId, clientRoleNamesToAdd); groupRepository.removeClientRoles(realmName, groupId, clientId, clientRoleNamesToRemove); @@ -301,6 +353,11 @@ private void deleteClientRolesMissingInImport( Map> existingClientRoleNames, Map> groupClientRoles ) { + + if (CollectionUtils.isEmpty(existingClientRoleNames)) { + return; + } + for (Map.Entry> existingClientRoleNamesEntry : existingClientRoleNames.entrySet()) { String clientId = existingClientRoleNamesEntry.getKey(); List clientRoleNames = existingClientRoleNamesEntry.getValue(); @@ -312,34 +369,37 @@ private void deleteClientRolesMissingInImport( } private List estimateClientRolesToRemove(List existingClientRoleNamesForClient, List clientRoleNamesFromImport) { - List clientRoleNamesToRemove = new ArrayList<>(); - if (existingClientRoleNamesForClient != null) { - for (String existingClientRoleNameForClient : existingClientRoleNamesForClient) { - if (!clientRoleNamesFromImport.contains(existingClientRoleNameForClient)) { - clientRoleNamesToRemove.add(existingClientRoleNameForClient); - } - } + if (CollectionUtils.isEmpty(existingClientRoleNamesForClient)) { + return Collections.emptyList(); } + List clientRoleNamesToRemove = new ArrayList<>(); + for (String existingClientRoleNameForClient : existingClientRoleNamesForClient) { + if (!clientRoleNamesFromImport.contains(existingClientRoleNameForClient)) { + clientRoleNamesToRemove.add(existingClientRoleNameForClient); + } + } return clientRoleNamesToRemove; } private List estimateClientRolesToAdd(List existingClientRoleNamesForClient, List clientRoleNamesFromImport) { - List clientRoleNamesToAdd = new ArrayList<>(); + if (CollectionUtils.isEmpty(existingClientRoleNamesForClient)) { + return clientRoleNamesFromImport; + } + + List clientRoleNamesToAdd = new ArrayList<>(); for (String clientRoleName : clientRoleNamesFromImport) { - if (existingClientRoleNamesForClient == null || !existingClientRoleNamesForClient.contains(clientRoleName)) { + if (!existingClientRoleNamesForClient.contains(clientRoleName)) { clientRoleNamesToAdd.add(clientRoleName); } } - return clientRoleNamesToAdd; } private void updateSubGroups(String realmName, String parentGroupId, List subGroups) { - GroupRepresentation existingGroup = groupRepository.getGroupById(realmName, parentGroupId); - List existingSubGroups = existingGroup.getSubGroups(); + List existingSubGroups = groupRepository.getSubGroups(realmName, parentGroupId); deleteAllSubGroupsMissingInImport(realmName, subGroups, existingSubGroups); diff --git a/src/main/java/de/adorsys/keycloak/config/util/JsonUtil.java b/src/main/java/de/adorsys/keycloak/config/util/JsonUtil.java index fd3087189..f7d289e93 100644 --- a/src/main/java/de/adorsys/keycloak/config/util/JsonUtil.java +++ b/src/main/java/de/adorsys/keycloak/config/util/JsonUtil.java @@ -70,4 +70,12 @@ private static JsonNode fromJsonAsNode(String value) { throw new ImportProcessingException(e); } } + + public static T readValue(String value, Class type) { + try { + return value == null ? null : objectMapper.readValue(value, type); + } catch (JsonProcessingException e) { + throw new ImportProcessingException(e); + } + } } diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index f88d18cf8..0e9250bfe 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -1,5 +1,13 @@ spring.output.ansi.enabled=ALWAYS spring.config.import=classpath:application-debug.properties -keycloak.url=http://localhost:8080/ -keycloak.password=admin123 -import.files.locations=contrib/example-config/moped.json +keycloak.url=https://localhost:8444/auth +#keycloak.url=http://localhost:8321/auth +#keycloak.url=https://barmerid-local.id.clone.bconnect.barmer.de/auth +keycloak.user=keycloak +keycloak.password=Start123! +#keycloak.password=y7c3XXTH8xYkK5ZAazsy +#keycloak.password=DA4MV?x&x2 +#keycloak.user=keycloak-barmer +#keycloak.password=5wWZ2ebvBujnYxA7zGjt +#keycloak.password=r37Hj6h5XmqQS6uvP28x +import.files.locations=/Users/jonas/IdeaProjects/bestands-idp/_realmdefinition/barmerid-local.bconnect.barmer.de.json diff --git a/src/main/resources/application2.properties b/src/main/resources/application2.properties new file mode 100644 index 000000000..88da78db7 --- /dev/null +++ b/src/main/resources/application2.properties @@ -0,0 +1,56 @@ +spring.cache.type=NONE +spring.main.web-application-type=NONE +spring.main.log-startup-info=true +spring.main.banner-mode=off +spring.main.lazy-initialization=true +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration + +keycloak.version=@keycloak.version@ +keycloak.login-realm=master +keycloak.user=admin +keycloak.client-secret= +keycloak.grant-type=password +keycloak.client-id=admin-cli +keycloak.ssl-verify=false +keycloak.connect-timeout=10s +keycloak.read-timeout=10s +keycloak.availability-check.enabled=false +keycloak.availability-check.timeout=120s +keycloak.availability-check.retry-delay=2s +import.validate=true +import.parallel=false +import.files.excludes="" +import.files.include-hidden-files=false +import.cache.enabled=true +import.cache.key=default +import.var-substitution.enabled=true +import.var-substitution.nested=true +import.var-substitution.undefined-is-error=true +import.var-substitution.prefix=$( +import.var-substitution.suffix=) +import.remote-state.enabled=false +# For security reasons, change this value if you want to encrypt the state +import.remote-state.encryption-salt=2B521C795FBE2F2425DB150CD3700BA9 +import.behaviors.remove-default-role-from-user=false +import.behaviors.skip-attributes-for-federated-user=false +import.behaviors.sync-user-federation=false +import.managed.authentication-flow=full +import.managed.group=full +import.managed.required-action=full +import.managed.client-scope=full +import.managed.scope-mapping=full +import.managed.client-scope-mapping=full +import.managed.component=full +import.managed.sub-component=full +import.managed.identity-provider=full +import.managed.identity-provider-mapper=full +import.managed.role=full +import.managed.client=full +import.managed.client-authorization-resources=full +import.managed.client-authorization-policies=full +import.managed.client-authorization-scopes=full + +logging.group.http=org.apache.http.wire +logging.group.realm-config=de.adorsys.keycloak.config.provider.KeycloakImportProvider +logging.group.keycloak-config-cli=de.adorsys.keycloak.config.service,de.adorsys.keycloak.config.KeycloakConfigRunner,de.adorsys.keycloak.config.provider.KeycloakProvider +logging.group.kcc=de.adorsys.keycloak.config.service,de.adorsys.keycloak.config.KeycloakConfigRunner,de.adorsys.keycloak.config.provider.KeycloakProvider diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportGroupsIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportGroupsIT.java index d6172a62d..456e07ea6 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportGroupsIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportGroupsIT.java @@ -22,15 +22,19 @@ import de.adorsys.keycloak.config.AbstractImportIT; import de.adorsys.keycloak.config.exception.KeycloakRepositoryException; +import de.adorsys.keycloak.config.util.VersionUtil; import org.hamcrest.Matchers; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.keycloak.admin.client.resource.GroupResource; import org.keycloak.admin.client.resource.GroupsResource; import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import java.io.IOException; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -60,12 +64,36 @@ void shouldCreateRealmWithGroups() throws IOException { assertThat("name not equal", createdGroup.getName(), is("My Group")); assertThat("path not equal", createdGroup.getPath(), is("/My Group")); - assertThat("attributes is null", createdGroup.getAttributes(), aMapWithSize(0)); - assertThat("realm roles is null", createdGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles not null", createdGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(createdGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(createdGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(createdGroup.getClientRoles()); assertThat("subgroups not empty", createdGroup.getSubGroups(), hasSize(0)); } + private void assertThatGroupAttributesAreEmpty(Map> attributes) { + if (VersionUtil.gt(KEYCLOAK_VERSION, "22")) { + assertThat("attributes is null", attributes, is(nullValue())); + } else { + assertThat("attributes is null", attributes, aMapWithSize(0)); + } + } + + private void assertThatGroupRealmRolesAreEmpty(List realmRoles) { + if (VersionUtil.gt(KEYCLOAK_VERSION, "22")) { + assertThat("realm roles is null", realmRoles, is(nullValue())); + } else { + assertThat("realm roles is null", realmRoles, hasSize(0)); + } + } + + private void assertThatGroupClientRolesAreEmpty(Map> clientRoles) { + if (VersionUtil.gt(KEYCLOAK_VERSION, "22")) { + assertThat("client roles not null", clientRoles, is(nullValue())); + } else { + assertThat("client roles not null", clientRoles, aMapWithSize(0)); + } + } + @Test @Order(1) void shouldUpdateRealmAddGroup() throws IOException { @@ -79,18 +107,18 @@ void shouldUpdateRealmAddGroup() throws IOException { assertThat("name not equal", existingGroup.getName(), is("My Group")); assertThat("path not equal", existingGroup.getPath(), is("/My Group")); - assertThat("attributes is null", existingGroup.getAttributes(), aMapWithSize(0)); - assertThat("realm roles is null", existingGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles is null", existingGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(existingGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(existingGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(existingGroup.getClientRoles()); assertThat("subgroups is null", existingGroup.getSubGroups(), hasSize(0)); GroupRepresentation addedGroup = loadGroup("/My Added Group"); assertThat("name not equal", addedGroup.getName(), is("My Added Group")); assertThat("path not equal", addedGroup.getPath(), is("/My Added Group")); - assertThat("attributes is null", addedGroup.getAttributes(), aMapWithSize(0)); - assertThat("realm roles is null", addedGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles is null", addedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(addedGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(addedGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(addedGroup.getClientRoles()); assertThat("subgroups is null", addedGroup.getSubGroups(), hasSize(0)); } @@ -111,8 +139,8 @@ void shouldUpdateRealmAddGroupWithAttribute() throws IOException { assertThat("attributes is null", addedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes is null", addedGroup.getAttributes(), hasEntry(is("my attribute"), containsInAnyOrder("my attribute value"))); - assertThat("realm roles is null", addedGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles is null", addedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupRealmRolesAreEmpty(addedGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(addedGroup.getClientRoles()); assertThat("subgroups is null", addedGroup.getSubGroups(), hasSize(0)); } @@ -129,9 +157,9 @@ void shouldUpdateRealmAddGroupWithRealmRole() throws IOException { assertThat("name not equal", addedGroup.getName(), is("Group with realm role")); assertThat("path not equal", addedGroup.getPath(), is("/Group with realm role")); - assertThat("attributes is null", addedGroup.getAttributes(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(addedGroup.getAttributes()); assertThat("realm roles is null", addedGroup.getRealmRoles(), contains("my_realm_role")); - assertThat("client roles is null", addedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupClientRolesAreEmpty(addedGroup.getClientRoles()); assertThat("subgroups is null", addedGroup.getSubGroups(), hasSize(0)); } @@ -148,8 +176,8 @@ void shouldUpdateRealmAddGroupWithClientRole() throws IOException { assertThat("name not equal", addedGroup.getName(), is("Group with client role")); assertThat("path not equal", addedGroup.getPath(), is("/Group with client role")); - assertThat("attributes is null", addedGroup.getAttributes(), aMapWithSize(0)); - assertThat("realm roles is null", addedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupAttributesAreEmpty(addedGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(addedGroup.getRealmRoles()); assertThat("client roles is null", addedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", addedGroup.getClientRoles(), hasEntry(is("moped-client"), containsInAnyOrder("my_client_role"))); @@ -170,9 +198,9 @@ void shouldUpdateRealmAddGroupWithSubGroup() throws IOException { assertThat("name not equal", addedGroup.getName(), is("Group with subgroup")); assertThat("path not equal", addedGroup.getPath(), is("/Group with subgroup")); - assertThat("attributes is null", addedGroup.getAttributes(), aMapWithSize(0)); - assertThat("realm roles is null", addedGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles is null", addedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(addedGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(addedGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(addedGroup.getClientRoles()); assertThat("subgroups is null", addedGroup.getSubGroups(), notNullValue()); assertThat("subgroups is empty", addedGroup.getSubGroups(), hasSize(1)); @@ -180,9 +208,9 @@ void shouldUpdateRealmAddGroupWithSubGroup() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/Group with subgroup/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -199,9 +227,9 @@ void shouldUpdateRealmAddGroupWithSubGroupWithRealmRole() throws IOException { assertThat("name not equal", addedGroup.getName(), is("Group with subgroup with realm role")); assertThat("path not equal", addedGroup.getPath(), is("/Group with subgroup with realm role")); - assertThat("attributes is null", addedGroup.getAttributes(), aMapWithSize(0)); - assertThat("realm roles is null", addedGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles is null", addedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(addedGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(addedGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(addedGroup.getClientRoles()); assertThat("subgroups is null", addedGroup.getSubGroups(), notNullValue()); assertThat("subgroups is empty", addedGroup.getSubGroups(), hasSize(1)); @@ -209,9 +237,9 @@ void shouldUpdateRealmAddGroupWithSubGroupWithRealmRole() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/Group with subgroup with realm role/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), contains("my_second_realm_role")); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -228,9 +256,9 @@ void shouldUpdateRealmAddGroupWithSubGroupWithClientRole() throws IOException { assertThat("name not equal", addedGroup.getName(), is("Group with subgroup with client role")); assertThat("path not equal", addedGroup.getPath(), is("/Group with subgroup with client role")); - assertThat("attributes is null", addedGroup.getAttributes(), aMapWithSize(0)); - assertThat("realm roles is null", addedGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles is null", addedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(addedGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(addedGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(addedGroup.getClientRoles()); assertThat("subgroups is null", addedGroup.getSubGroups(), notNullValue()); assertThat("subgroups is empty", addedGroup.getSubGroups(), hasSize(1)); @@ -238,8 +266,8 @@ void shouldUpdateRealmAddGroupWithSubGroupWithClientRole() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/Group with subgroup with client role/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(1)); assertThat("subgroup's client roles is null", subGroup.getClientRoles(), hasEntry(is("moped-client"), containsInAnyOrder("my_second_client_role"))); @@ -260,9 +288,9 @@ void shouldUpdateRealmAddGroupWithSubGroupWithSubGroup() throws IOException { assertThat("name not equal", addedGroup.getName(), is("Group with subgroup with subgroup")); assertThat("path not equal", addedGroup.getPath(), is("/Group with subgroup with subgroup")); - assertThat("attributes is null", addedGroup.getAttributes(), aMapWithSize(0)); - assertThat("realm roles is null", addedGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles is null", addedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(addedGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(addedGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(addedGroup.getClientRoles()); List subGroups = addedGroup.getSubGroups(); assertThat("subgroups is null", subGroups, notNullValue()); @@ -272,9 +300,9 @@ void shouldUpdateRealmAddGroupWithSubGroupWithSubGroup() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/Group with subgroup with subgroup/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); List innerSubGroups = subGroup.getSubGroups(); assertThat("subgroup's subgroups is null", innerSubGroups, hasSize(1)); @@ -283,9 +311,9 @@ void shouldUpdateRealmAddGroupWithSubGroupWithSubGroup() throws IOException { assertThat("subgroup is null", innerSubGroup, notNullValue()); assertThat("subgroup's name not equal", innerSubGroup.getName(), is("My Inner SubGroup")); assertThat("subgroup's path not equal", innerSubGroup.getPath(), is("/Group with subgroup with subgroup/My SubGroup/My Inner SubGroup")); - assertThat("subgroup's attributes is null", innerSubGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", innerSubGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", innerSubGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(innerSubGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(innerSubGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(innerSubGroup.getClientRoles()); } @Test @@ -304,8 +332,8 @@ void shouldUpdateRealmUpdateGroupAddAttribute() throws IOException { assertThat("attributes is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes is null", updatedGroup.getAttributes(), hasEntry(is("my added attribute"), containsInAnyOrder("my added attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); - assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(updatedGroup.getClientRoles()); assertThat("subgroups not empty", updatedGroup.getSubGroups(), hasSize(0)); } @@ -326,7 +354,7 @@ void shouldUpdateRealmUpdateGroupAddRealmRole() throws IOException { assertThat("attributes is null", updatedGroup.getAttributes(), hasEntry(is("my added attribute"), containsInAnyOrder("my added attribute value"))); assertThat("realm roles is null", updatedGroup.getRealmRoles(), contains("my_realm_role")); - assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupClientRolesAreEmpty(updatedGroup.getClientRoles()); assertThat("subgroups not empty", updatedGroup.getSubGroups(), hasSize(0)); } @@ -377,9 +405,9 @@ void shouldUpdateRealmUpdateGroupAddSubgroup() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -411,9 +439,9 @@ void shouldUpdateRealmUpdateGroupAddSecondSubgroup() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); GroupRepresentation sub2ndGroup = subGroups.stream() @@ -423,9 +451,9 @@ void shouldUpdateRealmUpdateGroupAddSecondSubgroup() throws IOException { assertThat("subgroup is null", sub2ndGroup, notNullValue()); assertThat("subgroup's name not equal", sub2ndGroup.getName(), is("My 2nd SubGroup")); assertThat("subgroup's path not equal", sub2ndGroup.getPath(), is("/My Group/My 2nd SubGroup")); - assertThat("subgroup's attributes is null", sub2ndGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", sub2ndGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", sub2ndGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(sub2ndGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(sub2ndGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(sub2ndGroup.getClientRoles()); assertThat("subgroup's subgroups is null", sub2ndGroup.getSubGroups(), hasSize(0)); } @@ -457,9 +485,9 @@ void shouldUpdateRealmUpdateGroupRemoveAndAddSecondSubgroup() throws IOException assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); GroupRepresentation sub2ndGroup = subGroups.stream() @@ -469,9 +497,9 @@ void shouldUpdateRealmUpdateGroupRemoveAndAddSecondSubgroup() throws IOException assertThat("subgroup is null", sub2ndGroup, notNullValue()); assertThat("subgroup's name not equal", sub2ndGroup.getName(), is("My other 2nd SubGroup")); assertThat("subgroup's path not equal", sub2ndGroup.getPath(), is("/My Group/My other 2nd SubGroup")); - assertThat("subgroup's attributes is null", sub2ndGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", sub2ndGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", sub2ndGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(sub2ndGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(sub2ndGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(sub2ndGroup.getClientRoles()); assertThat("subgroup's subgroups is null", sub2ndGroup.getSubGroups(), hasSize(0)); } @@ -501,9 +529,9 @@ void shouldUpdateRealmUpdateGroupAddSecondAttributeValue() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -534,9 +562,9 @@ void shouldUpdateRealmUpdateGroupAddSecondAttribute() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -567,9 +595,9 @@ void shouldUpdateRealmUpdateGroupChangeAttributeValue() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -601,9 +629,9 @@ void shouldUpdateRealmUpdateGroupChangeAttributeKey() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -634,9 +662,9 @@ void shouldUpdateRealmUpdateGroupDeleteAttribute() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -667,9 +695,9 @@ void shouldUpdateRealmUpdateGroupDeleteAttributeValue() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -699,9 +727,9 @@ void shouldUpdateRealmUpdateGroupAddSecondRealmRole() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -732,9 +760,9 @@ void shouldUpdateRealmUpdateGroupDeleteRealmRole() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -752,7 +780,7 @@ void shouldUpdateRealmUpdateGroupDeleteLastRealmRole() throws IOException { assertThat("path not equal", updatedGroup.getPath(), is("/My Group")); assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("moped-client"), containsInAnyOrder("my_client_role"))); @@ -763,9 +791,9 @@ void shouldUpdateRealmUpdateGroupDeleteLastRealmRole() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -785,7 +813,7 @@ void shouldUpdateRealmUpdateGroupAddSecondClientRole() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("moped-client"), containsInAnyOrder("my_client_role", "my_second_client_role"))); @@ -797,9 +825,9 @@ void shouldUpdateRealmUpdateGroupAddSecondClientRole() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -819,7 +847,7 @@ void shouldUpdateRealmUpdateGroupRemoveClientRole() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("moped-client"), containsInAnyOrder("my_second_client_role"))); @@ -830,9 +858,9 @@ void shouldUpdateRealmUpdateGroupRemoveClientRole() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -852,7 +880,7 @@ void shouldUpdateRealmUpdateGroupAddClientRolesFromSecondClient() throws IOExcep assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(2)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("moped-client"), containsInAnyOrder("my_second_client_role"))); @@ -865,9 +893,9 @@ void shouldUpdateRealmUpdateGroupAddClientRolesFromSecondClient() throws IOExcep assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -887,7 +915,7 @@ void shouldUpdateRealmUpdateGroupRemoveClient() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -899,9 +927,9 @@ void shouldUpdateRealmUpdateGroupRemoveClient() throws IOException { assertThat("subgroup is null", subGroup, notNullValue()); assertThat("subgroup's name not equal", subGroup.getName(), is("My SubGroup")); assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); - assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(subGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -921,7 +949,7 @@ void shouldUpdateRealmUpdateGroupAddAttributeToSubGroup() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -938,8 +966,8 @@ void shouldUpdateRealmUpdateGroupAddAttributeToSubGroup() throws IOException { assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(1)); assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my subgroup attribute"), containsInAnyOrder("my subgroup attribute value"))); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -959,7 +987,7 @@ void shouldUpdateRealmUpdateGroupAddAttributeValueToSubGroup() throws IOExceptio assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -972,8 +1000,8 @@ void shouldUpdateRealmUpdateGroupAddAttributeValueToSubGroup() throws IOExceptio assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(1)); assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my subgroup attribute"), containsInAnyOrder("my subgroup attribute value", "my subgroup attribute second value"))); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -993,7 +1021,7 @@ void shouldUpdateRealmUpdateGroupAddSecondAttributeToSubGroup() throws IOExcepti assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1009,8 +1037,8 @@ void shouldUpdateRealmUpdateGroupAddSecondAttributeToSubGroup() throws IOExcepti assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my subgroup attribute"), containsInAnyOrder("my subgroup attribute value", "my subgroup attribute second value"))); assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my second subgroup attribute"), containsInAnyOrder("my second subgroup attribute value", "my second subgroup attribute second value"))); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -1029,7 +1057,7 @@ void shouldUpdateRealmUpdateGroupRemoveAttributeValueFromSubGroup() throws IOExc assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1043,8 +1071,8 @@ void shouldUpdateRealmUpdateGroupRemoveAttributeValueFromSubGroup() throws IOExc assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(2)); assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my subgroup attribute"), containsInAnyOrder("my subgroup attribute second value"))); assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my second subgroup attribute"), containsInAnyOrder("my second subgroup attribute value", "my second subgroup attribute second value"))); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -1064,7 +1092,7 @@ void shouldUpdateRealmUpdateGroupRemoveAttributeFromSubGroup() throws IOExceptio assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1077,8 +1105,8 @@ void shouldUpdateRealmUpdateGroupRemoveAttributeFromSubGroup() throws IOExceptio assertThat("subgroup's path not equal", subGroup.getPath(), is("/My Group/My SubGroup")); assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(1)); assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my second subgroup attribute"), containsInAnyOrder("my second subgroup attribute value", "my second subgroup attribute second value"))); - assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupRealmRolesAreEmpty(subGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -1098,7 +1126,7 @@ void shouldUpdateRealmUpdateGroupAddRealmRoleToSubGroup() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1117,7 +1145,7 @@ void shouldUpdateRealmUpdateGroupAddRealmRoleToSubGroup() throws IOException { assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), contains("my_realm_role")); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -1137,7 +1165,7 @@ void shouldUpdateRealmUpdateGroupAddSecondRealmRoleToSubGroup() throws IOExcepti assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1151,7 +1179,7 @@ void shouldUpdateRealmUpdateGroupAddSecondRealmRoleToSubGroup() throws IOExcepti assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(1)); assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my second subgroup attribute"), containsInAnyOrder("my second subgroup attribute value", "my second subgroup attribute second value"))); assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), containsInAnyOrder("my_realm_role", "my_second_realm_role")); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -1171,7 +1199,7 @@ void shouldUpdateRealmUpdateGroupRemoveRealmRoleFromSubGroup() throws IOExceptio assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1185,7 +1213,7 @@ void shouldUpdateRealmUpdateGroupRemoveRealmRoleFromSubGroup() throws IOExceptio assertThat("subgroup's attributes is null", subGroup.getAttributes(), aMapWithSize(1)); assertThat("subgroup's attributes is null", subGroup.getAttributes(), hasEntry(is("my second subgroup attribute"), containsInAnyOrder("my second subgroup attribute value", "my second subgroup attribute second value"))); assertThat("subgroup's realm roles is null", subGroup.getRealmRoles(), contains("my_second_realm_role")); - assertThat("subgroup's client roles is null", subGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupClientRolesAreEmpty(subGroup.getClientRoles()); assertThat("subgroup's subgroups is null", subGroup.getSubGroups(), hasSize(0)); } @@ -1205,7 +1233,7 @@ void shouldUpdateRealmUpdateGroupAddClientRoleToSubGroup() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1240,7 +1268,7 @@ void shouldUpdateRealmUpdateGroupAddSecondClientRoleToSubGroup() throws IOExcept assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1275,7 +1303,7 @@ void shouldUpdateRealmUpdateGroupAddSecondClientRolesToSubGroup() throws IOExcep assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1311,7 +1339,7 @@ void shouldUpdateRealmUpdateGroupRemoveClientRoleFromSubGroup() throws IOExcepti assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1347,7 +1375,7 @@ void shouldUpdateRealmUpdateGroupRemoveClientRolesFromSubGroup() throws IOExcept assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1382,7 +1410,7 @@ void shouldUpdateRealmUpdateGroupAddSubGroupToSubGroup() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1406,9 +1434,9 @@ void shouldUpdateRealmUpdateGroupAddSubGroupToSubGroup() throws IOException { assertThat("inner subgroup is null", innerSubGroup, notNullValue()); assertThat("subgroup's name not equal", innerSubGroup.getName(), is("My inner SubGroup")); assertThat("subgroup's path not equal", innerSubGroup.getPath(), is("/My Group/My SubGroup/My inner SubGroup")); - assertThat("subgroup's attributes is null", innerSubGroup.getAttributes(), aMapWithSize(0)); - assertThat("subgroup's realm roles is null", innerSubGroup.getRealmRoles(), hasSize(0)); - assertThat("subgroup's client roles is null", innerSubGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(innerSubGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(innerSubGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(innerSubGroup.getClientRoles()); } @Test @@ -1427,7 +1455,7 @@ void shouldUpdateRealmUpdateGroupAddSecondSubGroupToSubGroup() throws IOExceptio assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1455,9 +1483,9 @@ void shouldUpdateRealmUpdateGroupAddSecondSubGroupToSubGroup() throws IOExceptio assertThat("inner subgroup is null", innerSubGroup, notNullValue()); assertThat("inner subgroup's name not equal", innerSubGroup.getName(), is("My inner SubGroup")); assertThat("inner subgroup's path not equal", innerSubGroup.getPath(), is("/My Group/My SubGroup/My inner SubGroup")); - assertThat("inner subgroup's attributes is null", innerSubGroup.getAttributes(), aMapWithSize(0)); - assertThat("inner subgroup's realm roles is null", innerSubGroup.getRealmRoles(), hasSize(0)); - assertThat("inner subgroup's client roles is null", innerSubGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(innerSubGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(innerSubGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(innerSubGroup.getClientRoles()); assertThat("inner subgroup's subgroups is null", innerSubGroup.getSubGroups(), hasSize(0)); innerSubGroup = innerSubGroups.stream() @@ -1467,9 +1495,9 @@ void shouldUpdateRealmUpdateGroupAddSecondSubGroupToSubGroup() throws IOExceptio assertThat("inner subgroup is null", innerSubGroup, notNullValue()); assertThat("inner subgroup's name not equal", innerSubGroup.getName(), is("My second inner SubGroup")); assertThat("inner subgroup's path not equal", innerSubGroup.getPath(), is("/My Group/My SubGroup/My second inner SubGroup")); - assertThat("inner subgroup's attributes is null", innerSubGroup.getAttributes(), aMapWithSize(0)); - assertThat("inner subgroup's realm roles is null", innerSubGroup.getRealmRoles(), hasSize(0)); - assertThat("inner subgroup's client roles is null", innerSubGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(innerSubGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(innerSubGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(innerSubGroup.getClientRoles()); assertThat("inner subgroup's subgroups is null", innerSubGroup.getSubGroups(), hasSize(0)); } @@ -1489,7 +1517,7 @@ void shouldUpdateRealmUpdateGroupUpdateSubGroupInSubGroup() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1529,10 +1557,9 @@ void shouldUpdateRealmUpdateGroupUpdateSubGroupInSubGroup() throws IOException { assertThat("inner inner subgroup is null", innerInnerSubGroup, notNullValue()); assertThat("inner inner subgroup's name not equal", innerInnerSubGroup.getName(), is("My inner inner SubGroup")); assertThat("inner inner subgroup's path not equal", innerInnerSubGroup.getPath(), is("/My Group/My SubGroup/My inner SubGroup/My inner inner SubGroup")); - assertThat("inner inner subgroup's attributes is null", innerInnerSubGroup.getAttributes(), aMapWithSize(0)); - assertThat("inner inner subgroup's realm roles is null", innerInnerSubGroup.getRealmRoles(), hasSize(0)); - assertThat("inner inner subgroup's client roles is null", innerInnerSubGroup.getClientRoles(), aMapWithSize(0)); - + assertThatGroupAttributesAreEmpty(innerInnerSubGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(innerInnerSubGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(innerInnerSubGroup.getClientRoles()); innerSubGroup = innerSubGroups.stream() .filter(s -> Objects.equals(s.getName(), "My second inner SubGroup")) @@ -1541,9 +1568,9 @@ void shouldUpdateRealmUpdateGroupUpdateSubGroupInSubGroup() throws IOException { assertThat("inner subgroup is null", innerSubGroup, notNullValue()); assertThat("inner subgroup's name not equal", innerSubGroup.getName(), is("My second inner SubGroup")); assertThat("inner subgroup's path not equal", innerSubGroup.getPath(), is("/My Group/My SubGroup/My second inner SubGroup")); - assertThat("inner subgroup's attributes is null", innerSubGroup.getAttributes(), aMapWithSize(0)); - assertThat("inner subgroup's realm roles is null", innerSubGroup.getRealmRoles(), hasSize(0)); - assertThat("inner subgroup's client roles is null", innerSubGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(innerSubGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(innerSubGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(innerSubGroup.getClientRoles()); assertThat("inner subgroup's subgroups is null", innerSubGroup.getSubGroups(), hasSize(0)); } @@ -1563,7 +1590,7 @@ void shouldUpdateRealmUpdateGroupDeleteSubGroupInSubGroup() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1591,9 +1618,9 @@ void shouldUpdateRealmUpdateGroupDeleteSubGroupInSubGroup() throws IOException { assertThat("inner subgroup is null", innerSubGroup, notNullValue()); assertThat("inner subgroup's name not equal", innerSubGroup.getName(), is("My second inner SubGroup")); assertThat("inner subgroup's path not equal", innerSubGroup.getPath(), is("/My Group/My SubGroup/My second inner SubGroup")); - assertThat("inner subgroup's attributes is null", innerSubGroup.getAttributes(), aMapWithSize(0)); - assertThat("inner subgroup's realm roles is null", innerSubGroup.getRealmRoles(), hasSize(0)); - assertThat("inner subgroup's client roles is null", innerSubGroup.getClientRoles(), aMapWithSize(0)); + assertThatGroupAttributesAreEmpty(innerSubGroup.getAttributes()); + assertThatGroupRealmRolesAreEmpty(innerSubGroup.getRealmRoles()); + assertThatGroupClientRolesAreEmpty(innerSubGroup.getClientRoles()); assertThat("inner subgroup's subgroups is null", innerSubGroup.getSubGroups(), hasSize(0)); } @@ -1613,7 +1640,7 @@ void shouldUpdateRealmUpdateGroupDeleteSubGroup() throws IOException { assertThat("attributes roles is null", updatedGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", updatedGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", updatedGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(updatedGroup.getRealmRoles()); assertThat("client roles is null", updatedGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", updatedGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1637,7 +1664,7 @@ void shouldUpdateRealmAddGroupWithSubstringOfExistingGroupName() throws IOExcept assertThat("attributes roles is null", existingGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", existingGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", existingGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(existingGroup.getRealmRoles()); assertThat("client roles is null", existingGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", existingGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1668,7 +1695,7 @@ void shouldUpdateRealmUpdateGroupWithSubstringOfExistingGroupName() throws IOExc assertThat("attributes roles is null", existingGroup.getAttributes(), aMapWithSize(1)); assertThat("attributes roles is null", existingGroup.getAttributes(), hasEntry(is("my changed attribute"), containsInAnyOrder("my changed attribute value"))); - assertThat("realm roles is null", existingGroup.getRealmRoles(), hasSize(0)); + assertThatGroupRealmRolesAreEmpty(existingGroup.getRealmRoles()); assertThat("client roles is null", existingGroup.getClientRoles(), aMapWithSize(1)); assertThat("client roles is null", existingGroup.getClientRoles(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_client_role_of_second-moped-client", "my_second_client_role_of_second-moped-client"))); @@ -1715,6 +1742,10 @@ void shouldUpdateRealmDeleteAllGroups() throws IOException { } private GroupRepresentation loadGroup(String groupPath) { + return loadGroup(groupPath, true); + } + + private GroupRepresentation loadGroup(String groupPath, boolean fetchSubGroupsRecursively) { GroupsResource groupsResource = keycloakProvider.getInstance() .realm(REALM_NAME) .groups(); @@ -1726,9 +1757,24 @@ private GroupRepresentation loadGroup(String groupPath) { .findFirst() .orElseThrow(() -> new KeycloakRepositoryException("Can't find group '%s'.", groupPath)); - return groupsResource - .group(groupRepresentation.getId()) + GroupResource groupResource = groupsResource + .group(groupRepresentation.getId()); + GroupRepresentation group = groupResource .toRepresentation(); + + if (fetchSubGroupsRecursively) { + tryToFetchSubGroups(groupsResource, group); + } + + return group; + } + + private void tryToFetchSubGroups(GroupsResource groupsResource, GroupRepresentation currentGroup) { + if (currentGroup.getSubGroupCount() > 0) { + List subGroups = new ArrayList<>(groupsResource.group(currentGroup.getId()).getSubGroups(0, 100, true)); + subGroups.forEach(subGroupRep -> tryToFetchSubGroups(groupsResource, subGroupRep)); + currentGroup.setSubGroups(subGroups); + } } private Optional tryToLoadGroup(String groupPath) { diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportUserProfileIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportUserProfileIT.java index d7c0a407b..ff1475011 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportUserProfileIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportUserProfileIT.java @@ -20,7 +20,10 @@ package de.adorsys.keycloak.config.service; import de.adorsys.keycloak.config.AbstractImportIT; +import de.adorsys.keycloak.config.util.JsonUtil; +import de.adorsys.keycloak.config.util.VersionUtil; import org.hamcrest.Matcher; +import org.junit.Assume; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; @@ -46,6 +49,9 @@ public class ImportUserProfileIT extends AbstractImportIT { @Order(0) @DisabledIfSystemProperty(named = "keycloak.version", matches = "16.1.1", disabledReason = "Not working") void shouldCreateRealmButNoUserProfileEnabled() throws IOException { + + Assume.assumeTrue(VersionUtil.le(KEYCLOAK_VERSION, "23")); // this behaviour changed in Keycloak 23 + doImport("00_ignore_realm_with_user_profile.json"); assertRealm(false); @@ -108,6 +114,9 @@ void shouldNotUpdateRealmByRemoveProfileWhenNothingSet() throws IOException { @Order(4) @DisabledIfSystemProperty(named = "keycloak.version", matches = "16.1.1", disabledReason = "Not working") void shouldUpdateRealmByRemoveProfileWhenSwitchedOff() throws IOException { + + Assume.assumeTrue(VersionUtil.le(KEYCLOAK_VERSION, "23")); // this behaviour changed in Keycloak 23 + doImport("04_update_realm_with_user_profile_switched_off.json"); assertRealm(false); @@ -129,7 +138,7 @@ private String assertRealmHasUserProfileConfigurationStringWith(Matcher assertThat(userProfileResourceConfiguration, matcher); - return userProfileResourceConfiguration; + return JsonUtil.toJson(userProfileResourceConfiguration); } } diff --git a/src/test/resources/import-files/exported-realm/23.0.1/master-realm.json b/src/test/resources/import-files/exported-realm/23.0.1/master-realm.json new file mode 100644 index 000000000..a6bb58ace --- /dev/null +++ b/src/test/resources/import-files/exported-realm/23.0.1/master-realm.json @@ -0,0 +1,1772 @@ +{ + "id" : "f864fc8e-1e4b-4ad5-ac32-3ef9ad0e4e99", + "realm" : "master", + "displayName" : "Keycloak", + "displayNameHtml" : "
Keycloak
", + "notBefore" : 0, + "defaultSignatureAlgorithm" : "RS256", + "revokeRefreshToken" : false, + "refreshTokenMaxReuse" : 0, + "accessTokenLifespan" : 60, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "ssoSessionIdleTimeoutRememberMe" : 0, + "ssoSessionMaxLifespanRememberMe" : 0, + "offlineSessionIdleTimeout" : 2592000, + "offlineSessionMaxLifespanEnabled" : false, + "offlineSessionMaxLifespan" : 5184000, + "clientSessionIdleTimeout" : 0, + "clientSessionMaxLifespan" : 0, + "clientOfflineSessionIdleTimeout" : 0, + "clientOfflineSessionMaxLifespan" : 0, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "actionTokenGeneratedByAdminLifespan" : 43200, + "actionTokenGeneratedByUserLifespan" : 300, + "oauth2DeviceCodeLifespan" : 600, + "oauth2DevicePollingInterval" : 5, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : false, + "registrationEmailAsUsername" : false, + "rememberMe" : false, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : false, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "permanentLockout" : false, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "becef492-ce9d-45f6-b346-335bb74cdd47", + "name" : "create-realm", + "description" : "${role_create-realm}", + "composite" : false, + "clientRole" : false, + "containerId" : "f864fc8e-1e4b-4ad5-ac32-3ef9ad0e4e99", + "attributes" : { } + }, { + "id" : "4f369d83-7eee-4c83-a8a8-8d8463712a2b", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "f864fc8e-1e4b-4ad5-ac32-3ef9ad0e4e99", + "attributes" : { } + }, { + "id" : "8cc019f6-0254-4940-9077-6e0f798d5bdb", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "f864fc8e-1e4b-4ad5-ac32-3ef9ad0e4e99", + "attributes" : { } + }, { + "id" : "f0a4ef41-dba8-464b-aa17-dcd80a84ab41", + "name" : "admin", + "description" : "${role_admin}", + "composite" : true, + "composites" : { + "realm" : [ "create-realm" ], + "client" : { + "master-realm" : [ "impersonation", "view-authorization", "view-realm", "query-groups", "view-clients", "create-client", "query-users", "manage-realm", "manage-clients", "manage-users", "view-identity-providers", "manage-events", "view-users", "query-realms", "view-events", "query-clients", "manage-authorization", "manage-identity-providers" ] + } + }, + "clientRole" : false, + "containerId" : "f864fc8e-1e4b-4ad5-ac32-3ef9ad0e4e99", + "attributes" : { } + }, { + "id" : "89685f71-2e15-408d-bc44-3e35b5b09cf7", + "name" : "default-roles-master", + "description" : "${role_default-roles}", + "composite" : true, + "composites" : { + "realm" : [ "offline_access", "uma_authorization" ], + "client" : { + "account" : [ "view-profile", "manage-account" ] + } + }, + "clientRole" : false, + "containerId" : "f864fc8e-1e4b-4ad5-ac32-3ef9ad0e4e99", + "attributes" : { } + } ], + "client" : { + "security-admin-console" : [ ], + "admin-cli" : [ ], + "account-console" : [ ], + "broker" : [ { + "id" : "e5cc8d64-41d8-4973-8e80-68c7cfc23aea", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "19d0e784-f869-4267-885c-4e88c150cddb", + "attributes" : { } + } ], + "master-realm" : [ { + "id" : "683eba20-d03e-49a7-927c-76f205837b98", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "d72ca93c-a3a9-48ed-a4b2-f542111cef44", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "23e2ad8e-fcbb-42a7-a1bf-b0113bbda244", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "212b1c23-3b18-4a98-9b41-671fa2aa06ed", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "bb238570-d5ca-4b85-bf8a-2519fa0f583f", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "5dd897fb-8dfc-43d3-9c4a-33fbe4d6a3d9", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "3dcbf2d9-0873-47ac-8040-129df12e1810", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "fd93e2fa-9686-4ccc-8439-4a9428e54f5b", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "d7e04c77-3887-4189-ab86-b07310f3ea5a", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "3bcbcf1e-2971-4376-95a6-455d12a18776", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "4a9f0ee4-9c99-46eb-8e62-62360d9ed63e", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "fff9d15b-e8c4-4e2d-8db5-a0b6d6576478", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "fe75aebc-5622-45a3-822b-a0ee80c14f27", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-groups", "query-users" ] + } + }, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "349f4b94-4a1f-4bda-8e0b-7c70e64fe40c", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "796b20f8-ac63-458e-8385-b65f073c2522", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "2d714ed6-3c44-43a8-903a-0dd548c474f3", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "a8222f81-cfaa-480e-8326-fa3aeba75282", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + }, { + "id" : "fc594691-3ba2-4f5d-ac52-13962cf9144a", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "attributes" : { } + } ], + "account" : [ { + "id" : "163b2aec-16c1-40ee-b207-4b1bad33a996", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "attributes" : { } + }, { + "id" : "ec792383-978e-4b65-841e-10a44d64ff2f", + "name" : "view-consent", + "description" : "${role_view-consent}", + "composite" : false, + "clientRole" : true, + "containerId" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "attributes" : { } + }, { + "id" : "cb7b33ac-9846-45fe-bda7-1a2dd77df293", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "attributes" : { } + }, { + "id" : "c788c27b-2630-410e-a6be-35d564aed14e", + "name" : "manage-consent", + "description" : "${role_manage-consent}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "view-consent" ] + } + }, + "clientRole" : true, + "containerId" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "attributes" : { } + }, { + "id" : "80e0cf12-d19f-4259-bee2-a7978b14be97", + "name" : "view-applications", + "description" : "${role_view-applications}", + "composite" : false, + "clientRole" : true, + "containerId" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "attributes" : { } + }, { + "id" : "2d004ebd-89ab-4594-ba5a-51b131c9649c", + "name" : "delete-account", + "description" : "${role_delete-account}", + "composite" : false, + "clientRole" : true, + "containerId" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "attributes" : { } + }, { + "id" : "c93b1813-cfec-433b-8273-34623b34dff1", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "attributes" : { } + }, { + "id" : "4a4eb610-927b-40ed-95a9-6bd4cd35924b", + "name" : "view-groups", + "description" : "${role_view-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "attributes" : { } + } ] + } + }, + "groups" : [ ], + "defaultRole" : { + "id" : "89685f71-2e15-408d-bc44-3e35b5b09cf7", + "name" : "default-roles-master", + "description" : "${role_default-roles}", + "composite" : true, + "clientRole" : false, + "containerId" : "f864fc8e-1e4b-4ad5-ac32-3ef9ad0e4e99" + }, + "requiredCredentials" : [ "password" ], + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "otpPolicyCodeReusable" : false, + "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ], + "localizationTexts" : { }, + "webAuthnPolicyRpEntityName" : "keycloak", + "webAuthnPolicySignatureAlgorithms" : [ "ES256" ], + "webAuthnPolicyRpId" : "", + "webAuthnPolicyAttestationConveyancePreference" : "not specified", + "webAuthnPolicyAuthenticatorAttachment" : "not specified", + "webAuthnPolicyRequireResidentKey" : "not specified", + "webAuthnPolicyUserVerificationRequirement" : "not specified", + "webAuthnPolicyCreateTimeout" : 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyAcceptableAaguids" : [ ], + "webAuthnPolicyExtraOrigins" : [ ], + "webAuthnPolicyPasswordlessRpEntityName" : "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ], + "webAuthnPolicyPasswordlessRpId" : "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified", + "webAuthnPolicyPasswordlessCreateTimeout" : 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ], + "webAuthnPolicyPasswordlessExtraOrigins" : [ ], + "scopeMappings" : [ { + "clientScope" : "offline_access", + "roles" : [ "offline_access" ] + } ], + "clientScopeMappings" : { + "account" : [ { + "client" : "account-console", + "roles" : [ "manage-account", "view-groups" ] + } ] + }, + "clients" : [ { + "id" : "23eb051d-1191-40cd-9cd0-cc140bab5c2b", + "clientId" : "account", + "name" : "${client_account}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/master/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/master/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "349c85e4-3ef1-4d40-91c8-9a6c4fbb0c99", + "clientId" : "account-console", + "name" : "${client_account-console}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/master/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/master/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "d70116a7-7b63-466e-9206-4ba26fff6671", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "37e83294-6acc-4d27-8a77-dc2b6e4c5bcb", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "19d0e784-f869-4267-885c-4e88c150cddb", + "clientId" : "broker", + "name" : "${client_broker}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "5afaa131-9945-49c6-8bde-9e0c37412971", + "clientId" : "master-realm", + "name" : "master Realm", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "e9d80ce4-1a35-42d1-a3b6-5be7ee6c0711", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "rootUrl" : "${authAdminUrl}", + "baseUrl" : "/admin/master/console/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/admin/master/console/*" ], + "webOrigins" : [ "+" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "9b9690ac-7667-4f91-9420-07e6a98a02af", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + } ], + "clientScopes" : [ { + "id" : "bedc83e2-ab6c-4821-8470-85641d15a4a0", + "name" : "email", + "description" : "OpenID Connect built-in scope: email", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${emailScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "74eeed0f-9d2c-413e-9e17-a3e0306de398", + "name" : "email verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "emailVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "c7c3d787-b341-45a1-b199-c72002dea855", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "63bda3c3-8815-4249-8914-a8fc2f65ce12", + "name" : "phone", + "description" : "OpenID Connect built-in scope: phone", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${phoneScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "e539c990-053a-47dd-b893-650afb6ebd6c", + "name" : "phone number", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumber", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number", + "jsonType.label" : "String" + } + }, { + "id" : "f1a0a179-ceb0-4363-aa97-af661fcfffec", + "name" : "phone number verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumberVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number_verified", + "jsonType.label" : "boolean" + } + } ] + }, { + "id" : "c0ee11df-fe36-4f1e-92f0-28e86193bbff", + "name" : "acr", + "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "ad987c7a-79c4-44f9-a49e-4bc3f7e165c4", + "name" : "acr loa level", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-acr-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "5c1ce5cf-25c1-4bfb-8595-8cb416722061", + "name" : "web-origins", + "description" : "OpenID Connect scope for add allowed web origins to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false", + "consent.screen.text" : "" + }, + "protocolMappers" : [ { + "id" : "fba18ee2-d8d0-47a3-ba77-bb56f5bfacb8", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "d635990b-4d4a-48bd-9e38-37e33a3dcf15", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "4c0089fd-e31d-4f23-a5ce-0a27f4f8c2bb", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + }, { + "id" : "b87fe1c7-d9de-4e02-83dd-6bdb46cdf900", + "name" : "profile", + "description" : "OpenID Connect built-in scope: profile", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${profileScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "3d81d620-85ab-4544-8a96-632a40c37d45", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "f6a7cc22-7bf0-4d49-9313-d1c8b3502dcb", + "name" : "gender", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "gender", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "gender", + "jsonType.label" : "String" + } + }, { + "id" : "bfd0ea27-8205-4ad3-872c-ddf8603b7f25", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "34b78b7f-68f8-4512-8b4e-34fbfb9a5cac", + "name" : "website", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "website", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "website", + "jsonType.label" : "String" + } + }, { + "id" : "a746b73c-8cdd-4a77-97b6-1bc829a79f3a", + "name" : "profile", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "profile", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "profile", + "jsonType.label" : "String" + } + }, { + "id" : "40fb3f80-8f17-46eb-96ba-20ef9636e183", + "name" : "birthdate", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "birthdate", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "birthdate", + "jsonType.label" : "String" + } + }, { + "id" : "e77ba200-1e24-41d1-a0b6-d821a5c1e98e", + "name" : "picture", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "picture", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "picture", + "jsonType.label" : "String" + } + }, { + "id" : "57e65e6e-6f41-4b60-b6dc-42e89ed15b7a", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "01fb8f70-7bc7-4bd9-ae04-3b6da6e62f58", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "b1e355e4-41d7-438a-a233-887da89f275f", + "name" : "middle name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "middleName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "middle_name", + "jsonType.label" : "String" + } + }, { + "id" : "f4c8e88f-cd09-4fe2-ab58-11934a3f71c7", + "name" : "updated at", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "updatedAt", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "updated_at", + "jsonType.label" : "long" + } + }, { + "id" : "d1deb1a4-7c5d-4d24-8d65-73c606dc963f", + "name" : "zoneinfo", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "zoneinfo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "zoneinfo", + "jsonType.label" : "String" + } + }, { + "id" : "9bccea0d-b080-4d78-9d53-76a6f6827ddc", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + }, { + "id" : "afa3fc4c-01da-4a03-a5ab-a6d50fd5d8c4", + "name" : "nickname", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "nickname", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "nickname", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "e647e4f0-74c0-4043-8dce-133541e90388", + "name" : "roles", + "description" : "OpenID Connect scope for add user roles to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${rolesScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "cae5508d-8be7-4b09-aba4-28c6136235fb", + "name" : "realm roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "user.attribute" : "foo", + "access.token.claim" : "true", + "claim.name" : "realm_access.roles", + "jsonType.label" : "String" + } + }, { + "id" : "accccc34-49b0-4517-9250-3cc3772e5b5a", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "b71ff5af-2224-4777-bdcd-efe0e603cc7f", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "user.attribute" : "foo", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "7f004867-b251-4278-a8d1-c1320506803a", + "name" : "offline_access", + "description" : "OpenID Connect built-in scope: offline_access", + "protocol" : "openid-connect", + "attributes" : { + "consent.screen.text" : "${offlineAccessScopeConsentText}", + "display.on.consent.screen" : "true" + } + }, { + "id" : "7b8f49ab-58bf-401f-af13-fedc56ae9b9d", + "name" : "microprofile-jwt", + "description" : "Microprofile - JWT built-in scope", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "395d2827-8258-4a22-a0a9-c621df065f63", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "upn", + "jsonType.label" : "String" + } + }, { + "id" : "5a8e78d0-4eeb-46eb-85d1-9bba51461451", + "name" : "groups", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "user.attribute" : "foo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "groups", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "1dcc80fa-0e32-4b4e-8eeb-edf2ac123562", + "name" : "address", + "description" : "OpenID Connect built-in scope: address", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${addressScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "f03d6ec2-f375-45f8-8020-f397013668a4", + "name" : "address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-address-mapper", + "consentRequired" : false, + "config" : { + "user.attribute.formatted" : "formatted", + "user.attribute.country" : "country", + "introspection.token.claim" : "true", + "user.attribute.postal_code" : "postal_code", + "userinfo.token.claim" : "true", + "user.attribute.street" : "street", + "id.token.claim" : "true", + "user.attribute.region" : "region", + "access.token.claim" : "true", + "user.attribute.locality" : "locality" + } + } ] + } ], + "defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins", "acr" ], + "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt" ], + "browserSecurityHeaders" : { + "contentSecurityPolicyReportOnly" : "", + "xContentTypeOptions" : "nosniff", + "referrerPolicy" : "no-referrer", + "xRobotsTag" : "none", + "xFrameOptions" : "SAMEORIGIN", + "xXSSProtection" : "1; mode=block", + "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "strictTransportSecurity" : "max-age=31536000; includeSubDomains" + }, + "smtpServer" : { }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "identityProviders" : [ ], + "identityProviderMappers" : [ ], + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "33d96fb5-9b88-4d75-aac2-03e909bd87d3", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "a65f2110-7443-407f-9b62-d6ca5460471a", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "saml-user-attribute-mapper" ] + } + }, { + "id" : "9bcdd083-a950-49a1-920b-9d834191b723", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "adf726d8-faf1-489e-812c-67e70a355318", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "fe150616-c52d-40b6-bbb2-88d9b48943aa", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "49be4701-73a6-40b1-96dc-0fdea354a2da", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper" ] + } + }, { + "id" : "b9be111a-59b3-43c9-a7c7-47d290c7793d", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "b5efa296-9805-4975-a864-4d35dca707d8", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "0c248c7a-ca13-4291-83f3-5317f6d514b5", + "name" : "aes-generated", + "providerId" : "aes-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "0fb17d18-dddb-4d1e-9315-d543330dcbc2" ], + "secret" : [ "jyT_gDXoXhA6TaceX39Npg" ], + "priority" : [ "100" ] + } + }, { + "id" : "58d06074-4a1f-46e6-8bbd-599566e24afa", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEAw82N5XLA8G7+i5vksWFnrHE+sDe/YDo1fdFnvrqyj9kfmIl1whkLkUzNTqGhn4zR7w1nHf4zbHrBQXXNfsIY9v7KEJ5h9g6DFUXajAm4zsY1pX3xzwVdti8cdxT6Jdx4x9WQ4GUnJSo2IQWISyaSz+souyKc4Yniocfl5E5JSA9w5S2nuu/CpB4X4ExWH4b9CxOsMJTXEj4tezgAq8cIdCMCNiZnDmnXzCt7aC1Jdm7ZGAapfhLFEL3e/CxiCxKP/b660QzRXYeiUpRDWNxE30LIKAW/rfTMph3JIE8c5RKJ522xQFm+GCxNnFqyi5n/wGtDMLzSQ/wUuwdb7uxLkwIDAQABAoIBABGYi9tmTBtvRhXCvTMJl1kCVklcwSiDIqJ7apDT008lCndZRwlZ2dXFap/Z253seEM815r06KcjgvGAhiaRh8/OhtcmfJQxqqsDO4ghKYf/fPuxzUS27Tx9kFfNPUugvAPtV9cqj/GBkRq3lg922HOx5NeoXSPRkdnLDohNVr2QaWkjKJufAqf7vhMBug/Sd31bGRJgNnmTR3fUVr+i/m6pzYirB0+iyfiegOuYYqHyvwRYy75VtCDN8PjZRFy+rC2pi61vLWL5AM9hKdayL4MQyONnmojLlZlabFUO6IVUBD5NwwNoHtepkixrxNWaa/oNbkBHu5+6GioFIzMJZkUCgYEA5sw1ICInU0BWns0vFZGIAcivJagzAHgEOlA4epaeYnp8HfLr0dI/oF3wgaS6UgUX90y95mxwmLjsEhWXIy4WJ1blqClI7ciMpmOhCcijx/4JDe8NvbC2Kpovs4B7OjuU2oOJhq/n9vOBHNcP8C+sCg5aELK4iqGVMydgETXK1gUCgYEA2S8XtOvBtRb0kVGKsxatZtktMec8qJoFDGVceZY+7BpJGkWYV7M3mYo+/qCj7CYEGarHZlNx8q733ZnrD/YsdxF8JaEvrHWD1AkeVbbnyCz/ZX8rK9o/mAe2dcvZd63WB3DYIkEyrKjQDs0pfudRUn/HmBZvYxt927mhdS7bdrcCgYAIBM5PuIAPR2v7Bnv9Ttof3b4gG9Dx0jmrYQAlWjhUiZboX3lMB/cH9luV1YhXsy+a+wKaD+h1le81zaQ7p61DXqSKDC0pfc9NNKbytRLjrvLXlhevIIWjw0mm/e7KHinU0b8ke9YeYWV6AArguHdMviTo8ZyxzF1nspWG44yRlQKBgQCJAdNDt8IQOjX4gmcsCO9ExVZkd8plVhw/MKZAsY5qJT7eiu7KzG0TuAl7Wd1u+KB3jKuTmqp0fPoyWonWHOb6Cha2KlPHyK5sEYCIdAUN240V+z5BwMGDZ8Ir13gNrqUpNn+yREzybOArpjM6MjS0BZXlFKoZ7FreROFc6j1aSwKBgQCqi6mOFpcMH/6sgyX1UR8MURO7uzDHi+tqM4EA4wnTK2vvIOwl1iFPeKNEiOrbYMguIuKf20bBqx7n6OS0hGJFcKxrn+NzszElydEWH2mubR2AY7MLQz4hS2e4+OIOhqmZ2kk3GHcPCK0IeKpgL1E+omd6Y4hu1gxIkGUkGZcdJQ==" ], + "keyUse" : [ "SIG" ], + "certificate" : [ "MIICmzCCAYMCBgGMNwwS6jANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjMxMjA0MjI1NDQ3WhcNMzMxMjA0MjI1NjI3WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDzY3lcsDwbv6Lm+SxYWescT6wN79gOjV90We+urKP2R+YiXXCGQuRTM1OoaGfjNHvDWcd/jNsesFBdc1+whj2/soQnmH2DoMVRdqMCbjOxjWlffHPBV22Lxx3FPol3HjH1ZDgZSclKjYhBYhLJpLP6yi7IpzhieKhx+XkTklID3DlLae678KkHhfgTFYfhv0LE6wwlNcSPi17OACrxwh0IwI2JmcOadfMK3toLUl2btkYBql+EsUQvd78LGILEo/9vrrRDNFdh6JSlENY3ETfQsgoBb+t9MymHckgTxzlEonnbbFAWb4YLE2cWrKLmf/Aa0MwvNJD/BS7B1vu7EuTAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADdW/GKNJg9amLMQLut+Rh+7c8UuvoqYg4LDXKrD6kBAlDS8ONdodoNe+plZ9n842uue+jeBDxc8y9Airk9nkZppyqaCT/yVThNCMtbWqKAjKHQWd6QDWs4zwRgKc5dogaZ36X1z8UJvkTolQtE+LgeU5YWLLHi3eLr4LYSYhEstIC0jXrw3w4VHD7hoZ5p4nJuqxgiZ3o90+Uo86KZJHu0LwNjknhLAk1D29G4IperGQvBvG0Hw5VMyMvy0LHtD3OlHbByayUYK9eaeTwLB/+mv1nzLjhZZe5E/h3ezifKHiGXml316RtDR47VVO0ZzScz0Vs1wcDt6bRFvAoh8ifc=" ], + "priority" : [ "100" ] + } + }, { + "id" : "c530d52a-e74d-4c55-9010-da330cf6e744", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "6d33354a-0ba3-4eda-8b73-66717982632c" ], + "secret" : [ "o3XvPWYpEThLZTBMo2WaBkXbxRFuyqfKgIfaF7YYtYXD1j1eDcHUcTzqkvvDvMtiYJBRh86KKe6CLA9mzqivwg" ], + "priority" : [ "100" ], + "algorithm" : [ "HS256" ] + } + }, { + "id" : "fb90f808-f9f3-4524-b25f-b2940b028155", + "name" : "rsa-enc-generated", + "providerId" : "rsa-enc-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEA3eIoo/pCe1yWpFVOcDsIcWznFaZVtShctejXM6sR9MdP2YAfxtyi28O8q54unlw5YBYhBKFvraCzqDqYMU9Vzcbj5Zg4tH7XdV6s4ZTQVet0VrVheRZG+z9UVr2wnznX4HJ++SY73nJxLJNE/69ga1e8em9wq327j3kmRYOGcckiMqZBZCpnoNYrkTSYdoOiu+N5rO6PJZ4ssTy7ZdRqlBDvZoZw+na65W5y7ORV7g9fPu9JuQdi0ZcK6gI4OqVxn/0r87z8rz/nbL5yiNuV3i4M07esDFCKDWgtmMb62IaAI1xFxAmOq9S4HPoAvueO6VzoWm0745HwZjrCz4aD7wIDAQABAoIBAAdZgJofOzOF4hwzEoQ82Fnqzw6/Bz4XG6xk4uKnFdMDWnLsamELxD3o/RIRjR7EFEcerzJNkfrw2fKbxO3L4HOOqn7bl3PscwDuxWWQKIR9ZkmhpscRhKwO3CF8FWJ40odF6PciG+qRj4vNRwRR0AJOPNkwts00vtE7pJe53xVcEeTQZOX2Y0lIBU3OgLMqszzwEQehHtQdBvomEfwgn7xDHuYiNqGqkTooj9ZROjSM7/yzhe/oYJzNV7kj6I2s9sivPxCxRB5BO8Jp8jMUpNBtgoZVZb8GpCxZk5fpG2qeGNeFCNzjqkNYDAI1QzMXGlND5yDw1yAQtSwS41D1xqECgYEA/mDQPerQimk/XlH8tL7/aCTc9v74GwI9XVgiSFoBhk51McEZXjsfp+7VjVgwF4oo6Q79CncMB25y8Xhf3onok9OVwwMlGj6bA5wzbDb2Uw9nTKvvYLNmZsyo7BA07yVnKaCkukU2lgjEdrtBB7RGfPbTo7Q0im5N6tZ3gT2UySECgYEA30xPAFihwCrgLn+H8QrS+d775p6JLfazaD1JXl2xEBNZXkCk5mvI9wHxcN3y5k4lQN4uqxw1RsSm/tVsnJqk332qFn8Rr6uB2B9aYtSd1Egu8dxHaQjgAwVDQyqUITv0nSKZ8H0/mniczXLyfijDYI+0waaZOnYNS5O50LZQWw8CgYAJxQQabKtHtZUWdUWkV3WNtWS7I725o9Nhg2IFr1dBpj/AAm+L++9STszq2ck3DjpWARpczYervWUyuvHLpTZGfyjQTY2ePWtMrzIWZOH+/Kd1/WB7MUisiA2wy0qNKL2WjrHk6YWYK4wIF1b/CcBvSjeEoQYnjub1Lvl2ADx3oQKBgQCeuYZaj6YCjDeotbxy6afIN+nFJ6IJSxiCGzZg3qZy794Rsk/E/o7ujbIK8amsbZXrg0OXG8j/EeBGunym4QIbXx8dOJvgzD/S2Y6NO+cos1qzT0pvbgCWBRKn1sdOzGh3ndXg7ZbdfaiwHWojpWQj6mKpWHwI40tWEp79rep2nwKBgQCy+TofuAimqF45cv2wqxNzbygjSH7XxmhSGWaaGUhyREtXm97WK18p0m6Wbu8cAxu5zhVaKiNWCWD4pPj2W/Qhndgscn8FAlcDn7PHGOPR8uLN+FkChygmJbTdrPfaqqmxpkYhzjBPBuqJiLeaZUcS6GuGvymrC6TTu12flIfASQ==" ], + "keyUse" : [ "ENC" ], + "certificate" : [ "MIICmzCCAYMCBgGMNwwTPjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjMxMjA0MjI1NDQ3WhcNMzMxMjA0MjI1NjI3WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDd4iij+kJ7XJakVU5wOwhxbOcVplW1KFy16NczqxH0x0/ZgB/G3KLbw7yrni6eXDlgFiEEoW+toLOoOpgxT1XNxuPlmDi0ftd1XqzhlNBV63RWtWF5Fkb7P1RWvbCfOdfgcn75JjvecnEsk0T/r2BrV7x6b3CrfbuPeSZFg4ZxySIypkFkKmeg1iuRNJh2g6K743ms7o8lniyxPLtl1GqUEO9mhnD6drrlbnLs5FXuD18+70m5B2LRlwrqAjg6pXGf/SvzvPyvP+dsvnKI25XeLgzTt6wMUIoNaC2YxvrYhoAjXEXECY6r1Lgc+gC+547pXOhabTvjkfBmOsLPhoPvAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKBe8AdTeW6yDn8NHIOS8e513huNRALZlfRmSXbZwOICmXaJe0KVFUW4A088iz3oiUpXK5r290GMEGm7+6Vb+0VNwpzxF8/V8+17hAzm3HtV5/Td3eonwb1WYj7PfRHPHDIGz0OafH9DGDTsyze3v9gjMQGFyoSyWAgKhluyOceauy9xmcHygeDql30zW+jPi9Dgf4qfQta/zgvvxnAvPB2LGVFPDEFhRvxvBv1fW209wTBN3TY3cEaHjvpzUEV4fN05MMXpLLNa4UmCOEs1JWlMkMTCaKnabQG8LfrXnGlTRehYPkmU7Rfae4LGQeCn4uw01AQHZrxtYIqTSJ0Bqeo=" ], + "priority" : [ "100" ], + "algorithm" : [ "RSA-OAEP" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "4f49ece2-dfc0-42ab-badc-5aaa30a4180e", + "alias" : "Account verification options", + "description" : "Method with which to verity the existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-email-verification", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Verify Existing Account by Re-authentication", + "userSetupAllowed" : false + } ] + }, { + "id" : "3b99f9b0-a260-49bf-b771-3dae88afa5ea", + "alias" : "Browser - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-otp-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "27e48546-3b96-4f65-8861-b46798555237", + "alias" : "Direct Grant - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "direct-grant-validate-otp", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "2c5831d9-476c-45df-b814-1f862a40b16a", + "alias" : "First broker login - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-otp-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "b6e0484c-bf9a-4e0e-b7e9-bdbda8e1e331", + "alias" : "Handle Existing Account", + "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-confirm-link", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Account verification options", + "userSetupAllowed" : false + } ] + }, { + "id" : "acaac2d0-9618-424d-a9db-599b9077bc5f", + "alias" : "Reset - Conditional OTP", + "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-otp", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "c58c0cb4-43d3-4021-85ef-4e52d467aa22", + "alias" : "User creation or linking", + "description" : "Flow for the existing/non-existing user alternatives", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "create unique user config", + "authenticator" : "idp-create-user-if-unique", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Handle Existing Account", + "userSetupAllowed" : false + } ] + }, { + "id" : "9ae63183-094d-486d-9675-73208a68b3f6", + "alias" : "Verify Existing Account by Re-authentication", + "description" : "Reauthentication of existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "First broker login - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "9a124908-86cd-4cb7-8f2d-e46b4149b2ad", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-spnego", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "identity-provider-redirector", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 25, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 30, + "autheticatorFlow" : true, + "flowAlias" : "forms", + "userSetupAllowed" : false + } ] + }, { + "id" : "d7730796-4688-4760-b66f-57a16efc1717", + "alias" : "clients", + "description" : "Base authentication for clients", + "providerId" : "client-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "client-secret", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-jwt", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-secret-jwt", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 30, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-x509", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 40, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "608e45e4-00af-4a04-b894-fec87b85146c", + "alias" : "direct grant", + "description" : "OpenID Connect Resource Owner Grant", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "direct-grant-validate-username", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "direct-grant-validate-password", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 30, + "autheticatorFlow" : true, + "flowAlias" : "Direct Grant - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "41e4050f-fe78-4ded-bf26-bf2fa0525719", + "alias" : "docker auth", + "description" : "Used by Docker clients to authenticate against the IDP", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "docker-http-basic-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "e678a415-599f-468a-bf43-88b39f9baf63", + "alias" : "first broker login", + "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "review profile config", + "authenticator" : "idp-review-profile", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "User creation or linking", + "userSetupAllowed" : false + } ] + }, { + "id" : "272bd5f4-8ce8-4df6-a529-f1527faa1c28", + "alias" : "forms", + "description" : "Username, password, otp and other auth forms.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Browser - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "a229685f-125f-4511-ab76-f2d15813dd2b", + "alias" : "registration", + "description" : "registration flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-page-form", + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : true, + "flowAlias" : "registration form", + "userSetupAllowed" : false + } ] + }, { + "id" : "e62ca3ea-d9d4-47bf-9cdd-a76eb23887ec", + "alias" : "registration form", + "description" : "registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-password-action", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 50, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-recaptcha-action", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 60, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-terms-and-conditions", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 70, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "b7240a18-d99f-4bfc-8eb2-346d2dcaf170", + "alias" : "reset credentials", + "description" : "Reset credentials for a user if they forgot their password or something", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "reset-credentials-choose-user", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-credential-email", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-password", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 30, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 40, + "autheticatorFlow" : true, + "flowAlias" : "Reset - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "2c2cfb02-81e5-4d06-9ddc-6c572fe1cc99", + "alias" : "saml ecp", + "description" : "SAML ECP Profile Authentication Flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "http-basic-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + } ], + "authenticatorConfig" : [ { + "id" : "6d76ec0f-a629-40ff-b44d-d7e742751082", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "06ab7b0e-cdef-4679-aa4a-bfa0de0c1d39", + "alias" : "review profile config", + "config" : { + "update.profile.on.first.login" : "missing" + } + } ], + "requiredActions" : [ { + "alias" : "CONFIGURE_TOTP", + "name" : "Configure OTP", + "providerId" : "CONFIGURE_TOTP", + "enabled" : true, + "defaultAction" : false, + "priority" : 10, + "config" : { } + }, { + "alias" : "TERMS_AND_CONDITIONS", + "name" : "Terms and Conditions", + "providerId" : "TERMS_AND_CONDITIONS", + "enabled" : false, + "defaultAction" : false, + "priority" : 20, + "config" : { } + }, { + "alias" : "UPDATE_PASSWORD", + "name" : "Update Password", + "providerId" : "UPDATE_PASSWORD", + "enabled" : true, + "defaultAction" : false, + "priority" : 30, + "config" : { } + }, { + "alias" : "UPDATE_PROFILE", + "name" : "Update Profile", + "providerId" : "UPDATE_PROFILE", + "enabled" : true, + "defaultAction" : false, + "priority" : 40, + "config" : { } + }, { + "alias" : "VERIFY_EMAIL", + "name" : "Verify Email", + "providerId" : "VERIFY_EMAIL", + "enabled" : true, + "defaultAction" : false, + "priority" : 50, + "config" : { } + }, { + "alias" : "delete_account", + "name" : "Delete Account", + "providerId" : "delete_account", + "enabled" : false, + "defaultAction" : false, + "priority" : 60, + "config" : { } + }, { + "alias" : "webauthn-register", + "name" : "Webauthn Register", + "providerId" : "webauthn-register", + "enabled" : true, + "defaultAction" : false, + "priority" : 70, + "config" : { } + }, { + "alias" : "webauthn-register-passwordless", + "name" : "Webauthn Register Passwordless", + "providerId" : "webauthn-register-passwordless", + "enabled" : true, + "defaultAction" : false, + "priority" : 80, + "config" : { } + }, { + "alias" : "update_user_locale", + "name" : "Update User Locale", + "providerId" : "update_user_locale", + "enabled" : true, + "defaultAction" : false, + "priority" : 1000, + "config" : { } + } ], + "browserFlow" : "browser", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "dockerAuthenticationFlow" : "docker auth", + "attributes" : { + "cibaBackchannelTokenDeliveryMode" : "poll", + "cibaExpiresIn" : "120", + "cibaAuthRequestedUserHint" : "login_hint", + "parRequestUriLifespan" : "60", + "cibaInterval" : "5", + "realmReusableOtpCode" : "false" + }, + "keycloakVersion" : "23.0.1", + "userManagedAccessAllowed" : false, + "clientProfiles" : { + "profiles" : [ ] + }, + "clientPolicies" : { + "policies" : [ ] + } +}