KEYCLOAK-13116 Fix backwards compatilbity changes in LocaleSelectorSPI
This commit is contained in:
parent
8ed355a5fe
commit
bcb542d9cc
13 changed files with 241 additions and 45 deletions
|
@ -16,12 +16,10 @@
|
|||
*/
|
||||
package org.keycloak.locale;
|
||||
|
||||
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.util.Locale;
|
||||
|
||||
public interface LocaleSelectorProvider extends Provider {
|
||||
|
@ -34,16 +32,9 @@ public interface LocaleSelectorProvider extends Provider {
|
|||
|
||||
/**
|
||||
* Resolve the locale which should be used for the request
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
Locale resolveLocale(UserModel user);
|
||||
|
||||
void updateUsersLocale(UserModel user, String locale);
|
||||
|
||||
void updateLocaleCookie(RealmModel realm, String locale, UriInfo uriInfo);
|
||||
|
||||
void expireLocaleCookie(RealmModel realm, UriInfo uriInfo);
|
||||
Locale resolveLocale(RealmModel realm, UserModel user);
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.keycloak.locale;
|
||||
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
public interface LocaleUpdaterProvider extends Provider {
|
||||
|
||||
void updateUsersLocale(UserModel user, String locale);
|
||||
|
||||
void updateLocaleCookie(String locale);
|
||||
|
||||
void expireLocaleCookie();
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2018 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.locale;
|
||||
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
public interface LocaleUpdaterProviderFactory extends ProviderFactory<LocaleUpdaterProvider> {
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2018 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.locale;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
public class LocaleUpdaterSPI implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "localeUpdater";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return LocaleUpdaterProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return LocaleUpdaterProviderFactory.class;
|
||||
}
|
||||
|
||||
}
|
|
@ -33,6 +33,7 @@
|
|||
#
|
||||
|
||||
org.keycloak.locale.LocaleSelectorSPI
|
||||
org.keycloak.locale.LocaleUpdaterSPI
|
||||
org.keycloak.storage.UserStorageProviderSpi
|
||||
org.keycloak.theme.ThemeResourceSpi
|
||||
org.keycloak.theme.ThemeSelectorSpi
|
||||
|
|
|
@ -5,6 +5,7 @@ import org.keycloak.authentication.RequiredActionContext;
|
|||
import org.keycloak.authentication.RequiredActionFactory;
|
||||
import org.keycloak.authentication.RequiredActionProvider;
|
||||
import org.keycloak.locale.LocaleSelectorProvider;
|
||||
import org.keycloak.locale.LocaleUpdaterProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
@ -20,15 +21,17 @@ public class UpdateUserLocaleAction implements RequiredActionProvider, RequiredA
|
|||
public void evaluateTriggers(RequiredActionContext context) {
|
||||
String userRequestedLocale = context.getAuthenticationSession().getAuthNote(LocaleSelectorProvider.USER_REQUEST_LOCALE);
|
||||
if (userRequestedLocale != null) {
|
||||
LocaleSelectorProvider provider = context.getSession().getProvider(LocaleSelectorProvider.class);
|
||||
provider.updateUsersLocale(context.getUser(), userRequestedLocale);
|
||||
LocaleUpdaterProvider updater = context.getSession().getProvider(LocaleUpdaterProvider.class);
|
||||
updater.updateUsersLocale(context.getUser(), userRequestedLocale);
|
||||
} else {
|
||||
String userLocale = context.getUser().getFirstAttribute(UserModel.LOCALE);
|
||||
LocaleSelectorProvider provider = context.getSession().getProvider(LocaleSelectorProvider.class);
|
||||
|
||||
if (userLocale != null) {
|
||||
provider.updateLocaleCookie(context.getRealm(), userLocale, context.getUriInfo());
|
||||
LocaleUpdaterProvider updater = context.getSession().getProvider(LocaleUpdaterProvider.class);
|
||||
updater.updateLocaleCookie(userLocale);
|
||||
} else {
|
||||
provider.expireLocaleCookie(context.getRealm(), context.getUriInfo());
|
||||
LocaleUpdaterProvider updater = context.getSession().getProvider(LocaleUpdaterProvider.class);
|
||||
updater.expireLocaleCookie();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,8 +43,7 @@ public class DefaultLocaleSelectorProvider implements LocaleSelectorProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Locale resolveLocale(UserModel user) {
|
||||
RealmModel realm = session.getContext().getRealm();
|
||||
public Locale resolveLocale(RealmModel realm, UserModel user) {
|
||||
HttpHeaders requestHeaders = session.getContext().getRequestHeaders();
|
||||
AuthenticationSessionModel session = this.session.getContext().getAuthenticationSession();
|
||||
|
||||
|
@ -65,29 +64,6 @@ public class DefaultLocaleSelectorProvider implements LocaleSelectorProvider {
|
|||
return Locale.ENGLISH;
|
||||
}
|
||||
|
||||
public void updateUsersLocale(UserModel user, String locale) {
|
||||
if (!locale.equals(user.getFirstAttribute("locale"))) {
|
||||
try {
|
||||
user.setSingleAttribute(UserModel.LOCALE, locale);
|
||||
updateLocaleCookie(session.getContext().getRealm(), locale, session.getContext().getUri());
|
||||
} catch (ReadOnlyException e) {
|
||||
logger.debug("Attempt to store 'locale' attribute to read only user model. Ignoring exception", e);
|
||||
}
|
||||
}
|
||||
logger.debugv("Setting locale for user {0} to {1}", user.getUsername(), locale);
|
||||
}
|
||||
|
||||
public void updateLocaleCookie(RealmModel realm, String locale, UriInfo uriInfo) {
|
||||
boolean secure = realm.getSslRequired().isRequired(uriInfo.getRequestUri().getHost());
|
||||
CookieHelper.addCookie(LocaleSelectorProvider.LOCALE_COOKIE, locale, AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, null, -1, secure, true);
|
||||
logger.debugv("Updating locale cookie to {0}", locale);
|
||||
}
|
||||
|
||||
public void expireLocaleCookie(RealmModel realm, UriInfo uriInfo) {
|
||||
boolean secure = realm.getSslRequired().isRequired(uriInfo.getRequestUri().getHost());
|
||||
CookieHelper.addCookie(LocaleSelectorProvider.LOCALE_COOKIE, "", AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, "Expiring cookie", 0, secure, true);
|
||||
}
|
||||
|
||||
private Locale getUserLocale(RealmModel realm, AuthenticationSessionModel session, UserModel user, HttpHeaders requestHeaders) {
|
||||
Locale locale;
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2018 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.locale;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.util.CookieHelper;
|
||||
import org.keycloak.storage.ReadOnlyException;
|
||||
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
public class DefaultLocaleUpdaterProvider implements LocaleUpdaterProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(LocaleSelectorProvider.class);
|
||||
|
||||
private KeycloakSession session;
|
||||
|
||||
public DefaultLocaleUpdaterProvider(KeycloakSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUsersLocale(UserModel user, String locale) {
|
||||
if (!locale.equals(user.getFirstAttribute("locale"))) {
|
||||
try {
|
||||
user.setSingleAttribute(UserModel.LOCALE, locale);
|
||||
updateLocaleCookie(locale);
|
||||
} catch (ReadOnlyException e) {
|
||||
logger.debug("Attempt to store 'locale' attribute to read only user model. Ignoring exception", e);
|
||||
}
|
||||
}
|
||||
logger.debugv("Setting locale for user {0} to {1}", user.getUsername(), locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocaleCookie(String locale) {
|
||||
RealmModel realm = session.getContext().getRealm();
|
||||
UriInfo uriInfo = session.getContext().getUri();
|
||||
|
||||
boolean secure = realm.getSslRequired().isRequired(uriInfo.getRequestUri().getHost());
|
||||
CookieHelper.addCookie(LocaleSelectorProvider.LOCALE_COOKIE, locale, AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, null, -1, secure, true);
|
||||
logger.debugv("Updating locale cookie to {0}", locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireLocaleCookie() {
|
||||
RealmModel realm = session.getContext().getRealm();
|
||||
UriInfo uriInfo = session.getContext().getUri();
|
||||
|
||||
boolean secure = realm.getSslRequired().isRequired(session.getContext().getConnection());
|
||||
CookieHelper.addCookie(LocaleSelectorProvider.LOCALE_COOKIE, "", AuthenticationManager.getRealmCookiePath(realm, uriInfo), null, "Expiring cookie", 0, secure, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2018 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.locale;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
public class DefaultLocaleUpdaterProviderFactory implements LocaleUpdaterProviderFactory {
|
||||
|
||||
@Override
|
||||
public LocaleUpdaterProvider create(KeycloakSession session) {
|
||||
return new DefaultLocaleUpdaterProvider(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "default";
|
||||
}
|
||||
|
||||
}
|
|
@ -129,7 +129,7 @@ public class DefaultKeycloakContext implements KeycloakContext {
|
|||
|
||||
@Override
|
||||
public Locale resolveLocale(UserModel user) {
|
||||
return session.getProvider(LocaleSelectorProvider.class).resolveLocale(user);
|
||||
return session.getProvider(LocaleSelectorProvider.class).resolveLocale(getRealm(), user);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -48,6 +48,8 @@ import org.keycloak.events.EventBuilder;
|
|||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.exceptions.TokenNotActiveException;
|
||||
import org.keycloak.locale.LocaleSelectorProvider;
|
||||
import org.keycloak.locale.LocaleSelectorSPI;
|
||||
import org.keycloak.locale.LocaleUpdaterProvider;
|
||||
import org.keycloak.models.ActionTokenKeyModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
|
@ -269,8 +271,9 @@ public class LoginActionsService {
|
|||
String locale = session.getContext().getUri().getQueryParameters().getFirst(LocaleSelectorProvider.KC_LOCALE_PARAM);
|
||||
if (locale != null) {
|
||||
authSession.setAuthNote(LocaleSelectorProvider.USER_REQUEST_LOCALE, locale);
|
||||
LocaleSelectorProvider localeSelectorProvider = session.getProvider(LocaleSelectorProvider.class);
|
||||
localeSelectorProvider.updateLocaleCookie(realm, locale, session.getContext().getUri());
|
||||
|
||||
LocaleUpdaterProvider localeUpdater = session.getProvider(LocaleUpdaterProvider.class);
|
||||
localeUpdater.updateLocaleCookie(locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.keycloak.forms.account.AccountPages;
|
|||
import org.keycloak.forms.account.AccountProvider;
|
||||
import org.keycloak.forms.login.LoginFormsProvider;
|
||||
import org.keycloak.locale.LocaleSelectorProvider;
|
||||
import org.keycloak.locale.LocaleUpdaterProvider;
|
||||
import org.keycloak.models.AccountRoles;
|
||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
|
@ -225,8 +226,8 @@ public class AccountFormService extends AbstractSecuredLocalService {
|
|||
|
||||
String locale = session.getContext().getUri().getQueryParameters().getFirst(LocaleSelectorProvider.KC_LOCALE_PARAM);
|
||||
if (locale != null) {
|
||||
LocaleSelectorProvider localeSelectorProvider = session.getProvider(LocaleSelectorProvider.class);
|
||||
localeSelectorProvider.updateUsersLocale(auth.getUser(), locale);
|
||||
LocaleUpdaterProvider updater = session.getProvider(LocaleUpdaterProvider.class);
|
||||
updater.updateUsersLocale(auth.getUser(), locale);
|
||||
}
|
||||
|
||||
return account.createResponse(page);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
org.keycloak.locale.DefaultLocaleUpdaterProviderFactory
|
Loading…
Reference in a new issue