diff --git a/tests/base/src/test/java/org/keycloak/test/admin/userprofile/UserProfileAdminTest.java b/tests/base/src/test/java/org/keycloak/test/admin/userprofile/UserProfileAdminTest.java new file mode 100644 index 000000000000..780942c3fa60 --- /dev/null +++ b/tests/base/src/test/java/org/keycloak/test/admin/userprofile/UserProfileAdminTest.java @@ -0,0 +1,142 @@ +package org.keycloak.test.admin.userprofile; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.keycloak.admin.client.resource.UserProfileResource; +import org.keycloak.models.UserModel; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.UserProfileAttributeGroupMetadata; +import org.keycloak.representations.idm.UserProfileMetadata; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPGroup; +import org.keycloak.test.framework.annotations.InjectRealm; +import org.keycloak.test.framework.annotations.KeycloakIntegrationTest; +import org.keycloak.test.framework.injection.LifeCycle; +import org.keycloak.test.framework.realm.ManagedRealm; +import org.keycloak.test.util.JsonTestUtils; +import org.keycloak.userprofile.config.UPConfigUtils; + +import java.util.List; +import java.util.Map; + +@KeycloakIntegrationTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class UserProfileAdminTest { + + @InjectRealm(lifecycle = LifeCycle.CLASS) + ManagedRealm realm; + + @Test + @Order(1) + public void testDefaultConfigIfNoneSet() { + JsonTestUtils.assertJsonEquals(UPConfigUtils.readSystemDefaultConfig(), realm.admin().users().userProfile().getConfiguration()); + } + + @Test + public void testSetDefaultConfig() { + UPConfig config = UPConfigUtils.parseSystemDefaultConfig().addOrReplaceAttribute(new UPAttribute("test")); + UserProfileResource userProfile = realm.admin().users().userProfile(); + userProfile.update(config); + + JsonTestUtils.assertJsonEquals(config, userProfile.getConfiguration()); + } + + @Test + public void testEmailRequiredIfEmailAsUsernameEnabled() { + RealmRepresentation realmRep = realm.admin().toRepresentation(); + realmRep.setRegistrationEmailAsUsername(true); + realm.admin().update(realmRep); + UserProfileResource userProfile = realm.admin().users().userProfile(); + UserProfileMetadata metadata = userProfile.getMetadata(); + Assertions.assertTrue(metadata.getAttributeMetadata(UserModel.EMAIL).isRequired()); + } + + @Test + public void testEmailNotRequiredIfEmailAsUsernameDisabled() { + RealmRepresentation realmRep = realm.admin().toRepresentation(); + realmRep.setRegistrationEmailAsUsername(false); + realm.admin().update(realmRep); + UserProfileResource userProfile = realm.admin().users().userProfile(); + UserProfileMetadata metadata = userProfile.getMetadata(); + Assertions.assertFalse(metadata.getAttributeMetadata(UserModel.EMAIL).isRequired()); + } + + @Test + public void testUsernameRequiredAndWritableIfEmailAsUsernameDisabledAndEditUsernameAllowed() { + RealmRepresentation realmRep = realm.admin().toRepresentation(); + realmRep.setRegistrationEmailAsUsername(false); + realm.admin().update(realmRep); + realmRep.setEditUsernameAllowed(true); + realm.admin().update(realmRep); + UserProfileResource userProfile = realm.admin().users().userProfile(); + UserProfileMetadata metadata = userProfile.getMetadata(); + Assertions.assertTrue(metadata.getAttributeMetadata(UserModel.USERNAME).isRequired()); + Assertions.assertFalse(metadata.getAttributeMetadata(UserModel.USERNAME).isReadOnly()); + } + + @Test + public void testUsernameRequiredAndWritableIfEmailAsUsernameDisabledAndEditUsernameDisabled() { + RealmRepresentation realmRep = realm.admin().toRepresentation(); + realmRep.setRegistrationEmailAsUsername(false); + realm.admin().update(realmRep); + realmRep.setEditUsernameAllowed(false); + realm.admin().update(realmRep); + UserProfileResource userProfile = realm.admin().users().userProfile(); + UserProfileMetadata metadata = userProfile.getMetadata(); + Assertions.assertTrue(metadata.getAttributeMetadata(UserModel.USERNAME).isRequired()); + Assertions.assertFalse(metadata.getAttributeMetadata(UserModel.USERNAME).isReadOnly()); + } + + @Test + public void testUsernameNotRequiredIfEmailAsUsernameEnabled() { + RealmRepresentation realmRep = realm.admin().toRepresentation(); + realmRep.setRegistrationEmailAsUsername(true); + realm.admin().update(realmRep); + UserProfileResource userProfile = realm.admin().users().userProfile(); + UserProfileMetadata metadata = userProfile.getMetadata(); + Assertions.assertFalse(metadata.getAttributeMetadata(UserModel.USERNAME).isRequired()); + Assertions.assertTrue(metadata.getAttributeMetadata(UserModel.USERNAME).isReadOnly()); + } + + @Test + public void testGroupsMetadata() { + UPConfig config = realm.admin().users().userProfile().getConfiguration(); + + for (int i = 0; i < 3; i++) { + UPGroup group = new UPGroup(); + group.setName("name-" + i); + group.setDisplayHeader("displayHeader-" + i); + group.setDisplayDescription("displayDescription-" + i); + group.setAnnotations(Map.of("k1", "v1", "k2", "v2", "k3", "v3")); + config.addGroup(group); + } + + UPAttribute firstName = config.getAttribute(UserModel.FIRST_NAME); + firstName.setGroup(config.getGroups().get(0).getName()); + UserProfileResource userProfile = realm.admin().users().userProfile(); + userProfile.update(config); + + UserProfileMetadata metadata = realm.admin().users().userProfile().getMetadata(); + List groups = metadata.getGroups(); + Assertions.assertNotNull(groups); + Assertions.assertFalse(groups.isEmpty()); + Assertions.assertEquals(config.getGroups().size(), groups.size()); + for (UPGroup group : config.getGroups()) { + UserProfileAttributeGroupMetadata mGroup = metadata.getAttributeGroupMetadata(group.getName()); + Assertions.assertNotNull(mGroup); + Assertions.assertEquals(group.getName(), mGroup.getName()); + Assertions.assertEquals(group.getDisplayHeader(), mGroup.getDisplayHeader()); + Assertions.assertEquals(group.getDisplayDescription(), mGroup.getDisplayDescription()); + if (group.getAnnotations() == null) { + Assertions.assertEquals(group.getAnnotations(), mGroup.getAnnotations()); + } else { + Assertions.assertEquals(group.getAnnotations().size(), mGroup.getAnnotations().size()); + } + } + Assertions.assertEquals(config.getGroups().get(0).getName(), metadata.getAttributeMetadata(UserModel.FIRST_NAME).getGroup()); + } +} diff --git a/tests/base/src/test/java/org/keycloak/test/util/JsonTestUtils.java b/tests/base/src/test/java/org/keycloak/test/util/JsonTestUtils.java new file mode 100644 index 000000000000..7f76f84936d8 --- /dev/null +++ b/tests/base/src/test/java/org/keycloak/test/util/JsonTestUtils.java @@ -0,0 +1,83 @@ +/* + * Copyright 2023 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.test.util; + +import org.junit.Assert; +import org.keycloak.util.JsonSerialization; + +import java.io.IOException; + +/** + * Utility for comparing JSON objects + * + * @author Marek Posolda + */ +public class JsonTestUtils { + + /** + * @param o1 + * @param o2 + * @return true if JSON objects are "equal" to each other + * @param + */ + public static void assertJsonEquals(T o1, T o2) { + try { + String o1Stripped = JsonSerialization.writeValueAsString(o1); + String o2Stripped = JsonSerialization.writeValueAsString(o2); + Assert.assertEquals(o1Stripped, o2Stripped); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + /** + * Compare Object in the JSON node with the "unparsed" String version of that object + * + * @param o1 String with JSON. Assumption is, that it can be "read" to the same object class of object o1 + * @param o2 + * @return + */ + public static void assertJsonEquals(String o1, Object o2) { + try { + Object o1Object = JsonSerialization.readValue(o1, o2.getClass()); + assertJsonEquals(o1Object, o2); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + /** + * Compares if 2 strings logically refers same JSON. + * + * @param o1 + * @param o2 + * @param clazz Java class, which strings o1 and o2 can be read into + * @return + */ + public static void assertJsonEquals(String o1, String o2, Class clazz) { + try { + Object o1Object = JsonSerialization.readValue(o1, clazz); + Object o2Object = JsonSerialization.readValue(o2, clazz); + assertJsonEquals(o1Object, o2Object); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/userprofile/UserProfileAdminTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/userprofile/UserProfileAdminTest.java deleted file mode 100644 index a3b9ddf17592..000000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/userprofile/UserProfileAdminTest.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * - * * Copyright 2021 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.admin.userprofile; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.keycloak.userprofile.config.UPConfigUtils.readSystemDefaultConfig; - -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.keycloak.admin.client.resource.RealmResource; -import org.keycloak.admin.client.resource.UserProfileResource; -import org.keycloak.models.UserModel; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.representations.idm.UserProfileAttributeGroupMetadata; -import org.keycloak.representations.idm.UserProfileMetadata; -import org.keycloak.testsuite.admin.AbstractAdminTest; -import org.keycloak.representations.userprofile.config.UPAttribute; -import org.keycloak.representations.userprofile.config.UPConfig; -import org.keycloak.representations.userprofile.config.UPGroup; -import org.keycloak.testsuite.util.JsonTestUtils; -import org.keycloak.userprofile.config.UPConfigUtils; - -/** - * @author Pedro Igor - */ -public class UserProfileAdminTest extends AbstractAdminTest { - - @Override - public void configureTestRealm(RealmRepresentation testRealm) { - } - - @Test - public void testDefaultConfigIfNoneSet() { - JsonTestUtils.assertJsonEquals(readSystemDefaultConfig(), testRealm().users().userProfile().getConfiguration()); - } - - @Test - public void testSetDefaultConfig() { - UPConfig config = UPConfigUtils.parseSystemDefaultConfig().addOrReplaceAttribute(new UPAttribute("test")); - UserProfileResource userProfile = testRealm().users().userProfile(); - userProfile.update(config); - getCleanup().addCleanup(() -> testRealm().users().userProfile().update(null)); - - JsonTestUtils.assertJsonEquals(config, userProfile.getConfiguration()); - } - - @Test - public void testEmailRequiredIfEmailAsUsernameEnabled() { - RealmResource realm = testRealm(); - RealmRepresentation realmRep = realm.toRepresentation(); - Boolean registrationEmailAsUsername = realmRep.isRegistrationEmailAsUsername(); - realmRep.setRegistrationEmailAsUsername(true); - realm.update(realmRep); - getCleanup().addCleanup(() -> { - realmRep.setRegistrationEmailAsUsername(registrationEmailAsUsername); - realm.update(realmRep); - }); - UserProfileResource userProfile = realm.users().userProfile(); - UserProfileMetadata metadata = userProfile.getMetadata(); - assertTrue(metadata.getAttributeMetadata(UserModel.EMAIL).isRequired()); - } - - @Test - public void testEmailNotRequiredIfEmailAsUsernameDisabled() { - RealmResource realm = testRealm(); - RealmRepresentation realmRep = realm.toRepresentation(); - Boolean registrationEmailAsUsername = realmRep.isRegistrationEmailAsUsername(); - realmRep.setRegistrationEmailAsUsername(false); - realm.update(realmRep); - getCleanup().addCleanup(() -> { - realmRep.setRegistrationEmailAsUsername(registrationEmailAsUsername); - realm.update(realmRep); - }); - UserProfileResource userProfile = realm.users().userProfile(); - UserProfileMetadata metadata = userProfile.getMetadata(); - assertFalse(metadata.getAttributeMetadata(UserModel.EMAIL).isRequired()); - } - - @Test - public void testUsernameRequiredAndWritableIfEmailAsUsernameDisabledAndEditUsernameAllowed() { - RealmResource realm = testRealm(); - RealmRepresentation realmRep = realm.toRepresentation(); - Boolean registrationEmailAsUsername = realmRep.isRegistrationEmailAsUsername(); - realmRep.setRegistrationEmailAsUsername(false); - realm.update(realmRep); - getCleanup().addCleanup(() -> { - realmRep.setRegistrationEmailAsUsername(registrationEmailAsUsername); - realm.update(realmRep); - }); - Boolean editUsernameAllowed = realmRep.isEditUsernameAllowed(); - realmRep.setEditUsernameAllowed(true); - realm.update(realmRep); - getCleanup().addCleanup(() -> { - realmRep.setEditUsernameAllowed(editUsernameAllowed); - realm.update(realmRep); - }); - UserProfileResource userProfile = realm.users().userProfile(); - UserProfileMetadata metadata = userProfile.getMetadata(); - assertTrue(metadata.getAttributeMetadata(UserModel.USERNAME).isRequired()); - assertFalse(metadata.getAttributeMetadata(UserModel.USERNAME).isReadOnly()); - } - - @Test - public void testUsernameRequiredAndWritableIfEmailAsUsernameDisabledAndEditUsernameDisabled() { - RealmResource realm = testRealm(); - RealmRepresentation realmRep = realm.toRepresentation(); - Boolean registrationEmailAsUsername = realmRep.isRegistrationEmailAsUsername(); - realmRep.setRegistrationEmailAsUsername(false); - realm.update(realmRep); - getCleanup().addCleanup(() -> { - realmRep.setRegistrationEmailAsUsername(registrationEmailAsUsername); - realm.update(realmRep); - }); - Boolean editUsernameAllowed = realmRep.isEditUsernameAllowed(); - realmRep.setEditUsernameAllowed(false); - realm.update(realmRep); - getCleanup().addCleanup(() -> { - realmRep.setEditUsernameAllowed(editUsernameAllowed); - realm.update(realmRep); - }); - UserProfileResource userProfile = realm.users().userProfile(); - UserProfileMetadata metadata = userProfile.getMetadata(); - assertTrue(metadata.getAttributeMetadata(UserModel.USERNAME).isRequired()); - assertFalse(metadata.getAttributeMetadata(UserModel.USERNAME).isReadOnly()); - } - - @Test - public void testUsernameNotRequiredIfEmailAsUsernameEnabled() { - RealmResource realm = testRealm(); - RealmRepresentation realmRep = realm.toRepresentation(); - Boolean registrationEmailAsUsername = realmRep.isRegistrationEmailAsUsername(); - realmRep.setRegistrationEmailAsUsername(true); - realm.update(realmRep); - getCleanup().addCleanup(() -> { - realmRep.setRegistrationEmailAsUsername(registrationEmailAsUsername); - realm.update(realmRep); - }); - UserProfileResource userProfile = realm.users().userProfile(); - UserProfileMetadata metadata = userProfile.getMetadata(); - assertFalse(metadata.getAttributeMetadata(UserModel.USERNAME).isRequired()); - assertTrue(metadata.getAttributeMetadata(UserModel.USERNAME).isReadOnly()); - } - - @Test - public void testGroupsMetadata() { - UPConfig config = testRealm().users().userProfile().getConfiguration(); - - for (int i = 0; i < 3; i++) { - UPGroup group = new UPGroup(); - group.setName("name-" + i); - group.setDisplayHeader("displayHeader-" + i); - group.setDisplayDescription("displayDescription-" + i); - group.setAnnotations(Map.of("k1", "v1", "k2", "v2", "k3", "v3")); - config.addGroup(group); - } - - UPAttribute firstName = config.getAttribute(UserModel.FIRST_NAME); - firstName.setGroup(config.getGroups().get(0).getName()); - UserProfileResource userProfile = testRealm().users().userProfile(); - userProfile.update(config); - getCleanup().addCleanup(() -> testRealm().users().userProfile().update(null)); - - UserProfileMetadata metadata = testRealm().users().userProfile().getMetadata(); - List groups = metadata.getGroups(); - assertNotNull(groups); - assertFalse(groups.isEmpty()); - assertEquals(config.getGroups().size(), groups.size()); - for (UPGroup group : config.getGroups()) { - UserProfileAttributeGroupMetadata mGroup = metadata.getAttributeGroupMetadata(group.getName()); - assertNotNull(mGroup); - assertEquals(group.getName(), mGroup.getName()); - assertEquals(group.getDisplayHeader(), mGroup.getDisplayHeader()); - assertEquals(group.getDisplayDescription(), mGroup.getDisplayDescription()); - if (group.getAnnotations() == null) { - assertEquals(group.getAnnotations(), mGroup.getAnnotations()); - } else { - assertEquals(group.getAnnotations().size(), mGroup.getAnnotations().size()); - } - } - assertEquals(config.getGroups().get(0).getName(), metadata.getAttributeMetadata(UserModel.FIRST_NAME).getGroup()); - } -}