Skip to content

Commit

Permalink
Fix bugs with logout redirect values
Browse files Browse the repository at this point in the history
  • Loading branch information
fhanik committed Feb 9, 2016
1 parent 34a2317 commit 8ee59a7
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 109 deletions.
@@ -1,5 +1,5 @@
/*******************************************************************************
* Cloud Foundry
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
Expand All @@ -12,19 +12,21 @@
*******************************************************************************/
package org.cloudfoundry.identity.uaa.login;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.util.StringUtils;

/**
* @author Dave Syer
*
*/
public class Prompt {

private final String name;
private final String text;
private final String type;

public Prompt(String name, String type, String text) {
@JsonCreator
public Prompt(@JsonProperty("name") String name,
@JsonProperty("type") String type,
@JsonProperty("text") String text) {
this.name = name;
this.type = type;
this.text = text;
Expand All @@ -34,6 +36,15 @@ public String getName() {
return name;
}

public String getText() {
return text;
}

public String getType() {
return type;
}

@JsonIgnore
public String[] getDetails() {
return new String[] { type, text };
}
Expand Down
Expand Up @@ -15,14 +15,24 @@

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.cloudfoundry.identity.uaa.login.Prompt;

import java.util.Arrays;
import java.util.List;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class IdentityZoneConfiguration {

private TokenPolicy tokenPolicy = new TokenPolicy();
private SamlConfig samlConfig = new SamlConfig();
private boolean disableInternalUserManagement = false;
private Links links = new Links();
private List<Prompt> prompts = Arrays.asList(
new Prompt("username", "text", "Email"),
new Prompt("password", "password", "Password"),
new Prompt("passcode", "password", "One Time Code (Get on at /passcode)")
);

public IdentityZoneConfiguration() {}

Expand Down Expand Up @@ -64,4 +74,13 @@ public IdentityZoneConfiguration setLinks(Links links) {
this.links = links;
return this;
}

public List<Prompt> getPrompts() {
return prompts;
}

public IdentityZoneConfiguration setPrompts(List<Prompt> prompts) {
this.prompts = prompts;
return this;
}
}
Expand Up @@ -17,7 +17,6 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

import java.util.Collections;
import java.util.List;

@JsonInclude(JsonInclude.Include.NON_NULL)
Expand Down Expand Up @@ -59,7 +58,7 @@ public static class Logout {
private String redirectUrl = "/login";
private String redirectParameterName = "redirect";
private boolean disableRedirectParameter = false;
private List<String> whitelist = Collections.EMPTY_LIST;
private List<String> whitelist = null;

public boolean isDisableRedirectParameter() {
return disableRedirectParameter;
Expand Down
Expand Up @@ -12,6 +12,7 @@
*******************************************************************************/
package org.cloudfoundry.identity.uaa.impl.config;

import org.cloudfoundry.identity.uaa.login.Prompt;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneConfiguration;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneProvisioning;
Expand All @@ -35,6 +36,7 @@ public class IdentityZoneConfigurationBootstrap implements InitializingBean {
private String logoutRedirectParameterName;
private String logoutDefaultRedirectUrl;
private boolean logoutDisableRedirectParameter = true;
private List<Prompt> prompts;


public IdentityZoneConfigurationBootstrap(IdentityZoneProvisioning provisioning) {
Expand Down Expand Up @@ -67,6 +69,9 @@ public void afterPropertiesSet() {
definition.getLinks().getLogout().setRedirectUrl(logoutDefaultRedirectUrl);
}
definition.getLinks().getLogout().setDisableRedirectParameter(logoutDisableRedirectParameter);
if (nonNull(prompts)) {
definition.setPrompts(prompts);
}

identityZone.setConfig(definition);
provisioning.update(identityZone);
Expand Down Expand Up @@ -109,4 +114,8 @@ public void setLogoutRedirectParameterName(String logoutRedirectParameterName) {
public void setLogoutRedirectWhitelist(List<String> logoutRedirectWhitelist) {
this.logoutRedirectWhitelist = logoutRedirectWhitelist;
}

public void setPrompts(List<Prompt> prompts) {
this.prompts = prompts;
}
}
Expand Up @@ -30,6 +30,7 @@
import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.cloudfoundry.identity.uaa.util.UaaStringUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneConfiguration;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.dao.EmptyResultDataAccessException;
Expand Down Expand Up @@ -75,6 +76,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.Objects.isNull;
import static org.cloudfoundry.identity.uaa.util.UaaUrlUtils.addSubdomainToUrl;
import static org.springframework.util.StringUtils.hasText;

Expand Down Expand Up @@ -170,19 +172,6 @@ public LoginInfoEndpoint() {
}
}

private List<Prompt> prompts = Arrays.asList(
new Prompt("username", "text", "Email"),
new Prompt("password", "password", "Password")
);

public void setPrompts(List<Prompt> prompts) {
this.prompts = prompts;
}

public List<Prompt> getPrompts() {
return prompts;
}

@RequestMapping(value = {"/login"}, headers = "Accept=application/json")
public String loginForJson(Model model, Principal principal) {
return login(model, principal, Collections.<String>emptyList(), true);
Expand Down Expand Up @@ -349,8 +338,12 @@ private void setCommitInfo(Model model) {


public void populatePrompts(Model model, List<String> exclude, boolean jsonResponse) {
IdentityZoneConfiguration zoneConfiguration = IdentityZoneHolder.get().getConfig();
if (isNull(zoneConfiguration)) {
zoneConfiguration = new IdentityZoneConfiguration();
}
Map<String, String[]> map = new LinkedHashMap<>();
for (Prompt prompt : getPrompts()) {
for (Prompt prompt : zoneConfiguration.getPrompts()) {
if (!exclude.contains(prompt.getName())) {
String[] details = prompt.getDetails();
if (PASSCODE.equals(prompt.getName()) && !IdentityZoneHolder.isUaa()) {
Expand Down
Expand Up @@ -27,9 +27,9 @@
import org.springframework.security.oauth2.provider.client.BaseClientDetails;

import java.util.Arrays;
import java.util.Collections;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -68,7 +68,7 @@ public void tearDown() throws Exception {
@Test
public void test_defaults() throws Exception {
WhitelistLogoutHandler whandler = handler.getZoneHandler();
assertEquals(Collections.EMPTY_LIST, whandler.getWhitelist());
assertNull(whandler.getWhitelist());
assertEquals("redirect", whandler.getTargetUrlParameter());
assertEquals("/login", whandler.getDefaultTargetUrl1());
assertTrue(whandler.isAlwaysUseDefaultTargetUrl());
Expand Down
Expand Up @@ -13,6 +13,7 @@
package org.cloudfoundry.identity.uaa.config;

import org.cloudfoundry.identity.uaa.impl.config.IdentityZoneConfigurationBootstrap;
import org.cloudfoundry.identity.uaa.login.Prompt;
import org.cloudfoundry.identity.uaa.test.JdbcTestBase;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneConfiguration;
Expand All @@ -25,6 +26,7 @@

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
Expand All @@ -35,33 +37,34 @@ public class IdentityZoneConfigurationBootstrapTests extends JdbcTestBase {

public static final String PRIVATE_KEY =
"-----BEGIN RSA PRIVATE KEY-----\n" +
"MIICXAIBAAKBgQDErZsZY70QAa7WdDD6eOv3RLBA4I5J0zZOiXMzoFB5yh64q0sm\n" +
"ESNtV4payOYE5TnHxWjMo0y7gDsGjI1omAG6wgfyp63I9WcLX7FDLyee43fG5+b9\n" +
"roofosL+OzJSXESSulsT9Y1XxSFFM5RMu4Ie9uM4/izKLCsAKiggMhnAmQIDAQAB\n" +
"AoGAAs2OllALk7zSZxAE2qz6f+2krWgF3xt5fKkM0UGJpBKzWWJnkcVQwfArcpvG\n" +
"W2+A4U347mGtaEatkKxUH5d6/s37jfRI7++HFXcLf6QJPmuE3+FtB2mX0lVJoaJb\n" +
"RLh+tOtt4ZJRAt/u6RjUCVNpDnJB6NZ032bpL3DijfNkRuECQQDkJR+JJPUpQGoI\n" +
"voPqcLl0i1tLX93XE7nu1YuwdQ5SmRaS0IJMozoBLBfFNmCWlSHaQpBORc38+eGC\n" +
"J9xsOrBNAkEA3LD1JoNI+wPSo/o71TED7BoVdwCXLKPqm0TnTr2EybCUPLNoff8r\n" +
"Ngm51jXc8mNvUkBtYiPfMKzpdqqFBWXXfQJAQ7D0E2gAybWQAHouf7/kdrzmYI3Y\n" +
"L3lt4HxBzyBcGIvNk9AD6SNBEZn4j44byHIFMlIvqNmzTY0CqPCUyRP8vQJBALXm\n" +
"ANmygferKfXP7XsFwGbdBO4mBXRc0qURwNkMqiMXMMdrVGftZq9Oiua9VJRQUtPn\n" +
"mIC4cmCLVI5jc+qEC30CQE+eOXomzxNNPxVnIp5k5f+savOWBBu83J2IoT2znnGb\n" +
"wTKZHjWybPHsW2q8Z6Moz5dvE+XMd11c5NtIG2/L97I=\n" +
"-----END RSA PRIVATE KEY-----";
"MIICXAIBAAKBgQDErZsZY70QAa7WdDD6eOv3RLBA4I5J0zZOiXMzoFB5yh64q0sm\n" +
"ESNtV4payOYE5TnHxWjMo0y7gDsGjI1omAG6wgfyp63I9WcLX7FDLyee43fG5+b9\n" +
"roofosL+OzJSXESSulsT9Y1XxSFFM5RMu4Ie9uM4/izKLCsAKiggMhnAmQIDAQAB\n" +
"AoGAAs2OllALk7zSZxAE2qz6f+2krWgF3xt5fKkM0UGJpBKzWWJnkcVQwfArcpvG\n" +
"W2+A4U347mGtaEatkKxUH5d6/s37jfRI7++HFXcLf6QJPmuE3+FtB2mX0lVJoaJb\n" +
"RLh+tOtt4ZJRAt/u6RjUCVNpDnJB6NZ032bpL3DijfNkRuECQQDkJR+JJPUpQGoI\n" +
"voPqcLl0i1tLX93XE7nu1YuwdQ5SmRaS0IJMozoBLBfFNmCWlSHaQpBORc38+eGC\n" +
"J9xsOrBNAkEA3LD1JoNI+wPSo/o71TED7BoVdwCXLKPqm0TnTr2EybCUPLNoff8r\n" +
"Ngm51jXc8mNvUkBtYiPfMKzpdqqFBWXXfQJAQ7D0E2gAybWQAHouf7/kdrzmYI3Y\n" +
"L3lt4HxBzyBcGIvNk9AD6SNBEZn4j44byHIFMlIvqNmzTY0CqPCUyRP8vQJBALXm\n" +
"ANmygferKfXP7XsFwGbdBO4mBXRc0qURwNkMqiMXMMdrVGftZq9Oiua9VJRQUtPn\n" +
"mIC4cmCLVI5jc+qEC30CQE+eOXomzxNNPxVnIp5k5f+savOWBBu83J2IoT2znnGb\n" +
"wTKZHjWybPHsW2q8Z6Moz5dvE+XMd11c5NtIG2/L97I=\n" +
"-----END RSA PRIVATE KEY-----";
public static final String PUBLIC_KEY =
"-----BEGIN RSA PUBLIC KEY-----\n" +
"MIGJAoGBAMStmxljvRABrtZ0MPp46/dEsEDgjknTNk6JczOgUHnKHrirSyYRI21X\n" +
"ilrI5gTlOcfFaMyjTLuAOwaMjWiYAbrCB/Knrcj1ZwtfsUMvJ57jd8bn5v2uih+i\n" +
"wv47MlJcRJK6WxP1jVfFIUUzlEy7gh724zj+LMosKwAqKCAyGcCZAgMBAAE=\n" +
"-----END RSA PUBLIC KEY-----";
"MIGJAoGBAMStmxljvRABrtZ0MPp46/dEsEDgjknTNk6JczOgUHnKHrirSyYRI21X\n" +
"ilrI5gTlOcfFaMyjTLuAOwaMjWiYAbrCB/Knrcj1ZwtfsUMvJ57jd8bn5v2uih+i\n" +
"wv47MlJcRJK6WxP1jVfFIUUzlEy7gh724zj+LMosKwAqKCAyGcCZAgMBAAE=\n" +
"-----END RSA PUBLIC KEY-----";

public static final String PASSWORD = "password";

public static final String ID = "id";
private IdentityZoneProvisioning provisioning;
private IdentityZoneConfigurationBootstrap bootstrap;
private Map<String, String> links = new HashMap<>();;
private Map<String, String> links = new HashMap<>();
;

@Before
public void configureProvisioning() {
Expand All @@ -73,7 +76,7 @@ public void configureProvisioning() {
public void tokenPolicy_configured_fromValuesInYaml() throws Exception {
TokenPolicy tokenPolicy = new TokenPolicy();
KeyPair key = new KeyPair(PRIVATE_KEY, PUBLIC_KEY, PASSWORD);
Map<String,KeyPair> keys = new HashMap<>();
Map<String, KeyPair> keys = new HashMap<>();
keys.put(ID, key);
tokenPolicy.setKeys(keys);
tokenPolicy.setAccessTokenValidity(3600);
Expand Down Expand Up @@ -150,4 +153,17 @@ public void test_logout_redirect() throws Exception {
assertEquals(Arrays.asList("http://single-url"), config.getLinks().getLogout().getWhitelist());
assertFalse(config.getLinks().getLogout().isDisableRedirectParameter());
}


@Test
public void test_prompts() throws Exception {
List<Prompt> prompts = Arrays.asList(
new Prompt("name1", "type1", "text1"),
new Prompt("name2", "type2", "text2")
);
bootstrap.setPrompts(prompts);
bootstrap.afterPropertiesSet();
IdentityZoneConfiguration config = provisioning.retrieve(IdentityZone.getUaa().getId()).getConfig();
assertEquals(prompts, config.getPrompts());
}
}
Expand Up @@ -525,7 +525,7 @@ private LoginInfoEndpoint getEndpoint() {
endpoint.setBaseUrl("http://someurl");
SamlIdentityProviderConfigurator emptyConfigurator = new SamlIdentityProviderConfigurator();
endpoint.setIdpDefinitions(emptyConfigurator);
endpoint.setPrompts(prompts);
IdentityZoneHolder.get().getConfig().setPrompts(prompts);
endpoint.setProviderProvisioning(identityProviderProvisioning);
return endpoint;
}
Expand Down
4 changes: 1 addition & 3 deletions uaa/src/main/webapp/WEB-INF/spring-servlet.xml
Expand Up @@ -376,7 +376,6 @@
<property name="entityID" ref="samlEntityID"/>
<property name="idpDefinitions" ref="metaDataProviders"/>
<property name="clientDetailsService" ref="jdbcClientDetailsService"/>
<property name="prompts" ref="prompts"/>
<property name="expiringCodeStore" ref="codeStore"/>
<property name="externalLoginUrl" value="${login.url:''}"/>
<property name="providerProvisioning" ref="identityProviderProvisioning"/>
Expand Down Expand Up @@ -411,8 +410,7 @@
<property name="logoutRedirectParameterName" value="redirect" />
<property name="logoutDefaultRedirectUrl" value="${logout.redirect.url:/login}" />
<property name="logoutDisableRedirectParameter" value="${logout.redirect.parameter.disable:true}"/>


<property name="prompts" ref="prompts"/>
</bean>

<bean id="ldapLoginAuthenticationMgr" class="org.cloudfoundry.identity.uaa.authentication.manager.LdapLoginAuthenticationManager">
Expand Down
Expand Up @@ -168,9 +168,18 @@ public void testRootContextDefaults() throws Exception {
assertNull(zoneConfiguration.getLinks().getHomeRedirect());
assertEquals("redirect", zoneConfiguration.getLinks().getLogout().getRedirectParameterName());
assertEquals("/login", zoneConfiguration.getLinks().getLogout().getRedirectUrl());
assertEquals(Collections.EMPTY_LIST, zoneConfiguration.getLinks().getLogout().getWhitelist());
assertNull(zoneConfiguration.getLinks().getLogout().getWhitelist());
assertTrue(zoneConfiguration.getLinks().getLogout().isDisableRedirectParameter());

assertEquals(
Arrays.asList(
new Prompt("username", "text", "Email"),
new Prompt("password", "password", "Password"),
new Prompt("passcode", "password", "One Time Code ( Get one at http://localhost:8080/uaa/passcode )")
),
zoneConfiguration.getPrompts()
);

Object links = context.getBean("links");
assertEquals(Collections.EMPTY_MAP, links);

Expand Down Expand Up @@ -269,17 +278,25 @@ public void testPropertyValuesWhenSetInYaml() throws Exception {
context = getServletContext(null, "login.yml", "test/bootstrap/bootstrap-test.yml", "file:./src/main/webapp/WEB-INF/spring-servlet.xml");

IdentityZoneProvisioning zoneProvisioning = context.getBean(IdentityZoneProvisioning.class);
IdentityZoneConfiguration zoneConfig = zoneProvisioning.retrieve(IdentityZone.getUaa().getId()).getConfig();
assertFalse(zoneConfig.getLinks().getSelfService().isSelfServiceLinksEnabled());
assertEquals("http://some.redirect.com/redirect", zoneConfig.getLinks().getHomeRedirect());
assertEquals("/configured_signup", zoneConfig.getLinks().getSelfService().getSignup());
assertEquals("/configured_passwd", zoneConfig.getLinks().getSelfService().getPasswd());
IdentityZoneConfiguration zoneConfiguration = zoneProvisioning.retrieve(IdentityZone.getUaa().getId()).getConfig();
assertFalse(zoneConfiguration.getLinks().getSelfService().isSelfServiceLinksEnabled());
assertEquals("http://some.redirect.com/redirect", zoneConfiguration.getLinks().getHomeRedirect());
assertEquals("/configured_signup", zoneConfiguration.getLinks().getSelfService().getSignup());
assertEquals("/configured_passwd", zoneConfiguration.getLinks().getSelfService().getPasswd());

assertEquals("redirect", zoneConfig.getLinks().getLogout().getRedirectParameterName());
assertEquals("/configured_login", zoneConfig.getLinks().getLogout().getRedirectUrl());
assertEquals(Arrays.asList("https://url1.domain1.com/logout-success","https://url2.domain2.com/logout-success"), zoneConfig.getLinks().getLogout().getWhitelist());
assertFalse(zoneConfig.getLinks().getLogout().isDisableRedirectParameter());
assertEquals("redirect", zoneConfiguration.getLinks().getLogout().getRedirectParameterName());
assertEquals("/configured_login", zoneConfiguration.getLinks().getLogout().getRedirectUrl());
assertEquals(Arrays.asList("https://url1.domain1.com/logout-success","https://url2.domain2.com/logout-success"), zoneConfiguration.getLinks().getLogout().getWhitelist());
assertFalse(zoneConfiguration.getLinks().getLogout().isDisableRedirectParameter());

assertEquals(
Arrays.asList(
new Prompt("username", "text", "Username"),
new Prompt("password", "password", "Your Secret"),
new Prompt("passcode", "password", "One Time Code ( Get one at https://login.some.test.domain.com:555/uaa/passcode )")
),
zoneConfiguration.getPrompts()
);

IdentityProviderProvisioning idpProvisioning = context.getBean(IdentityProviderProvisioning.class);
IdentityProvider<UaaIdentityProviderDefinition> uaaIdp = idpProvisioning.retrieveByOrigin(OriginKeys.UAA, IdentityZone.getUaa().getId());
Expand Down

0 comments on commit 8ee59a7

Please sign in to comment.