Skip to content

Commit 782ad86

Browse files
committed
Allow changing locale when using action tokens
Closes #37127 Signed-off-by: Pedro Igor <[email protected]>
1 parent a1f5e14 commit 782ad86

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import org.keycloak.forms.login.freemarker.model.UrlBean;
6363
import org.keycloak.forms.login.freemarker.model.VerifyProfileBean;
6464
import org.keycloak.forms.login.freemarker.model.X509ConfirmBean;
65+
import org.keycloak.http.HttpRequest;
6566
import org.keycloak.models.ClientModel;
6667
import org.keycloak.models.Constants;
6768
import org.keycloak.models.KeycloakSession;
@@ -548,6 +549,14 @@ protected void createCommonAttributes(Theme theme, Locale locale, Properties mes
548549

549550
if (authenticationSession != null && authenticationSession.getAuthNote(Constants.KEY) != null) {
550551
b.queryParam(Constants.KEY, authenticationSession.getAuthNote(Constants.KEY));
552+
} else {
553+
HttpRequest request = session.getContext().getHttpRequest();
554+
MultivaluedMap<String, String> queryParameters = request.getUri().getQueryParameters();
555+
556+
if (queryParameters != null && queryParameters.getFirst(Constants.TOKEN) != null) {
557+
// changing locale should forward the action token
558+
b.queryParam(Constants.TOKEN, queryParameters.getFirst(Constants.TOKEN));
559+
}
551560
}
552561

553562
final var localeBean = new LocaleBean(realm, locale, b, messagesBundle);

services/src/main/java/org/keycloak/services/resources/LoginActionsService.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,12 @@ public Response registerPage(@QueryParam(AUTH_SESSION_ID) String authSessionId,
760760
@QueryParam(Constants.EXECUTION) String execution,
761761
@QueryParam(Constants.CLIENT_ID) String clientId,
762762
@QueryParam(Constants.CLIENT_DATA) String clientData,
763-
@QueryParam(Constants.TAB_ID) String tabId) {
763+
@QueryParam(Constants.TAB_ID) String tabId,
764+
@QueryParam(Constants.TOKEN) String tokenString) {
765+
if (Profile.isFeatureEnabled(Profile.Feature.ORGANIZATION) && tokenString != null) {
766+
//this call should extract orgId from token and set the organization to the session context
767+
preHandleActionToken(tokenString);
768+
}
764769
return registerRequest(authSessionId, code, execution, clientId, tabId,clientData);
765770
}
766771

testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/RegisterPage.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
/**
3737
* @author <a href="mailto:[email protected]">Stian Thorgersen</a>
3838
*/
39-
public class RegisterPage extends AbstractPage {
39+
public class RegisterPage extends LanguageComboboxAwarePage
40+
{
4041

4142
@Page
4243
private AccountFields.AccountErrors accountErrors;

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/organization/admin/OrganizationInvitationLinkTest.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Arrays;
2828
import java.util.List;
2929
import java.util.Map;
30+
import java.util.Set;
3031
import java.util.concurrent.TimeUnit;
3132
import java.util.function.Predicate;
3233

@@ -239,6 +240,45 @@ public void testRegistrationEnabledWhenInvitingNewUser() throws Exception {
239240
}
240241
}
241242

243+
@Test
244+
public void testRegistrationEnabledWhenInvitingNewUserWithLocalization() throws Exception {
245+
String email = "inviteduser@email";
246+
247+
OrganizationResource organization = testRealm().organizations().get(createOrganization().getId());
248+
try (
249+
RealmAttributeUpdater rau = new RealmAttributeUpdater(testRealm()).setRegistrationAllowed(Boolean.TRUE).update();
250+
Response response = organization.members().inviteUser(email, null, null)
251+
) {
252+
RealmRepresentation realmRep = testRealm().toRepresentation();
253+
Boolean internationalizationEnabled = realmRep.isInternationalizationEnabled();
254+
realmRep.setInternationalizationEnabled(true);
255+
realmRep.setSupportedLocales(Set.of("en", "pt-BR"));
256+
testRealm().update(realmRep);
257+
getCleanup().addCleanup(() -> {
258+
realmRep.setInternationalizationEnabled(internationalizationEnabled);
259+
testRealm().update(realmRep);
260+
});
261+
262+
assertThat(response.getStatus(), equalTo(Response.Status.NO_CONTENT.getStatusCode()));
263+
264+
String link = getInvitationLinkFromEmail();
265+
driver.navigate().to(link);
266+
Assert.assertFalse(organization.members().list(-1, -1).stream().anyMatch(actual -> email.equals(actual.getEmail())));
267+
registerPage.assertCurrent(organizationName);
268+
registerPage.openLanguage("Portuguese");
269+
Assert.assertTrue(driver.getPageSource().contains("Campos obrigatórios"));
270+
registerPage.register("firstName", "lastName", email,
271+
"invitedUser", "password", "password", null, false, null);
272+
// authenticated to the account console
273+
Assert.assertTrue(driver.getPageSource().contains("Account Management"));
274+
Assert.assertNotNull(driver.manage().getCookieNamed(CookieType.IDENTITY.getName()));
275+
276+
List<MemberRepresentation> memberByEmail = organization.members().search(email, Boolean.TRUE, null, null);
277+
assertThat(memberByEmail, Matchers.hasSize(1));
278+
assertThat(memberByEmail.get(0).getMembershipType(), equalTo(MembershipType.MANAGED));
279+
}
280+
}
281+
242282
@Test
243283
public void testEmailDoesNotChangeOnRegistration() throws IOException, MessagingException {
244284
String email = "inviteduser@email";

0 commit comments

Comments
 (0)