KEYCLOAK-8152: Allow passing the current locale to OAuth2 identity providers

This commit is contained in:
Johannes Knutsen 2018-08-26 22:15:38 +02:00 committed by Marek Posolda
parent bf7a173e1e
commit 56c97407d4
6 changed files with 195 additions and 0 deletions

View file

@ -313,6 +313,10 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
uriBuilder.queryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM, loginHint);
}
if (getConfig().isUiLocales()) {
uriBuilder.queryParam(OIDCLoginProtocol.UI_LOCALES_PARAM, session.getContext().resolveLocale(null).toLanguageTag());
}
String prompt = getConfig().getPrompt();
if (prompt == null || prompt.isEmpty()) {
prompt = request.getAuthenticationSession().getClientNote(OAuth2Constants.PROMPT);

View file

@ -83,6 +83,14 @@ public class OAuth2IdentityProviderConfig extends IdentityProviderModel {
getConfig().put("loginHint", String.valueOf(loginHint));
}
public boolean isUiLocales() {
return Boolean.valueOf(getConfig().get("uiLocales"));
}
public void setUiLocales(boolean uiLocales) {
getConfig().put("uiLocales", String.valueOf(uiLocales));
}
public String getPrompt() {
return getConfig().get("prompt");
}

View file

@ -0,0 +1,87 @@
package org.keycloak.testsuite.broker;
import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.arquillian.SuiteContext;
import java.util.List;
import java.util.Map;
import static java.util.Locale.ENGLISH;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.keycloak.OAuth2Constants.UI_LOCALES_PARAM;
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_OIDC_ALIAS;
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_OIDC_PROVIDER_ID;
import static org.keycloak.testsuite.broker.BrokerTestTools.createIdentityProvider;
import static org.keycloak.testsuite.broker.BrokerTestTools.waitForPage;
public class KcOidcBrokerUiLocalesDisabledTest extends KcOidcBrokerTest {
@Override
protected BrokerConfiguration getBrokerConfiguration() {
return new KcOidcBrokerConfigurationWithUiLocalesDisabled();
}
private class KcOidcBrokerConfigurationWithUiLocalesDisabled extends KcOidcBrokerConfiguration {
@Override
public IdentityProviderRepresentation setUpIdentityProvider(SuiteContext suiteContext) {
IdentityProviderRepresentation idp = createIdentityProvider(IDP_OIDC_ALIAS, IDP_OIDC_PROVIDER_ID);
Map<String, String> config = idp.getConfig();
applyDefaultConfiguration(suiteContext, config);
config.put("uiLocales", "false");
return idp;
}
}
@Override
protected void loginUser() {
driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
driver.navigate().to(driver.getCurrentUrl());
log.debug("Clicking social " + bc.getIDPAlias());
accountLoginPage.clickSocial(bc.getIDPAlias());
waitForPage(driver, "log in to", true);
Assert.assertThat("Driver should be on the provider realm page right now",
driver.getCurrentUrl(), containsString("/auth/realms/" + bc.providerRealmName() + "/"));
Assert.assertThat(UI_LOCALES_PARAM + "=" + ENGLISH.toLanguageTag() + " should be part of the url",
driver.getCurrentUrl(), not(containsString(UI_LOCALES_PARAM + "=" + ENGLISH.toLanguageTag())));
accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
waitForPage(driver, "update account information", false);
updateAccountInformationPage.assertCurrent();
Assert.assertThat("We must be on correct realm right now",
driver.getCurrentUrl(), containsString("/auth/realms/" + bc.consumerRealmName() + "/"));
log.debug("Updating info on updateAccount page");
updateAccountInformationPage.updateAccountInformation(bc.getUserLogin(), bc.getUserEmail(), "Firstname", "Lastname");
UsersResource consumerUsers = adminClient.realm(bc.consumerRealmName()).users();
int userCount = consumerUsers.count();
Assert.assertTrue("There must be at least one user", userCount > 0);
List<UserRepresentation> users = consumerUsers.search("", 0, userCount);
boolean isUserFound = false;
for (UserRepresentation user : users) {
if (user.getUsername().equals(bc.getUserLogin()) && user.getEmail().equals(bc.getUserEmail())) {
isUserFound = true;
break;
}
}
Assert.assertTrue("There must be user " + bc.getUserLogin() + " in realm " + bc.consumerRealmName(),
isUserFound);
}
}

View file

@ -0,0 +1,87 @@
package org.keycloak.testsuite.broker;
import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.arquillian.SuiteContext;
import java.util.List;
import java.util.Map;
import static java.util.Locale.ENGLISH;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.keycloak.OAuth2Constants.UI_LOCALES_PARAM;
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_OIDC_ALIAS;
import static org.keycloak.testsuite.broker.BrokerTestConstants.IDP_OIDC_PROVIDER_ID;
import static org.keycloak.testsuite.broker.BrokerTestTools.createIdentityProvider;
import static org.keycloak.testsuite.broker.BrokerTestTools.waitForPage;
public class KcOidcBrokerUiLocalesEnabledTest extends KcOidcBrokerTest {
@Override
protected BrokerConfiguration getBrokerConfiguration() {
return new KcOidcBrokerConfigurationWithUiLocalesEnabled();
}
private class KcOidcBrokerConfigurationWithUiLocalesEnabled extends KcOidcBrokerConfiguration {
@Override
public IdentityProviderRepresentation setUpIdentityProvider(SuiteContext suiteContext) {
IdentityProviderRepresentation idp = createIdentityProvider(IDP_OIDC_ALIAS, IDP_OIDC_PROVIDER_ID);
Map<String, String> config = idp.getConfig();
applyDefaultConfiguration(suiteContext, config);
config.put("uiLocales", "true");
return idp;
}
}
@Override
protected void loginUser() {
driver.navigate().to(getAccountUrl(bc.consumerRealmName()));
driver.navigate().to(driver.getCurrentUrl());
log.debug("Clicking social " + bc.getIDPAlias());
accountLoginPage.clickSocial(bc.getIDPAlias());
waitForPage(driver, "log in to", true);
Assert.assertThat("Driver should be on the provider realm page right now",
driver.getCurrentUrl(), containsString("/auth/realms/" + bc.providerRealmName() + "/"));
Assert.assertThat(UI_LOCALES_PARAM + "=" + ENGLISH.toLanguageTag() + " should be part of the url",
driver.getCurrentUrl(), containsString(UI_LOCALES_PARAM + "=" + ENGLISH.toLanguageTag()));
accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword());
waitForPage(driver, "update account information", false);
updateAccountInformationPage.assertCurrent();
Assert.assertThat("We must be on correct realm right now",
driver.getCurrentUrl(), containsString("/auth/realms/" + bc.consumerRealmName() + "/"));
log.debug("Updating info on updateAccount page");
updateAccountInformationPage.updateAccountInformation(bc.getUserLogin(), bc.getUserEmail(), "Firstname", "Lastname");
UsersResource consumerUsers = adminClient.realm(bc.consumerRealmName()).users();
int userCount = consumerUsers.count();
Assert.assertTrue("There must be at least one user", userCount > 0);
List<UserRepresentation> users = consumerUsers.search("", 0, userCount);
boolean isUserFound = false;
for (UserRepresentation user : users) {
if (user.getUsername().equals(bc.getUserLogin()) && user.getEmail().equals(bc.getUserEmail())) {
isUserFound = true;
break;
}
}
Assert.assertTrue("There must be user " + bc.getUserLogin() + " in realm " + bc.consumerRealmName(),
isUserFound);
}
}

View file

@ -544,6 +544,8 @@ token-url=Token URL
token-url.tooltip=The Token URL.
loginHint=Pass login_hint
loginHint.tooltip=Pass login_hint to identity provider.
uiLocales=Pass current locale
uiLocales.tooltip=Pass the current locale to the identity provider as an ui_locales parameter.
logout-url=Logout URL
identity-provider.logout-url.tooltip=End session endpoint to use to logout user from external IDP.
backchannel-logout=Backchannel Logout

View file

@ -124,6 +124,13 @@
</div>
<kc-tooltip>{{:: 'loginHint.tooltip' | translate}}</kc-tooltip>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="uiLocales">{{:: 'uiLocales' | translate}}</label>
<div class="col-sm-4">
<input ng-model="identityProvider.config.uiLocales" id="uiLocales" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" />
</div>
<kc-tooltip>{{:: 'uiLocales.tooltip' | translate}}</kc-tooltip>
</div>
<div class="form-group clearfix">
<label class="col-md-2 control-label" for="tokenUrl"><span class="required">*</span> {{:: 'token-url' | translate}}</label>
<div class="col-md-6">