diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfiguration.java index a6a1db63d..b1bce979f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfiguration.java @@ -1,36 +1,70 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration; +import edu.internet2.tier.shibboleth.admin.ui.domain.IRelyingPartyOverrideProperty; import edu.internet2.tier.shibboleth.admin.ui.domain.RelyingPartyOverrideProperty; +import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -/** - * @author Bill Smith (wsmith@unicon.net) - */ +import javax.annotation.PostConstruct; + @Configuration -@ConfigurationProperties(prefix="custom") +@ConfigurationProperties(prefix = "custom") public class CustomPropertiesConfiguration { - private List> attributes = new ArrayList<>(); - private List overrides = new ArrayList<>(); + + private CustomEntityAttributesDefinitionService ceadService; + private HashMap overrides = new HashMap<>(); + + private List overridesFromConfigFile = new ArrayList<>(); + public List> getAttributes() { return attributes; } + public List getOverrides() { + return new ArrayList<>(overrides.values()); + } + public void setAttributes(List> attributes) { this.attributes = attributes; + } + + @Autowired + public void setCeadService(CustomEntityAttributesDefinitionService ceadService) { + this.ceadService = ceadService; + } - public List getOverrides() { - return overrides; + /** + * This setter will get used by Spring's property system to create objects from a config file (should the properties exist) + */ + public void setOverrides(List overridesFromConfigFile) { + this.overridesFromConfigFile = overridesFromConfigFile; + } + + @PostConstruct + public void postConstruct() { + // Register with service to get the updates when changes are made to the DB definitions + // ceadService.setCustomPropertiesConfiguration(this); + buildRelyingPartyOverrides(); } - public void setOverrides(List overrides) { - this.overrides = overrides; + private void buildRelyingPartyOverrides() { + // We only want to add to an override if the incoming override (by name) isn't already in the list of overrides + for(RelyingPartyOverrideProperty rpop : this.overridesFromConfigFile) { + if (!this.overrides.containsKey(rpop.getName())) { + this.overrides.put(rpop.getName(), rpop); + } + } } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/CustomEntityAttributeDefinition.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/CustomEntityAttributeDefinition.java index d852ba5ea..92111f713 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/CustomEntityAttributeDefinition.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/CustomEntityAttributeDefinition.java @@ -3,14 +3,12 @@ import java.util.HashSet; import java.util.Set; -import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; import org.hibernate.envers.Audited; @@ -19,28 +17,69 @@ @Entity(name = "custom_entity_attribute_definition") @Audited @Data -public class CustomEntityAttributeDefinition { +public class CustomEntityAttributeDefinition implements IRelyingPartyOverrideProperty { @Id @Column(nullable = false) String name; + + @Column(name = "attribute_friendly_name", nullable = true) + String attributeFriendlyName; - @Column(name = "help_text", nullable = true) - String helpText; + @Column(name = "attribute_name", nullable = true) + String attributeName; @Column(name = "attribute_type", nullable = false) CustomAttributeType attributeType; - @Column(name = "default_value", nullable = true) - String defaultValue; - @ElementCollection @CollectionTable(name = "custom_entity_attr_list_items", joinColumns = @JoinColumn(name = "name")) @Column(name = "value", nullable = false) Set customAttrListDefinitions = new HashSet<>(); - // @TODO: logic to ensure defaultValue matches an item from the list of values when SELECTION_LIST is the type ?? -} + @Column(name = "default_value", nullable = true) + String defaultValue; + + @Column(name = "display_name", nullable = true) + String displayName; + + @Column(name = "display_type", nullable = true) + String displayType; -enum CustomAttributeType { - STRING, BOOLEAN, INTEGER, LONG, DOUBLE, DURATION, SELECTION_LIST, SPRING_BEAN_ID + @Column(name = "help_text", nullable = true) + String helpText; + + @Column(name = "invert", nullable = true) + String invert; + + @Override + public Set getDefaultValues() { + return customAttrListDefinitions; + } + + @Override + public String getPersistType() { + return attributeType.toString(); + } + + @Override + public String getPersistValue() { + // Definitions don't have a persist value, here to comply with the interface only + return null; + } + + @Override + public void setDefaultValues(Set defaultValues) { + // This is here to comply with the interface only and should not be used to change the set of values in this implementation + } + + @Override + public void setPersistType(String persistType) { + // WHAT TO DO? This is "attributeType", but need to match up to AttributeTypes in ModelRepresentationConversions?? + } + + @Override + public void setPersistValue(String persistValue) { + // Definitions don't have a persist value, here to comply with the interface only + } + } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/IRelyingPartyOverrideProperty.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/IRelyingPartyOverrideProperty.java new file mode 100644 index 000000000..0c700a1af --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/IRelyingPartyOverrideProperty.java @@ -0,0 +1,53 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain; + +import java.util.Set; + +enum CustomAttributeType { + BOOLEAN, DOUBLE, DURATION, INTEGER, LONG, SELECTION_LIST, SPRING_BEAN_ID, STRING +} + +public interface IRelyingPartyOverrideProperty { + public String getAttributeFriendlyName(); + + public String getAttributeName(); + + public String getDefaultValue(); + + public Set getDefaultValues(); + + public String getDisplayName(); + + public String getDisplayType(); + + public String getHelpText(); + + public String getInvert(); + + public String getName(); + + public String getPersistType(); + + public String getPersistValue(); + + public void setAttributeFriendlyName(String attributeFriendlyName); + + public void setAttributeName(String attributeName); + + public void setDefaultValue(String defaultValue); + + public void setDefaultValues(Set defaultValues); + + public void setDisplayName(String displayName); + + public void setDisplayType(String displayType); + + public void setHelpText(String helpText); + + public void setInvert(String invert); + + public void setName(String name); + + public void setPersistType(String persistType); + + public void setPersistValue(String persistValue); +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RelyingPartyOverrideProperty.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RelyingPartyOverrideProperty.java index 1808ab6ef..1cc75c98b 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RelyingPartyOverrideProperty.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RelyingPartyOverrideProperty.java @@ -1,41 +1,27 @@ package edu.internet2.tier.shibboleth.admin.ui.domain; +import java.util.Set; + import lombok.Getter; import lombok.Setter; - -import java.util.List; +import lombok.ToString; /** * @author Bill Smith (wsmith@unicon.net) */ @Setter @Getter -public class RelyingPartyOverrideProperty { - private String name; +@ToString +public class RelyingPartyOverrideProperty implements IRelyingPartyOverrideProperty { + private String attributeFriendlyName; + private String attributeName; + private String defaultValue; + private Set defaultValues; private String displayName; private String displayType; - private String defaultValue; private String helpText; - private List defaultValues; + private String invert; + private String name; private String persistType; private String persistValue; - private String attributeName; - private String attributeFriendlyName; - private String invert; - - @Override - public String toString() { - return "RelyingPartyOverrideProperty{" - + "\nname='" + name + '\'' - + ", \ndisplayName='" + displayName + '\'' - + ", \ndisplayType='" + displayType + '\'' - + ", \ndefaultValue='" + defaultValue + '\'' - + ", \nhelpText='" + helpText + '\'' - + ", \npersistType='" + persistType + '\'' - + ", \npersistValue='" + persistValue + '\'' - + ", \ndefaultValues=" + defaultValues - + ", \nattributeName='" + attributeName + '\'' - + ", \nattributeFriendlyName='" + attributeFriendlyName + '\'' - + "\n}"; - } } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java index 7be97f308..a28aa9449 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java @@ -25,7 +25,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationName; import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationURL; import edu.internet2.tier.shibboleth.admin.ui.domain.PrivacyStatementURL; -import edu.internet2.tier.shibboleth.admin.ui.domain.RelyingPartyOverrideProperty; +import edu.internet2.tier.shibboleth.admin.ui.domain.IRelyingPartyOverrideProperty; import edu.internet2.tier.shibboleth.admin.ui.domain.SPSSODescriptor; import edu.internet2.tier.shibboleth.admin.ui.domain.SingleLogoutService; import edu.internet2.tier.shibboleth.admin.ui.domain.UIInfo; @@ -69,6 +69,7 @@ import static edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions.getStringListOfAttributeValues; import static edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions.getValueFromXMLObject; + /** * Default implementation of {@link EntityDescriptorService} * @@ -644,7 +645,7 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope } else { Optional override = ModelRepresentationConversions.getOverrideByAttributeName(jpaAttribute.getName()); if (override.isPresent()) { - RelyingPartyOverrideProperty overrideProperty = (RelyingPartyOverrideProperty)override.get(); + IRelyingPartyOverrideProperty overrideProperty = (IRelyingPartyOverrideProperty)override.get(); Object attributeValues = null; switch (ModelRepresentationConversions.AttributeTypes.valueOf(overrideProperty.getDisplayType().toUpperCase())) { case STRING: @@ -677,7 +678,7 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope .map(attributeValue -> getValueFromXMLObject(attributeValue)) .collect(Collectors.toList()); } - relyingPartyOverrides.put(((RelyingPartyOverrideProperty) override.get()).getName(), attributeValues); + relyingPartyOverrides.put(((IRelyingPartyOverrideProperty) override.get()).getName(), attributeValues); } } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityServiceImpl.java index 111adb394..595ce896b 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityServiceImpl.java @@ -1,23 +1,17 @@ package edu.internet2.tier.shibboleth.admin.ui.service; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.opensaml.saml.saml2.core.Attribute; +import org.springframework.beans.factory.annotation.Autowired; + import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration; -import edu.internet2.tier.shibboleth.admin.ui.domain.AttributeBuilder; -import edu.internet2.tier.shibboleth.admin.ui.domain.AttributeValue; -import edu.internet2.tier.shibboleth.admin.ui.domain.RelyingPartyOverrideProperty; -import edu.internet2.tier.shibboleth.admin.ui.domain.XSString; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; import edu.internet2.tier.shibboleth.admin.util.AttributeUtility; -import edu.internet2.tier.shibboleth.admin.util.MDDCConstants; import edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions; -import org.opensaml.saml.saml2.core.Attribute; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions.getAttributeFromObjectAndRelyingPartyOverrideProperty; public class JPAEntityServiceImpl implements EntityService { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java index 12a1bad82..909fa8ee6 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java @@ -2,7 +2,7 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration; import edu.internet2.tier.shibboleth.admin.ui.domain.Attribute; -import edu.internet2.tier.shibboleth.admin.ui.domain.RelyingPartyOverrideProperty; +import edu.internet2.tier.shibboleth.admin.ui.domain.IRelyingPartyOverrideProperty; import edu.internet2.tier.shibboleth.admin.ui.domain.XSAny; import edu.internet2.tier.shibboleth.admin.ui.domain.XSBoolean; import edu.internet2.tier.shibboleth.admin.ui.domain.XSInteger; @@ -14,11 +14,9 @@ import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Set; import java.util.stream.Collectors; /** @@ -90,7 +88,7 @@ public static Map getRelyingPartyOverridesRepresentationFromAttr Optional override = getOverrideByAttributeName(jpaAttribute.getName()); if (override.isPresent()) { - relyingPartyOverrides.put(((RelyingPartyOverrideProperty) override.get()).getName(), + relyingPartyOverrides.put(((IRelyingPartyOverrideProperty) override.get()).getName(), getOverrideFromAttribute(jpaAttribute)); } } @@ -98,16 +96,8 @@ public static Map getRelyingPartyOverridesRepresentationFromAttr return relyingPartyOverrides; } - private static Object getDefaultValueFromProperty(RelyingPartyOverrideProperty property) { - switch (property.getDisplayType()) { - case "boolean": - return Boolean.getBoolean(property.getDefaultValue()); - } - return null; - } - public static Object getOverrideFromAttribute(Attribute attribute) { - RelyingPartyOverrideProperty relyingPartyOverrideProperty = customPropertiesConfiguration.getOverrides().stream() + IRelyingPartyOverrideProperty relyingPartyOverrideProperty = customPropertiesConfiguration.getOverrides().stream() .filter(it -> it.getAttributeFriendlyName().equals(attribute.getFriendlyName())).findFirst().get(); List attributeValues = attribute.getAttributeValues(); @@ -161,13 +151,13 @@ public static List getAttributeListFromA public static List getAttributeListFromRelyingPartyOverridesRepresentation (Map relyingPartyOverridesRepresentation) { - List overridePropertyList = customPropertiesConfiguration.getOverrides(); + List overridePropertyList = customPropertiesConfiguration.getOverrides(); List list = new ArrayList<>(); if (relyingPartyOverridesRepresentation != null) { for (Map.Entry entry : relyingPartyOverridesRepresentation.entrySet()) { String key = (String) entry.getKey(); - RelyingPartyOverrideProperty overrideProperty = overridePropertyList.stream().filter(op -> op.getName().equals(key)).findFirst().get(); + IRelyingPartyOverrideProperty overrideProperty = overridePropertyList.stream().filter(op -> op.getName().equals(key)).findFirst().get(); Attribute attribute = getAttributeFromObjectAndRelyingPartyOverrideProperty(entry.getValue(), overrideProperty); if (attribute != null) { list.add(attribute); @@ -178,7 +168,7 @@ public static List getAttributeListFromA return (List) (List) list; } - public static Attribute getAttributeFromObjectAndRelyingPartyOverrideProperty(Object o, RelyingPartyOverrideProperty overrideProperty) { + public static Attribute getAttributeFromObjectAndRelyingPartyOverrideProperty(Object o, IRelyingPartyOverrideProperty overrideProperty) { switch (ModelRepresentationConversions.AttributeTypes.valueOf(overrideProperty.getDisplayType().toUpperCase())) { case BOOLEAN: if ((o instanceof Boolean && ((Boolean) o)) || diff --git a/testbed/postgres/.gitignore b/testbed/postgres/.gitignore new file mode 100644 index 000000000..32ed36f28 --- /dev/null +++ b/testbed/postgres/.gitignore @@ -0,0 +1 @@ +/dc-charles.yml