commit
8121a9391f
16 changed files with 220 additions and 248 deletions
|
@ -41,6 +41,9 @@ public interface OAuth2Constants {
|
||||||
// http://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
// http://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
||||||
String OFFLINE_ACCESS = "offline_access";
|
String OFFLINE_ACCESS = "offline_access";
|
||||||
|
|
||||||
|
String UI_LOCALES_PARAM = "ui_locales";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,6 @@ import org.keycloak.events.Event;
|
||||||
import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
|
import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
|
||||||
import org.keycloak.freemarker.FreeMarkerException;
|
import org.keycloak.freemarker.FreeMarkerException;
|
||||||
import org.keycloak.freemarker.FreeMarkerUtil;
|
import org.keycloak.freemarker.FreeMarkerUtil;
|
||||||
import org.keycloak.freemarker.LocaleHelper;
|
|
||||||
import org.keycloak.freemarker.Theme;
|
import org.keycloak.freemarker.Theme;
|
||||||
import org.keycloak.freemarker.ThemeProvider;
|
import org.keycloak.freemarker.ThemeProvider;
|
||||||
import org.keycloak.freemarker.beans.AdvancedMessageFormatterMethod;
|
import org.keycloak.freemarker.beans.AdvancedMessageFormatterMethod;
|
||||||
|
@ -65,7 +64,6 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
import org.keycloak.models.utils.FormMessage;
|
import org.keycloak.models.utils.FormMessage;
|
||||||
import org.keycloak.services.Urls;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -130,7 +128,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
||||||
logger.warn("Failed to load properties", e);
|
logger.warn("Failed to load properties", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Locale locale = LocaleHelper.getLocale(realm, user, uriInfo, headers);
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
Properties messagesBundle;
|
Properties messagesBundle;
|
||||||
try {
|
try {
|
||||||
messagesBundle = theme.getMessages(locale);
|
messagesBundle = theme.getMessages(locale);
|
||||||
|
@ -213,10 +211,6 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
||||||
String result = freeMarker.processTemplate(attributes, Templates.getTemplate(page), theme);
|
String result = freeMarker.processTemplate(attributes, Templates.getTemplate(page), theme);
|
||||||
Response.ResponseBuilder builder = Response.status(status).type(MediaType.TEXT_HTML).entity(result);
|
Response.ResponseBuilder builder = Response.status(status).type(MediaType.TEXT_HTML).entity(result);
|
||||||
BrowserSecurityHeaderSetup.headers(builder, realm);
|
BrowserSecurityHeaderSetup.headers(builder, realm);
|
||||||
|
|
||||||
String keycloakLocaleCookiePath = Urls.localeCookiePath(baseUri, realm.getName());
|
|
||||||
|
|
||||||
LocaleHelper.updateLocaleCookie(builder, locale, realm, uriInfo, keycloakLocaleCookiePath);
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
} catch (FreeMarkerException e) {
|
} catch (FreeMarkerException e) {
|
||||||
logger.error("Failed to process template", e);
|
logger.error("Failed to process template", e);
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
|
|
||||||
* as indicated by the @author tags. All rights reserved.
|
|
||||||
*
|
|
||||||
* 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.freemarker;
|
|
||||||
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.NewCookie;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
|
|
||||||
*/
|
|
||||||
public class LocaleHelper {
|
|
||||||
public final static String LOCALE_COOKIE = "KEYCLOAK_LOCALE";
|
|
||||||
public static final String UI_LOCALES_PARAM = "ui_locales";
|
|
||||||
public static final String KC_LOCALE_PARAM = "kc_locale";
|
|
||||||
|
|
||||||
public static Locale getLocale(RealmModel realm, UserModel user) {
|
|
||||||
return getLocale(realm, user, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Locale getLocale(RealmModel realm, UserModel user, UriInfo uriInfo, HttpHeaders httpHeaders) {
|
|
||||||
if(!realm.isInternationalizationEnabled()){
|
|
||||||
return Locale.ENGLISH;
|
|
||||||
}
|
|
||||||
|
|
||||||
//0. kc_locale query parameter
|
|
||||||
if(uriInfo != null && uriInfo.getQueryParameters().containsKey(KC_LOCALE_PARAM)){
|
|
||||||
String localeString = uriInfo.getQueryParameters().getFirst(KC_LOCALE_PARAM);
|
|
||||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
|
||||||
if(locale != null){
|
|
||||||
if(user != null){
|
|
||||||
user.setSingleAttribute(UserModel.LOCALE, locale.toLanguageTag());
|
|
||||||
}
|
|
||||||
return locale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//1. Locale cookie
|
|
||||||
if(httpHeaders != null && httpHeaders.getCookies().containsKey(LOCALE_COOKIE)){
|
|
||||||
String localeString = httpHeaders.getCookies().get(LOCALE_COOKIE).getValue();
|
|
||||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
|
||||||
if(locale != null){
|
|
||||||
if(user != null && user.getFirstAttribute(UserModel.LOCALE) == null){
|
|
||||||
user.setSingleAttribute(UserModel.LOCALE, locale.toLanguageTag());
|
|
||||||
}
|
|
||||||
return locale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//2. User profile
|
|
||||||
if(user != null && user.getAttributes().containsKey(UserModel.LOCALE)){
|
|
||||||
String localeString = user.getFirstAttribute(UserModel.LOCALE);
|
|
||||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
|
||||||
if(locale != null){
|
|
||||||
|
|
||||||
return locale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//3. ui_locales query parameter
|
|
||||||
if(uriInfo != null && uriInfo.getQueryParameters().containsKey(UI_LOCALES_PARAM)){
|
|
||||||
String localeString = uriInfo.getQueryParameters().getFirst(UI_LOCALES_PARAM);
|
|
||||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString.split(" "));
|
|
||||||
if(locale != null){
|
|
||||||
return locale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//4. Accept-Language http header
|
|
||||||
if(httpHeaders !=null && httpHeaders.getAcceptableLanguages() != null && !httpHeaders.getAcceptableLanguages().isEmpty()){
|
|
||||||
for(Locale l : httpHeaders.getAcceptableLanguages()){
|
|
||||||
String localeString = l.toLanguageTag();
|
|
||||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
|
||||||
if(locale != null){
|
|
||||||
return locale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//5. Default realm locale
|
|
||||||
if(realm.getDefaultLocale() != null){
|
|
||||||
return Locale.forLanguageTag(realm.getDefaultLocale());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Locale.ENGLISH;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updateLocaleCookie(Response.ResponseBuilder builder,
|
|
||||||
Locale locale,
|
|
||||||
RealmModel realm,
|
|
||||||
UriInfo uriInfo,
|
|
||||||
String path) {
|
|
||||||
if (locale == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
boolean secure = realm.getSslRequired().isRequired(uriInfo.getRequestUri().getHost());
|
|
||||||
builder.cookie(new NewCookie(LocaleHelper.LOCALE_COOKIE, locale.toLanguageTag(), path, null, null, 31536000, secure));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Locale findLocale(Set<String> supportedLocales, String ... localeStrings) {
|
|
||||||
for(String localeString : localeStrings){
|
|
||||||
Locale result = null;
|
|
||||||
Locale search = Locale.forLanguageTag(localeString);
|
|
||||||
for(String languageTag : supportedLocales) {
|
|
||||||
Locale locale = Locale.forLanguageTag(languageTag);
|
|
||||||
if(locale.getLanguage().equals(search.getLanguage())){
|
|
||||||
if(locale.getCountry().equals("") && result == null){
|
|
||||||
result = locale;
|
|
||||||
}
|
|
||||||
if(locale.getCountry().equals(search.getCountry())){
|
|
||||||
return locale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(result != null){
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.keycloak.freemarker.beans;
|
package org.keycloak.freemarker.beans;
|
||||||
|
|
||||||
import org.keycloak.freemarker.LocaleHelper;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
@ -22,7 +21,7 @@ public class LocaleBean {
|
||||||
supported = new LinkedList<>();
|
supported = new LinkedList<>();
|
||||||
for (String l : realm.getSupportedLocales()) {
|
for (String l : realm.getSupportedLocales()) {
|
||||||
String label = messages.getProperty("locale_" + l, l);
|
String label = messages.getProperty("locale_" + l, l);
|
||||||
String url = uriBuilder.replaceQueryParam(LocaleHelper.KC_LOCALE_PARAM, l).build().toString();
|
String url = uriBuilder.replaceQueryParam("kc_locale", l).build().toString();
|
||||||
supported.add(new Locale(label, url));
|
supported.add(new Locale(label, url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package org.keycloak.freemarke;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.keycloak.freemarker.LocaleHelper;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
|
|
||||||
*/
|
|
||||||
public class LocaleHelperTest {
|
|
||||||
@Test
|
|
||||||
public void findLocaleTest(){
|
|
||||||
Assert.assertEquals("de", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","en")), "de").toLanguageTag());
|
|
||||||
Assert.assertEquals("en", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","en")), "en").toLanguageTag());
|
|
||||||
Assert.assertEquals("de", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","en")), "de-CH").toLanguageTag());
|
|
||||||
Assert.assertEquals("de-CH", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","de-CH","de-DE")), "de-CH").toLanguageTag());
|
|
||||||
Assert.assertEquals("de-DE", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","de-CH","de-DE")), "de-DE").toLanguageTag());
|
|
||||||
Assert.assertEquals("de", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","de-CH","de-DE")), "de").toLanguageTag());
|
|
||||||
Assert.assertNull(LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de-CH","de-DE")), "de"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void findLocalesTest(){
|
|
||||||
Assert.assertEquals("de", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","en")), "de en".split(" ")).toLanguageTag());
|
|
||||||
Assert.assertEquals("en", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","en")), "en de".split(" ")).toLanguageTag());
|
|
||||||
Assert.assertEquals("de", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","en")), "de-CH en".split(" ")).toLanguageTag());
|
|
||||||
Assert.assertEquals("de-CH", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","de-CH","de-DE")), "de-CH de".split(" ")).toLanguageTag());
|
|
||||||
Assert.assertEquals("de-DE", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","de-CH","de-DE")), "de-DE de-CH de".split(" ")).toLanguageTag());
|
|
||||||
Assert.assertEquals("de", LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de","de-CH","de-DE")), "en fr de".split(" ")).toLanguageTag());
|
|
||||||
Assert.assertNull(LocaleHelper.findLocale(new HashSet<>(Arrays.asList("de-CH","de-DE")), "de en fr".split(" ")));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,6 +29,11 @@
|
||||||
<artifactId>keycloak-model-api</artifactId>
|
<artifactId>keycloak-model-api</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-services</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-events-api</artifactId>
|
<artifactId>keycloak-events-api</artifactId>
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.keycloak.events.Event;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.freemarker.FreeMarkerException;
|
import org.keycloak.freemarker.FreeMarkerException;
|
||||||
import org.keycloak.freemarker.FreeMarkerUtil;
|
import org.keycloak.freemarker.FreeMarkerUtil;
|
||||||
import org.keycloak.freemarker.LocaleHelper;
|
|
||||||
import org.keycloak.freemarker.Theme;
|
import org.keycloak.freemarker.Theme;
|
||||||
import org.keycloak.freemarker.ThemeProvider;
|
import org.keycloak.freemarker.ThemeProvider;
|
||||||
import org.keycloak.freemarker.beans.MessageFormatterMethod;
|
import org.keycloak.freemarker.beans.MessageFormatterMethod;
|
||||||
|
@ -110,7 +109,7 @@ public class FreeMarkerEmailProvider implements EmailProvider {
|
||||||
try {
|
try {
|
||||||
ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
|
ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
|
||||||
Theme theme = themeProvider.getTheme(realm.getEmailTheme(), Theme.Type.EMAIL);
|
Theme theme = themeProvider.getTheme(realm.getEmailTheme(), Theme.Type.EMAIL);
|
||||||
Locale locale = LocaleHelper.getLocale(realm, user);
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
attributes.put("locale", locale);
|
attributes.put("locale", locale);
|
||||||
Properties rb = theme.getMessages(locale);
|
Properties rb = theme.getMessages(locale);
|
||||||
attributes.put("msg", new MessageFormatterMethod(locale, rb));
|
attributes.put("msg", new MessageFormatterMethod(locale, rb));
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.keycloak.email.EmailProvider;
|
||||||
import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
|
import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
|
||||||
import org.keycloak.freemarker.FreeMarkerException;
|
import org.keycloak.freemarker.FreeMarkerException;
|
||||||
import org.keycloak.freemarker.FreeMarkerUtil;
|
import org.keycloak.freemarker.FreeMarkerUtil;
|
||||||
import org.keycloak.freemarker.LocaleHelper;
|
|
||||||
import org.keycloak.freemarker.Theme;
|
import org.keycloak.freemarker.Theme;
|
||||||
import org.keycloak.freemarker.ThemeProvider;
|
import org.keycloak.freemarker.ThemeProvider;
|
||||||
import org.keycloak.freemarker.beans.AdvancedMessageFormatterMethod;
|
import org.keycloak.freemarker.beans.AdvancedMessageFormatterMethod;
|
||||||
|
@ -201,7 +200,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties messagesBundle;
|
Properties messagesBundle;
|
||||||
Locale locale = LocaleHelper.getLocale(realm, user, uriInfo, session.getContext().getRequestHeaders());
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
try {
|
try {
|
||||||
messagesBundle = theme.getMessages(locale);
|
messagesBundle = theme.getMessages(locale);
|
||||||
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
||||||
|
@ -292,10 +291,6 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
for (Map.Entry<String, String> entry : httpResponseHeaders.entrySet()) {
|
for (Map.Entry<String, String> entry : httpResponseHeaders.entrySet()) {
|
||||||
builder.header(entry.getKey(), entry.getValue());
|
builder.header(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
String cookiePath = Urls.localeCookiePath(baseUri, realm.getName());
|
|
||||||
LocaleHelper.updateLocaleCookie(builder, locale, realm, uriInfo, cookiePath);
|
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
} catch (FreeMarkerException e) {
|
} catch (FreeMarkerException e) {
|
||||||
logger.error("Failed to process template", e);
|
logger.error("Failed to process template", e);
|
||||||
|
@ -345,7 +340,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties messagesBundle;
|
Properties messagesBundle;
|
||||||
Locale locale = LocaleHelper.getLocale(realm, user, uriInfo, session.getContext().getRequestHeaders());
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
try {
|
try {
|
||||||
messagesBundle = theme.getMessages(locale);
|
messagesBundle = theme.getMessages(locale);
|
||||||
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
||||||
|
@ -393,9 +388,6 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
for (Map.Entry<String, String> entry : httpResponseHeaders.entrySet()) {
|
for (Map.Entry<String, String> entry : httpResponseHeaders.entrySet()) {
|
||||||
builder.header(entry.getKey(), entry.getValue());
|
builder.header(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
String cookiePath = Urls.localeCookiePath(baseUri, realm.getName());
|
|
||||||
LocaleHelper.updateLocaleCookie(builder, locale, realm, uriInfo, cookiePath);
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
} catch (FreeMarkerException e) {
|
} catch (FreeMarkerException e) {
|
||||||
logger.error("Failed to process template", e);
|
logger.error("Failed to process template", e);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.keycloak.models.utils.RealmImporter;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -33,4 +34,6 @@ public interface KeycloakContext {
|
||||||
|
|
||||||
RealmImporter getRealmManager();
|
RealmImporter getRealmManager();
|
||||||
|
|
||||||
|
Locale resolveLocale(UserModel user);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -10,11 +9,11 @@ import java.util.Set;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public interface UserModel {
|
public interface UserModel {
|
||||||
public static final String USERNAME = "username";
|
String USERNAME = "username";
|
||||||
public static final String LAST_NAME = "lastName";
|
String LAST_NAME = "lastName";
|
||||||
public static final String FIRST_NAME = "firstName";
|
String FIRST_NAME = "firstName";
|
||||||
public static final String EMAIL = "email";
|
String EMAIL = "email";
|
||||||
public static final String LOCALE = "locale";
|
String LOCALE = "locale";
|
||||||
|
|
||||||
String getId();
|
String getId();
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,15 @@ package org.keycloak.services;
|
||||||
|
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.ClientConnection;
|
import org.keycloak.ClientConnection;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.*;
|
||||||
import org.keycloak.models.KeycloakContext;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.utils.RealmImporter;
|
import org.keycloak.models.utils.RealmImporter;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
|
import org.keycloak.services.util.LocaleHelper;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -87,4 +86,9 @@ public class DefaultKeycloakContext implements KeycloakContext {
|
||||||
manager.setContextPath(getContextPath());
|
manager.setContextPath(getContextPath());
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Locale resolveLocale(UserModel user) {
|
||||||
|
return LocaleHelper.getLocale(session, realm, user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,42 +33,24 @@ import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.jose.jws.JWSBuilder;
|
import org.keycloak.jose.jws.JWSBuilder;
|
||||||
import org.keycloak.login.LoginFormsProvider;
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.*;
|
||||||
import org.keycloak.models.ClientSessionModel;
|
|
||||||
import org.keycloak.models.RequiredActionProviderModel;
|
|
||||||
import org.keycloak.models.UserConsentModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.ProtocolMapperModel;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.RoleModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.protocol.LoginProtocol;
|
import org.keycloak.protocol.LoginProtocol;
|
||||||
import org.keycloak.protocol.RestartLoginCookie;
|
import org.keycloak.protocol.RestartLoginCookie;
|
||||||
import org.keycloak.protocol.oidc.TokenManager;
|
import org.keycloak.protocol.oidc.TokenManager;
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.IdentityBrokerService;
|
import org.keycloak.services.resources.IdentityBrokerService;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.Urls;
|
|
||||||
import org.keycloak.services.util.CookieHelper;
|
import org.keycloak.services.util.CookieHelper;
|
||||||
import org.keycloak.util.Time;
|
import org.keycloak.util.Time;
|
||||||
|
|
||||||
import javax.ws.rs.core.Cookie;
|
import javax.ws.rs.core.*;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
|
||||||
import javax.ws.rs.core.NewCookie;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.keycloak.freemarker.LocaleHelper;
|
|
||||||
import org.keycloak.util.TokenUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stateless object that manages authentication
|
* Stateless object that manages authentication
|
||||||
|
@ -413,7 +395,8 @@ public class AuthenticationManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLoginLocale(realm, userSession, request, uriInfo);
|
// Updates users locale if required
|
||||||
|
session.getContext().resolveLocale(userSession.getUser());
|
||||||
|
|
||||||
// refresh the cookies!
|
// refresh the cookies!
|
||||||
createLoginCookie(realm, userSession.getUser(), userSession, uriInfo, clientConnection);
|
createLoginCookie(realm, userSession.getUser(), userSession, uriInfo, clientConnection);
|
||||||
|
@ -428,17 +411,6 @@ public class AuthenticationManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a locale has been set on the login screen, associate that locale with the user
|
|
||||||
private static void handleLoginLocale(RealmModel realm, UserSessionModel userSession,
|
|
||||||
HttpRequest request, UriInfo uriInfo) {
|
|
||||||
Cookie localeCookie = request.getHttpHeaders().getCookies().get(LocaleHelper.LOCALE_COOKIE);
|
|
||||||
if (localeCookie == null) return;
|
|
||||||
|
|
||||||
UserModel user = userSession.getUser();
|
|
||||||
Locale locale = LocaleHelper.getLocale(realm, user, uriInfo, request.getHttpHeaders());
|
|
||||||
user.setSingleAttribute(UserModel.LOCALE, locale.toLanguageTag());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Response nextActionAfterAuthentication(KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession,
|
public static Response nextActionAfterAuthentication(KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession,
|
||||||
ClientConnection clientConnection,
|
ClientConnection clientConnection,
|
||||||
HttpRequest request, UriInfo uriInfo, EventBuilder event) {
|
HttpRequest request, UriInfo uriInfo, EventBuilder event) {
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
|
||||||
|
* as indicated by the @author tags. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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.services.util;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.spi.HttpResponse;
|
||||||
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
import org.keycloak.models.ClientSessionModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
|
import org.keycloak.util.ServerCookie;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
|
||||||
|
*/
|
||||||
|
public class LocaleHelper {
|
||||||
|
|
||||||
|
private static final String LOCALE_COOKIE = "KEYCLOAK_LOCALE";
|
||||||
|
private static final String UI_LOCALES_PARAM = "ui_locales";
|
||||||
|
private static final String KC_LOCALE_PARAM = "kc_locale";
|
||||||
|
|
||||||
|
public static Locale getLocale(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||||
|
if (!realm.isInternationalizationEnabled()) {
|
||||||
|
return Locale.ENGLISH;
|
||||||
|
} else {
|
||||||
|
Locale locale = getUserLocale(session, realm, user);
|
||||||
|
return locale != null ? locale : Locale.forLanguageTag(realm.getDefaultLocale());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Locale getUserLocale(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||||
|
UriInfo uriInfo = session.getContext().getUri();
|
||||||
|
HttpHeaders httpHeaders = session.getContext().getRequestHeaders();
|
||||||
|
|
||||||
|
// kc_locale query parameter
|
||||||
|
if (uriInfo != null && uriInfo.getQueryParameters().containsKey(KC_LOCALE_PARAM)) {
|
||||||
|
String localeString = uriInfo.getQueryParameters().getFirst(KC_LOCALE_PARAM);
|
||||||
|
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
||||||
|
if (locale != null) {
|
||||||
|
updateLocaleCookie(session, realm, localeString);
|
||||||
|
if (user != null) {
|
||||||
|
updateUsersLocale(user, localeString);
|
||||||
|
}
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// User profile
|
||||||
|
if (user != null && user.getAttributes().containsKey(UserModel.LOCALE)) {
|
||||||
|
String localeString = user.getFirstAttribute(UserModel.LOCALE);
|
||||||
|
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
||||||
|
if (locale != null) {
|
||||||
|
updateLocaleCookie(session, realm, localeString);
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locale cookie
|
||||||
|
if (httpHeaders != null && httpHeaders.getCookies().containsKey(LOCALE_COOKIE)) {
|
||||||
|
String localeString = httpHeaders.getCookies().get(LOCALE_COOKIE).getValue();
|
||||||
|
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
||||||
|
if (locale != null) {
|
||||||
|
if (user != null) {
|
||||||
|
updateUsersLocale(user, localeString);
|
||||||
|
}
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ui_locales query parameter
|
||||||
|
if (uriInfo != null && uriInfo.getQueryParameters().containsKey(UI_LOCALES_PARAM)) {
|
||||||
|
String localeString = uriInfo.getQueryParameters().getFirst(UI_LOCALES_PARAM);
|
||||||
|
Locale locale = findLocale(realm.getSupportedLocales(), localeString.split(" "));
|
||||||
|
if (locale != null) {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept-Language http header
|
||||||
|
if (httpHeaders != null && httpHeaders.getAcceptableLanguages() != null && !httpHeaders.getAcceptableLanguages().isEmpty()) {
|
||||||
|
for (Locale l : httpHeaders.getAcceptableLanguages()) {
|
||||||
|
String localeString = l.toLanguageTag();
|
||||||
|
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
||||||
|
if (locale != null) {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateLocaleCookie(KeycloakSession session,
|
||||||
|
RealmModel realm,
|
||||||
|
String locale) {
|
||||||
|
boolean secure = realm.getSslRequired().isRequired(session.getContext().getUri().getRequestUri().getHost());
|
||||||
|
addCookie(LOCALE_COOKIE, locale, AuthenticationManager.getRealmCookiePath(realm, session.getContext().getUri()), null, null, -1, secure, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly) {
|
||||||
|
HttpResponse response = ResteasyProviderFactory.getContextData(HttpResponse.class);
|
||||||
|
StringBuffer cookieBuf = new StringBuffer();
|
||||||
|
ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, comment, maxAge, secure, httpOnly);
|
||||||
|
String cookie = cookieBuf.toString();
|
||||||
|
response.getOutputHeaders().add(HttpHeaders.SET_COOKIE, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Locale findLocale(Set<String> supportedLocales, String... localeStrings) {
|
||||||
|
for (String localeString : localeStrings) {
|
||||||
|
Locale result = null;
|
||||||
|
Locale search = Locale.forLanguageTag(localeString);
|
||||||
|
for (String languageTag : supportedLocales) {
|
||||||
|
Locale locale = Locale.forLanguageTag(languageTag);
|
||||||
|
if (locale.getLanguage().equals(search.getLanguage())) {
|
||||||
|
if (locale.getCountry().equals("") && result == null) {
|
||||||
|
result = locale;
|
||||||
|
}
|
||||||
|
if (locale.getCountry().equals(search.getCountry())) {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateUsersLocale(UserModel user, String locale) {
|
||||||
|
if (!locale.equals(user.getFirstAttribute("locale"))) {
|
||||||
|
user.setSingleAttribute(UserModel.LOCALE, locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -24,7 +24,6 @@ package org.keycloak.testsuite;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.client.utils.URLEncodedUtils;
|
import org.apache.http.client.utils.URLEncodedUtils;
|
||||||
|
@ -37,7 +36,6 @@ import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.RSATokenVerifier;
|
import org.keycloak.RSATokenVerifier;
|
||||||
import org.keycloak.VerificationException;
|
import org.keycloak.VerificationException;
|
||||||
import org.keycloak.constants.AdapterConstants;
|
import org.keycloak.constants.AdapterConstants;
|
||||||
import org.keycloak.freemarker.LocaleHelper;
|
|
||||||
import org.keycloak.jose.jws.JWSInput;
|
import org.keycloak.jose.jws.JWSInput;
|
||||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
||||||
|
@ -397,7 +395,7 @@ public class OAuthClient {
|
||||||
b.queryParam(OAuth2Constants.STATE, state);
|
b.queryParam(OAuth2Constants.STATE, state);
|
||||||
}
|
}
|
||||||
if(uiLocales != null){
|
if(uiLocales != null){
|
||||||
b.queryParam(LocaleHelper.UI_LOCALES_PARAM, uiLocales);
|
b.queryParam(OAuth2Constants.UI_LOCALES_PARAM, uiLocales);
|
||||||
}
|
}
|
||||||
if (scope != null) {
|
if (scope != null) {
|
||||||
b.queryParam(OAuth2Constants.SCOPE, scope);
|
b.queryParam(OAuth2Constants.SCOPE, scope);
|
||||||
|
|
|
@ -54,7 +54,6 @@ public class EmailTest {
|
||||||
UserModel user = manager.getSession().users().addUser(appRealm, "login-test");
|
UserModel user = manager.getSession().users().addUser(appRealm, "login-test");
|
||||||
user.setEmail("login@test.com");
|
user.setEmail("login@test.com");
|
||||||
user.setEnabled(true);
|
user.setEnabled(true);
|
||||||
user.setSingleAttribute(UserModel.LOCALE, "de");
|
|
||||||
|
|
||||||
UserCredentialModel creds = new UserCredentialModel();
|
UserCredentialModel creds = new UserCredentialModel();
|
||||||
creds.setType(CredentialRepresentation.PASSWORD);
|
creds.setType(CredentialRepresentation.PASSWORD);
|
||||||
|
@ -86,7 +85,7 @@ public class EmailTest {
|
||||||
|
|
||||||
MimeMessage message = greenMail.getReceivedMessages()[0];
|
MimeMessage message = greenMail.getReceivedMessages()[0];
|
||||||
|
|
||||||
Assert.assertEquals("Passwort zurückzusetzen", message.getSubject());
|
Assert.assertEquals("Reset password", message.getSubject());
|
||||||
|
|
||||||
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,4 +105,31 @@ public class EmailTest {
|
||||||
|
|
||||||
Assert.assertEquals("Reset password", message.getSubject());
|
Assert.assertEquals("Reset password", message.getSubject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restPasswordEmailGerman() throws IOException, MessagingException {
|
||||||
|
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
||||||
|
@Override
|
||||||
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
|
manager.getSession().users().getUserByUsername("login-test", appRealm).setSingleAttribute(UserModel.LOCALE, "de");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loginPage.open();
|
||||||
|
loginPage.resetPassword();
|
||||||
|
resetPasswordPage.changePassword("login-test");
|
||||||
|
|
||||||
|
assertEquals(1, greenMail.getReceivedMessages().length);
|
||||||
|
|
||||||
|
MimeMessage message = greenMail.getReceivedMessages()[0];
|
||||||
|
|
||||||
|
Assert.assertEquals("Passwort zurückzusetzen", message.getSubject());
|
||||||
|
|
||||||
|
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
||||||
|
@Override
|
||||||
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
|
manager.getSession().users().getUserByUsername("login-test", appRealm).setSingleAttribute(UserModel.LOCALE, "en");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ import org.junit.ClassRule;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.adapters.HttpClientBuilder;
|
import org.keycloak.adapters.HttpClientBuilder;
|
||||||
import org.keycloak.freemarker.LocaleHelper;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.OAuthClient;
|
||||||
|
@ -87,7 +86,7 @@ public class LoginPageTest {
|
||||||
//test if cookie works
|
//test if cookie works
|
||||||
oauth.uiLocales("de");
|
oauth.uiLocales("de");
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
Assert.assertEquals("English", loginPage.getLanguageDropdownText());
|
Assert.assertEquals("Deutsch", loginPage.getLanguageDropdownText());
|
||||||
|
|
||||||
driver.manage().deleteAllCookies();
|
driver.manage().deleteAllCookies();
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
|
@ -113,10 +112,8 @@ public class LoginPageTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
Response response = client.target(driver.getCurrentUrl()).request().acceptLanguage("de").get();
|
Response response = client.target(driver.getCurrentUrl()).request().acceptLanguage("de").get();
|
||||||
Assert.assertTrue(response.readEntity(String.class).contains("Anmeldung bei test"));
|
Assert.assertTrue(response.readEntity(String.class).contains("Anmeldung bei test"));
|
||||||
Assert.assertEquals("de", response.getCookies().get(LocaleHelper.LOCALE_COOKIE).getValue());
|
|
||||||
|
|
||||||
response = client.target(driver.getCurrentUrl()).request().acceptLanguage("en").get();
|
response = client.target(driver.getCurrentUrl()).request().acceptLanguage("en").get();
|
||||||
Assert.assertTrue(response.readEntity(String.class).contains("Log in to test"));
|
Assert.assertTrue(response.readEntity(String.class).contains("Log in to test"));
|
||||||
Assert.assertEquals("en", response.getCookies().get(LocaleHelper.LOCALE_COOKIE).getValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue