diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedGroupMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedGroupMapperTest.java deleted file mode 100644 index 5e32025013..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedGroupMapperTest.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.keycloak.testsuite.broker; - -import static org.keycloak.models.IdentityProviderMapperSyncMode.FORCE; -import static org.keycloak.models.IdentityProviderMapperSyncMode.IMPORT; - -import org.junit.Test; -import org.keycloak.models.IdentityProviderMapperSyncMode; -import org.keycloak.representations.idm.IdentityProviderRepresentation; -import org.keycloak.representations.idm.UserRepresentation; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -import java.util.List; -import java.util.Map; - -/** - * @author Artur Baltabayev, - * Daniel Fesenmeyer - */ -public abstract class AbstractAdvancedGroupMapperTest extends AbstractGroupMapperTest { - - private static final String CLAIMS_OR_ATTRIBUTES = "[\n" + - " {\n" + - " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME + "\",\n" + - " \"value\": \"value 1\"\n" + - " },\n" + - " {\n" + - " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2 + "\",\n" + - " \"value\": \"value 2\"\n" + - " }\n" + - "]"; - - private static final String CLAIMS_OR_ATTRIBUTES_REGEX = "[\n" + - " {\n" + - " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME + "\",\n" + - " \"value\": \"va.*\"\n" + - " },\n" + - " {\n" + - " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2 + "\",\n" + - " \"value\": \"value 2\"\n" + - " }\n" + - "]"; - - private String newValueForAttribute2 = ""; - - @Test - public void allValuesMatch() { - createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES, false, MAPPER_TEST_GROUP_PATH); - createUserInProviderRealm(createMatchingAttributes()); - - logInAsUserInIDPForFirstTimeAndAssertSuccess(); - - UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); - assertThatUserHasBeenAssignedToGroup(user); - } - - @Test - public void valuesMismatch() { - createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES, false, MAPPER_TEST_GROUP_PATH); - createUserInProviderRealm(ImmutableMap.>builder() - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("value 1").build()) - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add("value mismatch").build()) - .build()); - - logInAsUserInIDPForFirstTimeAndAssertSuccess(); - - UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); - assertThatUserHasNotBeenAssignedToGroup(user); - } - - @Test - public void valuesMatchIfNoClaimsSpecified() { - createAdvancedGroupMapper("[]", false, MAPPER_TEST_GROUP_PATH); - createUserInProviderRealm(ImmutableMap.>builder() - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("some value").build()) - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add("some value").build()) - .build()); - - logInAsUserInIDPForFirstTimeAndAssertSuccess(); - - UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); - assertThatUserHasBeenAssignedToGroup(user); - } - - @Test - public void allValuesMatchRegex() { - createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES_REGEX, true, MAPPER_TEST_GROUP_PATH); - createUserInProviderRealm(createMatchingAttributes()); - - logInAsUserInIDPForFirstTimeAndAssertSuccess(); - - UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); - assertThatUserHasBeenAssignedToGroup(user); - } - - @Test - public void valuesMismatchRegex() { - createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES_REGEX, true, MAPPER_TEST_GROUP_PATH); - createUserInProviderRealm(ImmutableMap.>builder() - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("mismatch").build()) - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add("value 2").build()) - .build()); - - logInAsUserInIDPForFirstTimeAndAssertSuccess(); - - UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); - assertThatUserHasNotBeenAssignedToGroup(user); - } - - @Test - public void updateBrokeredUserMismatchLeavesGroup() { - newValueForAttribute2 = "value mismatch"; - UserRepresentation user = createMapperAndLoginAsUserTwiceWithMapper(FORCE, false, MAPPER_TEST_GROUP_PATH); - - assertThatUserHasNotBeenAssignedToGroup(user); - } - - @Test - public void updateBrokeredUserMismatchDoesNotLeaveGroupInImportMode() { - newValueForAttribute2 = "value mismatch"; - UserRepresentation user = createMapperAndLoginAsUserTwiceWithMapper(IMPORT, false, MAPPER_TEST_GROUP_PATH); - - assertThatUserHasBeenAssignedToGroup(user); - } - - @Test - public void updateBrokeredUserMatchDoesntLeaveGroup() { - newValueForAttribute2 = "value 2"; - UserRepresentation user = createMapperAndLoginAsUserTwiceWithMapper(FORCE, false, MAPPER_TEST_GROUP_PATH); - - assertThatUserHasBeenAssignedToGroup(user); - } - - @Test - public void tryToUpdateBrokeredUserWithMissingGroupDoesNotBreakLogin() { - newValueForAttribute2 = "value 2"; - UserRepresentation user = - createMapperAndLoginAsUserTwiceWithMapper(FORCE, true, MAPPER_TEST_NOT_EXISTING_GROUP_PATH); - - assertThatUserDoesNotHaveGroups(user); - } - - @Test - public void updateBrokeredUserIsAssignedToGroupInForceModeWhenCreatingTheMapperAfterFirstLogin() { - newValueForAttribute2 = "value 2"; - UserRepresentation user = createMapperAndLoginAsUserTwiceWithMapper(FORCE, true, MAPPER_TEST_GROUP_PATH); - - assertThatUserHasBeenAssignedToGroup(user); - } - - public UserRepresentation createMapperAndLoginAsUserTwiceWithMapper(IdentityProviderMapperSyncMode syncMode, - boolean createAfterFirstLogin, String groupPath) { - return loginAsUserTwiceWithMapper(syncMode, createAfterFirstLogin, createMatchingAttributes(), groupPath); - } - - @Override - protected void updateUser() { - UserRepresentation user = findUser(bc.providerRealmName(), bc.getUserLogin(), bc.getUserEmail()); - ImmutableMap> matchingAttributes = ImmutableMap.>builder() - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("value 1").build()) - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add(newValueForAttribute2).build()) - .put("some.other.attribute", ImmutableList.builder().add("some value").build()) - .build(); - user.setAttributes(matchingAttributes); - adminClient.realm(bc.providerRealmName()).users().get(user.getId()).update(user); - } - - - - @Override - protected String createMapperInIdp(IdentityProviderRepresentation idp, IdentityProviderMapperSyncMode syncMode, - String groupPath) { - return createMapperInIdp(idp, CLAIMS_OR_ATTRIBUTES, false, syncMode, groupPath); - } - - @Override - protected String setupScenarioWithGroupPath(String groupPath) { - String mapperId = createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES, false, groupPath); - createUserInProviderRealm(createMatchingAttributes()); - return mapperId; - } - - @Override - protected void setupScenarioWithNonExistingGroup() { - createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES, false, MAPPER_TEST_NOT_EXISTING_GROUP_PATH); - createUserInProviderRealm(createMatchingAttributes()); - } - - protected String createAdvancedGroupMapper(String claimsOrAttributeRepresentation, - boolean areClaimsOrAttributeValuesRegexes, String groupPath) { - IdentityProviderRepresentation idp = setupIdentityProvider(); - return createMapperInIdp(idp, claimsOrAttributeRepresentation, areClaimsOrAttributeValuesRegexes, IMPORT, - groupPath); - } - - abstract protected String createMapperInIdp( - IdentityProviderRepresentation idp, String claimsOrAttributeRepresentation, - boolean areClaimsOrAttributeValuesRegexes, IdentityProviderMapperSyncMode syncMode, String groupPath); - - private static Map> createMatchingAttributes() { - return ImmutableMap.> builder() - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, - ImmutableList. builder().add("value 1").build()) - .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, - ImmutableList. builder().add("value 2").build()) - .build(); - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupBrokerMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupBrokerMapperTest.java new file mode 100644 index 0000000000..1af47d0562 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupBrokerMapperTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.broker; + +import static org.keycloak.models.IdentityProviderMapperSyncMode.IMPORT; + +import java.util.List; +import java.util.Map; +import org.keycloak.models.IdentityProviderMapperSyncMode; +import org.keycloak.representations.idm.IdentityProviderRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public abstract class AbstractGroupBrokerMapperTest extends AbstractGroupMapperTest { + + protected static final String CLAIMS_OR_ATTRIBUTES = "[\n" + + " {\n" + + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME + "\",\n" + + " \"value\": \"value 1\"\n" + + " },\n" + + " {\n" + + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2 + "\",\n" + + " \"value\": \"value 2\"\n" + + " }\n" + + "]"; + + protected static final String CLAIMS_OR_ATTRIBUTES_REGEX = "[\n" + + " {\n" + + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME + "\",\n" + + " \"value\": \"va.*\"\n" + + " },\n" + + " {\n" + + " \"key\": \"" + KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2 + "\",\n" + + " \"value\": \"value 2\"\n" + + " }\n" + + "]"; + + protected String newValueForAttribute2 = ""; + + public UserRepresentation createMapperAndLoginAsUserTwiceWithMapper(IdentityProviderMapperSyncMode syncMode, + boolean createAfterFirstLogin, String groupPath) { + return loginAsUserTwiceWithMapper(syncMode, createAfterFirstLogin, createMatchingAttributes(), groupPath); + } + + @Override + protected void updateUser() { + UserRepresentation user = findUser(bc.providerRealmName(), bc.getUserLogin(), bc.getUserEmail()); + ImmutableMap> matchingAttributes = ImmutableMap.>builder() + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("value 1").build()) + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add(newValueForAttribute2).build()) + .put("some.other.attribute", ImmutableList.builder().add("some value").build()) + .build(); + user.setAttributes(matchingAttributes); + adminClient.realm(bc.providerRealmName()).users().get(user.getId()).update(user); + } + + + + @Override + protected String createMapperInIdp(IdentityProviderRepresentation idp, IdentityProviderMapperSyncMode syncMode, + String groupPath) { + return createMapperInIdp(idp, CLAIMS_OR_ATTRIBUTES, false, syncMode, groupPath); + } + + @Override + protected String setupScenarioWithGroupPath(String groupPath) { + String mapperId = createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES, false, groupPath); + createUserInProviderRealm(createMatchingAttributes()); + return mapperId; + } + + @Override + protected void setupScenarioWithNonExistingGroup() { + createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES, false, MAPPER_TEST_NOT_EXISTING_GROUP_PATH); + createUserInProviderRealm(createMatchingAttributes()); + } + + protected String createAdvancedGroupMapper(String claimsOrAttributeRepresentation, + boolean areClaimsOrAttributeValuesRegexes, String groupPath) { + IdentityProviderRepresentation idp = setupIdentityProvider(); + return createMapperInIdp(idp, claimsOrAttributeRepresentation, areClaimsOrAttributeValuesRegexes, IMPORT, + groupPath); + } + + abstract protected String createMapperInIdp( + IdentityProviderRepresentation idp, String claimsOrAttributeRepresentation, + boolean areClaimsOrAttributeValuesRegexes, IdentityProviderMapperSyncMode syncMode, String groupPath); + + protected static Map> createMatchingAttributes() { + return ImmutableMap.> builder() + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, + ImmutableList. builder().add("value 1").build()) + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, + ImmutableList. builder().add("value 2").build()) + .build(); + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupMapperTest.java index 917a348a08..8061f5297b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractGroupMapperTest.java @@ -60,127 +60,6 @@ public abstract class AbstractGroupMapperTest extends AbstractIdentityProviderMa mapperGroupId = CreatedResponseUtil.getCreatedId(response); } - @Test - public void tryToCreateBrokeredUserWithNonExistingGroupDoesNotBreakLogin() { - setupScenarioWithNonExistingGroup(); - - logInAsUserInIDPForFirstTimeAndAssertSuccess(); - - UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); - assertThatUserDoesNotHaveGroups(user); - } - - @Test - public void mapperStillWorksWhenTopLevelGroupIsConvertedToSubGroup() { - final String mapperId = setupScenarioWithGroupPath(MAPPER_TEST_GROUP_PATH); - - String newParentGroupName = "new-parent"; - GroupRepresentation newParentGroup = new GroupRepresentation(); - newParentGroup.setName(newParentGroupName); - String newParentGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(newParentGroup)); - - GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); - realm.groups().group(newParentGroupId).subGroup(mappedGroup).close(); - - String expectedNewGroupPath = buildGroupPath(newParentGroupName, MAPPER_TEST_GROUP_NAME); - - assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); - } - - @Test - public void mapperStillWorksWhenSubGroupChangesParent() { - String parentGroupName = "parent-group"; - GroupRepresentation parentGroup = new GroupRepresentation(); - parentGroup.setName(parentGroupName); - String parentGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(parentGroup)); - - GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); - realm.groups().group(parentGroupId).subGroup(mappedGroup).close(); - - String initialGroupPath = buildGroupPath(parentGroupName, MAPPER_TEST_GROUP_NAME); - - final String mapperId = setupScenarioWithGroupPath(initialGroupPath); - - String newParentGroupName = "new-parent-group"; - GroupRepresentation newParentGroup = new GroupRepresentation(); - newParentGroup.setName(newParentGroupName); - String newParentGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(newParentGroup)); - - realm.groups().group(newParentGroupId).subGroup(mappedGroup).close(); - - String expectedNewGroupPath = buildGroupPath(newParentGroupName, MAPPER_TEST_GROUP_NAME); - - assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); - } - - @Test - public void mapperStillWorksWhenSubGroupIsConvertedToTopLevelGroup() { - String parentGroupName = "parent-group"; - GroupRepresentation parentGroup = new GroupRepresentation(); - parentGroup.setName(parentGroupName); - String parentGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(parentGroup)); - - GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); - realm.groups().group(parentGroupId).subGroup(mappedGroup).close(); - - String initialGroupPath = buildGroupPath(parentGroupName, MAPPER_TEST_GROUP_NAME); - - final String mapperId = setupScenarioWithGroupPath(initialGroupPath); - - // convert the mapped group to a top-level group - realm.groups().add(realm.groups().group(mapperGroupId).toRepresentation()); - - String expectedNewGroupPath = buildGroupPath(MAPPER_TEST_GROUP_NAME); - - assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); - } - - @Test - public void mapperStillWorksWhenGroupIsRenamed() { - final String mapperId = setupScenarioWithGroupPath(MAPPER_TEST_GROUP_PATH); - - String newGroupName = "new-name-" + MAPPER_TEST_GROUP_NAME; - GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); - mappedGroup.setName(newGroupName); - realm.groups().group(mapperGroupId).update(mappedGroup); - - String expectedNewGroupPath = buildGroupPath(newGroupName); - - assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); - } - - @Test - public void mapperStillWorksWhenAncestorGroupIsRenamed() { - String topLevelGroupName = "top-level"; - GroupRepresentation topLevelGroup = new GroupRepresentation(); - topLevelGroup.setName(topLevelGroupName); - String topLevelGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(topLevelGroup)); - - String midLevelGroupName = "mid-level"; - GroupRepresentation midLevelGroup = new GroupRepresentation(); - midLevelGroup.setName(midLevelGroupName); - String midLevelGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(midLevelGroup)); - - midLevelGroup = realm.groups().group(midLevelGroupId).toRepresentation(); - realm.groups().group(topLevelGroupId).subGroup(midLevelGroup).close(); - - GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); - realm.groups().group(midLevelGroupId).subGroup(mappedGroup).close(); - - String initialGroupPath = buildGroupPath(topLevelGroupName, midLevelGroupName, MAPPER_TEST_GROUP_NAME); - - final String mapperId = setupScenarioWithGroupPath(initialGroupPath); - - String newTopLevelGroupName = "new-name-" + topLevelGroupName; - topLevelGroup = realm.groups().group(topLevelGroupId).toRepresentation(); - topLevelGroup.setName(newTopLevelGroupName); - realm.groups().group(topLevelGroupId).update(topLevelGroup); - - String expectedNewGroupPath = buildGroupPath(newTopLevelGroupName, midLevelGroupName, MAPPER_TEST_GROUP_NAME); - - assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); - } - protected UserRepresentation loginAsUserTwiceWithMapper( IdentityProviderMapperSyncMode syncMode, boolean createAfterFirstLogin, Map> userConfig, String groupPath) { @@ -213,7 +92,7 @@ public abstract class AbstractGroupMapperTest extends AbstractIdentityProviderMa return user; } - private void assertMapperHasExpectedPathAndSucceeds(String mapperId, String expectedGroupPath) { + protected void assertMapperHasExpectedPathAndSucceeds(String mapperId, String expectedGroupPath) { IdentityProviderMapperRepresentation mapper = realm.identityProviders().get(bc.getIDPAlias()).getMapperById(mapperId); Map config = mapper.getConfig(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcAdvancedClaimToGroupMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcAdvancedClaimToGroupMapperTest.java index 81368598fd..ba68868105 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcAdvancedClaimToGroupMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/OidcAdvancedClaimToGroupMapperTest.java @@ -1,14 +1,22 @@ package org.keycloak.testsuite.broker; +import static org.keycloak.models.IdentityProviderMapperSyncMode.FORCE; +import static org.keycloak.models.IdentityProviderMapperSyncMode.IMPORT; + +import java.util.List; +import org.junit.Test; import org.keycloak.admin.client.CreatedResponseUtil; import org.keycloak.admin.client.resource.IdentityProviderResource; import org.keycloak.broker.oidc.mappers.AdvancedClaimToGroupMapper; import org.keycloak.broker.provider.ConfigConstants; import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderMapperSyncMode; +import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import javax.ws.rs.core.Response; @@ -17,7 +25,7 @@ import javax.ws.rs.core.Response; * @author Artur Baltabayev, * Daniel Fesenmeyer */ -public class OidcAdvancedClaimToGroupMapperTest extends AbstractAdvancedGroupMapperTest { +public class OidcAdvancedClaimToGroupMapperTest extends AbstractGroupBrokerMapperTest { @Override protected BrokerConfiguration getBrokerConfiguration() { @@ -44,4 +52,229 @@ public class OidcAdvancedClaimToGroupMapperTest extends AbstractAdvancedGroupMap return CreatedResponseUtil.getCreatedId(response); } + @Test + public void allValuesMatch() { + createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES, false, MAPPER_TEST_GROUP_PATH); + createUserInProviderRealm(createMatchingAttributes()); + + logInAsUserInIDPForFirstTimeAndAssertSuccess(); + + UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); + assertThatUserHasBeenAssignedToGroup(user); + } + + @Test + public void valuesMismatch() { + createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES, false, MAPPER_TEST_GROUP_PATH); + createUserInProviderRealm(ImmutableMap.>builder() + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("value 1").build()) + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add("value mismatch").build()) + .build()); + + logInAsUserInIDPForFirstTimeAndAssertSuccess(); + + UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); + assertThatUserHasNotBeenAssignedToGroup(user); + } + + @Test + public void valuesMatchIfNoClaimsSpecified() { + createAdvancedGroupMapper("[]", false, MAPPER_TEST_GROUP_PATH); + createUserInProviderRealm(ImmutableMap.>builder() + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("some value").build()) + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add("some value").build()) + .build()); + + logInAsUserInIDPForFirstTimeAndAssertSuccess(); + + UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); + assertThatUserHasBeenAssignedToGroup(user); + } + + @Test + public void allValuesMatchRegex() { + createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES_REGEX, true, MAPPER_TEST_GROUP_PATH); + createUserInProviderRealm(createMatchingAttributes()); + + logInAsUserInIDPForFirstTimeAndAssertSuccess(); + + UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); + assertThatUserHasBeenAssignedToGroup(user); + } + + @Test + public void valuesMismatchRegex() { + createAdvancedGroupMapper(CLAIMS_OR_ATTRIBUTES_REGEX, true, MAPPER_TEST_GROUP_PATH); + createUserInProviderRealm(ImmutableMap.>builder() + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("mismatch").build()) + .put(KcOidcBrokerConfiguration.ATTRIBUTE_TO_MAP_NAME_2, ImmutableList.builder().add("value 2").build()) + .build()); + + logInAsUserInIDPForFirstTimeAndAssertSuccess(); + + UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); + assertThatUserHasNotBeenAssignedToGroup(user); + } + + @Test + public void updateBrokeredUserMismatchLeavesGroup() { + newValueForAttribute2 = "value mismatch"; + UserRepresentation user = createMapperAndLoginAsUserTwiceWithMapper(FORCE, false, MAPPER_TEST_GROUP_PATH); + + assertThatUserHasNotBeenAssignedToGroup(user); + } + + @Test + public void updateBrokeredUserMismatchDoesNotLeaveGroupInImportMode() { + newValueForAttribute2 = "value mismatch"; + UserRepresentation user = createMapperAndLoginAsUserTwiceWithMapper(IMPORT, false, MAPPER_TEST_GROUP_PATH); + + assertThatUserHasBeenAssignedToGroup(user); + } + + @Test + public void updateBrokeredUserMatchDoesntLeaveGroup() { + newValueForAttribute2 = "value 2"; + UserRepresentation user = createMapperAndLoginAsUserTwiceWithMapper(FORCE, false, MAPPER_TEST_GROUP_PATH); + + assertThatUserHasBeenAssignedToGroup(user); + } + + @Test + public void tryToUpdateBrokeredUserWithMissingGroupDoesNotBreakLogin() { + newValueForAttribute2 = "value 2"; + UserRepresentation user = + createMapperAndLoginAsUserTwiceWithMapper(FORCE, true, MAPPER_TEST_NOT_EXISTING_GROUP_PATH); + + assertThatUserDoesNotHaveGroups(user); + } + + @Test + public void updateBrokeredUserIsAssignedToGroupInForceModeWhenCreatingTheMapperAfterFirstLogin() { + newValueForAttribute2 = "value 2"; + UserRepresentation user = createMapperAndLoginAsUserTwiceWithMapper(FORCE, true, MAPPER_TEST_GROUP_PATH); + + assertThatUserHasBeenAssignedToGroup(user); + } + + @Test + public void tryToCreateBrokeredUserWithNonExistingGroupDoesNotBreakLogin() { + setupScenarioWithNonExistingGroup(); + + logInAsUserInIDPForFirstTimeAndAssertSuccess(); + + UserRepresentation user = findUser(bc.consumerRealmName(), bc.getUserLogin(), bc.getUserEmail()); + assertThatUserDoesNotHaveGroups(user); + } + + @Test + public void mapperStillWorksWhenTopLevelGroupIsConvertedToSubGroup() { + final String mapperId = setupScenarioWithGroupPath(MAPPER_TEST_GROUP_PATH); + + String newParentGroupName = "new-parent"; + GroupRepresentation newParentGroup = new GroupRepresentation(); + newParentGroup.setName(newParentGroupName); + String newParentGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(newParentGroup)); + + GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); + realm.groups().group(newParentGroupId).subGroup(mappedGroup).close(); + + String expectedNewGroupPath = buildGroupPath(newParentGroupName, MAPPER_TEST_GROUP_NAME); + + assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); + } + + @Test + public void mapperStillWorksWhenSubGroupChangesParent() { + String parentGroupName = "parent-group"; + GroupRepresentation parentGroup = new GroupRepresentation(); + parentGroup.setName(parentGroupName); + String parentGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(parentGroup)); + + GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); + realm.groups().group(parentGroupId).subGroup(mappedGroup).close(); + + String initialGroupPath = buildGroupPath(parentGroupName, MAPPER_TEST_GROUP_NAME); + + final String mapperId = setupScenarioWithGroupPath(initialGroupPath); + + String newParentGroupName = "new-parent-group"; + GroupRepresentation newParentGroup = new GroupRepresentation(); + newParentGroup.setName(newParentGroupName); + String newParentGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(newParentGroup)); + + realm.groups().group(newParentGroupId).subGroup(mappedGroup).close(); + + String expectedNewGroupPath = buildGroupPath(newParentGroupName, MAPPER_TEST_GROUP_NAME); + + assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); + } + + @Test + public void mapperStillWorksWhenSubGroupIsConvertedToTopLevelGroup() { + String parentGroupName = "parent-group"; + GroupRepresentation parentGroup = new GroupRepresentation(); + parentGroup.setName(parentGroupName); + String parentGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(parentGroup)); + + GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); + realm.groups().group(parentGroupId).subGroup(mappedGroup).close(); + + String initialGroupPath = buildGroupPath(parentGroupName, MAPPER_TEST_GROUP_NAME); + + final String mapperId = setupScenarioWithGroupPath(initialGroupPath); + + // convert the mapped group to a top-level group + realm.groups().add(realm.groups().group(mapperGroupId).toRepresentation()); + + String expectedNewGroupPath = buildGroupPath(MAPPER_TEST_GROUP_NAME); + + assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); + } + + @Test + public void mapperStillWorksWhenGroupIsRenamed() { + final String mapperId = setupScenarioWithGroupPath(MAPPER_TEST_GROUP_PATH); + + String newGroupName = "new-name-" + MAPPER_TEST_GROUP_NAME; + GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); + mappedGroup.setName(newGroupName); + realm.groups().group(mapperGroupId).update(mappedGroup); + + String expectedNewGroupPath = buildGroupPath(newGroupName); + + assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); + } + + @Test + public void mapperStillWorksWhenAncestorGroupIsRenamed() { + String topLevelGroupName = "top-level"; + GroupRepresentation topLevelGroup = new GroupRepresentation(); + topLevelGroup.setName(topLevelGroupName); + String topLevelGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(topLevelGroup)); + + String midLevelGroupName = "mid-level"; + GroupRepresentation midLevelGroup = new GroupRepresentation(); + midLevelGroup.setName(midLevelGroupName); + String midLevelGroupId = CreatedResponseUtil.getCreatedId(realm.groups().add(midLevelGroup)); + + midLevelGroup = realm.groups().group(midLevelGroupId).toRepresentation(); + realm.groups().group(topLevelGroupId).subGroup(midLevelGroup).close(); + + GroupRepresentation mappedGroup = realm.groups().group(mapperGroupId).toRepresentation(); + realm.groups().group(midLevelGroupId).subGroup(mappedGroup).close(); + + String initialGroupPath = buildGroupPath(topLevelGroupName, midLevelGroupName, MAPPER_TEST_GROUP_NAME); + + final String mapperId = setupScenarioWithGroupPath(initialGroupPath); + + String newTopLevelGroupName = "new-name-" + topLevelGroupName; + topLevelGroup = realm.groups().group(topLevelGroupId).toRepresentation(); + topLevelGroup.setName(newTopLevelGroupName); + realm.groups().group(topLevelGroupId).update(topLevelGroup); + + String expectedNewGroupPath = buildGroupPath(newTopLevelGroupName, midLevelGroupName, MAPPER_TEST_GROUP_NAME); + + assertMapperHasExpectedPathAndSucceeds(mapperId, expectedNewGroupPath); + } }