Skip to content

Commit

Permalink
Refactor IdentityProvider.config into a typed object
Browse files Browse the repository at this point in the history
https://www.pivotaltracker.com/story/show/107770792
[#107770792]

Attempt to consolidate SamlDefinition alias=IDP originKey and the zoneIds
We should remove the duplication of data when possible
  • Loading branch information
fhanik committed Nov 17, 2015
1 parent 1d74cbc commit 32b5ea9
Show file tree
Hide file tree
Showing 54 changed files with 853 additions and 484 deletions.
Expand Up @@ -14,12 +14,15 @@

package org.cloudfoundry.identity.uaa;

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

public abstract class AbstractIdentityProviderDefinition {
public class AbstractIdentityProviderDefinition {
public static final String EMAIL_DOMAIN_ATTR = "emailDomain";

private List<String> emailDomain;
private Map<String,Object> additionalConfiguration;

public List<String> getEmailDomain() {
return emailDomain;
Expand All @@ -29,4 +32,37 @@ public AbstractIdentityProviderDefinition setEmailDomain(List<String> emailDomai
this.emailDomain = emailDomain;
return this;
}

public Map<String, Object> getAdditionalConfiguration() {
return additionalConfiguration;
}

public AbstractIdentityProviderDefinition setAdditionalConfiguration(Map<String, Object> additionalConfiguration) {
this.additionalConfiguration = additionalConfiguration;
return this;
}

public AbstractIdentityProviderDefinition addAdditionalConfiguration(String key, Object value) {
if (additionalConfiguration==null) {
additionalConfiguration = new HashMap<>();
}
additionalConfiguration.put(key, value);
return this;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

AbstractIdentityProviderDefinition that = (AbstractIdentityProviderDefinition) o;

return !(emailDomain != null ? !emailDomain.equals(that.emailDomain) : that.emailDomain != null);

}

@Override
public int hashCode() {
return emailDomain != null ? emailDomain.hashCode() : 0;
}
}
Expand Up @@ -59,4 +59,26 @@ public Map<String, Object> getAttributeMappings() {
public void addAttributeMapping(String key, Object value) {
attributeMappings.put(key, value);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;

ExternalIdentityProviderDefinition that = (ExternalIdentityProviderDefinition) o;

if (getExternalGroupsWhitelist() != null ? !getExternalGroupsWhitelist().equals(that.getExternalGroupsWhitelist()) : that.getExternalGroupsWhitelist() != null)
return false;
return !(getAttributeMappings() != null ? !getAttributeMappings().equals(that.getAttributeMappings()) : that.getAttributeMappings() != null);

}

@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (getExternalGroupsWhitelist() != null ? getExternalGroupsWhitelist().hashCode() : 0);
result = 31 * result + (getAttributeMappings() != null ? getAttributeMappings().hashCode() : 0);
return result;
}
}
@@ -0,0 +1,41 @@
/*
* *****************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved.
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* *****************************************************************************
*/

package org.cloudfoundry.identity.uaa;

import java.util.Map;

public class KeystoneIdentityProviderDefinition extends ExternalIdentityProviderDefinition {

public KeystoneIdentityProviderDefinition() {
this(null);
}

public KeystoneIdentityProviderDefinition(Map<String, Object> configuration) {
setAdditionalConfiguration(configuration);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
return true;
}

@Override
public int hashCode() {
return super.hashCode();
}
}
Expand Up @@ -28,6 +28,7 @@ public class Origin {
public static final String KEYSTONE = "keystone";
public static final String SAML = "saml";
public static final String NotANumber = "NaN";
public static final String UNKNOWN = "unknown";

public static String getUserId(Authentication authentication) {
String id;
Expand Down
@@ -1,5 +1,5 @@
/*******************************************************************************
* Cloud Foundry
* Cloud Foundry
* Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
Expand Down Expand Up @@ -27,6 +27,7 @@
import org.cloudfoundry.identity.uaa.authentication.event.UserNotFoundEvent;
import org.cloudfoundry.identity.uaa.user.UaaUser;
import org.cloudfoundry.identity.uaa.user.UaaUserDatabase;
import org.cloudfoundry.identity.uaa.util.ObjectUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityProvider;
import org.cloudfoundry.identity.uaa.zone.IdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
Expand Down Expand Up @@ -55,7 +56,7 @@
/**
* @author Luke Taylor
* @author Dave Syer
*
*
*/
public class AuthzAuthenticationManager implements AuthenticationManager, ApplicationEventPublisherAware {

Expand Down Expand Up @@ -164,7 +165,7 @@ protected int getPasswordExpiresInMonths() {
int result = 0;
IdentityProvider provider = providerProvisioning.retrieveByOrigin(Origin.UAA, IdentityZoneHolder.get().getId());
if (provider!=null) {
UaaIdentityProviderDefinition idpDefinition = provider.getConfigValue(UaaIdentityProviderDefinition.class);
UaaIdentityProviderDefinition idpDefinition = ObjectUtils.castInstance(provider.getConfig(),UaaIdentityProviderDefinition.class);
if (idpDefinition!=null) {
if (null!=idpDefinition.getPasswordPolicy()) {
return idpDefinition.getPasswordPolicy().getExpirePasswordInMonths();
Expand Down
Expand Up @@ -20,6 +20,7 @@
import org.cloudfoundry.identity.uaa.ldap.LdapIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.ldap.extension.LdapAuthority;
import org.cloudfoundry.identity.uaa.user.UaaUser;
import org.cloudfoundry.identity.uaa.util.ObjectUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityProvider;
import org.cloudfoundry.identity.uaa.zone.IdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
Expand Down Expand Up @@ -54,7 +55,7 @@ protected MultiValueMap<String, String> getUserAttributes(UserDetails request) {
IdentityProvider provider = provisioning.retrieveByOrigin(getOrigin(), IdentityZoneHolder.get().getId());
if (request instanceof ExtendedLdapUserDetails) {
ExtendedLdapUserDetails ldapDetails = ((ExtendedLdapUserDetails) request);
LdapIdentityProviderDefinition ldapIdentityProviderDefinition = provider.getConfigValue(LdapIdentityProviderDefinition.class);
LdapIdentityProviderDefinition ldapIdentityProviderDefinition = ObjectUtils.castInstance(provider.getConfig(),LdapIdentityProviderDefinition.class);
Map<String, Object> providerMappings = ldapIdentityProviderDefinition.getAttributeMappings();
for (Map.Entry<String, Object> entry : providerMappings.entrySet()) {
if (entry.getKey().startsWith(USER_ATTRIBUTE_PREFIX) && entry.getValue() != null) {
Expand All @@ -75,7 +76,7 @@ protected List<String> getExternalUserAuthorities(UserDetails request) {
List<String> result = super.getExternalUserAuthorities(request);
if (provisioning!=null) {
IdentityProvider provider = provisioning.retrieveByOrigin(getOrigin(), IdentityZoneHolder.get().getId());
LdapIdentityProviderDefinition ldapIdentityProviderDefinition = provider.getConfigValue(LdapIdentityProviderDefinition.class);
LdapIdentityProviderDefinition ldapIdentityProviderDefinition = ObjectUtils.castInstance(provider.getConfig(),LdapIdentityProviderDefinition.class);
List<String> externalWhiteList = ldapIdentityProviderDefinition.getExternalGroupsWhitelist();
result = new LinkedList<>(getAuthoritesAsNames(request.getAuthorities()));
result.retainAll(externalWhiteList);
Expand Down Expand Up @@ -118,7 +119,7 @@ protected boolean isAutoAddAuthorities() {
Boolean result = true;
if (provisioning!=null) {
IdentityProvider provider = provisioning.retrieveByOrigin(getOrigin(), IdentityZoneHolder.get().getId());
LdapIdentityProviderDefinition ldapIdentityProviderDefinition = provider.getConfigValue(LdapIdentityProviderDefinition.class);
LdapIdentityProviderDefinition ldapIdentityProviderDefinition = ObjectUtils.castInstance(provider.getConfig(), LdapIdentityProviderDefinition.class);
if (ldapIdentityProviderDefinition!=null) {
result = ldapIdentityProviderDefinition.isAutoAddGroups();
}
Expand Down
@@ -1,5 +1,5 @@
/*******************************************************************************
* Cloud Foundry
* Cloud Foundry
* Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
Expand All @@ -12,8 +12,6 @@
*******************************************************************************/
package org.cloudfoundry.identity.uaa.authentication.manager;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cloudfoundry.identity.uaa.audit.AuditEvent;
Expand All @@ -22,19 +20,22 @@
import org.cloudfoundry.identity.uaa.authentication.Origin;
import org.cloudfoundry.identity.uaa.config.LockoutPolicy;
import org.cloudfoundry.identity.uaa.user.UaaUser;
import org.cloudfoundry.identity.uaa.util.ObjectUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityProvider;
import org.cloudfoundry.identity.uaa.zone.IdentityProviderProvisioning;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.cloudfoundry.identity.uaa.zone.UaaIdentityProviderDefinition;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import java.util.List;

/**
* Locks an account out for a configured period based on the number of failed
* logins since a specific time in the past.
* <p>
* Queries the audit service to obtain the relevant data for the user.
*
*
* @author Luke Taylor
*/
public class PeriodLockoutPolicy implements AccountLoginPolicy {
Expand Down Expand Up @@ -107,7 +108,7 @@ public void setLockoutPolicy(LockoutPolicy lockoutPolicy) {

private LockoutPolicy getLockoutPolicyFromDb() {
IdentityProvider idp = providerProvisioning.retrieveByOrigin(Origin.UAA, IdentityZoneHolder.get().getId());
UaaIdentityProviderDefinition idpDefinition = idp.getConfigValue(UaaIdentityProviderDefinition.class);
UaaIdentityProviderDefinition idpDefinition = ObjectUtils.castInstance(idp.getConfig(),UaaIdentityProviderDefinition.class);
if (idpDefinition != null && idpDefinition.getLockoutPolicy() !=null ) {
return idpDefinition.getLockoutPolicy();
}
Expand Down
Expand Up @@ -13,6 +13,8 @@
package org.cloudfoundry.identity.uaa.config;


import org.cloudfoundry.identity.uaa.AbstractIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.KeystoneIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.authentication.Origin;
import org.cloudfoundry.identity.uaa.ldap.LdapIdentityProviderDefinition;
import org.cloudfoundry.identity.uaa.login.saml.SamlIdentityProviderConfigurator;
Expand Down Expand Up @@ -41,12 +43,11 @@
import static org.cloudfoundry.identity.uaa.ldap.LdapIdentityProviderDefinition.LDAP_PROPERTY_TYPES;

public class IdentityProviderBootstrap implements InitializingBean {
public static final String DEFAULT_MAP = "{\"default\":\"default\"}";
private IdentityProviderProvisioning provisioning;
private List<IdentityProvider> providers = new LinkedList<>();
private SamlIdentityProviderConfigurator configurator;
private HashMap<String, Object> ldapConfig;
private HashMap<String, Object> keystoneConfig;
private Map<String, Object> ldapConfig;
private Map<String, Object> keystoneConfig;
private Environment environment;
private PasswordPolicy defaultPasswordPolicy;
private LockoutPolicy defaultLockoutPolicy;
Expand Down Expand Up @@ -75,7 +76,7 @@ protected void addSamlProviders() {
provider.setName("UAA SAML Identity Provider["+provider.getOriginKey()+"]");
provider.setActive(true);
try {
provider.setConfig(JsonUtils.writeValueAsString(def));
provider.setConfig(def);
} catch (JsonUtils.JsonUtilException x) {
throw new RuntimeException("Non serializable LDAP config");
}
Expand All @@ -98,7 +99,7 @@ protected void addLdapProvider() {
Map<String,Object> ldap = new HashMap<>();
ldap.put(LDAP, ldapConfig);
LdapIdentityProviderDefinition json = getLdapConfigAsDefinition(ldap);
provider.setConfig(JsonUtils.writeValueAsString(json));
provider.setConfig(json);
provider.setActive(ldapProfile && json.isConfigured());
providers.add(provider);
}
Expand Down Expand Up @@ -138,17 +139,20 @@ public void setKeystoneConfig(HashMap<String, Object> keystoneConfig) {
this.keystoneConfig = keystoneConfig;
}

protected AbstractIdentityProviderDefinition getKeystoneDefinition(Map<String, Object> config) {
return new KeystoneIdentityProviderDefinition(config);
}

protected void addKeystoneProvider() {
boolean keystoneProfile = Arrays.asList(environment.getActiveProfiles()).contains(Origin.KEYSTONE);
if (keystoneConfig != null || keystoneProfile) {
boolean active = keystoneProfile && keystoneConfig!=null;
IdentityProvider provider = new IdentityProvider();
provider.setOriginKey(Origin.KEYSTONE);
provider.setType(Origin.KEYSTONE);
provider.setName("UAA LDAP Provider");
provider.setName("UAA Keystone Provider");
provider.setActive(active);
String json = keystoneConfig != null ? JsonUtils.writeValueAsString(keystoneConfig) : DEFAULT_MAP;
provider.setConfig(json);
provider.setConfig(getKeystoneDefinition(keystoneConfig));
providers.add(provider);
}
}
Expand Down Expand Up @@ -202,7 +206,7 @@ private void deactivateUnusedProviders(String zoneId) {
protected void updateDefaultZoneUaaIDP() throws JSONException {
IdentityProvider internalIDP = provisioning.retrieveByOrigin(Origin.UAA, IdentityZone.getUaa().getId());
UaaIdentityProviderDefinition identityProviderDefinition = new UaaIdentityProviderDefinition(defaultPasswordPolicy, defaultLockoutPolicy, disableInternalUserManagement);
internalIDP.setConfig(JsonUtils.writeValueAsString(identityProviderDefinition));
internalIDP.setConfig(identityProviderDefinition);
String disableInternalAuth = environment.getProperty("disableInternalAuth");
if (disableInternalAuth != null) {
internalIDP.setActive(!Boolean.valueOf(disableInternalAuth));
Expand Down
Expand Up @@ -112,4 +112,33 @@ public PasswordPolicy setExpirePasswordInMonths(int expirePasswordInMonths) {
public boolean allPresentAndPositive() {
return minLength >= 0 && maxLength >= 0 && requireUpperCaseCharacter >= 0 && requireLowerCaseCharacter >= 0 && requireDigit >= 0 && requireSpecialCharacter >= 0 && expirePasswordInMonths >= 0;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

PasswordPolicy that = (PasswordPolicy) o;

if (getMinLength() != that.getMinLength()) return false;
if (getMaxLength() != that.getMaxLength()) return false;
if (getRequireUpperCaseCharacter() != that.getRequireUpperCaseCharacter()) return false;
if (getRequireLowerCaseCharacter() != that.getRequireLowerCaseCharacter()) return false;
if (getRequireDigit() != that.getRequireDigit()) return false;
if (getRequireSpecialCharacter() != that.getRequireSpecialCharacter()) return false;
return getExpirePasswordInMonths() == that.getExpirePasswordInMonths();

}

@Override
public int hashCode() {
int result = getMinLength();
result = 31 * result + getMaxLength();
result = 31 * result + getRequireUpperCaseCharacter();
result = 31 * result + getRequireLowerCaseCharacter();
result = 31 * result + getRequireDigit();
result = 31 * result + getRequireSpecialCharacter();
result = 31 * result + getExpirePasswordInMonths();
return result;
}
}

0 comments on commit 32b5ea9

Please sign in to comment.