diff --git a/services/src/main/java/org/keycloak/userprofile/config/UPAttribute.java b/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttribute.java similarity index 76% rename from services/src/main/java/org/keycloak/userprofile/config/UPAttribute.java rename to core/src/main/java/org/keycloak/representations/userprofile/config/UPAttribute.java index 648fc9e244..3e7ba12bfa 100644 --- a/services/src/main/java/org/keycloak/userprofile/config/UPAttribute.java +++ b/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttribute.java @@ -1,20 +1,22 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. + * 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 + * 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 + * 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. * - * 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.userprofile.config; +package org.keycloak.representations.userprofile.config; import java.util.HashMap; import java.util.Map; @@ -40,6 +42,13 @@ public class UPAttribute { private UPAttributeSelector selector; private String group; + public UPAttribute() { + } + + public UPAttribute(String name) { + this.name = name != null ? name.trim() : null; + } + public String getName() { return name; } diff --git a/services/src/main/java/org/keycloak/userprofile/config/UPAttributePermissions.java b/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributePermissions.java similarity index 55% rename from services/src/main/java/org/keycloak/userprofile/config/UPAttributePermissions.java rename to core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributePermissions.java index 8530443399..c04d3c5475 100644 --- a/services/src/main/java/org/keycloak/userprofile/config/UPAttributePermissions.java +++ b/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributePermissions.java @@ -1,20 +1,22 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. + * 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 + * 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 + * 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. * - * 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.userprofile.config; +package org.keycloak.representations.userprofile.config; import java.util.Collections; import java.util.Set; diff --git a/services/src/main/java/org/keycloak/userprofile/config/UPAttributeRequired.java b/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributeRequired.java similarity index 59% rename from services/src/main/java/org/keycloak/userprofile/config/UPAttributeRequired.java rename to core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributeRequired.java index 2ccce58fe8..51e7eea9f5 100644 --- a/services/src/main/java/org/keycloak/userprofile/config/UPAttributeRequired.java +++ b/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributeRequired.java @@ -1,20 +1,22 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. + * 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 + * 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 + * 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. * - * 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.userprofile.config; +package org.keycloak.representations.userprofile.config; import java.util.Set; diff --git a/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributeSelector.java b/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributeSelector.java new file mode 100644 index 0000000000..925ff0618d --- /dev/null +++ b/core/src/main/java/org/keycloak/representations/userprofile/config/UPAttributeSelector.java @@ -0,0 +1,46 @@ +/* + * 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.representations.userprofile.config; + +import java.util.Set; + +/** + * Config of the rules when attribute is selected. + * + * @author Vlastimil Elias + * + */ +public class UPAttributeSelector { + + private Set scopes; + + public Set getScopes() { + return scopes; + } + + public void setScopes(Set scopes) { + this.scopes = scopes; + } + + @Override + public String toString() { + return "UPAttributeSelector [scopes=" + scopes + "]"; + } + +} diff --git a/services/src/main/java/org/keycloak/userprofile/config/UPConfig.java b/core/src/main/java/org/keycloak/representations/userprofile/config/UPConfig.java similarity index 68% rename from services/src/main/java/org/keycloak/userprofile/config/UPConfig.java rename to core/src/main/java/org/keycloak/representations/userprofile/config/UPConfig.java index a65b9c0d70..ee97faa9f5 100644 --- a/services/src/main/java/org/keycloak/userprofile/config/UPConfig.java +++ b/core/src/main/java/org/keycloak/representations/userprofile/config/UPConfig.java @@ -1,20 +1,22 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. + * 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 + * 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 + * 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. * - * 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.userprofile.config; +package org.keycloak.representations.userprofile.config; import java.util.ArrayList; import java.util.Collections; diff --git a/services/src/main/java/org/keycloak/userprofile/config/UPGroup.java b/core/src/main/java/org/keycloak/representations/userprofile/config/UPGroup.java similarity index 59% rename from services/src/main/java/org/keycloak/userprofile/config/UPGroup.java rename to core/src/main/java/org/keycloak/representations/userprofile/config/UPGroup.java index d2e28b71c5..124427309a 100644 --- a/services/src/main/java/org/keycloak/userprofile/config/UPGroup.java +++ b/core/src/main/java/org/keycloak/representations/userprofile/config/UPGroup.java @@ -1,21 +1,23 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. + * 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 + * 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 + * 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. * - * 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.userprofile.config; +package org.keycloak.representations.userprofile.config; import java.util.Map; diff --git a/integration/admin-client-jee/src/main/java/org/keycloak/admin/client/resource/UserProfileResource.java b/integration/admin-client-jee/src/main/java/org/keycloak/admin/client/resource/UserProfileResource.java index b89b2b4d0a..9c07693af8 100644 --- a/integration/admin-client-jee/src/main/java/org/keycloak/admin/client/resource/UserProfileResource.java +++ b/integration/admin-client-jee/src/main/java/org/keycloak/admin/client/resource/UserProfileResource.java @@ -22,9 +22,9 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import org.keycloak.representations.idm.UserProfileMetadata; +import org.keycloak.representations.userprofile.config.UPConfig; /** * @author Vlastimil Elias @@ -33,16 +33,25 @@ import org.keycloak.representations.idm.UserProfileMetadata; @Produces(MediaType.APPLICATION_JSON) public interface UserProfileResource { + /** + * @return user profile configuration + */ @GET @Consumes(MediaType.APPLICATION_JSON) - String getConfiguration(); + UPConfig getConfiguration(); @GET @Path("/metadata") @Consumes(jakarta.ws.rs.core.MediaType.APPLICATION_JSON) UserProfileMetadata getMetadata(); + /** + * Updates user profile configuration. Using null as an argument could mean restart of the configuration to the default configuration + * + * @param config Could be null, which can mean restart to the default user-profile configuration (Can depend on the implementation) + * @return + */ @PUT @Produces(MediaType.APPLICATION_JSON) - Response update(String text); + void update(UPConfig config); } diff --git a/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileProvider.java b/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileProvider.java index 842291b1a7..ef324b37b8 100644 --- a/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileProvider.java +++ b/server-spi-private/src/main/java/org/keycloak/userprofile/UserProfileProvider.java @@ -22,6 +22,7 @@ import java.util.Map; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.provider.Provider; +import org.keycloak.representations.userprofile.config.UPConfig; /** *

The provider responsible for creating {@link UserProfile} instances. @@ -70,13 +71,12 @@ public interface UserProfileProvider extends Provider { UserProfile create(UserProfileContext context, Map attributes, UserModel user); /** - * Get current UserProfile configuration. JSON formatted file is expected, but - * depends on the implementation. + * Get current UserProfile configuration. * * @return current UserProfile configuration * @see #setConfiguration(String) */ - String getConfiguration(); + UPConfig getConfiguration(); /** * Set new UserProfile configuration. It is persisted inside of the provider. diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserProfileResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserProfileResource.java index 3af39cbdf9..4c973060ea 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserProfileResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserProfileResource.java @@ -55,8 +55,8 @@ import org.keycloak.userprofile.AttributeValidatorMetadata; import org.keycloak.userprofile.UserProfile; import org.keycloak.userprofile.UserProfileContext; import org.keycloak.userprofile.UserProfileProvider; -import org.keycloak.userprofile.config.UPConfig; -import org.keycloak.userprofile.config.UPGroup; +import org.keycloak.representations.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPGroup; import org.keycloak.util.JsonSerialization; import org.keycloak.validate.Validators; @@ -81,8 +81,7 @@ public class UserProfileResource { @Produces(MediaType.APPLICATION_JSON) @Tag(name = KeycloakOpenAPI.Admin.Tags.USERS) @Operation(description = "Get the configuration for the user profile") - @APIResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = UPConfig.class))) - public String getConfiguration() { + public UPConfig getConfiguration() { auth.requireAnyAdminRole(); return session.getProvider(UserProfileProvider.class).getConfiguration(); } @@ -133,13 +132,7 @@ public class UserProfileResource { .collect(Collectors.toList()); UserProfileProvider provider = session.getProvider(UserProfileProvider.class); - UPConfig config; - - try { - config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class); - } catch (Exception cause) { - throw new RuntimeException("Failed to parse configuration", cause); - } + UPConfig config = provider.getConfiguration(); List groups = config.getGroups().stream().map(new Function() { @Override diff --git a/services/src/main/java/org/keycloak/userprofile/AbstractUserProfileProvider.java b/services/src/main/java/org/keycloak/userprofile/AbstractUserProfileProvider.java index 3d2077ca1d..fe11825018 100644 --- a/services/src/main/java/org/keycloak/userprofile/AbstractUserProfileProvider.java +++ b/services/src/main/java/org/keycloak/userprofile/AbstractUserProfileProvider.java @@ -46,6 +46,7 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigurationBuilder; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.services.messages.Messages; import org.keycloak.userprofile.validator.BlankAttributeValidator; import org.keycloak.userprofile.validator.BrokeringFederatedUsernameHasValueValidator; @@ -256,7 +257,7 @@ public abstract class AbstractUserProfileProvider } @Override - public String getConfiguration() { + public UPConfig getConfiguration() { return null; } diff --git a/services/src/main/java/org/keycloak/userprofile/DeclarativeUserProfileProvider.java b/services/src/main/java/org/keycloak/userprofile/DeclarativeUserProfileProvider.java index 8d17a2267e..ce1b15259f 100644 --- a/services/src/main/java/org/keycloak/userprofile/DeclarativeUserProfileProvider.java +++ b/services/src/main/java/org/keycloak/userprofile/DeclarativeUserProfileProvider.java @@ -52,13 +52,13 @@ import org.keycloak.provider.ProviderConfigurationBuilder; import org.keycloak.services.messages.Messages; import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.userprofile.config.DeclarativeUserProfileModel; -import org.keycloak.userprofile.config.UPAttribute; -import org.keycloak.userprofile.config.UPAttributePermissions; -import org.keycloak.userprofile.config.UPAttributeRequired; -import org.keycloak.userprofile.config.UPAttributeSelector; -import org.keycloak.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPAttributePermissions; +import org.keycloak.representations.userprofile.config.UPAttributeRequired; +import org.keycloak.representations.userprofile.config.UPAttributeSelector; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.userprofile.config.UPConfigUtils; -import org.keycloak.userprofile.config.UPGroup; +import org.keycloak.representations.userprofile.config.UPGroup; import org.keycloak.userprofile.validator.AttributeRequiredByMetadataValidator; import org.keycloak.userprofile.validator.BlankAttributeValidator; import org.keycloak.userprofile.validator.ImmutableAttributeValidator; @@ -214,11 +214,11 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider< } @Override - public String getConfiguration() { + public UPConfig getConfiguration() { RealmModel realm = session.getContext().getRealm(); if (!isEnabled(realm)) { - return defaultRawConfig; + return getParsedConfig(defaultRawConfig); } Optional component = getComponentModel(); @@ -227,13 +227,13 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider< String cfg = getConfigJsonFromComponentModel(component.get()); if (isBlank(cfg)) { - return defaultRawConfig; + return getParsedConfig(defaultRawConfig); } - return cfg; + return getParsedConfig(cfg); } - return defaultRawConfig; + return getParsedConfig(defaultRawConfig); } @Override @@ -241,9 +241,8 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider< RealmModel realm = session.getContext().getRealm(); Optional optionalComponent = realm.getComponentsStream(realm.getId(), UserProfileProvider.class.getName()).findAny(); - if (isBlank(configuration) && !optionalComponent.isPresent()) { - return; - } + // Avoid creating componentModel and then removing it right away + if (!optionalComponent.isPresent() && isBlank(configuration)) return; ComponentModel component = optionalComponent.isPresent() ? optionalComponent.get() : createComponentModel(); diff --git a/services/src/main/java/org/keycloak/userprofile/config/DeclarativeUserProfileModel.java b/services/src/main/java/org/keycloak/userprofile/config/DeclarativeUserProfileModel.java index 903fdd648b..5616c47c5c 100644 --- a/services/src/main/java/org/keycloak/userprofile/config/DeclarativeUserProfileModel.java +++ b/services/src/main/java/org/keycloak/userprofile/config/DeclarativeUserProfileModel.java @@ -20,7 +20,6 @@ package org.keycloak.userprofile.config; import org.keycloak.component.ComponentModel; -import org.keycloak.userprofile.DeclarativeUserProfileProvider; import org.keycloak.userprofile.UserProfileProvider; /** diff --git a/services/src/main/java/org/keycloak/userprofile/config/UPAttributeSelector.java b/services/src/main/java/org/keycloak/userprofile/config/UPAttributeSelector.java deleted file mode 100644 index 9f3ee72049..0000000000 --- a/services/src/main/java/org/keycloak/userprofile/config/UPAttributeSelector.java +++ /dev/null @@ -1,44 +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.userprofile.config; - -import java.util.Set; - -/** - * Config of the rules when attribute is selected. - * - * @author Vlastimil Elias - * - */ -public class UPAttributeSelector { - - private Set scopes; - - public Set getScopes() { - return scopes; - } - - public void setScopes(Set scopes) { - this.scopes = scopes; - } - - @Override - public String toString() { - return "UPAttributeSelector [scopes=" + scopes + "]"; - } - -} diff --git a/services/src/main/java/org/keycloak/userprofile/config/UPConfigUtils.java b/services/src/main/java/org/keycloak/userprofile/config/UPConfigUtils.java index cf140b3936..1acf3a3acf 100644 --- a/services/src/main/java/org/keycloak/userprofile/config/UPConfigUtils.java +++ b/services/src/main/java/org/keycloak/userprofile/config/UPConfigUtils.java @@ -35,6 +35,8 @@ import org.keycloak.common.util.StreamUtil; import org.keycloak.models.ClientScopeModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.userprofile.UserProfileContext; import org.keycloak.util.JsonSerialization; import org.keycloak.validate.ValidationResult; @@ -107,7 +109,9 @@ public class UPConfigUtils { private static List validateAttributes(KeycloakSession session, UPConfig config) { List errors = new ArrayList<>(); - Set groups = config.getGroups().stream().map(g -> g.getName()).collect(Collectors.toSet()); + Set groups = config.getGroups().stream() + .map(g -> g.getName()) + .collect(Collectors.toSet()); if (config.getAttributes() != null) { Set attNamesCache = new HashSet<>(); diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/user/profile/CustomUserProfileProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/user/profile/CustomUserProfileProvider.java index fd4be419fe..ed09247c59 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/user/profile/CustomUserProfileProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/user/profile/CustomUserProfileProvider.java @@ -7,7 +7,7 @@ import org.keycloak.userprofile.UserProfile; import org.keycloak.userprofile.UserProfileContext; import org.keycloak.userprofile.UserProfileMetadata; import org.keycloak.userprofile.UserProfileProvider; -import org.keycloak.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPConfig; import java.util.Map; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTestWithUserProfile.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTestWithUserProfile.java index 692a973bf3..310e85905f 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTestWithUserProfile.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTestWithUserProfile.java @@ -39,9 +39,9 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.forms.VerifyProfileTest; -import org.keycloak.userprofile.config.UPAttribute; -import org.keycloak.userprofile.config.UPAttributePermissions; -import org.keycloak.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPAttributePermissions; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.util.JsonSerialization; @EnableFeature(Feature.DECLARATIVE_USER_PROFILE) @@ -58,7 +58,7 @@ public class UserTestWithUserProfile extends UserTest { realm.update(realmRep); assertAdminEvents.poll(); VerifyProfileTest.setUserProfileConfiguration(realm, null); - UPConfig upConfig = JsonSerialization.readValue(realm.users().userProfile().getConfiguration(), UPConfig.class); + UPConfig upConfig = realm.users().userProfile().getConfiguration(); for (String name : managedAttributes) { upConfig.addAttribute(createAttributeMetadata(name)); 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 index 4515a2ec25..afc642351b 100644 --- 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 @@ -41,10 +41,10 @@ import org.keycloak.representations.idm.UserProfileAttributeGroupMetadata; import org.keycloak.representations.idm.UserProfileMetadata; import org.keycloak.testsuite.admin.AbstractAdminTest; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; -import org.keycloak.userprofile.config.UPAttribute; -import org.keycloak.userprofile.config.UPConfig; -import org.keycloak.userprofile.config.UPGroup; -import org.keycloak.util.JsonSerialization; +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; /** * @author Pedro Igor @@ -62,17 +62,17 @@ public class UserProfileAdminTest extends AbstractAdminTest { @Test public void testDefaultConfigIfNoneSet() { - assertEquals(readDefaultConfig(), testRealm().users().userProfile().getConfiguration()); + JsonTestUtils.assertJsonEquals(readDefaultConfig(), testRealm().users().userProfile().getConfiguration()); } @Test public void testSetDefaultConfig() { - String rawConfig = "{\"attributes\": [{\"name\": \"test\"}]}"; + UPConfig config = new UPConfig().addAttribute(new UPAttribute("test")); UserProfileResource userProfile = testRealm().users().userProfile(); - userProfile.update(rawConfig); + userProfile.update(config); getCleanup().addCleanup(() -> testRealm().users().userProfile().update(null)); - assertEquals(rawConfig, userProfile.getConfiguration()); + JsonTestUtils.assertJsonEquals(config, userProfile.getConfiguration()); } @Test @@ -173,8 +173,8 @@ public class UserProfileAdminTest extends AbstractAdminTest { } @Test - public void testGroupsMetadata() throws IOException { - UPConfig config = JsonSerialization.readValue(testRealm().users().userProfile().getConfiguration(), UPConfig.class); + public void testGroupsMetadata() { + UPConfig config = testRealm().users().userProfile().getConfiguration(); for (int i = 0; i < 3; i++) { UPGroup group = new UPGroup(); @@ -188,7 +188,7 @@ public class UserProfileAdminTest extends AbstractAdminTest { UPAttribute firstName = config.getAttribute(UserModel.FIRST_NAME); firstName.setGroup(config.getGroups().get(0).getName()); UserProfileResource userProfile = testRealm().users().userProfile(); - userProfile.update(JsonSerialization.writeValueAsString(config)); + userProfile.update(config); getCleanup().addCleanup(() -> testRealm().users().userProfile().update(null)); UserProfileMetadata metadata = testRealm().users().userProfile().getMetadata(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java index ffc96a0d90..bc9c4f8769 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java @@ -40,14 +40,18 @@ import org.keycloak.representations.idm.RealmEventsConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.ProfileAssume; import org.keycloak.testsuite.client.resources.TestingExportImportResource; import org.keycloak.testsuite.forms.VerifyProfileTest; import org.keycloak.testsuite.runonserver.RunHelpers; +import org.keycloak.testsuite.util.JsonTestUtils; import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.userprofile.DeclarativeUserProfileProvider; +import org.keycloak.util.JsonSerialization; +import org.keycloak.utils.JsonUtils; import java.io.File; import java.io.IOException; @@ -270,7 +274,7 @@ public class ExportImportTest extends AbstractKeycloakTest { } @Test - public void testExportUserProfileConfig() { + public void testExportUserProfileConfig() throws IOException { //Enable user profile on realm RealmResource realmRes = adminClient.realm(TEST_REALM); RealmRepresentation realmRep = realmRes.toRepresentation(); @@ -304,7 +308,7 @@ public class ExportImportTest extends AbstractKeycloakTest { MultivaluedHashMap config = userProfileComponents.get(0).getConfig(); assertThat(config, notNullValue()); assertThat(config.size(), equalTo(1)); - assertThat(config.getFirst(DeclarativeUserProfileProvider.UP_COMPONENT_CONFIG_KEY), equalTo(VerifyProfileTest.CONFIGURATION_FOR_USER_EDIT)); + JsonTestUtils.assertJsonEquals(config.getFirst(DeclarativeUserProfileProvider.UP_COMPONENT_CONFIG_KEY), VerifyProfileTest.CONFIGURATION_FOR_USER_EDIT, UPConfig.class); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPAdminRestApiWithUserProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPAdminRestApiWithUserProfileTest.java index c8235a275e..b7275b1451 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPAdminRestApiWithUserProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPAdminRestApiWithUserProfileTest.java @@ -18,13 +18,10 @@ package org.keycloak.testsuite.federation.ldap; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.keycloak.testsuite.forms.VerifyProfileTest.disableDynamicUserProfile; import static org.keycloak.testsuite.forms.VerifyProfileTest.setUserProfileConfiguration; -import static org.keycloak.util.JsonSerialization.readValue; import static org.keycloak.util.JsonSerialization.writeValueAsString; import jakarta.ws.rs.BadRequestException; @@ -39,7 +36,6 @@ import org.keycloak.admin.client.resource.UserResource; import org.keycloak.common.Profile; import org.keycloak.models.LDAPConstants; import org.keycloak.representations.idm.ComponentRepresentation; -import org.keycloak.representations.idm.OAuth2ErrorRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.storage.UserStorageProvider; @@ -47,9 +43,9 @@ import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.forms.VerifyProfileTest; import org.keycloak.testsuite.util.UserBuilder; -import org.keycloak.userprofile.config.UPAttribute; -import org.keycloak.userprofile.config.UPAttributePermissions; -import org.keycloak.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPAttributePermissions; +import org.keycloak.representations.userprofile.config.UPConfig; @EnableFeature(value = Profile.Feature.DECLARATIVE_USER_PROFILE) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -101,7 +97,7 @@ public class LDAPAdminRestApiWithUserProfileTest extends LDAPAdminRestApiTest { testRealm().update(realmRep); - UPConfig upConfig = readValue(testRealm().users().userProfile().getConfiguration(), UPConfig.class); + UPConfig upConfig = testRealm().users().userProfile().getConfiguration(); UPAttribute attribute = new UPAttribute(); attribute.setName(LDAPConstants.LDAP_ID); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java index 70b88d7d84..fcac6b0a02 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.keycloak.userprofile.DeclarativeUserProfileProvider.REALM_USER_PROFILE_ENABLED; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -47,6 +48,7 @@ import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; @@ -56,11 +58,13 @@ import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.VerifyProfilePage; import org.keycloak.testsuite.runonserver.RunOnServer; import org.keycloak.testsuite.util.ClientScopeBuilder; +import org.keycloak.testsuite.util.JsonTestUtils; import org.keycloak.testsuite.util.KeycloakModelUtils; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.userprofile.UserProfileContext; +import org.keycloak.util.JsonSerialization; import org.openqa.selenium.By; /** @@ -1150,7 +1154,7 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest { } @Test - public void testConfigurationRemainsAfterReset() { + public void testConfigurationRemainsAfterReset() throws IOException { String customConfig = "{\"attributes\": [" + "{\"name\": \"firstName\"," + PERMISSIONS_ALL + ", \"required\": {}}," + "{\"name\": \"lastName\"," + PERMISSIONS_ALL + "}," @@ -1165,7 +1169,7 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest { enableDynamicUserProfile(realm); testRealm().update(realm); - Assert.assertEquals(customConfig, realmRes.users().userProfile().getConfiguration()); + JsonTestUtils.assertJsonEquals(customConfig, realmRes.users().userProfile().getConfiguration()); } protected UserRepresentation getUser(String userId) { @@ -1213,10 +1217,11 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest { public static void setUserProfileConfiguration(RealmResource testRealm, String configuration) { - try (Response r = testRealm.users().userProfile().update(configuration)) { - if (r.getStatus() != 200) { - Assert.fail("UserProfile Configuration not set due to error: " + r.readEntity(String.class)); - } + try { + UPConfig config = configuration == null ? null : JsonSerialization.readValue(configuration, UPConfig.class); + testRealm.users().userProfile().update(config); + } catch (IOException ioe) { + throw new RuntimeException("Failed to read configuration", ioe); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ImportTest.java index 8b08adfa98..4d30f90bad 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ImportTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ImportTest.java @@ -38,9 +38,9 @@ import org.keycloak.testsuite.ProfileAssume; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.runonserver.RunOnServerException; import org.keycloak.userprofile.UserProfileProvider; -import org.keycloak.userprofile.config.UPAttribute; -import org.keycloak.userprofile.config.UPAttributeSelector; -import org.keycloak.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPAttributeSelector; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.userprofile.config.UPConfigUtils; import org.keycloak.util.JsonSerialization; @@ -157,7 +157,7 @@ public class ImportTest extends AbstractTestRealmKeycloakTest { session.getContext().setRealm(realm); UserProfileProvider provider = session.getProvider(UserProfileProvider.class); - UPConfig config = UPConfigUtils.readConfig(new ByteArrayInputStream(provider.getConfiguration().getBytes())); + UPConfig config = provider.getConfiguration(); Assert.assertTrue(config.getAttributes().stream().map(UPAttribute::getName).anyMatch("email"::equals)); Assert.assertTrue(config.getAttributes().stream().map(UPAttribute::getName).anyMatch("test"::equals)); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/AbstractUserProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/AbstractUserProfileTest.java index 845ce23ee3..50c164d963 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/AbstractUserProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/AbstractUserProfileTest.java @@ -42,8 +42,8 @@ import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.forms.VerifyProfileTest; import org.keycloak.userprofile.UserProfileProvider; -import org.keycloak.userprofile.config.UPAttribute; -import org.keycloak.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.userprofile.config.UPConfigUtils; import org.keycloak.util.JsonSerialization; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/UserProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/UserProfileTest.java index e1df4317fa..72fc0a656d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/UserProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/UserProfileTest.java @@ -30,7 +30,6 @@ import static org.junit.Assert.fail; import static org.keycloak.userprofile.config.UPConfigUtils.ROLE_ADMIN; import static org.keycloak.userprofile.config.UPConfigUtils.ROLE_USER; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -57,11 +56,11 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.messages.Messages; import org.keycloak.testsuite.runonserver.RunOnServer; import org.keycloak.userprofile.AttributeGroupMetadata; -import org.keycloak.userprofile.config.UPAttribute; -import org.keycloak.userprofile.config.UPAttributePermissions; -import org.keycloak.userprofile.config.UPAttributeRequired; -import org.keycloak.userprofile.config.UPAttributeSelector; -import org.keycloak.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPAttributePermissions; +import org.keycloak.representations.userprofile.config.UPAttributeRequired; +import org.keycloak.representations.userprofile.config.UPAttributeSelector; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.testsuite.util.ClientScopeBuilder; import org.keycloak.testsuite.util.KeycloakModelUtils; import org.keycloak.userprofile.Attributes; @@ -235,7 +234,7 @@ public class UserProfileTest extends AbstractUserProfileTest { realm.setRegistrationEmailAsUsername(false); } - UPConfig config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class); + UPConfig config = provider.getConfiguration(); UPAttribute email = config.getAttribute("email"); @@ -439,7 +438,7 @@ public class UserProfileTest extends AbstractUserProfileTest { private static void testCreateAndUpdateUser(KeycloakSession session) throws IOException { UserProfileProvider provider = getUserProfileProvider(session); - UPConfig config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class); + UPConfig config = provider.getConfiguration(); UPAttribute attribute = new UPAttribute(); attribute.setName("address"); UPAttributePermissions permissions = new UPAttributePermissions(); @@ -895,7 +894,7 @@ public class UserProfileTest extends AbstractUserProfileTest { assertTrue(ve.hasError(Messages.INVALID_USERNAME)); } - UPConfig config = UPConfigUtils.readConfig(new ByteArrayInputStream(provider.getConfiguration().getBytes())); + UPConfig config = provider.getConfiguration(); for (UPAttribute attribute : config.getAttributes()) { if (UserModel.USERNAME.equals(attribute.getName())) { @@ -1509,7 +1508,7 @@ public class UserProfileTest extends AbstractUserProfileTest { private static void testUsernameAndEmailPermissionNotSetIfEmpty(KeycloakSession session) throws IOException { UserProfileProvider provider = getUserProfileProvider(session); - UPConfig config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class); + UPConfig config = provider.getConfiguration(); for (UPAttribute attribute : config.getAttributes()) { if (attribute.getName().equals(UserModel.USERNAME) || attribute.getName().equals(UserModel.EMAIL)) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/config/UPConfigParserTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/config/UPConfigParserTest.java index 353501bb1d..0210424d9a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/config/UPConfigParserTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/user/profile/config/UPConfigParserTest.java @@ -37,12 +37,12 @@ import org.keycloak.testsuite.runonserver.RunOnServer; import com.fasterxml.jackson.databind.JsonMappingException; import org.keycloak.testsuite.util.ClientScopeBuilder; -import org.keycloak.userprofile.config.UPAttribute; -import org.keycloak.userprofile.config.UPAttributePermissions; -import org.keycloak.userprofile.config.UPAttributeRequired; -import org.keycloak.userprofile.config.UPConfig; +import org.keycloak.representations.userprofile.config.UPAttribute; +import org.keycloak.representations.userprofile.config.UPAttributePermissions; +import org.keycloak.representations.userprofile.config.UPAttributeRequired; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.userprofile.config.UPConfigUtils; -import org.keycloak.userprofile.config.UPGroup; +import org.keycloak.representations.userprofile.config.UPGroup; /** * Unit test for {@link UPConfigUtils} functionality diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/JsonTestUtils.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/JsonTestUtils.java new file mode 100644 index 0000000000..ec41f3fd11 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/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.testsuite.util; + +import java.io.IOException; + +import org.junit.Assert; +import org.keycloak.util.JsonSerialization; + +/** + * 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); + } + } +}