Moving UPConfig and related classes from keycloak-services
closes #24535 Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
parent
e5eded0eab
commit
7863c3e563
25 changed files with 302 additions and 191 deletions
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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 + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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<>();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue