diff --git a/distribution/server-x-dist/src/main/content/bin/kc.sh b/distribution/server-x-dist/src/main/content/bin/kc.sh index 053731bc1f..b3540d65b2 100644 --- a/distribution/server-x-dist/src/main/content/bin/kc.sh +++ b/distribution/server-x-dist/src/main/content/bin/kc.sh @@ -23,7 +23,7 @@ fi GREP="grep" DIRNAME=`dirname "$RESOLVED_NAME"` -SERVER_OPTS="-Dkc.home.dir=$DIRNAME/../ -Djboss.server.config.dir=$DIRNAME/../conf -Dkeycloak.theme.dir=$DIRNAME/../themes -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +SERVER_OPTS="-Dkc.home.dir=$DIRNAME/../ -Djboss.server.config.dir=$DIRNAME/../conf -Djava.util.logging.manager=org.jboss.logmanager.LogManager" DEBUG_MODE="${DEBUG:-false}" DEBUG_PORT="${DEBUG_PORT:-8787}" 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 23acde3936..85b17bc110 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 @@ -124,6 +124,7 @@ import org.keycloak.representations.provider.ScriptProviderMetadata; import org.keycloak.quarkus.runtime.integration.web.NotFoundHandler; import org.keycloak.services.ServicesLogger; import org.keycloak.quarkus.runtime.services.health.KeycloakMetricsHandler; +import org.keycloak.theme.FolderThemeProviderFactory; import org.keycloak.transaction.JBossJtaTransactionManagerLookup; import org.keycloak.quarkus.runtime.Environment; import org.keycloak.util.JsonSerialization; @@ -141,6 +142,7 @@ class KeycloakProcessor { JBossJtaTransactionManagerLookup.class, DefaultJpaConnectionProviderFactory.class, DefaultLiquibaseConnectionProvider.class, + FolderThemeProviderFactory.class, LiquibaseJpaUpdaterProviderFactory.class); static { diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/Environment.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/Environment.java index 7d33289c91..2e0faff094 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/Environment.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/Environment.java @@ -40,6 +40,7 @@ public final class Environment { public static final String PROFILE ="kc.profile"; public static final String ENV_PROFILE ="KC_PROFILE"; public static final String DATA_PATH = "/data"; + public static final String DEFAULT_THEMES_PATH = "/themes"; private Environment() {} @@ -65,6 +66,10 @@ public final class Environment { return getHomeDir() + DATA_PATH; } + public static String getDefaultThemeRootDir() { + return getHomeDir() + DEFAULT_THEMES_PATH; + } + public static Path getProvidersPath() { Path homePath = Environment.getHomePath(); diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/themes/QuarkusFolderThemeProviderFactory.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/themes/QuarkusFolderThemeProviderFactory.java new file mode 100644 index 0000000000..8b83c6dd38 --- /dev/null +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/themes/QuarkusFolderThemeProviderFactory.java @@ -0,0 +1,66 @@ +package org.keycloak.quarkus.runtime.themes; + +import org.keycloak.Config; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.quarkus.runtime.Environment; +import org.keycloak.theme.FolderThemeProvider; +import org.keycloak.theme.ThemeProvider; +import org.keycloak.theme.ThemeProviderFactory; + +import java.io.File; +import java.util.Objects; + +public class QuarkusFolderThemeProviderFactory implements ThemeProviderFactory { + + private static final String CONFIG_DIR_KEY = "dir"; + private FolderThemeProvider themeProvider; + + @Override + public ThemeProvider create(KeycloakSession sessions) { + return themeProvider; + } + + @Override + public void init(Config.Scope config) { + String configDir = config.get(CONFIG_DIR_KEY); + File rootDir = getThemeRootDirWithFallback(configDir); + themeProvider = new FolderThemeProvider(rootDir); + } + + @Override + public void postInit(KeycloakSessionFactory factory) { + + } + + @Override + public void close() { + + } + + @Override + public String getId() { + return "folder"; + } + + /** + * Determines if the theme root directory we get + * from {@link Config} exists. + * If not, uses the default theme directory as a fallback. + * + * @param rootDirFromConfig string value from {@link Config} + * @return Directory to use as theme root directory in {@link File} format, either from config or from default. Null if none is available. + * @throws RuntimeException when filesystem path is not accessible + */ + private File getThemeRootDirWithFallback(String rootDirFromConfig) { + File themeRootDir; + + themeRootDir = new File(Objects.requireNonNullElseGet(rootDirFromConfig, Environment::getDefaultThemeRootDir)); + + if (!themeRootDir.exists()) { + return null; + } + + return themeRootDir; + } +} diff --git a/quarkus/runtime/src/main/resources/META-INF/services/org.keycloak.theme.ThemeProviderFactory b/quarkus/runtime/src/main/resources/META-INF/services/org.keycloak.theme.ThemeProviderFactory new file mode 100755 index 0000000000..cff141f457 --- /dev/null +++ b/quarkus/runtime/src/main/resources/META-INF/services/org.keycloak.theme.ThemeProviderFactory @@ -0,0 +1,3 @@ +org.keycloak.quarkus.runtime.themes.QuarkusFolderThemeProviderFactory + + diff --git a/quarkus/server/src/main/resources/META-INF/keycloak.properties b/quarkus/server/src/main/resources/META-INF/keycloak.properties index d208ed7ca4..8754fdf069 100644 --- a/quarkus/server/src/main/resources/META-INF/keycloak.properties +++ b/quarkus/server/src/main/resources/META-INF/keycloak.properties @@ -9,9 +9,6 @@ http.enabled=false # Metrics and healthcheck are disabled by default metrics.enabled=false -# Themes -spi.theme.folder.dir=${kc.home.dir:}/themes - # Basic settings for running in production. Change accordingly before deploying the server. # Database #%prod.db=postgres diff --git a/testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/keycloak.properties b/testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/keycloak.properties index a341bbe592..e1841f01e0 100644 --- a/testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/keycloak.properties +++ b/testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/keycloak.properties @@ -27,9 +27,6 @@ spi.truststore.file.password=secret spi.user-profile.declarative-user-profile.read-only-attributes=deniedFoo,deniedBar*,deniedSome/thing,deniedsome*thing spi.user-profile.declarative-user-profile.admin-read-only-attributes=deniedSomeAdmin -#theme folders dir -spi.theme.folder.dir=${kc.home.dir:}/themes - #password-blacklists path spi.password-policy.password-blacklist.blacklists-path=${kc.home.dir:}/dependency/password-blacklists