diff --git a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java index 6df206abbb..81f74c5360 100644 --- a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java +++ b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/KeycloakProcessor.java @@ -101,6 +101,7 @@ import org.keycloak.quarkus.runtime.storage.database.jpa.NamedJpaConnectionProvi import org.keycloak.quarkus.runtime.themes.FlatClasspathThemeResourceProviderFactory; import org.keycloak.representations.provider.ScriptProviderDescriptor; import org.keycloak.representations.provider.ScriptProviderMetadata; +import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.services.ServicesLogger; import org.keycloak.services.resources.KeycloakApplication; import org.keycloak.theme.ClasspathThemeProviderFactory; @@ -112,6 +113,7 @@ import org.keycloak.transaction.JBossJtaTransactionManagerLookup; import org.keycloak.url.DefaultHostnameProviderFactory; import org.keycloak.url.FixedHostnameProviderFactory; import org.keycloak.url.RequestHostnameProviderFactory; +import org.keycloak.userprofile.DeclarativeUserProfileProviderFactory; import org.keycloak.util.JsonSerialization; import org.keycloak.vault.FilesKeystoreVaultProviderFactory; import org.keycloak.vault.FilesPlainTextVaultProviderFactory; @@ -134,7 +136,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import java.util.Properties; -import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.jar.JarEntry; @@ -259,6 +260,27 @@ class KeycloakProcessor { } } + /** + * Parse the default configuration for the User Profile provider + */ + @BuildStep + @Produce(UserProfileBuildItem.class) + UserProfileBuildItem parseDefaultUserProfileConfig() { + final UPConfig defaultConfig = DeclarativeUserProfileProviderFactory.parseDefaultConfig(); + logger.debug("Parsing default configuration for the User Profile provider"); + return new UserProfileBuildItem(defaultConfig); + } + + /** + * Set the default configuration to the User Profile provider + */ + @BuildStep + @Consume(ProfileBuildItem.class) + @Record(ExecutionTime.STATIC_INIT) + void setDefaultUserProfileConfig(KeycloakRecorder recorder, UserProfileBuildItem configuration) { + recorder.setDefaultUserProfileConfiguration(configuration.getDefaultConfig()); + } + /** *
Configures the persistence unit for Quarkus.
*
diff --git a/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/UserProfileBuildItem.java b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/UserProfileBuildItem.java
new file mode 100644
index 0000000000..d88be338fc
--- /dev/null
+++ b/quarkus/deployment/src/main/java/org/keycloak/quarkus/deployment/UserProfileBuildItem.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024 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.quarkus.deployment;
+
+import io.quarkus.builder.item.SimpleBuildItem;
+import org.keycloak.representations.userprofile.config.UPConfig;
+
+/**
+ * Build item that store default configuration for a User Profile provider
+ */
+public final class UserProfileBuildItem extends SimpleBuildItem {
+ private final UPConfig defaultConfig;
+
+ public UserProfileBuildItem(UPConfig defaultConfig) {
+ this.defaultConfig = defaultConfig;
+ }
+
+ public UPConfig getDefaultConfig() {
+ return defaultConfig;
+ }
+}
\ No newline at end of file
diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakRecorder.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakRecorder.java
index e28dce4e72..d5ffa75a88 100644
--- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakRecorder.java
+++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakRecorder.java
@@ -49,6 +49,7 @@ import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.Spi;
import org.keycloak.quarkus.runtime.storage.legacy.infinispan.CacheManagerFactory;
+import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.theme.ClasspathThemeProviderFactory;
import org.keycloak.truststore.TruststoreBuilder;
@@ -56,6 +57,7 @@ import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
import liquibase.servicelocator.ServiceLocator;
+import org.keycloak.userprofile.DeclarativeUserProfileProviderFactory;
@Recorder
public class KeycloakRecorder {
@@ -123,6 +125,10 @@ public class KeycloakRecorder {
}
}
+ public void setDefaultUserProfileConfiguration(UPConfig configuration) {
+ DeclarativeUserProfileProviderFactory.setDefaultConfig(configuration);
+ }
+
public void registerShutdownHook(ShutdownContext shutdownContext) {
shutdownContext.addShutdownTask(new Runnable() {
@Override
diff --git a/services/src/main/java/org/keycloak/userprofile/DeclarativeUserProfileProviderFactory.java b/services/src/main/java/org/keycloak/userprofile/DeclarativeUserProfileProviderFactory.java
index 4ac172983e..c287adbb1d 100644
--- a/services/src/main/java/org/keycloak/userprofile/DeclarativeUserProfileProviderFactory.java
+++ b/services/src/main/java/org/keycloak/userprofile/DeclarativeUserProfileProviderFactory.java
@@ -87,9 +87,12 @@ public class DeclarativeUserProfileProviderFactory implements UserProfileProvide
private static final Pattern readOnlyAttributesPattern = getRegexPatternString(DEFAULT_READ_ONLY_ATTRIBUTES);
private static final Pattern adminReadOnlyAttributesPattern = getRegexPatternString(DEFAULT_ADMIN_READ_ONLY_ATTRIBUTES);
- private UPConfig parsedDefaultRawConfig;
+ private static volatile UPConfig PARSED_DEFAULT_RAW_CONFIG;
private final Map