Moving UPConfig and related classes from keycloak-services

closes #24535

Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
mposolda 2023-10-31 15:13:00 +01:00 committed by Marek Posolda
parent e5eded0eab
commit 7863c3e563
25 changed files with 302 additions and 191 deletions

View file

@ -1,20 +1,22 @@
/* /*
* Copyright 2021 Red Hat, Inc. and/or its affiliates * Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags. * and other contributors as indicated by the @author tags.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * 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.HashMap;
import java.util.Map; import java.util.Map;
@ -40,6 +42,13 @@ public class UPAttribute {
private UPAttributeSelector selector; private UPAttributeSelector selector;
private String group; private String group;
public UPAttribute() {
}
public UPAttribute(String name) {
this.name = name != null ? name.trim() : null;
}
public String getName() { public String getName() {
return name; return name;
} }

View file

@ -1,20 +1,22 @@
/* /*
* Copyright 2021 Red Hat, Inc. and/or its affiliates * Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags. * and other contributors as indicated by the @author tags.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * 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.Collections;
import java.util.Set; import java.util.Set;

View file

@ -1,20 +1,22 @@
/* /*
* Copyright 2021 Red Hat, Inc. and/or its affiliates * Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags. * and other contributors as indicated by the @author tags.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * 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; import java.util.Set;

View file

@ -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 <velias@redhat.com>
*
*/
public class UPAttributeSelector {
private Set<String> scopes;
public Set<String> getScopes() {
return scopes;
}
public void setScopes(Set<String> scopes) {
this.scopes = scopes;
}
@Override
public String toString() {
return "UPAttributeSelector [scopes=" + scopes + "]";
}
}

View file

@ -1,20 +1,22 @@
/* /*
* Copyright 2021 Red Hat, Inc. and/or its affiliates * Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags. * and other contributors as indicated by the @author tags.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * 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.ArrayList;
import java.util.Collections; import java.util.Collections;

View file

@ -1,21 +1,23 @@
/* /*
* Copyright 2021 Red Hat, Inc. and/or its affiliates * Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags. * and other contributors as indicated by the @author tags.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * 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; import java.util.Map;

View file

@ -22,9 +22,9 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.keycloak.representations.idm.UserProfileMetadata; import org.keycloak.representations.idm.UserProfileMetadata;
import org.keycloak.representations.userprofile.config.UPConfig;
/** /**
* @author Vlastimil Elias <velias@redhat.com> * @author Vlastimil Elias <velias@redhat.com>
@ -33,16 +33,25 @@ import org.keycloak.representations.idm.UserProfileMetadata;
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public interface UserProfileResource { public interface UserProfileResource {
/**
* @return user profile configuration
*/
@GET @GET
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
String getConfiguration(); UPConfig getConfiguration();
@GET @GET
@Path("/metadata") @Path("/metadata")
@Consumes(jakarta.ws.rs.core.MediaType.APPLICATION_JSON) @Consumes(jakarta.ws.rs.core.MediaType.APPLICATION_JSON)
UserProfileMetadata getMetadata(); 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 @PUT
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
Response update(String text); void update(UPConfig config);
} }

View file

@ -22,6 +22,7 @@ import java.util.Map;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.provider.Provider; import org.keycloak.provider.Provider;
import org.keycloak.representations.userprofile.config.UPConfig;
/** /**
* <p>The provider responsible for creating {@link UserProfile} instances. * <p>The provider responsible for creating {@link UserProfile} instances.
@ -70,13 +71,12 @@ public interface UserProfileProvider extends Provider {
UserProfile create(UserProfileContext context, Map<String, ?> attributes, UserModel user); UserProfile create(UserProfileContext context, Map<String, ?> attributes, UserModel user);
/** /**
* Get current UserProfile configuration. JSON formatted file is expected, but * Get current UserProfile configuration.
* depends on the implementation.
* *
* @return current UserProfile configuration * @return current UserProfile configuration
* @see #setConfiguration(String) * @see #setConfiguration(String)
*/ */
String getConfiguration(); UPConfig getConfiguration();
/** /**
* Set new UserProfile configuration. It is persisted inside of the provider. * Set new UserProfile configuration. It is persisted inside of the provider.

View file

@ -55,8 +55,8 @@ import org.keycloak.userprofile.AttributeValidatorMetadata;
import org.keycloak.userprofile.UserProfile; import org.keycloak.userprofile.UserProfile;
import org.keycloak.userprofile.UserProfileContext; import org.keycloak.userprofile.UserProfileContext;
import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.userprofile.config.UPGroup; import org.keycloak.representations.userprofile.config.UPGroup;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
import org.keycloak.validate.Validators; import org.keycloak.validate.Validators;
@ -81,8 +81,7 @@ public class UserProfileResource {
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.USERS) @Tag(name = KeycloakOpenAPI.Admin.Tags.USERS)
@Operation(description = "Get the configuration for the user profile") @Operation(description = "Get the configuration for the user profile")
@APIResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = UPConfig.class))) public UPConfig getConfiguration() {
public String getConfiguration() {
auth.requireAnyAdminRole(); auth.requireAnyAdminRole();
return session.getProvider(UserProfileProvider.class).getConfiguration(); return session.getProvider(UserProfileProvider.class).getConfiguration();
} }
@ -133,13 +132,7 @@ public class UserProfileResource {
.collect(Collectors.toList()); .collect(Collectors.toList());
UserProfileProvider provider = session.getProvider(UserProfileProvider.class); UserProfileProvider provider = session.getProvider(UserProfileProvider.class);
UPConfig config; UPConfig config = provider.getConfiguration();
try {
config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class);
} catch (Exception cause) {
throw new RuntimeException("Failed to parse configuration", cause);
}
List<UserProfileAttributeGroupMetadata> groups = config.getGroups().stream().map(new Function<UPGroup, UserProfileAttributeGroupMetadata>() { List<UserProfileAttributeGroupMetadata> groups = config.getGroups().stream().map(new Function<UPGroup, UserProfileAttributeGroupMetadata>() {
@Override @Override

View file

@ -46,6 +46,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderConfigurationBuilder; import org.keycloak.provider.ProviderConfigurationBuilder;
import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;
import org.keycloak.userprofile.validator.BlankAttributeValidator; import org.keycloak.userprofile.validator.BlankAttributeValidator;
import org.keycloak.userprofile.validator.BrokeringFederatedUsernameHasValueValidator; import org.keycloak.userprofile.validator.BrokeringFederatedUsernameHasValueValidator;
@ -256,7 +257,7 @@ public abstract class AbstractUserProfileProvider<U extends UserProfileProvider>
} }
@Override @Override
public String getConfiguration() { public UPConfig getConfiguration() {
return null; return null;
} }

View file

@ -52,13 +52,13 @@ import org.keycloak.provider.ProviderConfigurationBuilder;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;
import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.userprofile.config.DeclarativeUserProfileModel; import org.keycloak.userprofile.config.DeclarativeUserProfileModel;
import org.keycloak.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttribute;
import org.keycloak.userprofile.config.UPAttributePermissions; import org.keycloak.representations.userprofile.config.UPAttributePermissions;
import org.keycloak.userprofile.config.UPAttributeRequired; import org.keycloak.representations.userprofile.config.UPAttributeRequired;
import org.keycloak.userprofile.config.UPAttributeSelector; import org.keycloak.representations.userprofile.config.UPAttributeSelector;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.userprofile.config.UPConfigUtils; 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.AttributeRequiredByMetadataValidator;
import org.keycloak.userprofile.validator.BlankAttributeValidator; import org.keycloak.userprofile.validator.BlankAttributeValidator;
import org.keycloak.userprofile.validator.ImmutableAttributeValidator; import org.keycloak.userprofile.validator.ImmutableAttributeValidator;
@ -214,11 +214,11 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
} }
@Override @Override
public String getConfiguration() { public UPConfig getConfiguration() {
RealmModel realm = session.getContext().getRealm(); RealmModel realm = session.getContext().getRealm();
if (!isEnabled(realm)) { if (!isEnabled(realm)) {
return defaultRawConfig; return getParsedConfig(defaultRawConfig);
} }
Optional<ComponentModel> component = getComponentModel(); Optional<ComponentModel> component = getComponentModel();
@ -227,13 +227,13 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
String cfg = getConfigJsonFromComponentModel(component.get()); String cfg = getConfigJsonFromComponentModel(component.get());
if (isBlank(cfg)) { if (isBlank(cfg)) {
return defaultRawConfig; return getParsedConfig(defaultRawConfig);
} }
return cfg; return getParsedConfig(cfg);
} }
return defaultRawConfig; return getParsedConfig(defaultRawConfig);
} }
@Override @Override
@ -241,9 +241,8 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
RealmModel realm = session.getContext().getRealm(); RealmModel realm = session.getContext().getRealm();
Optional<ComponentModel> optionalComponent = realm.getComponentsStream(realm.getId(), UserProfileProvider.class.getName()).findAny(); Optional<ComponentModel> optionalComponent = realm.getComponentsStream(realm.getId(), UserProfileProvider.class.getName()).findAny();
if (isBlank(configuration) && !optionalComponent.isPresent()) { // Avoid creating componentModel and then removing it right away
return; if (!optionalComponent.isPresent() && isBlank(configuration)) return;
}
ComponentModel component = optionalComponent.isPresent() ? optionalComponent.get() : createComponentModel(); ComponentModel component = optionalComponent.isPresent() ? optionalComponent.get() : createComponentModel();

View file

@ -20,7 +20,6 @@
package org.keycloak.userprofile.config; package org.keycloak.userprofile.config;
import org.keycloak.component.ComponentModel; import org.keycloak.component.ComponentModel;
import org.keycloak.userprofile.DeclarativeUserProfileProvider;
import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.userprofile.UserProfileProvider;
/** /**

View file

@ -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 <velias@redhat.com>
*
*/
public class UPAttributeSelector {
private Set<String> scopes;
public Set<String> getScopes() {
return scopes;
}
public void setScopes(Set<String> scopes) {
this.scopes = scopes;
}
@Override
public String toString() {
return "UPAttributeSelector [scopes=" + scopes + "]";
}
}

