Add FreeMarkerProvider to prevent multiple instances of FreeMarker templates (#14062)
* Add FreeMarkerProvider to prevent multiple instances of FreeMarker templates Closes #19185
This commit is contained in:
parent
090f7f89d5
commit
aeba5e9f4b
18 changed files with 139 additions and 73 deletions
|
@ -30,8 +30,8 @@ import org.keycloak.services.ServicesLogger;
|
||||||
import org.keycloak.services.managers.ApplianceBootstrap;
|
import org.keycloak.services.managers.ApplianceBootstrap;
|
||||||
import org.keycloak.services.util.CacheControlUtil;
|
import org.keycloak.services.util.CacheControlUtil;
|
||||||
import org.keycloak.services.util.CookieHelper;
|
import org.keycloak.services.util.CookieHelper;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
import org.keycloak.theme.Theme;
|
import org.keycloak.theme.Theme;
|
||||||
|
import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.urls.UrlType;
|
import org.keycloak.urls.UrlType;
|
||||||
import org.keycloak.utils.MediaType;
|
import org.keycloak.utils.MediaType;
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ public class QuarkusWelcomeResource {
|
||||||
if (errorMessage != null) {
|
if (errorMessage != null) {
|
||||||
map.put("errorMessage", errorMessage);
|
map.put("errorMessage", errorMessage);
|
||||||
}
|
}
|
||||||
FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
|
FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class);
|
||||||
String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme);
|
String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme);
|
||||||
|
|
||||||
ResponseBuilder rb = Response.status(errorMessage == null ? Status.OK : Status.BAD_REQUEST)
|
ResponseBuilder rb = Response.status(errorMessage == null ? Status.OK : Status.BAD_REQUEST)
|
||||||
|
|
|
@ -43,10 +43,10 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||||
import org.keycloak.theme.FreeMarkerException;
|
import org.keycloak.theme.FreeMarkerException;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
import org.keycloak.theme.Theme;
|
import org.keycloak.theme.Theme;
|
||||||
import org.keycloak.theme.beans.LinkExpirationFormatterMethod;
|
import org.keycloak.theme.beans.LinkExpirationFormatterMethod;
|
||||||
import org.keycloak.theme.beans.MessageFormatterMethod;
|
import org.keycloak.theme.beans.MessageFormatterMethod;
|
||||||
|
import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.utils.StringUtil;
|
import org.keycloak.utils.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,14 +60,14 @@ public class FreeMarkerEmailTemplateProvider implements EmailTemplateProvider {
|
||||||
* etc.)!
|
* etc.)!
|
||||||
*/
|
*/
|
||||||
protected AuthenticationSessionModel authenticationSession;
|
protected AuthenticationSessionModel authenticationSession;
|
||||||
protected FreeMarkerUtil freeMarker;
|
protected FreeMarkerProvider freeMarker;
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
protected UserModel user;
|
protected UserModel user;
|
||||||
protected final Map<String, Object> attributes = new HashMap<>();
|
protected final Map<String, Object> attributes = new HashMap<>();
|
||||||
|
|
||||||
public FreeMarkerEmailTemplateProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
|
public FreeMarkerEmailTemplateProvider(KeycloakSession session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.freeMarker = freeMarker;
|
this.freeMarker = session.getProvider(FreeMarkerProvider.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,23 +22,19 @@ import org.keycloak.email.EmailTemplateProvider;
|
||||||
import org.keycloak.email.EmailTemplateProviderFactory;
|
import org.keycloak.email.EmailTemplateProviderFactory;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class FreeMarkerEmailTemplateProviderFactory implements EmailTemplateProviderFactory {
|
public class FreeMarkerEmailTemplateProviderFactory implements EmailTemplateProviderFactory {
|
||||||
|
|
||||||
private FreeMarkerUtil freeMarker;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmailTemplateProvider create(KeycloakSession session) {
|
public EmailTemplateProvider create(KeycloakSession session) {
|
||||||
return new FreeMarkerEmailTemplateProvider(session, freeMarker);
|
return new FreeMarkerEmailTemplateProvider(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
freeMarker = new FreeMarkerUtil();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +43,6 @@ public class FreeMarkerEmailTemplateProviderFactory implements EmailTemplateProv
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
freeMarker = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -39,7 +39,6 @@ import org.keycloak.models.UserSessionModel;
|
||||||
import org.keycloak.models.utils.FormMessage;
|
import org.keycloak.models.utils.FormMessage;
|
||||||
import org.keycloak.services.util.CacheControlUtil;
|
import org.keycloak.services.util.CacheControlUtil;
|
||||||
import org.keycloak.theme.FreeMarkerException;
|
import org.keycloak.theme.FreeMarkerException;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
import org.keycloak.theme.Theme;
|
import org.keycloak.theme.Theme;
|
||||||
import org.keycloak.theme.beans.AdvancedMessageFormatterMethod;
|
import org.keycloak.theme.beans.AdvancedMessageFormatterMethod;
|
||||||
import org.keycloak.theme.beans.LocaleBean;
|
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.MessageFormatterMethod;
|
||||||
import org.keycloak.theme.beans.MessageType;
|
import org.keycloak.theme.beans.MessageType;
|
||||||
import org.keycloak.theme.beans.MessagesPerFieldBean;
|
import org.keycloak.theme.beans.MessagesPerFieldBean;
|
||||||
|
import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.utils.MediaType;
|
import org.keycloak.utils.MediaType;
|
||||||
import org.keycloak.utils.StringUtil;
|
import org.keycloak.utils.StringUtil;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
||||||
protected boolean passwordUpdateSupported;
|
protected boolean passwordUpdateSupported;
|
||||||
protected boolean passwordSet;
|
protected boolean passwordSet;
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
protected FreeMarkerUtil freeMarker;
|
protected FreeMarkerProvider freeMarker;
|
||||||
protected HttpHeaders headers;
|
protected HttpHeaders headers;
|
||||||
protected Map<String, Object> attributes;
|
protected Map<String, Object> attributes;
|
||||||
|
|
||||||
|
@ -97,9 +97,9 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
||||||
protected MessageType messageType = MessageType.ERROR;
|
protected MessageType messageType = MessageType.ERROR;
|
||||||
private boolean authorizationSupported;
|
private boolean authorizationSupported;
|
||||||
|
|
||||||
public FreeMarkerAccountProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
|
public FreeMarkerAccountProvider(KeycloakSession session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.freeMarker = freeMarker;
|
this.freeMarker = session.getProvider(FreeMarkerProvider.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountProvider setUriInfo(UriInfo uriInfo) {
|
public AccountProvider setUriInfo(UriInfo uriInfo) {
|
||||||
|
|
|
@ -22,23 +22,19 @@ import org.keycloak.forms.account.AccountProvider;
|
||||||
import org.keycloak.forms.account.AccountProviderFactory;
|
import org.keycloak.forms.account.AccountProviderFactory;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class FreeMarkerAccountProviderFactory implements AccountProviderFactory {
|
public class FreeMarkerAccountProviderFactory implements AccountProviderFactory {
|
||||||
|
|
||||||
private FreeMarkerUtil freeMarker;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccountProvider create(KeycloakSession session) {
|
public AccountProvider create(KeycloakSession session) {
|
||||||
return new FreeMarkerAccountProvider(session, freeMarker);
|
return new FreeMarkerAccountProvider(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
freeMarker = new FreeMarkerUtil();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +43,6 @@ public class FreeMarkerAccountProviderFactory implements AccountProviderFactory
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
freeMarker = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -81,7 +81,6 @@ import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.LoginActionsService;
|
import org.keycloak.services.resources.LoginActionsService;
|
||||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||||
import org.keycloak.theme.FreeMarkerException;
|
import org.keycloak.theme.FreeMarkerException;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
import org.keycloak.theme.Theme;
|
import org.keycloak.theme.Theme;
|
||||||
import org.keycloak.theme.beans.AdvancedMessageFormatterMethod;
|
import org.keycloak.theme.beans.AdvancedMessageFormatterMethod;
|
||||||
import org.keycloak.theme.beans.LocaleBean;
|
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.MessageFormatterMethod;
|
||||||
import org.keycloak.theme.beans.MessageType;
|
import org.keycloak.theme.beans.MessageType;
|
||||||
import org.keycloak.theme.beans.MessagesPerFieldBean;
|
import org.keycloak.theme.beans.MessagesPerFieldBean;
|
||||||
|
import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.userprofile.UserProfileContext;
|
import org.keycloak.userprofile.UserProfileContext;
|
||||||
import org.keycloak.userprofile.UserProfileProvider;
|
import org.keycloak.userprofile.UserProfileProvider;
|
||||||
import org.keycloak.utils.MediaType;
|
import org.keycloak.utils.MediaType;
|
||||||
|
@ -121,15 +121,15 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
protected ClientModel client;
|
protected ClientModel client;
|
||||||
protected UriInfo uriInfo;
|
protected UriInfo uriInfo;
|
||||||
|
|
||||||
protected FreeMarkerUtil freeMarker;
|
protected FreeMarkerProvider freeMarker;
|
||||||
|
|
||||||
protected UserModel user;
|
protected UserModel user;
|
||||||
|
|
||||||
protected final Map<String, Object> attributes = new HashMap<>();
|
protected final Map<String, Object> attributes = new HashMap<>();
|
||||||
|
|
||||||
public FreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
|
public FreeMarkerLoginFormsProvider(KeycloakSession session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.freeMarker = freeMarker;
|
this.freeMarker = session.getProvider(FreeMarkerProvider.class);
|
||||||
this.attributes.put("scripts", new LinkedList<>());
|
this.attributes.put("scripts", new LinkedList<>());
|
||||||
this.realm = session.getContext().getRealm();
|
this.realm = session.getContext().getRealm();
|
||||||
this.client = session.getContext().getClient();
|
this.client = session.getContext().getClient();
|
||||||
|
|
|
@ -22,23 +22,19 @@ import org.keycloak.forms.login.LoginFormsProvider;
|
||||||
import org.keycloak.forms.login.LoginFormsProviderFactory;
|
import org.keycloak.forms.login.LoginFormsProviderFactory;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class FreeMarkerLoginFormsProviderFactory implements LoginFormsProviderFactory {
|
public class FreeMarkerLoginFormsProviderFactory implements LoginFormsProviderFactory {
|
||||||
|
|
||||||
private FreeMarkerUtil freeMarker;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoginFormsProvider create(KeycloakSession session) {
|
public LoginFormsProvider create(KeycloakSession session) {
|
||||||
return new FreeMarkerLoginFormsProvider(session, freeMarker);
|
return new FreeMarkerLoginFormsProvider(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
freeMarker = new FreeMarkerUtil();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +43,6 @@ public class FreeMarkerLoginFormsProviderFactory implements LoginFormsProviderFa
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
freeMarker = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,12 +14,12 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
|
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
import org.keycloak.theme.Theme;
|
import org.keycloak.theme.Theme;
|
||||||
import org.keycloak.theme.beans.LocaleBean;
|
import org.keycloak.theme.beans.LocaleBean;
|
||||||
import org.keycloak.theme.beans.MessageBean;
|
import org.keycloak.theme.beans.MessageBean;
|
||||||
import org.keycloak.theme.beans.MessageFormatterMethod;
|
import org.keycloak.theme.beans.MessageFormatterMethod;
|
||||||
import org.keycloak.theme.beans.MessageType;
|
import org.keycloak.theme.beans.MessageType;
|
||||||
|
import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.utils.MediaType;
|
import org.keycloak.utils.MediaType;
|
||||||
import org.keycloak.utils.MediaTypeMatcher;
|
import org.keycloak.utils.MediaTypeMatcher;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ public class KeycloakErrorHandler implements ExceptionMapper<Throwable> {
|
||||||
|
|
||||||
Locale locale = session.getContext().resolveLocale(null);
|
Locale locale = session.getContext().resolveLocale(null);
|
||||||
|
|
||||||
FreeMarkerUtil freeMarker = new FreeMarkerUtil();
|
FreeMarkerProvider freeMarker = session.getProvider(FreeMarkerProvider.class);
|
||||||
Map<String, Object> attributes = initAttributes(session, realm, theme, locale, statusCode);
|
Map<String, Object> attributes = initAttributes(session, realm, theme, locale, statusCode);
|
||||||
|
|
||||||
String templateName = "error.ftl";
|
String templateName = "error.ftl";
|
||||||
|
|
|
@ -28,8 +28,8 @@ import org.keycloak.services.ServicesLogger;
|
||||||
import org.keycloak.services.managers.ApplianceBootstrap;
|
import org.keycloak.services.managers.ApplianceBootstrap;
|
||||||
import org.keycloak.services.util.CacheControlUtil;
|
import org.keycloak.services.util.CacheControlUtil;
|
||||||
import org.keycloak.services.util.CookieHelper;
|
import org.keycloak.services.util.CookieHelper;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
import org.keycloak.theme.Theme;
|
import org.keycloak.theme.Theme;
|
||||||
|
import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.urls.UrlType;
|
import org.keycloak.urls.UrlType;
|
||||||
import org.keycloak.utils.MediaType;
|
import org.keycloak.utils.MediaType;
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ public class WelcomeResource {
|
||||||
if (errorMessage != null) {
|
if (errorMessage != null) {
|
||||||
map.put("errorMessage", errorMessage);
|
map.put("errorMessage", errorMessage);
|
||||||
}
|
}
|
||||||
FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
|
FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class);
|
||||||
String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme);
|
String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme);
|
||||||
|
|
||||||
ResponseBuilder rb = Response.status(errorMessage == null ? Status.OK : Status.BAD_REQUEST)
|
ResponseBuilder rb = Response.status(errorMessage == null ? Status.OK : Status.BAD_REQUEST)
|
||||||
|
|
|
@ -41,9 +41,9 @@ import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.util.ResolveRelative;
|
import org.keycloak.services.util.ResolveRelative;
|
||||||
import org.keycloak.services.validation.Validation;
|
import org.keycloak.services.validation.Validation;
|
||||||
import org.keycloak.theme.FreeMarkerException;
|
import org.keycloak.theme.FreeMarkerException;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
import org.keycloak.theme.Theme;
|
import org.keycloak.theme.Theme;
|
||||||
import org.keycloak.theme.beans.MessageFormatterMethod;
|
import org.keycloak.theme.beans.MessageFormatterMethod;
|
||||||
|
import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.urls.UrlType;
|
import org.keycloak.urls.UrlType;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.keycloak.utils.MediaType;
|
import org.keycloak.utils.MediaType;
|
||||||
|
@ -151,7 +151,7 @@ public class AccountConsole {
|
||||||
RequiredActionProviderModel updateEmailActionProvider = realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.UPDATE_EMAIL.name());
|
RequiredActionProviderModel updateEmailActionProvider = realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.UPDATE_EMAIL.name());
|
||||||
map.put("updateEmailActionEnabled", updateEmailActionProvider != null && updateEmailActionProvider.isEnabled());
|
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);
|
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);
|
Response.ResponseBuilder builder = Response.status(Response.Status.OK).type(MediaType.TEXT_HTML_UTF_8).language(Locale.ENGLISH).entity(result);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -42,8 +42,8 @@ import org.keycloak.services.managers.ClientManager;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resources.Cors;
|
import org.keycloak.services.resources.Cors;
|
||||||
import org.keycloak.theme.FreeMarkerException;
|
import org.keycloak.theme.FreeMarkerException;
|
||||||
import org.keycloak.theme.FreeMarkerUtil;
|
|
||||||
import org.keycloak.theme.Theme;
|
import org.keycloak.theme.Theme;
|
||||||
|
import org.keycloak.theme.freemarker.FreeMarkerProvider;
|
||||||
import org.keycloak.urls.UrlType;
|
import org.keycloak.urls.UrlType;
|
||||||
import org.keycloak.utils.MediaType;
|
import org.keycloak.utils.MediaType;
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ public class AdminConsole {
|
||||||
map.put("loginRealm", realm.getName());
|
map.put("loginRealm", realm.getName());
|
||||||
map.put("properties", theme.getProperties());
|
map.put("properties", theme.getProperties());
|
||||||
|
|
||||||
FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
|
FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class);
|
||||||
String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme);
|
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);
|
Response.ResponseBuilder builder = Response.status(Response.Status.OK).type(MediaType.TEXT_HTML_UTF_8).language(Locale.ENGLISH).entity(result);
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,12 @@
|
||||||
/*
|
package org.keycloak.theme.freemarker;
|
||||||
* 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;
|
|
||||||
|
|
||||||
import freemarker.cache.URLTemplateLoader;
|
import freemarker.cache.URLTemplateLoader;
|
||||||
import freemarker.core.HTMLOutputFormat;
|
import freemarker.core.HTMLOutputFormat;
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
import freemarker.template.Template;
|
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.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
@ -30,29 +15,25 @@ import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
public class DefaultFreeMarkerProvider implements FreeMarkerProvider {
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
private final ConcurrentHashMap<String, Template> cache;
|
||||||
*/
|
private final KeycloakSanitizerMethod kcSanitizeMethod;
|
||||||
public class FreeMarkerUtil {
|
|
||||||
|
|
||||||
private ConcurrentHashMap<String, Template> cache;
|
public DefaultFreeMarkerProvider(ConcurrentHashMap<String, Template> cache, KeycloakSanitizerMethod kcSanitizeMethod) {
|
||||||
private final KeycloakSanitizerMethod kcSanitizeMethod = new KeycloakSanitizerMethod();
|
this.cache = cache;
|
||||||
|
this.kcSanitizeMethod = kcSanitizeMethod;
|
||||||
public FreeMarkerUtil() {
|
|
||||||
if (Config.scope("theme").getBoolean("cacheTemplates", true)) {
|
|
||||||
cache = new ConcurrentHashMap<>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String processTemplate(Object data, String templateName, Theme theme) throws FreeMarkerException {
|
public String processTemplate(Object data, String templateName, Theme theme) throws FreeMarkerException {
|
||||||
if (data instanceof Map) {
|
if (data instanceof Map) {
|
||||||
((Map)data).put("kcSanitize", kcSanitizeMethod);
|
((Map)data).put("kcSanitize", kcSanitizeMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Template template;
|
Template template;
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
String key = theme.getName() + "/" + templateName;
|
String key = theme.getType().toString().toLowerCase() + "/" + theme.getName() + "/" + templateName;
|
||||||
template = cache.get(key);
|
template = cache.get(key);
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
template = getTemplate(templateName, theme);
|
template = getTemplate(templateName, theme);
|
||||||
|
@ -80,7 +61,7 @@ public class FreeMarkerUtil {
|
||||||
if (templateName.toLowerCase().endsWith(".ftl")) {
|
if (templateName.toLowerCase().endsWith(".ftl")) {
|
||||||
cfg.setOutputFormat(HTMLOutputFormat.INSTANCE);
|
cfg.setOutputFormat(HTMLOutputFormat.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.setTemplateLoader(new ThemeTemplateLoader(theme));
|
cfg.setTemplateLoader(new ThemeTemplateLoader(theme));
|
||||||
return cfg.getTemplate(templateName, "UTF-8");
|
return cfg.getTemplate(templateName, "UTF-8");
|
||||||
}
|
}
|
||||||
|
@ -104,4 +85,8 @@ public class FreeMarkerUtil {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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<String, Template> 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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package org.keycloak.theme.freemarker;
|
||||||
|
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
|
||||||
|
public interface FreeMarkerProviderFactory extends ProviderFactory<FreeMarkerProvider> {
|
||||||
|
}
|
|
@ -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<? extends Provider> getProviderClass() {
|
||||||
|
return FreeMarkerProvider.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||||
|
return FreeMarkerProviderFactory.class;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,3 +29,4 @@ org.keycloak.protocol.oidc.grants.ciba.resolvers.CIBALoginUserResolverSpi
|
||||||
org.keycloak.protocol.oidc.rar.AuthorizationRequestParserSpi
|
org.keycloak.protocol.oidc.rar.AuthorizationRequestParserSpi
|
||||||
org.keycloak.services.resources.admin.ext.AdminRealmResourceSpi
|
org.keycloak.services.resources.admin.ext.AdminRealmResourceSpi
|
||||||
org.keycloak.services.legacysessionsupport.LegacySessionSupportSpi
|
org.keycloak.services.legacysessionsupport.LegacySessionSupportSpi
|
||||||
|
org.keycloak.theme.freemarker.FreeMarkerSPI
|
|
@ -0,0 +1 @@
|
||||||
|
org.keycloak.theme.freemarker.DefaultFreeMarkerProviderFactory
|
Loading…
Reference in a new issue