diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/services/resources/QuarkusWelcomeResource.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/services/resources/QuarkusWelcomeResource.java index c74a5c9bc1..deb36889a6 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/services/resources/QuarkusWelcomeResource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/services/resources/QuarkusWelcomeResource.java @@ -30,8 +30,8 @@ import org.keycloak.services.ServicesLogger; import org.keycloak.services.managers.ApplianceBootstrap; import org.keycloak.services.util.CacheControlUtil; import org.keycloak.services.util.CookieHelper; -import org.keycloak.theme.FreeMarkerUtil; import org.keycloak.theme.Theme; +import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.urls.UrlType; import org.keycloak.utils.MediaType; @@ -204,7 +204,7 @@ public class QuarkusWelcomeResource { if (errorMessage != null) { map.put("errorMessage", errorMessage); } - FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil(); + FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class); String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme); ResponseBuilder rb = Response.status(errorMessage == null ? Status.OK : Status.BAD_REQUEST) diff --git a/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java b/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java index 4ffabf0a8d..4c7ba37418 100755 --- a/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java +++ b/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java @@ -43,10 +43,10 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.theme.FreeMarkerException; -import org.keycloak.theme.FreeMarkerUtil; import org.keycloak.theme.Theme; import org.keycloak.theme.beans.LinkExpirationFormatterMethod; import org.keycloak.theme.beans.MessageFormatterMethod; +import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.utils.StringUtil; /** @@ -60,14 +60,14 @@ public class FreeMarkerEmailTemplateProvider implements EmailTemplateProvider { * etc.)! */ protected AuthenticationSessionModel authenticationSession; - protected FreeMarkerUtil freeMarker; + protected FreeMarkerProvider freeMarker; protected RealmModel realm; protected UserModel user; protected final Map attributes = new HashMap<>(); - public FreeMarkerEmailTemplateProvider(KeycloakSession session, FreeMarkerUtil freeMarker) { + public FreeMarkerEmailTemplateProvider(KeycloakSession session) { this.session = session; - this.freeMarker = freeMarker; + this.freeMarker = session.getProvider(FreeMarkerProvider.class); } @Override diff --git a/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProviderFactory.java b/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProviderFactory.java index 0cda51d329..b6d94a319a 100755 --- a/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProviderFactory.java +++ b/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProviderFactory.java @@ -22,23 +22,19 @@ import org.keycloak.email.EmailTemplateProvider; import org.keycloak.email.EmailTemplateProviderFactory; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.theme.FreeMarkerUtil; /** * @author Stian Thorgersen */ public class FreeMarkerEmailTemplateProviderFactory implements EmailTemplateProviderFactory { - private FreeMarkerUtil freeMarker; - @Override public EmailTemplateProvider create(KeycloakSession session) { - return new FreeMarkerEmailTemplateProvider(session, freeMarker); + return new FreeMarkerEmailTemplateProvider(session); } @Override public void init(Config.Scope config) { - freeMarker = new FreeMarkerUtil(); } @Override @@ -47,7 +43,6 @@ public class FreeMarkerEmailTemplateProviderFactory implements EmailTemplateProv @Override public void close() { - freeMarker = null; } @Override diff --git a/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java b/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java index 419d4ece7f..bac9ed9aec 100755 --- a/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java +++ b/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java @@ -39,7 +39,6 @@ import org.keycloak.models.UserSessionModel; import org.keycloak.models.utils.FormMessage; import org.keycloak.services.util.CacheControlUtil; import org.keycloak.theme.FreeMarkerException; -import org.keycloak.theme.FreeMarkerUtil; import org.keycloak.theme.Theme; import org.keycloak.theme.beans.AdvancedMessageFormatterMethod; import org.keycloak.theme.beans.LocaleBean; @@ -47,6 +46,7 @@ import org.keycloak.theme.beans.MessageBean; import org.keycloak.theme.beans.MessageFormatterMethod; import org.keycloak.theme.beans.MessageType; import org.keycloak.theme.beans.MessagesPerFieldBean; +import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.utils.MediaType; import org.keycloak.utils.StringUtil; @@ -87,7 +87,7 @@ public class FreeMarkerAccountProvider implements AccountProvider { protected boolean passwordUpdateSupported; protected boolean passwordSet; protected KeycloakSession session; - protected FreeMarkerUtil freeMarker; + protected FreeMarkerProvider freeMarker; protected HttpHeaders headers; protected Map attributes; @@ -97,9 +97,9 @@ public class FreeMarkerAccountProvider implements AccountProvider { protected MessageType messageType = MessageType.ERROR; private boolean authorizationSupported; - public FreeMarkerAccountProvider(KeycloakSession session, FreeMarkerUtil freeMarker) { + public FreeMarkerAccountProvider(KeycloakSession session) { this.session = session; - this.freeMarker = freeMarker; + this.freeMarker = session.getProvider(FreeMarkerProvider.class); } public AccountProvider setUriInfo(UriInfo uriInfo) { diff --git a/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProviderFactory.java b/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProviderFactory.java index 2902353292..703b4cf1be 100755 --- a/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProviderFactory.java +++ b/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProviderFactory.java @@ -22,23 +22,19 @@ import org.keycloak.forms.account.AccountProvider; import org.keycloak.forms.account.AccountProviderFactory; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.theme.FreeMarkerUtil; /** * @author Stian Thorgersen */ public class FreeMarkerAccountProviderFactory implements AccountProviderFactory { - private FreeMarkerUtil freeMarker; - @Override public AccountProvider create(KeycloakSession session) { - return new FreeMarkerAccountProvider(session, freeMarker); + return new FreeMarkerAccountProvider(session); } @Override public void init(Config.Scope config) { - freeMarker = new FreeMarkerUtil(); } @Override @@ -47,7 +43,6 @@ public class FreeMarkerAccountProviderFactory implements AccountProviderFactory } @Override public void close() { - freeMarker = null; } @Override diff --git a/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java b/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java index 5d6a2a2523..b2df16336f 100755 --- a/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java +++ b/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java @@ -81,7 +81,6 @@ import org.keycloak.services.messages.Messages; import org.keycloak.services.resources.LoginActionsService; import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.theme.FreeMarkerException; -import org.keycloak.theme.FreeMarkerUtil; import org.keycloak.theme.Theme; import org.keycloak.theme.beans.AdvancedMessageFormatterMethod; import org.keycloak.theme.beans.LocaleBean; @@ -89,6 +88,7 @@ import org.keycloak.theme.beans.MessageBean; import org.keycloak.theme.beans.MessageFormatterMethod; import org.keycloak.theme.beans.MessageType; import org.keycloak.theme.beans.MessagesPerFieldBean; +import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.userprofile.UserProfileContext; import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.utils.MediaType; @@ -121,15 +121,15 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider { protected ClientModel client; protected UriInfo uriInfo; - protected FreeMarkerUtil freeMarker; + protected FreeMarkerProvider freeMarker; protected UserModel user; protected final Map attributes = new HashMap<>(); - public FreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil freeMarker) { + public FreeMarkerLoginFormsProvider(KeycloakSession session) { this.session = session; - this.freeMarker = freeMarker; + this.freeMarker = session.getProvider(FreeMarkerProvider.class); this.attributes.put("scripts", new LinkedList<>()); this.realm = session.getContext().getRealm(); this.client = session.getContext().getClient(); diff --git a/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProviderFactory.java b/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProviderFactory.java index c801b05dc8..1ee8118227 100755 --- a/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProviderFactory.java +++ b/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProviderFactory.java @@ -22,23 +22,19 @@ import org.keycloak.forms.login.LoginFormsProvider; import org.keycloak.forms.login.LoginFormsProviderFactory; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.theme.FreeMarkerUtil; /** * @author Stian Thorgersen */ public class FreeMarkerLoginFormsProviderFactory implements LoginFormsProviderFactory { - private FreeMarkerUtil freeMarker; - @Override public LoginFormsProvider create(KeycloakSession session) { - return new FreeMarkerLoginFormsProvider(session, freeMarker); + return new FreeMarkerLoginFormsProvider(session); } @Override public void init(Config.Scope config) { - freeMarker = new FreeMarkerUtil(); } @Override @@ -47,7 +43,6 @@ public class FreeMarkerLoginFormsProviderFactory implements LoginFormsProviderFa } @Override public void close() { - freeMarker = null; } @Override diff --git a/services/src/main/java/org/keycloak/services/error/KeycloakErrorHandler.java b/services/src/main/java/org/keycloak/services/error/KeycloakErrorHandler.java index e069dab945..45932fe9c3 100644 --- a/services/src/main/java/org/keycloak/services/error/KeycloakErrorHandler.java +++ b/services/src/main/java/org/keycloak/services/error/KeycloakErrorHandler.java @@ -14,12 +14,12 @@ import org.keycloak.models.RealmModel; import org.keycloak.representations.idm.OAuth2ErrorRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.messages.Messages; -import org.keycloak.theme.FreeMarkerUtil; import org.keycloak.theme.Theme; import org.keycloak.theme.beans.LocaleBean; import org.keycloak.theme.beans.MessageBean; import org.keycloak.theme.beans.MessageFormatterMethod; import org.keycloak.theme.beans.MessageType; +import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.utils.MediaType; import org.keycloak.utils.MediaTypeMatcher; @@ -87,7 +87,7 @@ public class KeycloakErrorHandler implements ExceptionMapper { Locale locale = session.getContext().resolveLocale(null); - FreeMarkerUtil freeMarker = new FreeMarkerUtil(); + FreeMarkerProvider freeMarker = session.getProvider(FreeMarkerProvider.class); Map attributes = initAttributes(session, realm, theme, locale, statusCode); String templateName = "error.ftl"; diff --git a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java index e017d48533..e6f330e09c 100755 --- a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java +++ b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java @@ -28,8 +28,8 @@ import org.keycloak.services.ServicesLogger; import org.keycloak.services.managers.ApplianceBootstrap; import org.keycloak.services.util.CacheControlUtil; import org.keycloak.services.util.CookieHelper; -import org.keycloak.theme.FreeMarkerUtil; import org.keycloak.theme.Theme; +import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.urls.UrlType; import org.keycloak.utils.MediaType; @@ -203,7 +203,7 @@ public class WelcomeResource { if (errorMessage != null) { map.put("errorMessage", errorMessage); } - FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil(); + FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class); String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme); ResponseBuilder rb = Response.status(errorMessage == null ? Status.OK : Status.BAD_REQUEST) diff --git a/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java b/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java index 737c0e2af2..64765e51e4 100644 --- a/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java +++ b/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java @@ -41,9 +41,9 @@ import org.keycloak.services.resources.RealmsResource; import org.keycloak.services.util.ResolveRelative; import org.keycloak.services.validation.Validation; import org.keycloak.theme.FreeMarkerException; -import org.keycloak.theme.FreeMarkerUtil; import org.keycloak.theme.Theme; import org.keycloak.theme.beans.MessageFormatterMethod; +import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.urls.UrlType; import org.keycloak.util.JsonSerialization; import org.keycloak.utils.MediaType; @@ -151,7 +151,7 @@ public class AccountConsole { RequiredActionProviderModel updateEmailActionProvider = realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.UPDATE_EMAIL.name()); map.put("updateEmailActionEnabled", updateEmailActionProvider != null && updateEmailActionProvider.isEnabled()); - FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil(); + FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class); String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme); Response.ResponseBuilder builder = Response.status(Response.Status.OK).type(MediaType.TEXT_HTML_UTF_8).language(Locale.ENGLISH).entity(result); return builder.build(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java index 0a0a758814..b91b6e5ded 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java @@ -42,8 +42,8 @@ import org.keycloak.services.managers.ClientManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.resources.Cors; import org.keycloak.theme.FreeMarkerException; -import org.keycloak.theme.FreeMarkerUtil; import org.keycloak.theme.Theme; +import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.urls.UrlType; import org.keycloak.utils.MediaType; @@ -345,7 +345,7 @@ public class AdminConsole { map.put("loginRealm", realm.getName()); map.put("properties", theme.getProperties()); - FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil(); + FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class); String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme); Response.ResponseBuilder builder = Response.status(Response.Status.OK).type(MediaType.TEXT_HTML_UTF_8).language(Locale.ENGLISH).entity(result); diff --git a/services/src/main/java/org/keycloak/theme/FreeMarkerUtil.java b/services/src/main/java/org/keycloak/theme/freemarker/DefaultFreeMarkerProvider.java old mode 100755 new mode 100644 similarity index 64% rename from services/src/main/java/org/keycloak/theme/FreeMarkerUtil.java rename to services/src/main/java/org/keycloak/theme/freemarker/DefaultFreeMarkerProvider.java index 13a8d33b1d..1be2d539a1 --- a/services/src/main/java/org/keycloak/theme/FreeMarkerUtil.java +++ b/services/src/main/java/org/keycloak/theme/freemarker/DefaultFreeMarkerProvider.java @@ -1,27 +1,12 @@ -/* - * Copyright 2016 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.theme; +package org.keycloak.theme.freemarker; import freemarker.cache.URLTemplateLoader; import freemarker.core.HTMLOutputFormat; import freemarker.template.Configuration; import freemarker.template.Template; -import org.keycloak.Config; +import org.keycloak.theme.FreeMarkerException; +import org.keycloak.theme.KeycloakSanitizerMethod; +import org.keycloak.theme.Theme; import java.io.IOException; import java.io.StringWriter; @@ -30,29 +15,25 @@ import java.net.URL; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -/** - * @author Stian Thorgersen - */ -public class FreeMarkerUtil { +public class DefaultFreeMarkerProvider implements FreeMarkerProvider { + private final ConcurrentHashMap cache; + private final KeycloakSanitizerMethod kcSanitizeMethod; - private ConcurrentHashMap cache; - private final KeycloakSanitizerMethod kcSanitizeMethod = new KeycloakSanitizerMethod(); - - public FreeMarkerUtil() { - if (Config.scope("theme").getBoolean("cacheTemplates", true)) { - cache = new ConcurrentHashMap<>(); - } + public DefaultFreeMarkerProvider(ConcurrentHashMap cache, KeycloakSanitizerMethod kcSanitizeMethod) { + this.cache = cache; + this.kcSanitizeMethod = kcSanitizeMethod; } + @Override public String processTemplate(Object data, String templateName, Theme theme) throws FreeMarkerException { if (data instanceof Map) { ((Map)data).put("kcSanitize", kcSanitizeMethod); } - + try { Template template; if (cache != null) { - String key = theme.getName() + "/" + templateName; + String key = theme.getType().toString().toLowerCase() + "/" + theme.getName() + "/" + templateName; template = cache.get(key); if (template == null) { template = getTemplate(templateName, theme); @@ -80,7 +61,7 @@ public class FreeMarkerUtil { if (templateName.toLowerCase().endsWith(".ftl")) { cfg.setOutputFormat(HTMLOutputFormat.INSTANCE); } - + cfg.setTemplateLoader(new ThemeTemplateLoader(theme)); return cfg.getTemplate(templateName, "UTF-8"); } @@ -104,4 +85,8 @@ public class FreeMarkerUtil { } + @Override + public void close() { + + } } diff --git a/services/src/main/java/org/keycloak/theme/freemarker/DefaultFreeMarkerProviderFactory.java b/services/src/main/java/org/keycloak/theme/freemarker/DefaultFreeMarkerProviderFactory.java new file mode 100644 index 0000000000..51a54e82a1 --- /dev/null +++ b/services/src/main/java/org/keycloak/theme/freemarker/DefaultFreeMarkerProviderFactory.java @@ -0,0 +1,50 @@ +package org.keycloak.theme.freemarker; + +import freemarker.template.Template; +import org.keycloak.Config; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.theme.KeycloakSanitizerMethod; + +import java.util.concurrent.ConcurrentHashMap; + +public class DefaultFreeMarkerProviderFactory implements FreeMarkerProviderFactory { + + private DefaultFreeMarkerProvider provider; + private ConcurrentHashMap cache; + private KeycloakSanitizerMethod kcSanitizeMethod; + + @Override + public DefaultFreeMarkerProvider create(KeycloakSession session) { + if (provider == null) { + synchronized (this) { + if (provider == null) { + if (Config.scope("theme").getBoolean("cacheTemplates", true)) { + cache = new ConcurrentHashMap<>(); + } + kcSanitizeMethod = new KeycloakSanitizerMethod(); + provider = new DefaultFreeMarkerProvider(cache, kcSanitizeMethod); + } + } + } + return provider; + } + + @Override + public void init(Config.Scope config) { + } + + @Override + public void postInit(KeycloakSessionFactory factory) { + } + + @Override + public void close() { + } + + @Override + public String getId() { + return "default"; + } + +} diff --git a/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerProvider.java b/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerProvider.java new file mode 100644 index 0000000000..240aa88d4f --- /dev/null +++ b/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerProvider.java @@ -0,0 +1,11 @@ +package org.keycloak.theme.freemarker; + +import org.keycloak.provider.Provider; +import org.keycloak.theme.FreeMarkerException; +import org.keycloak.theme.Theme; + +public interface FreeMarkerProvider extends Provider { + + public String processTemplate(Object data, String templateName, Theme theme) throws FreeMarkerException; + +} diff --git a/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerProviderFactory.java b/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerProviderFactory.java new file mode 100644 index 0000000000..285683a27d --- /dev/null +++ b/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerProviderFactory.java @@ -0,0 +1,6 @@ +package org.keycloak.theme.freemarker; + +import org.keycloak.provider.ProviderFactory; + +public interface FreeMarkerProviderFactory extends ProviderFactory { +} diff --git a/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerSPI.java b/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerSPI.java new file mode 100644 index 0000000000..c58b8329a1 --- /dev/null +++ b/services/src/main/java/org/keycloak/theme/freemarker/FreeMarkerSPI.java @@ -0,0 +1,27 @@ +package org.keycloak.theme.freemarker; + +import org.keycloak.provider.Provider; +import org.keycloak.provider.ProviderFactory; +import org.keycloak.provider.Spi; + +public class FreeMarkerSPI implements Spi { + @Override + public boolean isInternal() { + return true; + } + + @Override + public String getName() { + return "freemarker"; + } + + @Override + public Class getProviderClass() { + return FreeMarkerProvider.class; + } + + @Override + public Class getProviderFactoryClass() { + return FreeMarkerProviderFactory.class; + } +} diff --git a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi index baf42d0345..6fd962bfad 100755 --- a/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi +++ b/services/src/main/resources/META-INF/services/org.keycloak.provider.Spi @@ -29,3 +29,4 @@ org.keycloak.protocol.oidc.grants.ciba.resolvers.CIBALoginUserResolverSpi org.keycloak.protocol.oidc.rar.AuthorizationRequestParserSpi org.keycloak.services.resources.admin.ext.AdminRealmResourceSpi org.keycloak.services.legacysessionsupport.LegacySessionSupportSpi +org.keycloak.theme.freemarker.FreeMarkerSPI \ No newline at end of file diff --git a/services/src/main/resources/META-INF/services/org.keycloak.theme.freemarker.FreeMarkerProviderFactory b/services/src/main/resources/META-INF/services/org.keycloak.theme.freemarker.FreeMarkerProviderFactory new file mode 100644 index 0000000000..8c2c30752b --- /dev/null +++ b/services/src/main/resources/META-INF/services/org.keycloak.theme.freemarker.FreeMarkerProviderFactory @@ -0,0 +1 @@ +org.keycloak.theme.freemarker.DefaultFreeMarkerProviderFactory \ No newline at end of file