View file

@ -35,6 +35,8 @@ import org.keycloak.common.util.StreamUtil;
import org.keycloak.models.ClientScopeModel; import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; 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.userprofile.UserProfileContext;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
import org.keycloak.validate.ValidationResult; import org.keycloak.validate.ValidationResult;
@ -107,7 +109,9 @@ public class UPConfigUtils {
private static List<String> validateAttributes(KeycloakSession session, UPConfig config) { private static List<String> validateAttributes(KeycloakSession session, UPConfig config) {
List<String> errors = new ArrayList<>(); List<String> errors = new ArrayList<>();
Set<String> groups = config.getGroups().stream().map(g -> g.getName()).collect(Collectors.toSet()); Set<String> groups = config.getGroups().stream()
.map(g -> g.getName())
.collect(Collectors.toSet());
if (config.getAttributes() != null) { if (config.getAttributes() != null) {
Set<String> attNamesCache = new HashSet<>(); Set<String> attNamesCache = new HashSet<>();

View file

@ -7,7 +7,7 @@ import org.keycloak.userprofile.UserProfile;
import org.keycloak.userprofile.UserProfileContext; import org.keycloak.userprofile.UserProfileContext;
import org.keycloak.userprofile.UserProfileMetadata; import org.keycloak.userprofile.UserProfileMetadata;
import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import java.util.Map; import java.util.Map;

View file

@ -39,9 +39,9 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.forms.VerifyProfileTest; import org.keycloak.testsuite.forms.VerifyProfileTest;
import org.keycloak.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttribute;
import org.keycloak.userprofile.config.UPAttributePermissions; import org.keycloak.representations.userprofile.config.UPAttributePermissions;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
@EnableFeature(Feature.DECLARATIVE_USER_PROFILE) @EnableFeature(Feature.DECLARATIVE_USER_PROFILE)
@ -58,7 +58,7 @@ public class UserTestWithUserProfile extends UserTest {
realm.update(realmRep); realm.update(realmRep);
assertAdminEvents.poll(); assertAdminEvents.poll();
VerifyProfileTest.setUserProfileConfiguration(realm, null); VerifyProfileTest.setUserProfileConfiguration(realm, null);
UPConfig upConfig = JsonSerialization.readValue(realm.users().userProfile().getConfiguration(), UPConfig.class); UPConfig upConfig = realm.users().userProfile().getConfiguration();
for (String name : managedAttributes) { for (String name : managedAttributes) {
upConfig.addAttribute(createAttributeMetadata(name)); upConfig.addAttribute(createAttributeMetadata(name));

View file

@ -41,10 +41,10 @@ import org.keycloak.representations.idm.UserProfileAttributeGroupMetadata;
import org.keycloak.representations.idm.UserProfileMetadata; import org.keycloak.representations.idm.UserProfileMetadata;
import org.keycloak.testsuite.admin.AbstractAdminTest; import org.keycloak.testsuite.admin.AbstractAdminTest;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttribute;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.userprofile.config.UPGroup; import org.keycloak.representations.userprofile.config.UPGroup;
import org.keycloak.util.JsonSerialization; import org.keycloak.testsuite.util.JsonTestUtils;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -62,17 +62,17 @@ public class UserProfileAdminTest extends AbstractAdminTest {
@Test @Test
public void testDefaultConfigIfNoneSet() { public void testDefaultConfigIfNoneSet() {
assertEquals(readDefaultConfig(), testRealm().users().userProfile().getConfiguration()); JsonTestUtils.assertJsonEquals(readDefaultConfig(), testRealm().users().userProfile().getConfiguration());
} }
@Test @Test
public void testSetDefaultConfig() { public void testSetDefaultConfig() {
String rawConfig = "{\"attributes\": [{\"name\": \"test\"}]}"; UPConfig config = new UPConfig().addAttribute(new UPAttribute("test"));
UserProfileResource userProfile = testRealm().users().userProfile(); UserProfileResource userProfile = testRealm().users().userProfile();
userProfile.update(rawConfig); userProfile.update(config);
getCleanup().addCleanup(() -> testRealm().users().userProfile().update(null)); getCleanup().addCleanup(() -> testRealm().users().userProfile().update(null));
assertEquals(rawConfig, userProfile.getConfiguration()); JsonTestUtils.assertJsonEquals(config, userProfile.getConfiguration());
} }
@Test @Test
@ -173,8 +173,8 @@ public class UserProfileAdminTest extends AbstractAdminTest {
} }
@Test @Test
public void testGroupsMetadata() throws IOException { public void testGroupsMetadata() {
UPConfig config = JsonSerialization.readValue(testRealm().users().userProfile().getConfiguration(), UPConfig.class); UPConfig config = testRealm().users().userProfile().getConfiguration();
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
UPGroup group = new UPGroup(); UPGroup group = new UPGroup();
@ -188,7 +188,7 @@ public class UserProfileAdminTest extends AbstractAdminTest {
UPAttribute firstName = config.getAttribute(UserModel.FIRST_NAME); UPAttribute firstName = config.getAttribute(UserModel.FIRST_NAME);
firstName.setGroup(config.getGroups().get(0).getName()); firstName.setGroup(config.getGroups().get(0).getName());
UserProfileResource userProfile = testRealm().users().userProfile(); UserProfileResource userProfile = testRealm().users().userProfile();
userProfile.update(JsonSerialization.writeValueAsString(config)); userProfile.update(config);
getCleanup().addCleanup(() -> testRealm().users().userProfile().update(null)); getCleanup().addCleanup(() -> testRealm().users().userProfile().update(null));
UserProfileMetadata metadata = testRealm().users().userProfile().getMetadata(); UserProfileMetadata metadata = testRealm().users().userProfile().getMetadata();

View file

@ -40,14 +40,18 @@ import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.ProfileAssume; import org.keycloak.testsuite.ProfileAssume;
import org.keycloak.testsuite.client.resources.TestingExportImportResource; import org.keycloak.testsuite.client.resources.TestingExportImportResource;
import org.keycloak.testsuite.forms.VerifyProfileTest; import org.keycloak.testsuite.forms.VerifyProfileTest;
import org.keycloak.testsuite.runonserver.RunHelpers; import org.keycloak.testsuite.runonserver.RunHelpers;
import org.keycloak.testsuite.util.JsonTestUtils;
import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.testsuite.util.UserBuilder;
import org.keycloak.userprofile.DeclarativeUserProfileProvider; import org.keycloak.userprofile.DeclarativeUserProfileProvider;
import org.keycloak.util.JsonSerialization;
import org.keycloak.utils.JsonUtils;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -270,7 +274,7 @@ public class ExportImportTest extends AbstractKeycloakTest {
} }
@Test @Test
public void testExportUserProfileConfig() { public void testExportUserProfileConfig() throws IOException {
//Enable user profile on realm //Enable user profile on realm
RealmResource realmRes = adminClient.realm(TEST_REALM); RealmResource realmRes = adminClient.realm(TEST_REALM);
RealmRepresentation realmRep = realmRes.toRepresentation(); RealmRepresentation realmRep = realmRes.toRepresentation();
@ -304,7 +308,7 @@ public class ExportImportTest extends AbstractKeycloakTest {
MultivaluedHashMap<String, String> config = userProfileComponents.get(0).getConfig(); MultivaluedHashMap<String, String> config = userProfileComponents.get(0).getConfig();
assertThat(config, notNullValue()); assertThat(config, notNullValue());
assertThat(config.size(), equalTo(1)); 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 @Test

View file

@ -18,13 +18,10 @@
package org.keycloak.testsuite.federation.ldap; 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.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.keycloak.testsuite.forms.VerifyProfileTest.disableDynamicUserProfile; import static org.keycloak.testsuite.forms.VerifyProfileTest.disableDynamicUserProfile;
import static org.keycloak.testsuite.forms.VerifyProfileTest.setUserProfileConfiguration; import static org.keycloak.testsuite.forms.VerifyProfileTest.setUserProfileConfiguration;
import static org.keycloak.util.JsonSerialization.readValue;
import static org.keycloak.util.JsonSerialization.writeValueAsString; import static org.keycloak.util.JsonSerialization.writeValueAsString;
import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.BadRequestException;
@ -39,7 +36,6 @@ import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.models.LDAPConstants; import org.keycloak.models.LDAPConstants;
import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.storage.UserStorageProvider; 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.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.forms.VerifyProfileTest; import org.keycloak.testsuite.forms.VerifyProfileTest;
import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.testsuite.util.UserBuilder;
import org.keycloak.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttribute;
import org.keycloak.userprofile.config.UPAttributePermissions; import org.keycloak.representations.userprofile.config.UPAttributePermissions;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
@EnableFeature(value = Profile.Feature.DECLARATIVE_USER_PROFILE) @EnableFeature(value = Profile.Feature.DECLARATIVE_USER_PROFILE)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -101,7 +97,7 @@ public class LDAPAdminRestApiWithUserProfileTest extends LDAPAdminRestApiTest {
testRealm().update(realmRep); testRealm().update(realmRep);
UPConfig upConfig = readValue(testRealm().users().userProfile().getConfiguration(), UPConfig.class); UPConfig upConfig = testRealm().users().userProfile().getConfiguration();
UPAttribute attribute = new UPAttribute(); UPAttribute attribute = new UPAttribute();
attribute.setName(LDAPConstants.LDAP_ID); attribute.setName(LDAPConstants.LDAP_ID);

View file

@ -23,6 +23,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.keycloak.userprofile.DeclarativeUserProfileProvider.REALM_USER_PROFILE_ENABLED; import static org.keycloak.userprofile.DeclarativeUserProfileProvider.REALM_USER_PROFILE_ENABLED;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; 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.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature; 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.pages.VerifyProfilePage;
import org.keycloak.testsuite.runonserver.RunOnServer; import org.keycloak.testsuite.runonserver.RunOnServer;
import org.keycloak.testsuite.util.ClientScopeBuilder; import org.keycloak.testsuite.util.ClientScopeBuilder;
import org.keycloak.testsuite.util.JsonTestUtils;
import org.keycloak.testsuite.util.KeycloakModelUtils; import org.keycloak.testsuite.util.KeycloakModelUtils;
import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.testsuite.util.UserBuilder;
import org.keycloak.userprofile.UserProfileContext; import org.keycloak.userprofile.UserProfileContext;
import org.keycloak.util.JsonSerialization;
import org.openqa.selenium.By; import org.openqa.selenium.By;
/** /**
@ -1150,7 +1154,7 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest {
} }
@Test @Test
public void testConfigurationRemainsAfterReset() { public void testConfigurationRemainsAfterReset() throws IOException {
String customConfig = "{\"attributes\": [" String customConfig = "{\"attributes\": ["
+ "{\"name\": \"firstName\"," + PERMISSIONS_ALL + ", \"required\": {}}," + "{\"name\": \"firstName\"," + PERMISSIONS_ALL + ", \"required\": {}},"
+ "{\"name\": \"lastName\"," + PERMISSIONS_ALL + "}," + "{\"name\": \"lastName\"," + PERMISSIONS_ALL + "},"
@ -1165,7 +1169,7 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest {
enableDynamicUserProfile(realm); enableDynamicUserProfile(realm);
testRealm().update(realm); testRealm().update(realm);
Assert.assertEquals(customConfig, realmRes.users().userProfile().getConfiguration()); JsonTestUtils.assertJsonEquals(customConfig, realmRes.users().userProfile().getConfiguration());
} }
protected UserRepresentation getUser(String userId) { protected UserRepresentation getUser(String userId) {
@ -1213,10 +1217,11 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest {
public static void setUserProfileConfiguration(RealmResource testRealm, String configuration) { public static void setUserProfileConfiguration(RealmResource testRealm, String configuration) {
try (Response r = testRealm.users().userProfile().update(configuration)) { try {
if (r.getStatus() != 200) { UPConfig config = configuration == null ? null : JsonSerialization.readValue(configuration, UPConfig.class);
Assert.fail("UserProfile Configuration not set due to error: " + r.readEntity(String.class)); testRealm.users().userProfile().update(config);
} } catch (IOException ioe) {
throw new RuntimeException("Failed to read configuration", ioe);
} }
} }

View file

@ -38,9 +38,9 @@ import org.keycloak.testsuite.ProfileAssume;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.runonserver.RunOnServerException; import org.keycloak.testsuite.runonserver.RunOnServerException;
import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttribute;
import org.keycloak.userprofile.config.UPAttributeSelector; import org.keycloak.representations.userprofile.config.UPAttributeSelector;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.userprofile.config.UPConfigUtils; import org.keycloak.userprofile.config.UPConfigUtils;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
@ -157,7 +157,7 @@ public class ImportTest extends AbstractTestRealmKeycloakTest {
session.getContext().setRealm(realm); session.getContext().setRealm(realm);
UserProfileProvider provider = session.getProvider(UserProfileProvider.class); 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("email"::equals));
Assert.assertTrue(config.getAttributes().stream().map(UPAttribute::getName).anyMatch("test"::equals)); Assert.assertTrue(config.getAttributes().stream().map(UPAttribute::getName).anyMatch("test"::equals));

View file

@ -42,8 +42,8 @@ import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.forms.VerifyProfileTest; import org.keycloak.testsuite.forms.VerifyProfileTest;
import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.userprofile.UserProfileProvider;
import org.keycloak.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttribute;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.userprofile.config.UPConfigUtils; import org.keycloak.userprofile.config.UPConfigUtils;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;

View file

@ -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_ADMIN;
import static org.keycloak.userprofile.config.UPConfigUtils.ROLE_USER; import static org.keycloak.userprofile.config.UPConfigUtils.ROLE_USER;
import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -57,11 +56,11 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;
import org.keycloak.testsuite.runonserver.RunOnServer; import org.keycloak.testsuite.runonserver.RunOnServer;
import org.keycloak.userprofile.AttributeGroupMetadata; import org.keycloak.userprofile.AttributeGroupMetadata;
import org.keycloak.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttribute;
import org.keycloak.userprofile.config.UPAttributePermissions; import org.keycloak.representations.userprofile.config.UPAttributePermissions;
import org.keycloak.userprofile.config.UPAttributeRequired; import org.keycloak.representations.userprofile.config.UPAttributeRequired;
import org.keycloak.userprofile.config.UPAttributeSelector; import org.keycloak.representations.userprofile.config.UPAttributeSelector;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.testsuite.util.ClientScopeBuilder; import org.keycloak.testsuite.util.ClientScopeBuilder;
import org.keycloak.testsuite.util.KeycloakModelUtils; import org.keycloak.testsuite.util.KeycloakModelUtils;
import org.keycloak.userprofile.Attributes; import org.keycloak.userprofile.Attributes;
@ -235,7 +234,7 @@ public class UserProfileTest extends AbstractUserProfileTest {
realm.setRegistrationEmailAsUsername(false); realm.setRegistrationEmailAsUsername(false);
} }
UPConfig config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class); UPConfig config = provider.getConfiguration();
UPAttribute email = config.getAttribute("email"); UPAttribute email = config.getAttribute("email");
@ -439,7 +438,7 @@ public class UserProfileTest extends AbstractUserProfileTest {
private static void testCreateAndUpdateUser(KeycloakSession session) throws IOException { private static void testCreateAndUpdateUser(KeycloakSession session) throws IOException {
UserProfileProvider provider = getUserProfileProvider(session); UserProfileProvider provider = getUserProfileProvider(session);
UPConfig config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class); UPConfig config = provider.getConfiguration();
UPAttribute attribute = new UPAttribute(); UPAttribute attribute = new UPAttribute();
attribute.setName("address"); attribute.setName("address");
UPAttributePermissions permissions = new UPAttributePermissions(); UPAttributePermissions permissions = new UPAttributePermissions();
@ -895,7 +894,7 @@ public class UserProfileTest extends AbstractUserProfileTest {
assertTrue(ve.hasError(Messages.INVALID_USERNAME)); assertTrue(ve.hasError(Messages.INVALID_USERNAME));
} }
UPConfig config = UPConfigUtils.readConfig(new ByteArrayInputStream(provider.getConfiguration().getBytes())); UPConfig config = provider.getConfiguration();
for (UPAttribute attribute : config.getAttributes()) { for (UPAttribute attribute : config.getAttributes()) {
if (UserModel.USERNAME.equals(attribute.getName())) { if (UserModel.USERNAME.equals(attribute.getName())) {
@ -1509,7 +1508,7 @@ public class UserProfileTest extends AbstractUserProfileTest {
private static void testUsernameAndEmailPermissionNotSetIfEmpty(KeycloakSession session) throws IOException { private static void testUsernameAndEmailPermissionNotSetIfEmpty(KeycloakSession session) throws IOException {
UserProfileProvider provider = getUserProfileProvider(session); UserProfileProvider provider = getUserProfileProvider(session);
UPConfig config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class); UPConfig config = provider.getConfiguration();
for (UPAttribute attribute : config.getAttributes()) { for (UPAttribute attribute : config.getAttributes()) {
if (attribute.getName().equals(UserModel.USERNAME) || attribute.getName().equals(UserModel.EMAIL)) { if (attribute.getName().equals(UserModel.USERNAME) || attribute.getName().equals(UserModel.EMAIL)) {

View file

@ -37,12 +37,12 @@ import org.keycloak.testsuite.runonserver.RunOnServer;
import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonMappingException;
import org.keycloak.testsuite.util.ClientScopeBuilder; import org.keycloak.testsuite.util.ClientScopeBuilder;
import org.keycloak.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttribute;
import org.keycloak.userprofile.config.UPAttributePermissions; import org.keycloak.representations.userprofile.config.UPAttributePermissions;
import org.keycloak.userprofile.config.UPAttributeRequired; import org.keycloak.representations.userprofile.config.UPAttributeRequired;
import org.keycloak.userprofile.config.UPConfig; import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.userprofile.config.UPConfigUtils; 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 * Unit test for {@link UPConfigUtils} functionality

View file

@ -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 <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class JsonTestUtils {
/**
* @param o1
* @param o2
* @return true if JSON objects are "equal" to each other
* @param <T>
*/
public static <T> 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);
}
}
}