KEYCLOAK-18590 Realm localizations of one realm must not affect themes displayed in context of other realms.
This commit is contained in:
parent
fbaeb18a5f
commit
2c8d4ad9b4
5 changed files with 70 additions and 26 deletions
|
@ -207,9 +207,9 @@ public class FreeMarkerEmailTemplateProvider implements EmailTemplateProvider {
|
||||||
Theme theme = getTheme();
|
Theme theme = getTheme();
|
||||||
Locale locale = session.getContext().resolveLocale(user);
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
attributes.put("locale", locale);
|
attributes.put("locale", locale);
|
||||||
Properties rb = theme.getMessages(locale);
|
Properties rb = new Properties();
|
||||||
Map<String, String> localizationTexts = realm.getRealmLocalizationTextsByLocale(locale.toLanguageTag());
|
rb.putAll(theme.getMessages(locale));
|
||||||
rb.putAll(localizationTexts);
|
rb.putAll(realm.getRealmLocalizationTextsByLocale(locale.toLanguageTag()));
|
||||||
attributes.put("msg", new MessageFormatterMethod(locale, rb));
|
attributes.put("msg", new MessageFormatterMethod(locale, rb));
|
||||||
attributes.put("properties", theme.getProperties());
|
attributes.put("properties", theme.getProperties());
|
||||||
String subject = new MessageFormat(rb.getProperty(subjectKey, subjectKey), locale).format(subjectAttributes.toArray());
|
String subject = new MessageFormat(rb.getProperty(subjectKey, subjectKey), locale).format(subjectAttributes.toArray());
|
||||||
|
|
|
@ -129,8 +129,6 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
||||||
|
|
||||||
Locale locale = session.getContext().resolveLocale(user);
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
Properties messagesBundle = handleThemeResources(theme, locale, attributes);
|
Properties messagesBundle = handleThemeResources(theme, locale, attributes);
|
||||||
Map<String, String> localizationTexts = realm.getRealmLocalizationTextsByLocale(locale.toLanguageTag());
|
|
||||||
messagesBundle.putAll(localizationTexts);
|
|
||||||
|
|
||||||
URI baseUri = uriInfo.getBaseUri();
|
URI baseUri = uriInfo.getBaseUri();
|
||||||
UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
|
UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
|
||||||
|
@ -217,9 +215,10 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
||||||
* @return message bundle for other use
|
* @return message bundle for other use
|
||||||
*/
|
*/
|
||||||
protected Properties handleThemeResources(Theme theme, Locale locale, Map<String, Object> attributes) {
|
protected Properties handleThemeResources(Theme theme, Locale locale, Map<String, Object> attributes) {
|
||||||
Properties messagesBundle;
|
Properties messagesBundle = new Properties();
|
||||||
try {
|
try {
|
||||||
messagesBundle = theme.getMessages(locale);
|
messagesBundle.putAll(theme.getMessages(locale));
|
||||||
|
messagesBundle.putAll(realm.getRealmLocalizationTextsByLocale(locale.toLanguageTag()));
|
||||||
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to load messages", e);
|
logger.warn("Failed to load messages", e);
|
||||||
|
|
|
@ -198,8 +198,6 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
|
|
||||||
Locale locale = session.getContext().resolveLocale(user);
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
Properties messagesBundle = handleThemeResources(theme, locale);
|
Properties messagesBundle = handleThemeResources(theme, locale);
|
||||||
Map<String, String> localizationTexts = realm.getRealmLocalizationTextsByLocale(locale.toLanguageTag());
|
|
||||||
messagesBundle.putAll(localizationTexts);
|
|
||||||
|
|
||||||
handleMessages(locale, messagesBundle);
|
handleMessages(locale, messagesBundle);
|
||||||
|
|
||||||
|
@ -288,8 +286,6 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
|
|
||||||
Locale locale = session.getContext().resolveLocale(user);
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
Properties messagesBundle = handleThemeResources(theme, locale);
|
Properties messagesBundle = handleThemeResources(theme, locale);
|
||||||
Map<String, String> localizationTexts = realm.getRealmLocalizationTextsByLocale(locale.getCountry());
|
|
||||||
messagesBundle.putAll(localizationTexts);
|
|
||||||
|
|
||||||
handleMessages(locale, messagesBundle);
|
handleMessages(locale, messagesBundle);
|
||||||
|
|
||||||
|
@ -339,9 +335,10 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
* @return message bundle for other use
|
* @return message bundle for other use
|
||||||
*/
|
*/
|
||||||
protected Properties handleThemeResources(Theme theme, Locale locale) {
|
protected Properties handleThemeResources(Theme theme, Locale locale) {
|
||||||
Properties messagesBundle;
|
Properties messagesBundle = new Properties();
|
||||||
try {
|
try {
|
||||||
messagesBundle = theme.getMessages(locale);
|
messagesBundle.putAll(theme.getMessages(locale));
|
||||||
|
messagesBundle.putAll(realm.getRealmLocalizationTextsByLocale(locale.toLanguageTag()));
|
||||||
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
||||||
attributes.put("advancedMsg", new AdvancedMessageFormatterMethod(locale, messagesBundle));
|
attributes.put("advancedMsg", new AdvancedMessageFormatterMethod(locale, messagesBundle));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -48,10 +48,10 @@ public class AdminMessageFormatter implements BiFunction<String, Object[], Strin
|
||||||
try {
|
try {
|
||||||
KeycloakContext context = session.getContext();
|
KeycloakContext context = session.getContext();
|
||||||
locale = context.resolveLocale(user);
|
locale = context.resolveLocale(user);
|
||||||
messages = getTheme(session).getMessages(locale);
|
messages = new Properties();
|
||||||
|
messages.putAll(getTheme(session).getMessages(locale));
|
||||||
RealmModel realm = context.getRealm();
|
RealmModel realm = context.getRealm();
|
||||||
Map<String, String> localizationTexts = realm.getRealmLocalizationTextsByLocale(locale.toLanguageTag());
|
messages.putAll(realm.getRealmLocalizationTextsByLocale(locale.toLanguageTag()));
|
||||||
messages.putAll(localizationTexts);
|
|
||||||
} catch (IOException cause) {
|
} catch (IOException cause) {
|
||||||
throw new RuntimeException("Failed to configure error messages", cause);
|
throw new RuntimeException("Failed to configure error messages", cause);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,12 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.i18n;
|
package org.keycloak.testsuite.i18n;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
||||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||||
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
|
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
|
||||||
|
@ -44,6 +47,8 @@ import org.keycloak.testsuite.pages.OAuthGrantPage;
|
||||||
import org.keycloak.testsuite.util.IdentityProviderBuilder;
|
import org.keycloak.testsuite.util.IdentityProviderBuilder;
|
||||||
import org.openqa.selenium.Cookie;
|
import org.openqa.selenium.Cookie;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
|
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
|
||||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||||
|
@ -117,21 +122,25 @@ public class LoginPageTest extends AbstractI18NTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void acceptLanguageHeader() {
|
public void acceptLanguageHeader() throws IOException {
|
||||||
ProfileAssume.assumeCommunity();
|
ProfileAssume.assumeCommunity();
|
||||||
|
|
||||||
CloseableHttpClient httpClient = (CloseableHttpClient) new HttpClientBuilder().build();
|
try(CloseableHttpClient httpClient = (CloseableHttpClient) new HttpClientBuilder().build()) {
|
||||||
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
|
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
|
||||||
ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
|
ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
|
||||||
|
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
Response response = client.target(driver.getCurrentUrl()).request().acceptLanguage("de").get();
|
|
||||||
Assert.assertTrue(response.readEntity(String.class).contains("Anmeldung bei test"));
|
|
||||||
|
|
||||||
response = client.target(driver.getCurrentUrl()).request().acceptLanguage("en").get();
|
try(Response responseDe = client.target(driver.getCurrentUrl()).request().acceptLanguage("de").get()) {
|
||||||
Assert.assertTrue(response.readEntity(String.class).contains("Sign in to test"));
|
Assert.assertTrue(responseDe.readEntity(String.class).contains("Anmeldung bei test"));
|
||||||
|
|
||||||
client.close();
|
try(Response responseEn = client.target(driver.getCurrentUrl()).request().acceptLanguage("en").get()) {
|
||||||
|
Assert.assertTrue(responseEn.readEntity(String.class).contains("Sign in to test"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -242,6 +251,45 @@ public class LoginPageTest extends AbstractI18NTest {
|
||||||
Assert.assertNull(localeCookie);
|
Assert.assertNull(localeCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KEYCLOAK-18590
|
||||||
|
@Test
|
||||||
|
public void realmLocalizationMessagesAreNotCachedWithinTheTheme() throws IOException {
|
||||||
|
final String locale = Locale.ENGLISH.toLanguageTag();
|
||||||
|
|
||||||
|
final String realmLocalizationMessageKey = "loginAccountTitle";
|
||||||
|
final String realmLocalizationMessageValue = "Localization Test";
|
||||||
|
|
||||||
|
try(CloseableHttpClient httpClient = (CloseableHttpClient) new HttpClientBuilder().build()) {
|
||||||
|
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);
|
||||||
|
|
||||||
|
testRealm().localization().saveRealmLocalizationText(locale, realmLocalizationMessageKey,
|
||||||
|
realmLocalizationMessageValue);
|
||||||
|
|
||||||
|
ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
|
||||||
|
|
||||||
|
loginPage.open();
|
||||||
|
|
||||||
|
try(Response responseWithLocalization =
|
||||||
|
client.target(driver.getCurrentUrl()).request().acceptLanguage(locale).get()) {
|
||||||
|
|
||||||
|
assertThat(responseWithLocalization.readEntity(String.class),
|
||||||
|
Matchers.containsString(realmLocalizationMessageValue));
|
||||||
|
|
||||||
|
testRealm().localization().deleteRealmLocalizationText(locale, realmLocalizationMessageKey);
|
||||||
|
|
||||||
|
loginPage.open();
|
||||||
|
|
||||||
|
try(Response responseWithoutLocalization =
|
||||||
|
client.target(driver.getCurrentUrl()).request().acceptLanguage(locale).get()) {
|
||||||
|
|
||||||
|
assertThat(responseWithoutLocalization.readEntity(String.class),
|
||||||
|
Matchers.not(Matchers.containsString(realmLocalizationMessageValue)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void switchLanguageToGermanAndBack(String expectedEnglishMessage, String expectedGermanMessage, LanguageComboboxAwarePage page) {
|
private void switchLanguageToGermanAndBack(String expectedEnglishMessage, String expectedGermanMessage, LanguageComboboxAwarePage page) {
|
||||||
// Switch language to Deutsch
|
// Switch language to Deutsch
|
||||||
|
|
Loading…
Reference in a new issue