Make Locale updater generate an event and use the user profile

Closes #24369

Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
rmartinc 2023-10-31 11:49:48 +01:00 committed by Marek Posolda
parent 3ebf5be5da
commit c2e41b0eeb
2 changed files with 32 additions and 5 deletions

View file

@ -16,7 +16,11 @@
*/
package org.keycloak.locale;
import jakarta.ws.rs.core.UriInfo;
import org.jboss.logging.Logger;
import org.keycloak.events.Details;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
@ -24,13 +28,11 @@ import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.util.CookieHelper;
import org.keycloak.storage.ReadOnlyException;
import jakarta.ws.rs.core.UriInfo;
public class DefaultLocaleUpdaterProvider implements LocaleUpdaterProvider {
private static final Logger logger = Logger.getLogger(LocaleSelectorProvider.class);
private KeycloakSession session;
private final KeycloakSession session;
public DefaultLocaleUpdaterProvider(KeycloakSession session) {
this.session = session;
@ -38,10 +40,18 @@ public class DefaultLocaleUpdaterProvider implements LocaleUpdaterProvider {
@Override
public void updateUsersLocale(UserModel user, String locale) {
if (!locale.equals(user.getFirstAttribute("locale"))) {
final String previousLocale = user.getFirstAttribute("locale");
if (!locale.equals(previousLocale)) {
try {
EventBuilder event = new EventBuilder(session.getContext().getRealm(), session, session.getContext().getConnection())
.event(EventType.UPDATE_PROFILE)
.user(user)
.client(session.getContext().getClient())
.detail(Details.PREF_PREVIOUS + UserModel.LOCALE, previousLocale)
.detail(Details.PREF_UPDATED + UserModel.LOCALE, locale);
user.setSingleAttribute(UserModel.LOCALE, locale);
updateLocaleCookie(locale);
event.success();
} catch (ReadOnlyException e) {
logger.debug("Attempt to store 'locale' attribute to read only user model. Ignoring exception", e);
}

View file

@ -27,16 +27,20 @@ import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.HttpClientBuilder;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.forms.login.freemarker.DetachedInfoStateChecker;
import org.keycloak.locale.LocaleSelectorProvider;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.ErrorPage;
@ -76,6 +80,8 @@ public class LoginPageTest extends AbstractI18NTest {
@Page
protected OAuthGrantPage grantPage;
@Rule
public AssertEvents events = new AssertEvents(this);
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
@ -228,9 +234,20 @@ public class LoginPageTest extends AbstractI18NTest {
Cookie localeCookie = driver.manage().getCookieNamed(LocaleSelectorProvider.LOCALE_COOKIE);
assertEquals("de", localeCookie.getValue());
UserResource user = ApiUtil.findUserByUsernameId(testRealm(), "test-user@localhost");
String userId = user.toRepresentation().getId();
loginPage.login("test-user@localhost", "password");
UserResource user = ApiUtil.findUserByUsernameId(testRealm(), "test-user@localhost");
events.expect(EventType.UPDATE_PROFILE)
.user(userId)
.client("test-app")
.detail(Details.PREF_UPDATED + UserModel.LOCALE, "de")
.assertEvent();
events.expectLogin()
.user(userId)
.client("test-app")
.assertEvent();
UserRepresentation userRep = user.toRepresentation();
assertEquals("de", userRep.getAttributes().get("locale").get(0));