From d650f34d150bb411b7b7db1f65bfe975ca0e39bc Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 7 Jun 2021 14:43:50 -0700 Subject: [PATCH 01/51] SHIBUI-1788 Midstream work checkin (tests broken) --- .../CustomPropertiesConfiguration.java | 54 +++++++++++++--- .../CustomEntityAttributeDefinition.java | 63 +++++++++++++++---- .../domain/IRelyingPartyOverrideProperty.java | 53 ++++++++++++++++ .../domain/RelyingPartyOverrideProperty.java | 36 ++++------- .../JPAEntityDescriptorServiceImpl.java | 7 ++- .../ui/service/JPAEntityServiceImpl.java | 20 +++--- .../util/ModelRepresentationConversions.java | 22 ++----- testbed/postgres/.gitignore | 1 + 8 files changed, 177 insertions(+), 79 deletions(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/IRelyingPartyOverrideProperty.java create mode 100644 testbed/postgres/.gitignore 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 From 2b4c3741655fc53db0da81900348a49bb572ba29 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 7 Jun 2021 17:08:00 -0700 Subject: [PATCH 02/51] SHIBUI-1788 Updated test configurations to fix autowired dependencies --- ...EntityAttributesDefinitionServiceImpl.java | 2 ++ .../ui/configuration/TestConfiguration.groovy | 25 +++++++++++++++++++ .../ui/domain/EntityDescriptorTest.groovy | 2 +- .../EntityDescriptorRepositoryTest.groovy | 21 ++++++++++++++-- ...JPAMetadataResolverServiceImplTests.groovy | 4 +-- ...JPAMetadataResolverServiceImplTests.groovy | 2 +- 6 files changed, 50 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java index 95f654386..c164c7f01 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java @@ -5,6 +5,7 @@ import javax.persistence.EntityManager; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; @@ -13,6 +14,7 @@ import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeFilterValueRepository; @Service +@Primary public class CustomEntityAttributesDefinitionServiceImpl implements CustomEntityAttributesDefinitionService { @Autowired private CustomEntityAttributeDefinitionRepository repository; diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy index 5e3c0ad1b..4a6e492de 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy @@ -2,11 +2,17 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects +import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeDefinitionRepository +import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeFilterValueRepository import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository import edu.internet2.tier.shibboleth.admin.ui.security.DefaultAuditorAware +import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionServiceImpl import edu.internet2.tier.shibboleth.admin.ui.service.IndexWriterService import net.shibboleth.ext.spring.resource.ResourceHelper import net.shibboleth.utilities.java.support.component.ComponentInitializationException + +import javax.persistence.EntityManager + import org.apache.lucene.document.Document import org.apache.lucene.document.Field import org.apache.lucene.document.StringField @@ -35,11 +41,30 @@ class TestConfiguration { final MetadataResolverRepository metadataResolverRepository final Logger logger = LoggerFactory.getLogger(TestConfiguration.class); + @Autowired + private CustomEntityAttributeDefinitionRepository repository; + + @Autowired + CustomEntityAttributeFilterValueRepository customEntityAttributeFilterValueRepository; + + @Autowired + EntityManager entityManager + TestConfiguration(final OpenSamlObjects openSamlObjects, final MetadataResolverRepository metadataResolverRepository) { this.openSamlObjects =openSamlObjects this.metadataResolverRepository = metadataResolverRepository } + @Bean + CustomEntityAttributesDefinitionServiceImpl ceadService() { + new CustomEntityAttributesDefinitionServiceImpl().with { + it.entityManager = entityManager + it.repository = repository + it.customEntityAttributeFilterValueRepository = customEntityAttributeFilterValueRepository + return it + } + } + @Bean JavaMailSender javaMailSender() { return new JavaMailSenderImpl().with { diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/EntityDescriptorTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/EntityDescriptorTest.groovy index 5fe53b85b..b0906a68c 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/EntityDescriptorTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/EntityDescriptorTest.groovy @@ -33,7 +33,7 @@ import java.nio.file.Files * @author Bill Smith (wsmith@unicon.net) */ @DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, SearchConfiguration, InternationalizationConfiguration, MyConfig, PlaceholderResolverComponentsConfiguration]) +@ContextConfiguration(classes=[CoreShibUiConfiguration, SearchConfiguration, InternationalizationConfiguration, MyConfig, PlaceholderResolverComponentsConfiguration, edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration]) @EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) @EntityScan("edu.internet2.tier.shibboleth.admin.ui") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy index 86fe1b74e..5fab1b0a2 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy @@ -8,6 +8,7 @@ import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService +import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionServiceImpl import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl import org.apache.lucene.analysis.Analyzer @@ -29,7 +30,7 @@ import javax.persistence.EntityManager * A highly unnecessary test so that I can check to make sure that persistence is correct for the model */ @DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, InternationalizationConfiguration, Config]) +@ContextConfiguration(classes=[CoreShibUiConfiguration, InternationalizationConfiguration, LocalConfig]) @EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) @EntityScan("edu.internet2.tier.shibboleth.admin.ui") @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) @@ -37,6 +38,12 @@ class EntityDescriptorRepositoryTest extends Specification { @Autowired EntityDescriptorRepository entityDescriptorRepository + @Autowired + private CustomEntityAttributeDefinitionRepository repository; + + @Autowired + CustomEntityAttributeFilterValueRepository customEntityAttributeFilterValueRepository; + @Autowired EntityManager entityManager @@ -86,7 +93,7 @@ class EntityDescriptorRepositoryTest extends Specification { } @TestConfiguration - static class Config { + static class LocalConfig { @Bean MetadataResolver metadataResolver() { new OpenSamlChainingMetadataResolver().with { @@ -100,5 +107,15 @@ class EntityDescriptorRepositoryTest extends Specification { Analyzer analyzer() { return new EnglishAnalyzer() } + + @Bean + CustomEntityAttributesDefinitionServiceImpl ceadService() { + new CustomEntityAttributesDefinitionServiceImpl().with { + it.entityManager = entityManager + it.repository = repository + it.customEntityAttributeFilterValueRepository = customEntityAttributeFilterValueRepository + return it + } + } } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy index 110ebffc4..31cec75b2 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy @@ -30,7 +30,7 @@ import spock.lang.Specification import static edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers.* @DataJpaTest -@ContextConfiguration(classes = [CoreShibUiConfiguration, SearchConfiguration, InternationalizationConfiguration, TestConfig]) +@ContextConfiguration(classes = [CoreShibUiConfiguration, SearchConfiguration, InternationalizationConfiguration, edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration ,LocalConfig]) @EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) @EntityScan("edu.internet2.tier.shibboleth.admin.ui") class IncommonJPAMetadataResolverServiceImplTests extends Specification { @@ -106,7 +106,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification { //TODO: check that this configuration is sufficient @TestConfiguration - static class TestConfig { + static class LocalConfig { @Autowired OpenSamlObjects openSamlObjects diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy index 9470b6046..3ab2154ea 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy @@ -51,7 +51,7 @@ import spock.lang.Unroll import static edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers.generatedXmlIsTheSameAsExpectedXml @DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, MetadataResolverConverterConfiguration, SearchConfiguration, InternationalizationConfiguration, PlaceholderResolverComponentsConfiguration, Config]) +@ContextConfiguration(classes=[CoreShibUiConfiguration, MetadataResolverConverterConfiguration, SearchConfiguration, InternationalizationConfiguration, PlaceholderResolverComponentsConfiguration, edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration ,Config]) @EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) @EntityScan("edu.internet2.tier.shibboleth.admin.ui") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) From d670d3a8308db338100c2099c61373303005c6ce Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 8 Jun 2021 11:46:50 -0700 Subject: [PATCH 03/51] SHIBUI-1788 Adding testing to validate callback to the configuration is updated properly when the definitions are changed --- .../CustomPropertiesConfiguration.java | 61 +++++++----- ...stomEntityAttributesDefinitionService.java | 2 + ...EntityAttributesDefinitionServiceImpl.java | 27 +++++- ...tomEntityAttributesDefinitionListener.java | 5 + .../CustomPropertiesConfigurationTests.groovy | 93 +++++++++++++++++++ .../ui/configuration/TestConfiguration.groovy | 3 + 6 files changed, 163 insertions(+), 28 deletions(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ICustomEntityAttributesDefinitionListener.java create mode 100644 backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfigurationTests.groovy 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 b1bce979f..a1835932d 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 @@ -3,10 +3,10 @@ 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 edu.internet2.tier.shibboleth.admin.ui.service.ICustomEntityAttributesDefinitionListener; 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; @@ -18,7 +18,7 @@ @Configuration @ConfigurationProperties(prefix = "custom") -public class CustomPropertiesConfiguration { +public class CustomPropertiesConfiguration implements ICustomEntityAttributesDefinitionListener { private List> attributes = new ArrayList<>(); private CustomEntityAttributesDefinitionService ceadService; @@ -27,22 +27,53 @@ public class CustomPropertiesConfiguration { private List overridesFromConfigFile = new ArrayList<>(); - public List> getAttributes() { - return attributes; + private void buildRelyingPartyOverrides() { + // Start over with a clean map and get the CustomEntityAttributesDefinitions from the DB + overrides = new HashMap<>(); + ceadService.getAllDefinitions().forEach(def -> overrides.put(def.getName(), def)); + + // We only want to add to an override from the config file if the incoming override (by name) isn't already in + // the list of overrides (ie DB > file config) + for(RelyingPartyOverrideProperty rpop : this.overridesFromConfigFile) { + if (!this.overrides.containsKey(rpop.getName())) { + this.overrides.put(rpop.getName(), rpop); + } + } + } + + /** + * We don't know what change occurred, so the easiest thing to do is just rebuild our map of overrides. + * (especially since the small occurrence of this and number of items makes doing this ok perf-wise). + */ + @Override + public void customEntityAttributesDefinitionChangeOccurred() { + buildRelyingPartyOverrides(); } + public List> getAttributes() { + return attributes; + } + public List getOverrides() { return new ArrayList<>(overrides.values()); } + @PostConstruct + public void postConstruct() { + // Register with service to get the updates when changes are made to the DB definitions + ceadService.addCustomEntityAttributesDefinitionListener(this); + + // Make sure we have the right data + buildRelyingPartyOverrides(); + } + public void setAttributes(List> attributes) { this.attributes = attributes; - } - + } + @Autowired public void setCeadService(CustomEntityAttributesDefinitionService ceadService) { this.ceadService = ceadService; - } /** @@ -51,20 +82,4 @@ public void setCeadService(CustomEntityAttributesDefinitionService ceadService) 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(); - } - - 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/service/CustomEntityAttributesDefinitionService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java index 4087ad221..1ec6d772d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java @@ -6,6 +6,8 @@ public interface CustomEntityAttributesDefinitionService { + void addCustomEntityAttributesDefinitionListener(ICustomEntityAttributesDefinitionListener listener); + CustomEntityAttributeDefinition createOrUpdateDefinition(CustomEntityAttributeDefinition definition); void deleteDefinition(CustomEntityAttributeDefinition definition); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java index c164c7f01..dd1000736 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.service; +import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; @@ -7,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.CustomEntityAttributeFilterValue; @@ -16,21 +18,32 @@ @Service @Primary public class CustomEntityAttributesDefinitionServiceImpl implements CustomEntityAttributesDefinitionService { - @Autowired - private CustomEntityAttributeDefinitionRepository repository; - @Autowired CustomEntityAttributeFilterValueRepository customEntityAttributeFilterValueRepository; @Autowired EntityManager entityManager; + + private List listeners = new ArrayList<>(); + @Autowired + private CustomEntityAttributeDefinitionRepository repository; + @Override - public CustomEntityAttributeDefinition createOrUpdateDefinition(CustomEntityAttributeDefinition definition) { - return repository.save(definition); + public void addCustomEntityAttributesDefinitionListener(ICustomEntityAttributesDefinitionListener listener) { + listeners.add(listener); } @Override + @Transactional + public CustomEntityAttributeDefinition createOrUpdateDefinition(CustomEntityAttributeDefinition definition) { + CustomEntityAttributeDefinition result = repository.save(definition); + notifyListeners(); + return result; + } + + @Override + @Transactional public void deleteDefinition(CustomEntityAttributeDefinition definition) { // must remove any CustomEntityAttributeFilterValues first to avoid integrity constraint issues List customEntityValues = customEntityAttributeFilterValueRepository.findAllByCustomEntityAttributeDefinition(definition); @@ -41,6 +54,7 @@ public void deleteDefinition(CustomEntityAttributeDefinition definition) { }); CustomEntityAttributeDefinition entityToRemove = repository.findByName(definition.getName()); repository.delete(entityToRemove); + notifyListeners(); } @Override @@ -53,4 +67,7 @@ public List getAllDefinitions() { return repository.findAll(); } + private void notifyListeners() { + listeners.forEach(l -> l.customEntityAttributesDefinitionChangeOccurred()); + } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ICustomEntityAttributesDefinitionListener.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ICustomEntityAttributesDefinitionListener.java new file mode 100644 index 000000000..4ae2d2f27 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ICustomEntityAttributesDefinitionListener.java @@ -0,0 +1,5 @@ +package edu.internet2.tier.shibboleth.admin.ui.service; + +public interface ICustomEntityAttributesDefinitionListener { + void customEntityAttributesDefinitionChangeOccurred(); +} diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfigurationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfigurationTests.groovy new file mode 100644 index 000000000..e90e7974e --- /dev/null +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfigurationTests.groovy @@ -0,0 +1,93 @@ +package edu.internet2.tier.shibboleth.admin.ui.configuration + +import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration +import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition +import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects +import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeDefinitionRepository +import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeFilterValueRepository +import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository +import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository +import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService +import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionServiceImpl + +import javax.persistence.EntityManager + +import org.opensaml.saml.metadata.resolver.MetadataResolver +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean +import org.springframework.data.jpa.repository.config.EnableJpaRepositories +import org.springframework.security.core.userdetails.UsernameNotFoundException +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.ContextConfiguration + +import spock.lang.Specification + +/** + * Tests for edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration + */ +@DataJpaTest +@ContextConfiguration(classes=[CoreShibUiConfiguration, InternationalizationConfiguration, SearchConfiguration, edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration]) +@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) +@EntityScan("edu.internet2.tier.shibboleth.admin.ui") +class CustomPropertiesConfigurationTests extends Specification { + + @Autowired + @Qualifier(value="customPropertiesConfiguration") + CustomPropertiesConfiguration configUnderTest + + @Autowired + CustomEntityAttributesDefinitionService ceadService + + @Autowired + CustomEntityAttributeDefinitionRepository repository; + + @Autowired + EntityManager entityManager + + def "Updating Custom Entity Attribute Definitions will update the CustomPropertiesConfiguration automatically"() { + given: 'Test defaults loaded (ie no CEADs in DB)' + + expect: + ceadService.getAllDefinitions().size() == 0 + configUnderTest.getOverrides().size() == 10 + + def ca = new CustomEntityAttributeDefinition().with { + it.name = "newDefName" + it.attributeType = "STRING" + it.defaultValue = "foobar" + it + } + + ceadService.createOrUpdateDefinition(ca) + entityManager.flush() + + ceadService.getAllDefinitions().size() == 1 + configUnderTest.getOverrides().size() == 11 + + def ca2 = new CustomEntityAttributeDefinition().with { + it.name = "newDefName2" + it.attributeType = "STRING" + it.defaultValue = "foobar2" + it + } + + ceadService.createOrUpdateDefinition(ca2) + entityManager.flush() + + ceadService.getAllDefinitions().size() == 2 + configUnderTest.getOverrides().size() == 12 + + ceadService.deleteDefinition(ca) + entityManager.flush() + + ceadService.getAllDefinitions().size() == 1 + configUnderTest.getOverrides().size() == 11 + } +} diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy index 4a6e492de..4e6e78db8 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy @@ -32,6 +32,9 @@ import org.springframework.data.domain.AuditorAware import org.springframework.mail.javamail.JavaMailSender import org.springframework.mail.javamail.JavaMailSenderImpl +/** + * NOT A TEST - this is configuration FOR tests + */ @Configuration class TestConfiguration { @Autowired From 10ee2a64f9c34fbb32843d75bfb146b3eda3a71a Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 8 Jun 2021 12:11:18 -0700 Subject: [PATCH 04/51] SHIBUI-1788 Handle conversion of custom entity attributes to XML objects by including the types supported by the UI --- .../util/ModelRepresentationConversions.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) 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 909fa8ee6..4ef0c3080 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 @@ -110,15 +110,20 @@ public static Object getOverrideFromAttribute(Attribute attribute) { return Boolean.valueOf(relyingPartyOverrideProperty.getInvert()) ^ Boolean.valueOf(((XSBoolean) attributeValues.get(0)).getStoredValue()); } case INTEGER: + case LONG: return ((XSInteger) attributeValues.get(0)).getValue(); case STRING: + case DOUBLE: + case DURATION: + case SPRING_BEAN_ID: if (attributeValues.get(0) instanceof XSAny) { return ((XSAny) attributeValues.get(0)).getTextContent(); } else { return ((XSString) attributeValues.get(0)).getValue(); } - case LIST: case SET: + case LIST: + case SELECTION_LIST: return attributeValues.stream().map(it -> ((XSString) it).getValue()).collect(Collectors.toList()); default: throw new UnsupportedOperationException("An unsupported persist type was specified (" + relyingPartyOverrideProperty.getPersistType() + ")!"); @@ -193,19 +198,20 @@ public static Attribute getAttributeFromObjectAndRelyingPartyOverrideProperty(Ob } return null; case INTEGER: + case LONG: return ATTRIBUTE_UTILITY.createAttributeWithIntegerValue(overrideProperty.getAttributeName(), overrideProperty.getAttributeFriendlyName(), Integer.valueOf((String) o)); case STRING: + case DOUBLE: + case DURATION: + case SPRING_BEAN_ID: return ATTRIBUTE_UTILITY.createAttributeWithStringValues(overrideProperty.getAttributeName(), overrideProperty.getAttributeFriendlyName(), (String) o); case SET: - return ATTRIBUTE_UTILITY.createAttributeWithStringValues(overrideProperty.getAttributeName(), - overrideProperty.getAttributeFriendlyName(), - (List) o); - case LIST: + case SELECTION_LIST: return ATTRIBUTE_UTILITY.createAttributeWithStringValues(overrideProperty.getAttributeName(), overrideProperty.getAttributeFriendlyName(), (List) o); @@ -215,11 +221,19 @@ public static Attribute getAttributeFromObjectAndRelyingPartyOverrideProperty(Ob } } + // These are the types for which there are org.opensaml.core.xml.schema.XS[TYPE] definitions that we are supporting + // The ones with comments are the types supported by the Custom Entity Attribute UI and are mapped accordingly + // @see edu.internet2.tier.shibboleth.admin.ui.domain.CustomAttributeType (part of IRelyingPartyOverrideProperty) public enum AttributeTypes { BOOLEAN, INTEGER, STRING, SET, - LIST + LIST, + DOUBLE, // no org.opensaml.core.xml.schema.XSTYPE - will treat as STRING + DURATION, // no org.opensaml.core.xml.schema.XSTYPE - will treat as STRING + LONG, // no org.opensaml.core.xml.schema.XSTYPE - will treat as INTEGER for generating XML + SELECTION_LIST, // another name for LIST + SPRING_BEAN_ID // treat as STRING } } From 0ce8050ce27427e57bf7c2ef98abc0e6c97820b1 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 8 Jun 2021 12:36:24 -0700 Subject: [PATCH 05/51] SHIBUI-1788 Clarification/change to comment --- .../admin/ui/domain/CustomEntityAttributeDefinition.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 92111f713..f049787a8 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 @@ -74,7 +74,8 @@ public void setDefaultValues(Set defaultValues) { @Override public void setPersistType(String persistType) { - // WHAT TO DO? This is "attributeType", but need to match up to AttributeTypes in ModelRepresentationConversions?? + // This is "attributeType", but this is only here to comply with the interface, we don't intend for this to be + // used, we want to match up against the actual ENUM types of CustomAttributeType } @Override From 0f90717cbf792a1bfbf450c222eab963b9ec1cc3 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 9 Jun 2021 15:03:35 -0700 Subject: [PATCH 06/51] NOJIRA Updated hibernate to current final release to fix issue with POSTGRES and clobs (hibernate bug in pre-5.4 versions) --- backend/build.gradle | 2 +- gradle.properties | 2 +- testbed/postgres/conf/.gitignore | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 testbed/postgres/conf/.gitignore diff --git a/backend/build.gradle b/backend/build.gradle index 9744cbf84..180630e68 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -156,7 +156,7 @@ dependencies { runtimeOnly 'org.glassfish.jaxb:jaxb-runtime:2.3.0' compile "com.h2database:h2" - runtimeOnly "org.postgresql:postgresql" + runtimeOnly "org.postgresql:postgresql:42.2.20" runtimeOnly 'org.mariadb.jdbc:mariadb-java-client:2.2.0' runtimeOnly 'mysql:mysql-connector-java:5.1.48' diff --git a/gradle.properties b/gradle.properties index ca31f82be..056038aae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ opensaml.version=3.4.3 spring-boot.version=2.4.2 -hibernate.version=5.3.14.Final +hibernate.version=5.5.0.Final lucene.version=8.1.1 diff --git a/testbed/postgres/conf/.gitignore b/testbed/postgres/conf/.gitignore new file mode 100644 index 000000000..f3e10820d --- /dev/null +++ b/testbed/postgres/conf/.gitignore @@ -0,0 +1 @@ +/charles.yml From 8bb03ef61e738fa35abe5d1747297e3e4b17b5f2 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 9 Jun 2021 17:21:13 -0700 Subject: [PATCH 07/51] SHIBUI-1946 Added a flag so that the front end would get the list of custom entity attribute definitions AND the list of RelyingPartyOverrideProperties (from any config file) together and be able to differentiate which ones from the DB and which were from a file. --- ...CustomEntityAttributesDefinitionsController.java | 13 +++++++++---- .../ui/domain/CustomEntityAttributeDefinition.java | 5 +++++ .../ui/domain/IRelyingPartyOverrideProperty.java | 2 ++ .../ui/domain/RelyingPartyOverrideProperty.java | 5 +++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java index 56183dfdb..33811f28e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java @@ -1,7 +1,5 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; -import java.util.List; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -17,8 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration; import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; -import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor; import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService; @Controller @@ -26,6 +24,9 @@ public class CustomEntityAttributesDefinitionsController { @Autowired private CustomEntityAttributesDefinitionService caService; + + @Autowired + private CustomPropertiesConfiguration customPropertiesConfiguration; @PostMapping("/attribute") @Transactional @@ -63,10 +64,14 @@ public ResponseEntity update(@RequestBody CustomEntityAttributeDefinition def return ResponseEntity.ok(result); } + /** + * @return List of IRelyingPartyOverrideProperty objects. This will include all of the CustomEntityAttributeDefinition + * and the RelyingPartyOverrideProperties from any configuration file that was read in at startup. + */ @GetMapping("/attributes") @Transactional(readOnly = true) public ResponseEntity getAll() { - return ResponseEntity.ok(caService.getAllDefinitions()); + return ResponseEntity.ok(customPropertiesConfiguration.getOverrides()); } @GetMapping("/attribute/{name}") 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 f049787a8..d5450e31a 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 @@ -56,6 +56,11 @@ public Set getDefaultValues() { return customAttrListDefinitions; } + @Override + public Boolean getFromConfigFile() { + return Boolean.FALSE; + } + @Override public String getPersistType() { return attributeType.toString(); 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 index 0c700a1af..8a217f36c 100644 --- 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 @@ -19,6 +19,8 @@ public interface IRelyingPartyOverrideProperty { public String getDisplayType(); + public Boolean getFromConfigFile(); + public String getHelpText(); public String getInvert(); 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 1cc75c98b..3a8a85ac6 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 @@ -24,4 +24,9 @@ public class RelyingPartyOverrideProperty implements IRelyingPartyOverrideProper private String name; private String persistType; private String persistValue; + + @Override + public Boolean getFromConfigFile() { + return Boolean.TRUE; + } } \ No newline at end of file From 78ae4d027b7f3b133cd281fc555e3aad44cc4bd1 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 10 Jun 2021 10:33:35 -0700 Subject: [PATCH 08/51] SHIBUI-1788 Refactored tests to handle the multiple beans found issue and removed the @Primary annotation from the service class --- .../ui/service/CustomEntityAttributesDefinitionServiceImpl.java | 1 - .../shibboleth/admin/ui/configuration/TestConfiguration.groovy | 2 +- .../admin/ui/repository/EntityDescriptorRepositoryTest.groovy | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java index dd1000736..33e660077 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java @@ -16,7 +16,6 @@ import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeFilterValueRepository; @Service -@Primary public class CustomEntityAttributesDefinitionServiceImpl implements CustomEntityAttributesDefinitionService { @Autowired CustomEntityAttributeFilterValueRepository customEntityAttributeFilterValueRepository; diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy index 4e6e78db8..775103ac0 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy @@ -59,7 +59,7 @@ class TestConfiguration { } @Bean - CustomEntityAttributesDefinitionServiceImpl ceadService() { + CustomEntityAttributesDefinitionServiceImpl customEntityAttributesDefinitionServiceImpl() { new CustomEntityAttributesDefinitionServiceImpl().with { it.entityManager = entityManager it.repository = repository diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy index 5fab1b0a2..282961b79 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy @@ -109,7 +109,7 @@ class EntityDescriptorRepositoryTest extends Specification { } @Bean - CustomEntityAttributesDefinitionServiceImpl ceadService() { + CustomEntityAttributesDefinitionServiceImpl customEntityAttributesDefinitionServiceImpl() { new CustomEntityAttributesDefinitionServiceImpl().with { it.entityManager = entityManager it.repository = repository From e3e0ca303a690cb454721655d827a3d3bdc6bd4f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 10 Jun 2021 11:11:16 -0700 Subject: [PATCH 09/51] SHIBUI-1788 Refactored event notification to use Spring event model --- .../CustomPropertiesConfiguration.java | 28 +- ...stomEntityAttributesDefinitionService.java | 2 - ...EntityAttributesDefinitionServiceImpl.java | 20 +- ...tomEntityAttributesDefinitionListener.java | 5 - ui/package-lock.json | 267 +++++++++--------- 5 files changed, 159 insertions(+), 163 deletions(-) delete mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ICustomEntityAttributesDefinitionListener.java 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 a1835932d..5b73b1fb1 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 @@ -3,10 +3,11 @@ 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 edu.internet2.tier.shibboleth.admin.ui.service.ICustomEntityAttributesDefinitionListener; +import edu.internet2.tier.shibboleth.admin.ui.service.events.CustomEntityAttributeDefinitionChangeEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; @@ -18,7 +19,7 @@ @Configuration @ConfigurationProperties(prefix = "custom") -public class CustomPropertiesConfiguration implements ICustomEntityAttributesDefinitionListener { +public class CustomPropertiesConfiguration implements ApplicationListener { private List> attributes = new ArrayList<>(); private CustomEntityAttributesDefinitionService ceadService; @@ -41,15 +42,6 @@ private void buildRelyingPartyOverrides() { } } - /** - * We don't know what change occurred, so the easiest thing to do is just rebuild our map of overrides. - * (especially since the small occurrence of this and number of items makes doing this ok perf-wise). - */ - @Override - public void customEntityAttributesDefinitionChangeOccurred() { - buildRelyingPartyOverrides(); - } - public List> getAttributes() { return attributes; } @@ -58,15 +50,21 @@ public List getOverrides() { return new ArrayList<>(overrides.values()); } + /** + * We don't know what change occurred, so the easiest thing to do is just rebuild our map of overrides. + * (especially since the small occurrence of this and number of items makes doing this ok perf-wise). + */ + @Override + public void onApplicationEvent(CustomEntityAttributeDefinitionChangeEvent arg0) { + buildRelyingPartyOverrides(); + } + @PostConstruct public void postConstruct() { - // Register with service to get the updates when changes are made to the DB definitions - ceadService.addCustomEntityAttributesDefinitionListener(this); - // Make sure we have the right data buildRelyingPartyOverrides(); } - + public void setAttributes(List> attributes) { this.attributes = attributes; } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java index 1ec6d772d..4087ad221 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java @@ -6,8 +6,6 @@ public interface CustomEntityAttributesDefinitionService { - void addCustomEntityAttributesDefinitionListener(ICustomEntityAttributesDefinitionListener listener); - CustomEntityAttributeDefinition createOrUpdateDefinition(CustomEntityAttributeDefinition definition); void deleteDefinition(CustomEntityAttributeDefinition definition); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java index 33e660077..90438164a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java @@ -1,12 +1,11 @@ package edu.internet2.tier.shibboleth.admin.ui.service; -import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Primary; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,25 +13,22 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.CustomEntityAttributeFilterValue; import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeDefinitionRepository; import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeFilterValueRepository; +import edu.internet2.tier.shibboleth.admin.ui.service.events.CustomEntityAttributeDefinitionChangeEvent; @Service -public class CustomEntityAttributesDefinitionServiceImpl implements CustomEntityAttributesDefinitionService { +public class CustomEntityAttributesDefinitionServiceImpl implements CustomEntityAttributesDefinitionService { + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + @Autowired CustomEntityAttributeFilterValueRepository customEntityAttributeFilterValueRepository; @Autowired EntityManager entityManager; - private List listeners = new ArrayList<>(); - @Autowired private CustomEntityAttributeDefinitionRepository repository; - - @Override - public void addCustomEntityAttributesDefinitionListener(ICustomEntityAttributesDefinitionListener listener) { - listeners.add(listener); - } - + @Override @Transactional public CustomEntityAttributeDefinition createOrUpdateDefinition(CustomEntityAttributeDefinition definition) { @@ -67,6 +63,6 @@ public List getAllDefinitions() { } private void notifyListeners() { - listeners.forEach(l -> l.customEntityAttributesDefinitionChangeOccurred()); + applicationEventPublisher.publishEvent(new CustomEntityAttributeDefinitionChangeEvent(this)); } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ICustomEntityAttributesDefinitionListener.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ICustomEntityAttributesDefinitionListener.java deleted file mode 100644 index 4ae2d2f27..000000000 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ICustomEntityAttributesDefinitionListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package edu.internet2.tier.shibboleth.admin.ui.service; - -public interface ICustomEntityAttributesDefinitionListener { - void customEntityAttributesDefinitionChangeOccurred(); -} diff --git a/ui/package-lock.json b/ui/package-lock.json index 516c84556..f13e4df3b 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1323,6 +1323,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.10", @@ -1345,6 +1346,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -1353,6 +1355,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -1363,6 +1366,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -1373,6 +1377,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -1381,6 +1386,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -1389,6 +1395,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -1398,12 +1405,14 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -1414,6 +1423,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -1430,6 +1440,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1440,6 +1451,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -1448,6 +1460,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -1455,12 +1468,14 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -1867,6 +1882,7 @@ "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, "requires": { "@babel/types": "^7.12.7" }, @@ -1875,6 +1891,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1887,6 +1904,7 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, "requires": { "@babel/types": "^7.12.5" }, @@ -1895,6 +1913,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1907,6 +1926,7 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.1", "@babel/helper-replace-supers": "^7.12.1", @@ -1923,6 +1943,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -1931,6 +1952,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -1941,6 +1963,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -1951,6 +1974,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -1959,6 +1983,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -1967,6 +1992,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -1976,12 +2002,14 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -1992,6 +2020,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2008,6 +2037,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2018,6 +2048,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -2025,12 +2056,14 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -2038,6 +2071,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, "requires": { "@babel/types": "^7.12.10" }, @@ -2046,6 +2080,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2088,6 +2123,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.12.7", "@babel/helper-optimise-call-expression": "^7.12.10", @@ -2099,6 +2135,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2107,6 +2144,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -2117,6 +2155,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -2127,6 +2166,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -2135,6 +2175,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -2143,6 +2184,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2152,12 +2194,14 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2168,6 +2212,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2184,6 +2229,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2194,6 +2240,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -2201,12 +2248,14 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -2214,6 +2263,7 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, "requires": { "@babel/types": "^7.12.1" }, @@ -2222,6 +2272,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2277,7 +2328,8 @@ "@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true }, "@babel/helper-validator-option": { "version": "7.12.11", @@ -2429,6 +2481,7 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "dev": true, "requires": { "@babel/template": "^7.10.4", "@babel/traverse": "^7.12.5", @@ -2439,6 +2492,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2447,6 +2501,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -2457,6 +2512,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -2467,6 +2523,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -2475,6 +2532,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -2483,6 +2541,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2492,12 +2551,14 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2508,6 +2569,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2524,6 +2586,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2534,6 +2597,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -2541,12 +2605,14 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -3548,7 +3614,8 @@ "@istanbuljs/schema": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true }, "@jsdevtools/coverage-istanbul-loader": { "version": "3.0.5", @@ -4533,6 +4600,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -4839,7 +4907,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base": { "version": "0.11.2", @@ -5139,6 +5208,7 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5533,6 +5603,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", + "dev": true, "requires": { "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", @@ -5910,6 +5981,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, "requires": { "color-name": "^1.1.1" } @@ -5917,7 +5989,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "color-string": { "version": "1.5.4", @@ -6062,7 +6135,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "concat-stream": { "version": "1.6.0", @@ -7901,7 +7975,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "eslint-scope": { "version": "4.0.3", @@ -8843,7 +8918,8 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true }, "get-caller-file": { "version": "2.0.5", @@ -8932,7 +9008,8 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, "globby": { "version": "11.0.2", @@ -9078,7 +9155,8 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true }, "has-symbols": { "version": "1.0.0", @@ -9270,7 +9348,8 @@ "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, "http-cache-semantics": { "version": "4.1.0", @@ -10007,12 +10086,14 @@ "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true }, "istanbul-lib-instrument": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, "requires": { "@babel/core": "^7.7.5", "@istanbuljs/schema": "^0.1.2", @@ -10023,7 +10104,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -10031,6 +10113,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", @@ -10040,96 +10123,17 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { - "glob": "^7.1.3" + "has-flag": "^4.0.0" } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -10137,6 +10141,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -10213,7 +10218,8 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "js-yaml": { "version": "3.14.1", @@ -10277,6 +10283,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -10620,6 +10627,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz", "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==", + "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^4.0.1", @@ -10633,6 +10641,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -10641,6 +10650,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -10650,28 +10660,17 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, - "karma-coverage-istanbul-reporter": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz", - "integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^3.0.2", - "minimatch": "^3.0.4" - } - }, "karma-jasmine": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.1.tgz", @@ -10909,7 +10908,8 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true }, "lodash.get": { "version": "4.4.2", @@ -11042,6 +11042,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, "requires": { "semver": "^6.0.0" }, @@ -11049,7 +11050,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -11413,6 +11415,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -11420,7 +11423,8 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "minipass": { "version": "3.1.3", @@ -16092,7 +16096,8 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true }, "safe-regex": { "version": "1.1.0", @@ -16247,7 +16252,8 @@ "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true }, "semver-dsl": { "version": "1.0.1", @@ -16836,7 +16842,8 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "source-map-loader": { "version": "1.1.3", @@ -17520,6 +17527,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { "has-flag": "^2.0.0" } @@ -17941,7 +17949,8 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true }, "to-object-path": { "version": "0.3.0", From c1a909b5b22221938f1d5d07c3fd8c3e68466bd7 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 10 Jun 2021 11:12:00 -0700 Subject: [PATCH 10/51] SHIBUI-1788 missed add from commit --- ...ustomEntityAttributeDefinitionChangeEvent.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/events/CustomEntityAttributeDefinitionChangeEvent.java diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/events/CustomEntityAttributeDefinitionChangeEvent.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/events/CustomEntityAttributeDefinitionChangeEvent.java new file mode 100644 index 000000000..f0495f615 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/events/CustomEntityAttributeDefinitionChangeEvent.java @@ -0,0 +1,15 @@ +package edu.internet2.tier.shibboleth.admin.ui.service.events; + +import org.springframework.context.ApplicationEvent; + +/** + * The event could be any operation (new, update, delete). + */ +public class CustomEntityAttributeDefinitionChangeEvent extends ApplicationEvent { + private static final long serialVersionUID = 1L; + + public CustomEntityAttributeDefinitionChangeEvent(Object source) { + super(source); + } + +} From 581e4c02db13c42cc9b88675686d53bea5ecae0f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 10 Jun 2021 11:18:36 -0700 Subject: [PATCH 11/51] SHIBUI-1788 replacing with previous --- ui/package-lock.json | 267 +++++++++++++++++++++---------------------- 1 file changed, 129 insertions(+), 138 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index f13e4df3b..516c84556 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1323,7 +1323,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.10", @@ -1346,7 +1345,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -1355,7 +1353,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -1366,7 +1363,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -1377,7 +1373,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -1386,7 +1381,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -1395,7 +1389,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -1405,14 +1398,12 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -1423,7 +1414,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -1440,7 +1430,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1451,7 +1440,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -1460,7 +1448,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -1468,14 +1455,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -1882,7 +1867,6 @@ "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", - "dev": true, "requires": { "@babel/types": "^7.12.7" }, @@ -1891,7 +1875,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1904,7 +1887,6 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dev": true, "requires": { "@babel/types": "^7.12.5" }, @@ -1913,7 +1895,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1926,7 +1907,6 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.1", "@babel/helper-replace-supers": "^7.12.1", @@ -1943,7 +1923,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -1952,7 +1931,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -1963,7 +1941,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -1974,7 +1951,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -1983,7 +1959,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -1992,7 +1967,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2002,14 +1976,12 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2020,7 +1992,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2037,7 +2008,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2048,7 +2018,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -2056,14 +2025,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -2071,7 +2038,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "dev": true, "requires": { "@babel/types": "^7.12.10" }, @@ -2080,7 +2046,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2123,7 +2088,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", - "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.12.7", "@babel/helper-optimise-call-expression": "^7.12.10", @@ -2135,7 +2099,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2144,7 +2107,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -2155,7 +2117,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -2166,7 +2127,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -2175,7 +2135,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -2184,7 +2143,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2194,14 +2152,12 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2212,7 +2168,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2229,7 +2184,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2240,7 +2194,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -2248,14 +2201,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -2263,7 +2214,6 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", - "dev": true, "requires": { "@babel/types": "^7.12.1" }, @@ -2272,7 +2222,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2328,8 +2277,7 @@ "@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" }, "@babel/helper-validator-option": { "version": "7.12.11", @@ -2481,7 +2429,6 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", - "dev": true, "requires": { "@babel/template": "^7.10.4", "@babel/traverse": "^7.12.5", @@ -2492,7 +2439,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2501,7 +2447,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -2512,7 +2457,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -2523,7 +2467,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -2532,7 +2475,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -2541,7 +2483,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2551,14 +2492,12 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2569,7 +2508,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2586,7 +2524,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2597,7 +2534,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -2605,14 +2541,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -3614,8 +3548,7 @@ "@istanbuljs/schema": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" }, "@jsdevtools/coverage-istanbul-loader": { "version": "3.0.5", @@ -4600,7 +4533,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -4907,8 +4839,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", @@ -5208,7 +5139,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5603,7 +5533,6 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", - "dev": true, "requires": { "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", @@ -5981,7 +5910,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, "requires": { "color-name": "^1.1.1" } @@ -5989,8 +5917,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "1.5.4", @@ -6135,8 +6062,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.0", @@ -7975,8 +7901,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint-scope": { "version": "4.0.3", @@ -8918,8 +8843,7 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-caller-file": { "version": "2.0.5", @@ -9008,8 +8932,7 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "globby": { "version": "11.0.2", @@ -9155,8 +9078,7 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" }, "has-symbols": { "version": "1.0.0", @@ -9348,8 +9270,7 @@ "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "http-cache-semantics": { "version": "4.1.0", @@ -10086,14 +10007,12 @@ "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" }, "istanbul-lib-instrument": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, "requires": { "@babel/core": "^7.7.5", "@istanbuljs/schema": "^0.1.2", @@ -10104,8 +10023,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -10113,7 +10031,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", @@ -10123,25 +10040,103 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } } } }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "istanbul-reports": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -10218,8 +10213,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.14.1", @@ -10283,7 +10277,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, "requires": { "minimist": "^1.2.5" } @@ -10627,7 +10620,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz", "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==", - "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^4.0.1", @@ -10641,7 +10633,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -10650,7 +10641,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -10660,17 +10650,28 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, + "karma-coverage-istanbul-reporter": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz", + "integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^3.0.2", + "minimatch": "^3.0.4" + } + }, "karma-jasmine": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.1.tgz", @@ -10908,8 +10909,7 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.get": { "version": "4.4.2", @@ -11042,7 +11042,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, "requires": { "semver": "^6.0.0" }, @@ -11050,8 +11049,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -11415,7 +11413,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -11423,8 +11420,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { "version": "3.1.3", @@ -16096,8 +16092,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "safe-regex": { "version": "1.1.0", @@ -16252,8 +16247,7 @@ "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" }, "semver-dsl": { "version": "1.0.1", @@ -16842,8 +16836,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-loader": { "version": "1.1.3", @@ -17527,7 +17520,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, "requires": { "has-flag": "^2.0.0" } @@ -17949,8 +17941,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-object-path": { "version": "0.3.0", From cfcb8ab4b72292ad0a0b03933c96958dc13cbdd4 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 14 Jun 2021 10:13:31 -0700 Subject: [PATCH 12/51] Added custom entity attribute fields --- .../main/resources/i18n/messages.properties | 7 +++++ .../schema/attribute/attribute.schema.json | 26 ++++++++++++++++++- .../attribute/CustomAttributeDefinition.js | 3 +++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 50049f5cb..802f36372 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -140,11 +140,18 @@ label.entity-attribute-default=Default Value tooltip.entity-attribute-default=Default Value label.entity-attribute-list-options=List options tooltip.entity-attribute-list-options=List options +label.entity-attribute-friendly-name=Friendly name +tooltip.entity-attribute-friendly-name=Friendly name +label.entity-attribute-attr-name=Attribute name +tooltip.entity-attribute-attr-name=This is normally a uri or urn +label.entity-attribute-display-name=Display name +tooltip.entity-attribute-display-name=Display name label.entity-attributes=Entity Attributes label.custom-entity-attributes=Custom Entity Attributes label.help-text=Help text label.default-value=Default Value +label.new-attribute=New Custom Entity Attribute label.metadata-source=Metadata Source label.metadata-sources=Metadata Sources diff --git a/ui/public/assets/schema/attribute/attribute.schema.json b/ui/public/assets/schema/attribute/attribute.schema.json index cc99dc3a6..b821ed7bb 100644 --- a/ui/public/assets/schema/attribute/attribute.schema.json +++ b/ui/public/assets/schema/attribute/attribute.schema.json @@ -2,7 +2,10 @@ "type": "object", "required": [ "name", - "attributeType" + "attributeType", + "attributeFriendlyName", + "attributeName", + "displayName" ], "properties": { "name": { @@ -27,6 +30,27 @@ "value.list" ] }, + "attributeFriendlyName": { + "type": "string", + "title": "label.entity-attribute-friendly-name", + "description": "tooltip.entity-attribute-friendly-name", + "minLength": 1, + "maxLength": 255 + }, + "attributeName": { + "type": "string", + "title": "label.entity-attribute-attr-name", + "description": "tooltip.entity-attribute-attr-name", + "minLength": 1, + "maxLength": 255 + }, + "displayName": { + "type": "string", + "title": "label.entity-attribute-display-name", + "description": "tooltip.entity-attribute-display-name", + "minLength": 1, + "maxLength": 255 + }, "helpText": { "title": "label.entity-attribute-help", "description": "tooltip.entity-attribute-help", diff --git a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js index d04cfab6e..a5ea258c6 100644 --- a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js +++ b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js @@ -15,6 +15,9 @@ export const CustomAttributeDefinition = { fields: [ 'name', 'attributeType', + 'attributeName', + 'attributeFriendlyName', + 'displayName', 'helpText' ] }, From ebbbe1a28acb5841fc3390c566ff3c62c0674338 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 15 Jun 2021 10:13:28 -0700 Subject: [PATCH 13/51] SHIBUI-1788 Updates to incorporate the React changes to the UI with these changes --- .../service/JsonSchemaBuilderService.groovy | 7 +-- .../CustomEntityAttributeDefinition.java | 55 +++++++++---------- .../domain/IRelyingPartyOverrideProperty.java | 4 +- .../domain/RelyingPartyOverrideProperty.java | 14 ++++- 4 files changed, 46 insertions(+), 34 deletions(-) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy index b9eeb57c5..fa606f53b 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy @@ -29,8 +29,7 @@ class JsonSchemaBuilderService { def properties = [:] customPropertiesConfiguration.getOverrides().each { def property - if (it['displayType'] == 'list' - || it['displayType'] == 'set') { + if (it['displayType'] == 'list' || it['displayType'] == 'set' || it['displayType'] == 'selection_list') { property = [$ref: '#/definitions/' + it['name']] } else { property = @@ -46,13 +45,13 @@ class JsonSchemaBuilderService { void addRelyingPartyOverridesCollectionDefinitionsToJson(Object json) { customPropertiesConfiguration.getOverrides().stream().filter { - it -> it['displayType'] && (it['displayType'] == 'list' || it['displayType'] == 'set') + it -> it['displayType'] && (it['displayType'] == 'list' || it['displayType'] == 'set' || it['displayType'] == 'selection_list') }.each { def definition = [title : it['displayName'], description: it['helpText'], type : 'array', default : null] - if (it['displayType'] == 'set') { + if (it['displayType'] == 'set' || it['displayType'] == 'selection_list') { definition['uniqueItems'] = true } else if (it['displayType'] == 'list') { definition['uniqueItems'] = false 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 d5450e31a..adc9072fa 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 @@ -10,6 +10,8 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; import org.hibernate.envers.Audited; import lombok.Data; @@ -18,13 +20,9 @@ @Audited @Data public class CustomEntityAttributeDefinition implements IRelyingPartyOverrideProperty { - @Id - @Column(nullable = false) - String name; - @Column(name = "attribute_friendly_name", nullable = true) String attributeFriendlyName; - + @Column(name = "attribute_name", nullable = true) String attributeName; @@ -33,23 +31,31 @@ public class CustomEntityAttributeDefinition implements IRelyingPartyOverridePro @ElementCollection @CollectionTable(name = "custom_entity_attr_list_items", joinColumns = @JoinColumn(name = "name")) + @Fetch(FetchMode.JOIN) @Column(name = "value", nullable = false) Set customAttrListDefinitions = new HashSet<>(); - + @Column(name = "default_value", nullable = true) String defaultValue; - + @Column(name = "display_name", nullable = true) String displayName; - - @Column(name = "display_type", nullable = true) - String displayType; @Column(name = "help_text", nullable = true) String helpText; - + @Column(name = "invert", nullable = true) String invert; + + @Id + @Column(nullable = false) + String name; + + @Column(name = "persist_type", nullable = true) + String persistType; + + @Column(name = "persist_value", nullable = true) + String persistValue; @Override public Set getDefaultValues() { @@ -57,19 +63,19 @@ public Set getDefaultValues() { } @Override - public Boolean getFromConfigFile() { - return Boolean.FALSE; + public String getDisplayName() { + // This is here only to ensure proper functionality works until the full definition is revised with all the fields + return displayName == null ? "DEFAULTED to name: " + name : displayName; } @Override - public String getPersistType() { - return attributeType.toString(); + public String getDisplayType() { + return attributeType.name().toLowerCase(); } @Override - public String getPersistValue() { - // Definitions don't have a persist value, here to comply with the interface only - return null; + public Boolean getFromConfigFile() { + return Boolean.FALSE; } @Override @@ -78,14 +84,7 @@ public void setDefaultValues(Set defaultValues) { } @Override - public void setPersistType(String persistType) { - // This is "attributeType", but this is only here to comply with the interface, we don't intend for this to be - // used, we want to match up against the actual ENUM types of CustomAttributeType - } - - @Override - public void setPersistValue(String persistValue) { - // Definitions don't have a persist value, here to comply with the interface only - } - + public void setDisplayType(String displayType) { + // This is here to comply with the interface only and should not be used to change the value in this implementation + } } 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 index 8a217f36c..822d3ad28 100644 --- 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 @@ -10,7 +10,9 @@ public interface IRelyingPartyOverrideProperty { public String getAttributeFriendlyName(); public String getAttributeName(); - + + public CustomAttributeType getAttributeType(); + public String getDefaultValue(); public Set getDefaultValues(); 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 3a8a85ac6..4c8b9daa6 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 @@ -24,9 +24,21 @@ public class RelyingPartyOverrideProperty implements IRelyingPartyOverrideProper private String name; private String persistType; private String persistValue; - + @Override public Boolean getFromConfigFile() { return Boolean.TRUE; } + + @Override + public CustomAttributeType getAttributeType() { + switch (displayType) { + case ("set"): + case ("list"): + return CustomAttributeType.SELECTION_LIST; + default: + return CustomAttributeType.valueOf(displayType.toUpperCase()); + } + + } } \ No newline at end of file From efcf415010f7e59e46930966c7809b8026378f55 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 15 Jun 2021 11:57:43 -0700 Subject: [PATCH 14/51] SHIBUI-1788 Bug fix that allows the CEAD to be added to metadata source via the RelyingPartyOverride interface --- .../admin/ui/domain/CustomEntityAttributeDefinition.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 adc9072fa..0df210269 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 @@ -57,6 +57,12 @@ public class CustomEntityAttributeDefinition implements IRelyingPartyOverridePro @Column(name = "persist_value", nullable = true) String persistValue; + @Override + public String getAttributeName() { + // This is a bit of a hack because we don't have attribute name in the UI yet... + return attributeName == null ? name : attributeName; + } + @Override public Set getDefaultValues() { return customAttrListDefinitions; From 222a3db187f6ffafea91399206e1b642b6797a77 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 15 Jun 2021 16:10:17 -0700 Subject: [PATCH 15/51] SHIBUI-1788 Fixes for lists in custom attribute definitions showing up on the relying party override config in metadata --- .../service/JsonSchemaBuilderService.groovy | 4 +-- .../CustomPropertiesConfiguration.java | 27 ++++++++++--------- .../CustomEntityAttributeDefinition.java | 16 ++++++++--- .../domain/RelyingPartyOverrideProperty.java | 9 +++++-- backend/src/main/resources/application.yml | 4 +-- 5 files changed, 39 insertions(+), 21 deletions(-) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy index fa606f53b..6857a0109 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy @@ -36,7 +36,7 @@ class JsonSchemaBuilderService { [title : it['displayName'], description: it['helpText'], type : it['displayType'], - examples : it['defaultValues']] + examples : it['examples']] } properties[(String) it['name']] = property } @@ -59,7 +59,7 @@ class JsonSchemaBuilderService { def items = [type : 'string', minLength: 1, // TODO: should this be configurable? maxLength: 255] //TODO: or this? - items.examples = it['defaultValues'] + items.examples = it['examples'] definition['items'] = items json[(String) it['name']] = definition 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 5b73b1fb1..66063c490 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 @@ -21,21 +21,24 @@ @ConfigurationProperties(prefix = "custom") public class CustomPropertiesConfiguration implements ApplicationListener { private List> attributes = new ArrayList<>(); - + private CustomEntityAttributesDefinitionService ceadService; private HashMap overrides = new HashMap<>(); - + private List overridesFromConfigFile = new ArrayList<>(); - + private void buildRelyingPartyOverrides() { // Start over with a clean map and get the CustomEntityAttributesDefinitions from the DB overrides = new HashMap<>(); - ceadService.getAllDefinitions().forEach(def -> overrides.put(def.getName(), def)); - - // We only want to add to an override from the config file if the incoming override (by name) isn't already in + ceadService.getAllDefinitions().forEach(def -> { + def.updateExamplesList(); // totally non-ooo, but @PostLoad wasn't working and JPA/Hibernate is doing some reflection crap + overrides.put(def.getName(), def); + }); + + // We only want to add to an override from the config file if the incoming override (by name) isn't already in // the list of overrides (ie DB > file config) - for(RelyingPartyOverrideProperty rpop : this.overridesFromConfigFile) { + for (RelyingPartyOverrideProperty rpop : this.overridesFromConfigFile) { if (!this.overrides.containsKey(rpop.getName())) { this.overrides.put(rpop.getName(), rpop); } @@ -44,10 +47,10 @@ private void buildRelyingPartyOverrides() { public List> getAttributes() { return attributes; - } - + } + public List getOverrides() { - return new ArrayList<>(overrides.values()); + return new ArrayList<>(overrides.values()); } /** @@ -56,9 +59,9 @@ public List getOverrides() { */ @Override public void onApplicationEvent(CustomEntityAttributeDefinitionChangeEvent arg0) { - buildRelyingPartyOverrides(); + buildRelyingPartyOverrides(); } - + @PostConstruct public void postConstruct() { // Make sure we have the right data 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 0df210269..6c3186ea9 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 @@ -7,8 +7,11 @@ import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; +import javax.persistence.EntityListeners; import javax.persistence.Id; import javax.persistence.JoinColumn; +import javax.persistence.PostLoad; +import javax.persistence.Transient; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; @@ -41,6 +44,9 @@ public class CustomEntityAttributeDefinition implements IRelyingPartyOverridePro @Column(name = "display_name", nullable = true) String displayName; + @Transient + Set examples; + @Column(name = "help_text", nullable = true) String helpText; @@ -78,12 +84,12 @@ public String getDisplayName() { public String getDisplayType() { return attributeType.name().toLowerCase(); } - + @Override public Boolean getFromConfigFile() { return Boolean.FALSE; } - + @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 @@ -92,5 +98,9 @@ public void setDefaultValues(Set defaultValues) { @Override public void setDisplayType(String displayType) { // This is here to comply with the interface only and should not be used to change the value in this implementation - } + } + + public void updateExamplesList() { + examples = customAttrListDefinitions; + } } 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 4c8b9daa6..a958095b6 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 @@ -19,12 +19,13 @@ public class RelyingPartyOverrideProperty implements IRelyingPartyOverrideProper private Set defaultValues; private String displayName; private String displayType; + private Set examples; private String helpText; private String invert; private String name; private String persistType; private String persistValue; - + @Override public Boolean getFromConfigFile() { return Boolean.TRUE; @@ -39,6 +40,10 @@ public CustomAttributeType getAttributeType() { default: return CustomAttributeType.valueOf(displayType.toUpperCase()); } - + } + + public void setDefaultValues(Set defaults) { + defaultValues = defaults; + examples = defaults; } } \ No newline at end of file diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index ea5222d05..e9301289a 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -118,7 +118,7 @@ custom: displayName: label.nameid-format-to-send displayType: set helpText: tooltip.nameid-format - examples: + defaultValues: - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent @@ -129,7 +129,7 @@ custom: displayName: label.authentication-methods-to-use displayType: set helpText: tooltip.authentication-methods-to-use - examples: + defaultValues: - https://refeds.org/profile/mfa - urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken - urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport From 770cdc6e52e1933db33de31870f8ef932fd93f4b Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 15 Jun 2021 17:10:09 -0700 Subject: [PATCH 16/51] SHIBUI-1788 Bug fix for list items in the relying party config screen --- .../admin/ui/domain/CustomEntityAttributeDefinition.java | 2 +- .../admin/ui/service/JPAEntityDescriptorServiceImpl.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) 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 6c3186ea9..d0522c0d6 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 @@ -77,7 +77,7 @@ public Set getDefaultValues() { @Override public String getDisplayName() { // This is here only to ensure proper functionality works until the full definition is revised with all the fields - return displayName == null ? "DEFAULTED to name: " + name : displayName; + return displayName == null ? name : displayName; } @Override 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 e30800cd9..4409731d2 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 @@ -650,12 +650,16 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope Object attributeValues = null; switch (ModelRepresentationConversions.AttributeTypes.valueOf(overrideProperty.getDisplayType().toUpperCase())) { case STRING: + case DOUBLE: + case DURATION: + case SPRING_BEAN_ID: if (jpaAttribute.getAttributeValues().size() != 1) { throw new RuntimeException("Multiple/No values detected where one is expected!"); } attributeValues = getValueFromXMLObject(jpaAttribute.getAttributeValues().get(0)); break; case INTEGER: + case LONG: if (jpaAttribute.getAttributeValues().size() != 1) { throw new RuntimeException("Multiple/No values detected where one is expected!"); } @@ -675,6 +679,7 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope break; case SET: case LIST: + case SELECTION_LIST: attributeValues = jpaAttribute.getAttributeValues().stream() .map(attributeValue -> getValueFromXMLObject(attributeValue)) .collect(Collectors.toList()); From 98ca11ff2f1df02340d5113dab1ac2820bdb4582 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 17 Jun 2021 13:50:09 -0700 Subject: [PATCH 17/51] SHIBUI-1788 Quick feedback adjustments --- .../configuration/CustomPropertiesConfiguration.java | 10 ++++++---- .../CustomEntityAttributesDefinitionsController.java | 6 +----- 2 files changed, 7 insertions(+), 9 deletions(-) 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 66063c490..af8aef206 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 @@ -30,19 +30,21 @@ public class CustomPropertiesConfiguration implements ApplicationListener(); + HashMap reloaded = new HashMap<>(); ceadService.getAllDefinitions().forEach(def -> { def.updateExamplesList(); // totally non-ooo, but @PostLoad wasn't working and JPA/Hibernate is doing some reflection crap - overrides.put(def.getName(), def); + reloaded.put(def.getName(), def); }); // We only want to add to an override from the config file if the incoming override (by name) isn't already in // the list of overrides (ie DB > file config) for (RelyingPartyOverrideProperty rpop : this.overridesFromConfigFile) { - if (!this.overrides.containsKey(rpop.getName())) { - this.overrides.put(rpop.getName(), rpop); + if (!reloaded.containsKey(rpop.getName())) { + reloaded.put(rpop.getName(), rpop); } } + + this.overrides = reloaded; } public List> getAttributes() { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java index 33811f28e..fa83d2b45 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java @@ -15,7 +15,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration; import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService; @@ -24,9 +23,6 @@ public class CustomEntityAttributesDefinitionsController { @Autowired private CustomEntityAttributesDefinitionService caService; - - @Autowired - private CustomPropertiesConfiguration customPropertiesConfiguration; @PostMapping("/attribute") @Transactional @@ -71,7 +67,7 @@ public ResponseEntity update(@RequestBody CustomEntityAttributeDefinition def @GetMapping("/attributes") @Transactional(readOnly = true) public ResponseEntity getAll() { - return ResponseEntity.ok(customPropertiesConfiguration.getOverrides()); + return ResponseEntity.ok(caService.getAllDefinitions()); } @GetMapping("/attribute/{name}") From fa801f2642817591bf5dbd5b7e21736d02780db5 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 17 Jun 2021 14:45:39 -0700 Subject: [PATCH 18/51] adding custom attribute types --- .../schema/attribute/attribute.schema.json | 107 ++++++++++++++++-- ui/src/app/App.js | 1 + 2 files changed, 101 insertions(+), 7 deletions(-) diff --git a/ui/public/assets/schema/attribute/attribute.schema.json b/ui/public/assets/schema/attribute/attribute.schema.json index b821ed7bb..97bf5c4f0 100644 --- a/ui/public/assets/schema/attribute/attribute.schema.json +++ b/ui/public/assets/schema/attribute/attribute.schema.json @@ -22,12 +22,20 @@ "enum": [ "STRING", "BOOLEAN", - "SELECTION_LIST" + "SELECTION_LIST", + "LONG", + "DOUBLE", + "DURATION", + "SPRING_BEAN_ID" ], "enumNames": [ "value.string", "value.boolean", - "value.list" + "value.list", + "value.long", + "value.double", + "value.duration", + "value.spring-bean-id" ] }, "attributeFriendlyName": { @@ -44,6 +52,30 @@ "minLength": 1, "maxLength": 255 }, + "persistFriendlyName": { + "type": "string", + "title": "label.entity-attribute-friendly-name", + "description": "tooltip.entity-attribute-friendly-name", + "minLength": 1, + "maxLength": 255 + }, + "persistType": { + "type": "string", + "title": "label.entity-attribute-attr-name", + "description": "tooltip.entity-attribute-attr-name", + "minLength": 1, + "maxLength": 255, + "enum": [ + "boolean", + "string", + "number" + ], + "enumNames": [ + "boolean", + "string", + "number" + ] + }, "displayName": { "type": "string", "title": "label.entity-attribute-display-name", @@ -69,7 +101,7 @@ "STRING" ] }, - "defaultValueString": { + "defaultValue": { "title": "label.entity-attribute-default", "description": "tooltip.entity-attribute-default", "type": "string" @@ -83,12 +115,73 @@ "BOOLEAN" ] }, - "defaultValueBoolean": { + "defaultValue": { + "title": "label.entity-attribute-default", + "description": "tooltip.entity-attribute-default", + "type": "string", + "default": "true", + "enumNames": [ + "True", + "False" + ] + } + } + }, + { + "properties": { + "attributeType": { + "enum": [ + "DURATION" + ] + }, + "defaultValue": { + "title": "label.entity-attribute-default", + "description": "tooltip.entity-attribute-default", + "type": "string", + "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" + } + } + }, + { + "properties": { + "attributeType": { + "enum": [ + "LONG" + ] + }, + "defaultValue": { + "title": "label.entity-attribute-default", + "description": "tooltip.entity-attribute-default", + "type": "string" + } + } + }, + { + "properties": { + "attributeType": { + "enum": [ + "DOUBLE" + ] + }, + "defaultValue": { + "title": "label.entity-attribute-default", + "description": "tooltip.entity-attribute-default", + "type": "string" + } + } + }, + { + "properties": { + "attributeType": { + "enum": [ + "INTEGER" + ] + }, + "defaultValue": { "title": "label.entity-attribute-default", "description": "tooltip.entity-attribute-default", - "type": "boolean", - "default": true, - "enumNames": ["True", "False"] + "type": "string", + "pattern": "^\\d+$" } } }, diff --git a/ui/src/app/App.js b/ui/src/app/App.js index 097c0095d..5d0c4e1e4 100644 --- a/ui/src/app/App.js +++ b/ui/src/app/App.js @@ -34,6 +34,7 @@ function App() { const [showTimeout] = React.useState(); const httpOptions = { + cachePolicy: 'no-cache', redirect: 'manual', interceptors: { request: async ({options, url, path, route}) => { From 1c8e24eff76e5df7a956f5ddf4f6e7c26c1eff0c Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 17 Jun 2021 15:43:34 -0700 Subject: [PATCH 19/51] Fixed cache, added error messages --- ui/src/app/App.js | 1 + .../form/component/fields/StringListWithDefaultField.js | 2 +- ui/src/app/metadata/new/NewAttribute.js | 7 ++++++- ui/src/app/metadata/view/MetadataAttributeEdit.js | 7 ++++++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ui/src/app/App.js b/ui/src/app/App.js index 097c0095d..5d0c4e1e4 100644 --- a/ui/src/app/App.js +++ b/ui/src/app/App.js @@ -34,6 +34,7 @@ function App() { const [showTimeout] = React.useState(); const httpOptions = { + cachePolicy: 'no-cache', redirect: 'manual', interceptors: { request: async ({options, url, path, route}) => { diff --git a/ui/src/app/form/component/fields/StringListWithDefaultField.js b/ui/src/app/form/component/fields/StringListWithDefaultField.js index 3f8ba8b74..c29fe31d2 100644 --- a/ui/src/app/form/component/fields/StringListWithDefaultField.js +++ b/ui/src/app/form/component/fields/StringListWithDefaultField.js @@ -121,7 +121,7 @@ const StringListWithDefaultField = ({
{items && items.map((p, idx) => -
+
Date: Fri, 18 Jun 2021 11:02:26 -0700 Subject: [PATCH 20/51] SHIBUI-1783 Removed added code around custom entity attributes and filters that ended up being un-needed. Fixed bug (NPE) on creating attribute from custom entity attribute --- .../CustomEntityAttributeDefinition.java | 6 + .../CustomEntityAttributeFilterValue.java | 43 ----- .../filters/EntityAttributesFilter.java | 12 +- ...mEntityAttributeFilterValueRepository.java | 16 -- ...EntityAttributesDefinitionServiceImpl.java | 12 -- .../CustomPropertiesConfigurationTests.groovy | 1 - .../ui/configuration/TestConfiguration.groovy | 7 +- .../EntityDescriptorRepositoryTest.groovy | 4 - .../repository/FilterRepositoryTests.groovy | 178 ------------------ 9 files changed, 8 insertions(+), 271 deletions(-) delete mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/CustomEntityAttributeFilterValue.java delete mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeFilterValueRepository.java 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 d0522c0d6..f4d5d1054 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 @@ -85,6 +85,12 @@ public String getDisplayType() { return attributeType.name().toLowerCase(); } + @Override + public String getAttributeFriendlyName() { + // This is here only to ensure proper functionality works until the full definition is revised with all the fields + return attributeFriendlyName == null ? name : attributeFriendlyName; + } + @Override public Boolean getFromConfigFile() { return Boolean.FALSE; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/CustomEntityAttributeFilterValue.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/CustomEntityAttributeFilterValue.java deleted file mode 100644 index ed6715631..000000000 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/CustomEntityAttributeFilterValue.java +++ /dev/null @@ -1,43 +0,0 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.filters; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.hibernate.envers.Audited; - -import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; -import lombok.Getter; -import lombok.Setter; - - -@Entity(name = "custom_entity_attr_filter_value") -@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "filter_id", "custom_entity_attribute_name" }) }) -@Audited -// NOTE: lombok's toString and equals cause an infinite loop somewhere that causes stack overflows, so if we need impls, -// do it manually. Do not replace the Getter and Setter with @Data... -@Getter -@Setter -public class CustomEntityAttributeFilterValue { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - @Column(name = "generated_id") - private Integer id; - - @ManyToOne - @JoinColumn(name = "filter_id", nullable = false) - EntityAttributesFilter entityAttributesFilter; - - @ManyToOne - @JoinColumn(name = "custom_entity_attribute_name", referencedColumnName = "name", nullable = false) - CustomEntityAttributeDefinition customEntityAttributeDefinition; - - @Column(name = "value", nullable = false) - String value; -} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilter.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilter.java index 28926358f..7643f483d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilter.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilter.java @@ -53,16 +53,7 @@ public EntityAttributesFilter() { @Transient private List attributeRelease = new ArrayList<>(); - - @JsonIgnore - @OneToMany(cascade = CascadeType.ALL, mappedBy = "entityAttributesFilter", orphanRemoval = true) - private Set customEntityAttributes = new HashSet<>(); - - public void setCustomEntityAttributes (Set newValues) { - customEntityAttributes.clear(); - customEntityAttributes.addAll(newValues); - } - + public void setAttributeRelease(List attributeRelease) { this.attributeRelease = attributeRelease; this.rebuildAttributes(); @@ -95,7 +86,6 @@ private EntityAttributesFilter updateConcreteFilterTypeData(EntityAttributesFilt filterToBeUpdated.setEntityAttributesFilterTarget(getEntityAttributesFilterTarget()); filterToBeUpdated.setRelyingPartyOverrides(getRelyingPartyOverrides()); filterToBeUpdated.setAttributeRelease(getAttributeRelease()); - filterToBeUpdated.setCustomEntityAttributes(customEntityAttributes); return filterToBeUpdated; } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeFilterValueRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeFilterValueRepository.java deleted file mode 100644 index a6a7be164..000000000 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeFilterValueRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package edu.internet2.tier.shibboleth.admin.ui.repository; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; - -import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.CustomEntityAttributeFilterValue; -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter; - -public interface CustomEntityAttributeFilterValueRepository extends JpaRepository { - // Not entirely sure this is needed for the core, but it did make validation/unit testing a whole lot easier - CustomEntityAttributeFilterValue findByEntityAttributesFilterAndCustomEntityAttributeDefinition(EntityAttributesFilter eaf , CustomEntityAttributeDefinition cead); - - List findAllByCustomEntityAttributeDefinition(CustomEntityAttributeDefinition definition); -} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java index 90438164a..a7d1c46dc 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java @@ -10,9 +10,7 @@ import org.springframework.transaction.annotation.Transactional; import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.CustomEntityAttributeFilterValue; import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeDefinitionRepository; -import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeFilterValueRepository; import edu.internet2.tier.shibboleth.admin.ui.service.events.CustomEntityAttributeDefinitionChangeEvent; @Service @@ -20,9 +18,6 @@ public class CustomEntityAttributesDefinitionServiceImpl implements CustomEntity @Autowired private ApplicationEventPublisher applicationEventPublisher; - @Autowired - CustomEntityAttributeFilterValueRepository customEntityAttributeFilterValueRepository; - @Autowired EntityManager entityManager; @@ -40,13 +35,6 @@ public CustomEntityAttributeDefinition createOrUpdateDefinition(CustomEntityAttr @Override @Transactional public void deleteDefinition(CustomEntityAttributeDefinition definition) { - // must remove any CustomEntityAttributeFilterValues first to avoid integrity constraint issues - List customEntityValues = customEntityAttributeFilterValueRepository.findAllByCustomEntityAttributeDefinition(definition); - customEntityValues.forEach(value -> { - value.getEntityAttributesFilter().getCustomEntityAttributes().remove(value); - entityManager.remove(value); - customEntityAttributeFilterValueRepository.delete(value); - }); CustomEntityAttributeDefinition entityToRemove = repository.findByName(definition.getName()); repository.delete(entityToRemove); notifyListeners(); diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfigurationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfigurationTests.groovy index e90e7974e..74ecb9796 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfigurationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomPropertiesConfigurationTests.groovy @@ -6,7 +6,6 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeDefinitionRepository -import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeFilterValueRepository import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy index 775103ac0..7f12a050d 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy @@ -3,7 +3,6 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeDefinitionRepository -import edu.internet2.tier.shibboleth.admin.ui.repository.CustomEntityAttributeFilterValueRepository import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository import edu.internet2.tier.shibboleth.admin.ui.security.DefaultAuditorAware import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionServiceImpl @@ -46,10 +45,7 @@ class TestConfiguration { @Autowired private CustomEntityAttributeDefinitionRepository repository; - - @Autowired - CustomEntityAttributeFilterValueRepository customEntityAttributeFilterValueRepository; - + @Autowired EntityManager entityManager @@ -63,7 +59,6 @@ class TestConfiguration { new CustomEntityAttributesDefinitionServiceImpl().with { it.entityManager = entityManager it.repository = repository - it.customEntityAttributeFilterValueRepository = customEntityAttributeFilterValueRepository return it } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy index 282961b79..70331ffe6 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy @@ -41,9 +41,6 @@ class EntityDescriptorRepositoryTest extends Specification { @Autowired private CustomEntityAttributeDefinitionRepository repository; - @Autowired - CustomEntityAttributeFilterValueRepository customEntityAttributeFilterValueRepository; - @Autowired EntityManager entityManager @@ -113,7 +110,6 @@ class EntityDescriptorRepositoryTest extends Specification { new CustomEntityAttributesDefinitionServiceImpl().with { it.entityManager = entityManager it.repository = repository - it.customEntityAttributeFilterValueRepository = customEntityAttributeFilterValueRepository return it } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FilterRepositoryTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FilterRepositoryTests.groovy index 48a042e5b..f233684fd 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FilterRepositoryTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FilterRepositoryTests.groovy @@ -5,7 +5,6 @@ import javax.persistence.EntityManager import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.domain.EntityScan import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest -import org.springframework.context.annotation.ComponentScan import org.springframework.data.jpa.repository.config.EnableJpaRepositories import org.springframework.test.context.ContextConfiguration @@ -16,9 +15,7 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.Internationalization import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.CustomEntityAttributeFilterValue import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter -import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import spock.lang.Specification @@ -26,18 +23,11 @@ import spock.lang.Specification @ContextConfiguration(classes=[CoreShibUiConfiguration, SearchConfiguration, TestConfiguration, InternationalizationConfiguration]) @EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) @EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@ComponentScan("edu.internet2.tier.shibboleth.admin.ui.service") class FilterRepositoryTests extends Specification { @Autowired FilterRepository repositoryUnderTest - @Autowired - CustomEntityAttributesDefinitionService ceadService - - @Autowired - CustomEntityAttributeFilterValueRepository ceafvRepo - @Autowired EntityManager entityManager @@ -96,172 +86,4 @@ class FilterRepositoryTests extends Specification { persistedFilter.audId > 0L persistedFilter.formats.size() == 1 } - - def "FilterRepository + EntityAttributesFilter CRUD ops with custom entity attributes correctly"(){ - given: - def ca = new CustomEntityAttributeDefinition().with { - it.name = "ca-name" - it.attributeType = "STRING" - it.defaultValue = "foo" - it - } - ceadService.createOrUpdateDefinition(ca) - entityManager.flush() - entityManager.clear() - - def entityAttributesFilterJson = '''{ - "name": "EntityAttributes", - "resourceId": "29a5d409-562a-41cd-acee-e9b3d7098d05", - "filterEnabled": false, - "entityAttributesFilterTarget": { - "entityAttributesFilterTargetType": "CONDITION_SCRIPT", - "value": [ - "TwUuSOz5O6" - ] - }, - "attributeRelease": [ - "WbkhLQNI3m" - ], - "relyingPartyOverrides": { - "signAssertion": true, - "dontSignResponse": true, - "turnOffEncryption": true, - "useSha": true, - "ignoreAuthenticationMethod": false, - "omitNotBefore": true, - "responderId": null, - "nameIdFormats": [ - "xLenUFmCLn" - ], - "authenticationMethods": [] - }, - "@type": "EntityAttributes" - }''' - def filter = new ObjectMapper().readValue(entityAttributesFilterJson.bytes, EntityAttributesFilter.class) - def persistedFilter = repositoryUnderTest.save(filter) - entityManager.flush() - - def savedFilter = repositoryUnderTest.findByResourceId(persistedFilter.resourceId) - def saveEAD = ceadService.find("ca-name") - - def ceafv = new CustomEntityAttributeFilterValue().with { - it.entityAttributesFilter = savedFilter - it.customEntityAttributeDefinition = saveEAD - it.value = "bar" - it - } - - def customEntityAttributes = new HashSet() - - when: - customEntityAttributes.add(ceafv) // nothing to do yet, just here to let us verify nothing in the CEAFV table in 'then' block - - then: - ((Set)ceafvRepo.findAll()).size() == 0 //nothing yet - ((EntityAttributesFilter)savedFilter).setCustomEntityAttributes(customEntityAttributes) - repositoryUnderTest.save(savedFilter) - entityManager.flush() - - then: - def listOfceafv = ceafvRepo.findAll() - listOfceafv.size() == 1 - - def ceafvFromDb = listOfceafv.get(0).asType(CustomEntityAttributeFilterValue) - ceafvFromDb.getEntityAttributesFilter().getResourceId().equals("29a5d409-562a-41cd-acee-e9b3d7098d05") - - def filterFromDb = (EntityAttributesFilter) repositoryUnderTest.findByResourceId("29a5d409-562a-41cd-acee-e9b3d7098d05") - filterFromDb.getCustomEntityAttributes().size() == 1 - - // now remove all - def emptySet = new HashSet() - filterFromDb.setCustomEntityAttributes(emptySet) - repositoryUnderTest.save(filterFromDb) - entityManager.flush() - - ceafvRepo.findAll().size() == 0 - } - - def "Delete custom entity attributes definition removes entries from filter correctly"(){ - given: - def ca = new CustomEntityAttributeDefinition().with { - it.name = "ca-name" - it.attributeType = "STRING" - it.defaultValue = "foo" - it - } - ceadService.createOrUpdateDefinition(ca) - entityManager.flush() - entityManager.clear() - - def entityAttributesFilterJson = '''{ - "name": "EntityAttributes", - "resourceId": "29a5d409-562a-41cd-acee-e9b3d7098d05", - "filterEnabled": false, - "entityAttributesFilterTarget": { - "entityAttributesFilterTargetType": "CONDITION_SCRIPT", - "value": [ - "TwUuSOz5O6" - ] - }, - "attributeRelease": [ - "WbkhLQNI3m" - ], - "relyingPartyOverrides": { - "signAssertion": true, - "dontSignResponse": true, - "turnOffEncryption": true, - "useSha": true, - "ignoreAuthenticationMethod": false, - "omitNotBefore": true, - "responderId": null, - "nameIdFormats": [ - "xLenUFmCLn" - ], - "authenticationMethods": [] - }, - "@type": "EntityAttributes" - }''' - def filter = new ObjectMapper().readValue(entityAttributesFilterJson.bytes, EntityAttributesFilter.class) - def persistedFilter = repositoryUnderTest.save(filter) - entityManager.flush() - - def savedFilter = repositoryUnderTest.findByResourceId(persistedFilter.resourceId) - def saveEAD = ceadService.find("ca-name"); - - def ceafv = new CustomEntityAttributeFilterValue().with { - it.entityAttributesFilter = savedFilter - it.customEntityAttributeDefinition = saveEAD - it.value = "bar" - it - } - - def customEntityAttributes = new HashSet() - - when: - customEntityAttributes.add(ceafv) // nothing to do yet, just here to let us verify nothing in the CEAFV table in 'then' block - - then: - ((Set)ceafvRepo.findAll()).size() == 0 //nothing yet - ((EntityAttributesFilter)savedFilter).setCustomEntityAttributes(customEntityAttributes) - repositoryUnderTest.save(savedFilter) - entityManager.flush() - - then: - def listOfceafv = ceafvRepo.findAll() - listOfceafv.size() == 1 - - def ceafvFromDb = listOfceafv.get(0).asType(CustomEntityAttributeFilterValue) - ceafvFromDb.getEntityAttributesFilter().getResourceId().equals("29a5d409-562a-41cd-acee-e9b3d7098d05") - - def filterFromDb = (EntityAttributesFilter) repositoryUnderTest.findByResourceId("29a5d409-562a-41cd-acee-e9b3d7098d05") - filterFromDb.getCustomEntityAttributes().size() == 1 - - // now remove the definition - ceadService.deleteDefinition(saveEAD) - entityManager.flush() - entityManager.clear() - - def filterFromDb2 = (EntityAttributesFilter)repositoryUnderTest.findByResourceId("29a5d409-562a-41cd-acee-e9b3d7098d05") - filterFromDb2.getCustomEntityAttributes().size() == 0 - } } From 871db98026f6659d61b95ac4bd39a3a34feaf765 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 18 Jun 2021 12:10:07 -0700 Subject: [PATCH 21/51] SHIBUI-1967 Included/added back the default value from relyingpartyoverrides in the JSON being sent to the front end --- .../admin/ui/service/JsonSchemaBuilderService.groovy | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy index 6857a0109..e6afb7bf2 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy @@ -33,10 +33,11 @@ class JsonSchemaBuilderService { property = [$ref: '#/definitions/' + it['name']] } else { property = - [title : it['displayName'], - description: it['helpText'], - type : it['displayType'], - examples : it['examples']] + [title : it['displayName'], + description : it['helpText'], + type : it['displayType'], + defaultValue: it['defaultValue'], + examples : it['examples']] } properties[(String) it['name']] = property } @@ -60,8 +61,10 @@ class JsonSchemaBuilderService { minLength: 1, // TODO: should this be configurable? maxLength: 255] //TODO: or this? items.examples = it['examples'] + definition['items'] = items + definition['defaultValue'] = it['defaultValue'] json[(String) it['name']] = definition } } From 6427a77ab2cefab4027fab1a1f5e0ed54817e777 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 18 Jun 2021 12:22:28 -0700 Subject: [PATCH 22/51] SHIBUI-1967 Adjusted name of default value to "default" --- .../admin/ui/service/JsonSchemaBuilderService.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy index e6afb7bf2..685328795 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy @@ -36,7 +36,7 @@ class JsonSchemaBuilderService { [title : it['displayName'], description : it['helpText'], type : it['displayType'], - defaultValue: it['defaultValue'], + deafult : it['defaultValue'], examples : it['examples']] } properties[(String) it['name']] = property @@ -51,7 +51,7 @@ class JsonSchemaBuilderService { def definition = [title : it['displayName'], description: it['helpText'], type : 'array', - default : null] + default : it['defaultValue']] if (it['displayType'] == 'set' || it['displayType'] == 'selection_list') { definition['uniqueItems'] = true } else if (it['displayType'] == 'list') { @@ -64,7 +64,7 @@ class JsonSchemaBuilderService { definition['items'] = items - definition['defaultValue'] = it['defaultValue'] + definition['default'] = it['defaultValue'] json[(String) it['name']] = definition } } From 12c04f0ddd3db1c50fea9846beccb92b409104c2 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 18 Jun 2021 12:24:54 -0700 Subject: [PATCH 23/51] SHIBUI-1967 Corrected typo in word default --- .../shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy index 685328795..893021d20 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy @@ -36,7 +36,7 @@ class JsonSchemaBuilderService { [title : it['displayName'], description : it['helpText'], type : it['displayType'], - deafult : it['defaultValue'], + default : it['defaultValue'], examples : it['examples']] } properties[(String) it['name']] = property From f11db6a29487747833edb996d05f8b16bfdea0b5 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 18 Jun 2021 12:59:45 -0700 Subject: [PATCH 24/51] Fixed json-schema builder --- .../admin/ui/service/JsonSchemaBuilderService.groovy | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy index 893021d20..d1c5b98fa 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy @@ -50,8 +50,7 @@ class JsonSchemaBuilderService { }.each { def definition = [title : it['displayName'], description: it['helpText'], - type : 'array', - default : it['defaultValue']] + type : 'array'] if (it['displayType'] == 'set' || it['displayType'] == 'selection_list') { definition['uniqueItems'] = true } else if (it['displayType'] == 'list') { @@ -61,10 +60,10 @@ class JsonSchemaBuilderService { minLength: 1, // TODO: should this be configurable? maxLength: 255] //TODO: or this? items.examples = it['examples'] + items['default'] = it['defaultValue'] definition['items'] = items - definition['default'] = it['defaultValue'] json[(String) it['name']] = definition } } From 263ca11ed28e570a59d70f7b4d574a15dba3f58d Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 18 Jun 2021 14:22:48 -0700 Subject: [PATCH 25/51] SHIBUI-1967 Fix for boolean default values --- .../shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy index d1c5b98fa..58942971b 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JsonSchemaBuilderService.groovy @@ -36,7 +36,7 @@ class JsonSchemaBuilderService { [title : it['displayName'], description : it['helpText'], type : it['displayType'], - default : it['defaultValue'], + default : it['displayType'] == 'boolean' ? Boolean.getBoolean(it['defaultValue']) : it['defaultValue'], examples : it['examples']] } properties[(String) it['name']] = property From d064f0acac055f82a5a18b2904f53922085e968b Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 21 Jun 2021 13:31:29 -0700 Subject: [PATCH 26/51] Updated attributes definition --- backend/src/main/resources/i18n/messages.properties | 13 +++++++++++++ .../assets/schema/attribute/attribute.schema.json | 8 ++++---- .../domain/attribute/CustomAttributeDefinition.js | 2 ++ .../app/metadata/editor/MetadataAttributeEditor.js | 4 +++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 802f36372..5ed4a9874 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -104,9 +104,17 @@ value.template=Template value.string=String value.boolean=Boolean value.list=List +value.long=Long +value.double=Double +value.duration=Duration +value.spring-bean-id=Spring Bean ID value.BOOLEAN=Boolean value.SELECTION_LIST=List value.STRING=String +value.LONG=Long +value.DOUBLE=Double +value.DURATION=Duration +value.SPRING_BEAN_ID=Spring Bean ID brand.header.title=Source Management brand.logo-link-label=Shibboleth @@ -147,6 +155,11 @@ tooltip.entity-attribute-attr-name=This is normally a uri or urn label.entity-attribute-display-name=Display name tooltip.entity-attribute-display-name=Display name +label.entity-attribute-persist-friendly-name=Persist Friendly Name +label.entity-attribute-persist-type=Persist Type +tooltip.entity-attribute-persist-friendly-name=Persist Friendly Name +tooltip.entity-attribute-persist-type=Persist Type + label.entity-attributes=Entity Attributes label.custom-entity-attributes=Custom Entity Attributes label.help-text=Help text diff --git a/ui/public/assets/schema/attribute/attribute.schema.json b/ui/public/assets/schema/attribute/attribute.schema.json index 97bf5c4f0..bb731f20b 100644 --- a/ui/public/assets/schema/attribute/attribute.schema.json +++ b/ui/public/assets/schema/attribute/attribute.schema.json @@ -54,15 +54,15 @@ }, "persistFriendlyName": { "type": "string", - "title": "label.entity-attribute-friendly-name", - "description": "tooltip.entity-attribute-friendly-name", + "title": "label.entity-attribute-persist-friendly-name", + "description": "tooltip.entity-attribute-persist-friendly-name", "minLength": 1, "maxLength": 255 }, "persistType": { "type": "string", - "title": "label.entity-attribute-attr-name", - "description": "tooltip.entity-attribute-attr-name", + "title": "label.entity-attribute-persist-type", + "description": "tooltip.entity-attribute-persist-type", "minLength": 1, "maxLength": 255, "enum": [ diff --git a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js index a5ea258c6..833a3962d 100644 --- a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js +++ b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js @@ -18,6 +18,8 @@ export const CustomAttributeDefinition = { 'attributeName', 'attributeFriendlyName', 'displayName', + 'persistFriendlyName', + 'persistType', 'helpText' ] }, diff --git a/ui/src/app/metadata/editor/MetadataAttributeEditor.js b/ui/src/app/metadata/editor/MetadataAttributeEditor.js index 9c13e2a5f..126444729 100644 --- a/ui/src/app/metadata/editor/MetadataAttributeEditor.js +++ b/ui/src/app/metadata/editor/MetadataAttributeEditor.js @@ -1,6 +1,7 @@ import React from 'react'; import { MetadataFormContext, setFormDataAction, setFormErrorAction } from '../hoc/MetadataFormContext'; import { MetadataDefinitionContext, MetadataSchemaContext } from '../hoc/MetadataSchema'; +import { transformErrors } from '../domain/transform'; import Form from '@rjsf/bootstrap-4'; @@ -44,7 +45,8 @@ export function MetadataAttributeEditor({ children }) { fields={fields} widgets={widgets} liveValidate={true} - ErrorList={ErrorListTemplate}> + ErrorList={ErrorListTemplate} + transformErrors={transformErrors}> <>
From c3eb4f9d92ea2ce2d047043eb0f275e08752cc51 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 21 Jun 2021 14:49:47 -0700 Subject: [PATCH 27/51] Added additional fields --- backend/src/main/resources/i18n/messages.properties | 4 ++-- ui/public/assets/schema/attribute/attribute.schema.json | 8 +++++--- .../domain/attribute/CustomAttributeDefinition.js | 2 +- ui/src/app/metadata/editor/MetadataAttributeEditor.js | 1 + 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 5ed4a9874..a530bc7c0 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -155,9 +155,9 @@ tooltip.entity-attribute-attr-name=This is normally a uri or urn label.entity-attribute-display-name=Display name tooltip.entity-attribute-display-name=Display name -label.entity-attribute-persist-friendly-name=Persist Friendly Name +label.entity-attribute-persist-value=Persist Value label.entity-attribute-persist-type=Persist Type -tooltip.entity-attribute-persist-friendly-name=Persist Friendly Name +tooltip.entity-attribute-persist-value=Persist Value tooltip.entity-attribute-persist-type=Persist Type label.entity-attributes=Entity Attributes diff --git a/ui/public/assets/schema/attribute/attribute.schema.json b/ui/public/assets/schema/attribute/attribute.schema.json index bb731f20b..612fec00c 100644 --- a/ui/public/assets/schema/attribute/attribute.schema.json +++ b/ui/public/assets/schema/attribute/attribute.schema.json @@ -5,6 +5,8 @@ "attributeType", "attributeFriendlyName", "attributeName", + "persistValue", + "persistType", "displayName" ], "properties": { @@ -52,10 +54,10 @@ "minLength": 1, "maxLength": 255 }, - "persistFriendlyName": { + "persistValue": { "type": "string", - "title": "label.entity-attribute-persist-friendly-name", - "description": "tooltip.entity-attribute-persist-friendly-name", + "title": "label.entity-attribute-persist-value", + "description": "tooltip.entity-attribute-persist-value", "minLength": 1, "maxLength": 255 }, diff --git a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js index 833a3962d..4add96ea5 100644 --- a/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js +++ b/ui/src/app/metadata/domain/attribute/CustomAttributeDefinition.js @@ -18,7 +18,7 @@ export const CustomAttributeDefinition = { 'attributeName', 'attributeFriendlyName', 'displayName', - 'persistFriendlyName', + 'persistValue', 'persistType', 'helpText' ] diff --git a/ui/src/app/metadata/editor/MetadataAttributeEditor.js b/ui/src/app/metadata/editor/MetadataAttributeEditor.js index 126444729..915ca2bc4 100644 --- a/ui/src/app/metadata/editor/MetadataAttributeEditor.js +++ b/ui/src/app/metadata/editor/MetadataAttributeEditor.js @@ -51,6 +51,7 @@ export function MetadataAttributeEditor({ children }) {
+
{JSON.stringify(errors, null, 4)}
); } \ No newline at end of file From 32ee29e8742ccce08cdde551c04da55613c03dc9 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 23 Jun 2021 10:25:29 -0700 Subject: [PATCH 28/51] SHIBUI-1968 updated custom entity attribute with resource id and changed the APIs to use the resource id instead of name for id of the CEAD --- ...EntityAttributesDefinitionsController.java | 20 +++++----- .../CustomEntityAttributeDefinition.java | 8 ++-- ...omEntityAttributeDefinitionRepository.java | 2 + ...stomEntityAttributesDefinitionService.java | 2 +- ...EntityAttributesDefinitionServiceImpl.java | 6 +-- ...yAttributeDefinitionRepositoryTests.groovy | 40 ++++++++----------- 6 files changed, 37 insertions(+), 41 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java index fa83d2b45..a51ea77c8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java @@ -70,34 +70,34 @@ public ResponseEntity getAll() { return ResponseEntity.ok(caService.getAllDefinitions()); } - @GetMapping("/attribute/{name}") + @GetMapping("/attribute/{resourceId}") @Transactional(readOnly = true) - public ResponseEntity getOne(@PathVariable String name) { - CustomEntityAttributeDefinition cad = caService.find(name); + public ResponseEntity getOne(@PathVariable String resourceId) { + CustomEntityAttributeDefinition cad = caService.find(resourceId); if (cad == null) { HttpHeaders headers = new HttpHeaders(); headers.setLocation( - ServletUriComponentsBuilder.fromCurrentServletMapping().path("/api/custom/entity/attribute/" + name).build().toUri()); + ServletUriComponentsBuilder.fromCurrentServletMapping().path("/api/custom/entity/attribute/" + resourceId).build().toUri()); return ResponseEntity.status(HttpStatus.NOT_FOUND).headers(headers) .body(new ErrorResponse(String.valueOf(HttpStatus.NOT_FOUND.value()), - String.format("The custom attribute definition with name: [%s] does not already exist.", name))); + String.format("The custom attribute definition with resource id: [%s] does not already exist.", resourceId))); } return ResponseEntity.ok(cad); } - @DeleteMapping("/attribute/{name}") + @DeleteMapping("/attribute/{resourceId}") @Transactional - public ResponseEntity delete(@PathVariable String name) { - CustomEntityAttributeDefinition cad = caService.find(name); + public ResponseEntity delete(@PathVariable String resourceId) { + CustomEntityAttributeDefinition cad = caService.find(resourceId); if (cad == null) { HttpHeaders headers = new HttpHeaders(); headers.setLocation( - ServletUriComponentsBuilder.fromCurrentServletMapping().path("/api/custom/entity/attribute/" + name).build().toUri()); + ServletUriComponentsBuilder.fromCurrentServletMapping().path("/api/custom/entity/attribute/" + resourceId).build().toUri()); return ResponseEntity.status(HttpStatus.NOT_FOUND).headers(headers) .body(new ErrorResponse(String.valueOf(HttpStatus.NOT_FOUND.value()), - String.format("The custom attribute definition with name: [%s] does not already exist.", name))); + String.format("The custom attribute definition with resource id: [%s] does not already exist.", resourceId))); } caService.deleteDefinition(cad); return ResponseEntity.noContent().build(); 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 f4d5d1054..c06492ce8 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 @@ -2,15 +2,14 @@ import java.util.HashSet; import java.util.Set; +import java.util.UUID; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; -import javax.persistence.EntityListeners; import javax.persistence.Id; import javax.persistence.JoinColumn; -import javax.persistence.PostLoad; import javax.persistence.Transient; import org.hibernate.annotations.Fetch; @@ -53,7 +52,6 @@ public class CustomEntityAttributeDefinition implements IRelyingPartyOverridePro @Column(name = "invert", nullable = true) String invert; - @Id @Column(nullable = false) String name; @@ -62,6 +60,10 @@ public class CustomEntityAttributeDefinition implements IRelyingPartyOverridePro @Column(name = "persist_value", nullable = true) String persistValue; + + @Id + @Column(name = "resource_id", nullable = false) + String resourceId = UUID.randomUUID().toString(); @Override public String getAttributeName() { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeDefinitionRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeDefinitionRepository.java index 677d7cf87..db3724ea5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeDefinitionRepository.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeDefinitionRepository.java @@ -15,6 +15,8 @@ public interface CustomEntityAttributeDefinitionRepository extends JpaRepository CustomEntityAttributeDefinition findByName(String name); + CustomEntityAttributeDefinition findByResourceId(String resourceId); + @SuppressWarnings("unchecked") CustomEntityAttributeDefinition save(CustomEntityAttributeDefinition attribute); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java index 4087ad221..f4539a15e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionService.java @@ -10,7 +10,7 @@ public interface CustomEntityAttributesDefinitionService { void deleteDefinition(CustomEntityAttributeDefinition definition); - CustomEntityAttributeDefinition find(String name); + CustomEntityAttributeDefinition find(String resourceId); List getAllDefinitions(); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java index a7d1c46dc..6fe0a8c25 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java @@ -35,14 +35,14 @@ public CustomEntityAttributeDefinition createOrUpdateDefinition(CustomEntityAttr @Override @Transactional public void deleteDefinition(CustomEntityAttributeDefinition definition) { - CustomEntityAttributeDefinition entityToRemove = repository.findByName(definition.getName()); + CustomEntityAttributeDefinition entityToRemove = repository.findByResourceId(definition.getResourceId()); repository.delete(entityToRemove); notifyListeners(); } @Override - public CustomEntityAttributeDefinition find(String name) { - return repository.findByName(name); + public CustomEntityAttributeDefinition find(String resourceId) { + return repository.findByResourceId(resourceId); } @Override diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeDefinitionRepositoryTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeDefinitionRepositoryTests.groovy index 2601d4d42..5c7f8cf8e 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeDefinitionRepositoryTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/CustomEntityAttributeDefinitionRepositoryTests.groovy @@ -142,11 +142,7 @@ class CustomEntityAttributeDefinitionRepositoryTests extends Specification { // delete tests when: - def delByName = new CustomEntityAttributeDefinition().with { - it.name = "ca-name" - it - } - repo.delete(delByName) + repo.delete(caFromDb1) entityManager.flush() entityManager.clear() @@ -159,24 +155,12 @@ class CustomEntityAttributeDefinitionRepositoryTests extends Specification { def setItems2 = new HashSet(["val2", "val1"]) def setItems3 = new HashSet(["val1", "val2", "val3"]) def setItems4 = new HashSet(["val1", "val2", "val3", "val4"]) - def ca2 = new CustomEntityAttributeDefinition().with { - it.name = "ca-name" - it.attributeType = "SELECTION_LIST" - it.customAttrListDefinitions = setItems2 - it - } def ca3 = new CustomEntityAttributeDefinition().with { it.name = "ca-name" it.attributeType = "SELECTION_LIST" it.customAttrListDefinitions = setItems3 it } - def ca4 = new CustomEntityAttributeDefinition().with { - it.name = "ca-name" - it.attributeType = "SELECTION_LIST" - it.customAttrListDefinitions = setItems4 - it - } when: repo.save(ca3) @@ -186,31 +170,39 @@ class CustomEntityAttributeDefinitionRepositoryTests extends Specification { then: def cas = repo.findAll() cas.size() == 1 - def caFromDb = cas.get(0).asType(CustomEntityAttributeDefinition) - caFromDb.equals(ca3) == true + def ca3FromDb = cas.get(0).asType(CustomEntityAttributeDefinition) + ca3FromDb.equals(ca3) == true // now update the attribute list items - caFromDb.with { + ca3FromDb.with { it.customAttrListDefinitions = setItems4 it } - repo.save(caFromDb) + repo.save(ca3FromDb) entityManager.flush() entityManager.clear() def caFromDb4 = repo.findAll().get(0).asType(CustomEntityAttributeDefinition) + def ca4 = new CustomEntityAttributeDefinition().with { + it.name = "ca-name" + it.attributeType = "SELECTION_LIST" + it.customAttrListDefinitions = setItems4 + it.resourceId = ca3FromDb.resourceId + it + } caFromDb4.equals(ca4) == true // now remove items - caFromDb.with { + ca3FromDb.with { it.customAttrListDefinitions = setItems2 it } - repo.save(caFromDb) + repo.save(ca3FromDb) entityManager.flush() entityManager.clear() def caFromDb2 = repo.findAll().get(0).asType(CustomEntityAttributeDefinition) - caFromDb2.equals(ca2) == true + ca3FromDb.resourceId == caFromDb2.resourceId + ca3FromDb.customAttrListDefinitions.equals(caFromDb2.customAttrListDefinitions) } } \ No newline at end of file From 40dd2c15d3779fcfbe07035be4db5c00552c6d0f Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 23 Jun 2021 10:48:19 -0700 Subject: [PATCH 29/51] updated schema --- .../schema/attribute/attribute.schema.json | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/ui/public/assets/schema/attribute/attribute.schema.json b/ui/public/assets/schema/attribute/attribute.schema.json index 612fec00c..2410125c4 100644 --- a/ui/public/assets/schema/attribute/attribute.schema.json +++ b/ui/public/assets/schema/attribute/attribute.schema.json @@ -54,30 +54,6 @@ "minLength": 1, "maxLength": 255 }, - "persistValue": { - "type": "string", - "title": "label.entity-attribute-persist-value", - "description": "tooltip.entity-attribute-persist-value", - "minLength": 1, - "maxLength": 255 - }, - "persistType": { - "type": "string", - "title": "label.entity-attribute-persist-type", - "description": "tooltip.entity-attribute-persist-type", - "minLength": 1, - "maxLength": 255, - "enum": [ - "boolean", - "string", - "number" - ], - "enumNames": [ - "boolean", - "string", - "number" - ] - }, "displayName": { "type": "string", "title": "label.entity-attribute-display-name", @@ -122,10 +98,32 @@ "description": "tooltip.entity-attribute-default", "type": "string", "default": "true", + "enum": [ + "true", + "false" + ], "enumNames": [ "True", "False" ] + }, + "persistValue": { + "type": "string", + "title": "label.entity-attribute-persist-value", + "description": "tooltip.entity-attribute-persist-value", + "minLength": 1, + "maxLength": 255 + }, + "persistType": { + "type": "string", + "title": "label.entity-attribute-persist-type", + "description": "tooltip.entity-attribute-persist-type", + "default": "string" + }, + "invert": { + "type": "boolean", + "title": "label.entity-attribute-invert", + "description": "tooltip.entity-attribute-invert" } } }, From 3a968af73eb6704e1863f97cb380642b302b8bc9 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 23 Jun 2021 14:14:45 -0700 Subject: [PATCH 30/51] fixing attribute form --- .../assets/schema/attribute/attribute.schema.json | 14 +++----------- .../app/form/component/widgets/CheckboxWidget.js | 2 +- ui/src/app/form/component/widgets/RadioWidget.js | 2 +- .../domain/attribute/CustomAttributeDefinition.js | 13 +++++++++---- .../app/metadata/editor/MetadataAttributeEditor.js | 1 - ui/src/app/metadata/view/MetadataAttributeEdit.js | 2 +- ui/src/app/metadata/view/MetadataAttributeList.js | 4 ++-- 7 files changed, 17 insertions(+), 21 deletions(-) diff --git a/ui/public/assets/schema/attribute/attribute.schema.json b/ui/public/assets/schema/attribute/attribute.schema.json index 2410125c4..d723d8d2a 100644 --- a/ui/public/assets/schema/attribute/attribute.schema.json +++ b/ui/public/assets/schema/attribute/attribute.schema.json @@ -93,19 +93,11 @@ "BOOLEAN" ] }, - "defaultValue": { + "defaultValueBoolean": { "title": "label.entity-attribute-default", "description": "tooltip.entity-attribute-default", - "type": "string", - "default": "true", - "enum": [ - "true", - "false" - ], - "enumNames": [ - "True", - "False" - ] + "type": "boolean", + "default": true }, "persistValue": { "type": "string", diff --git a/ui/src/app/form/component/widgets/CheckboxWidget.js b/ui/src/app/form/component/widgets/CheckboxWidget.js index b1833159c..c95d7e921 100644 --- a/ui/src/app/form/component/widgets/CheckboxWidget.js +++ b/ui/src/app/form/component/widgets/CheckboxWidget.js @@ -41,7 +41,7 @@ const CheckboxWidget = (props) => { {schema.description && } } - checked={typeof value === "undefined" ? false : value} + checked={typeof value === "undefined" ? false : typeof value === 'boolean' ? value : value === 'true' ? true : false} required={required} disabled={disabled || readonly} autoFocus={autofocus} diff --git a/ui/src/app/form/component/widgets/RadioWidget.js b/ui/src/app/form/component/widgets/RadioWidget.js index c92d63e95..2ce07349d 100644 --- a/ui/src/app/form/component/widgets/RadioWidget.js +++ b/ui/src/app/form/component/widgets/RadioWidget.js @@ -46,7 +46,7 @@ const RadioWidget = ({ const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1; - const checked = option.value === value; + const checked = option.value.toString() === value.toString(); const radio = ( -
{JSON.stringify(errors, null, 4)}
); } \ No newline at end of file diff --git a/ui/src/app/metadata/view/MetadataAttributeEdit.js b/ui/src/app/metadata/view/MetadataAttributeEdit.js index d0c04f287..ea81c975e 100644 --- a/ui/src/app/metadata/view/MetadataAttributeEdit.js +++ b/ui/src/app/metadata/view/MetadataAttributeEdit.js @@ -35,7 +35,7 @@ export function MetadataAttributeEdit() { } async function save(metadata) { - const resp = await put(``, definition.parser(metadata)); + const resp = await put(`/${id}`, definition.parser(metadata)); if (response.ok) { gotoDetail({ refresh: true }); } else { diff --git a/ui/src/app/metadata/view/MetadataAttributeList.js b/ui/src/app/metadata/view/MetadataAttributeList.js index b72c3c0e7..f585f805f 100644 --- a/ui/src/app/metadata/view/MetadataAttributeList.js +++ b/ui/src/app/metadata/view/MetadataAttributeList.js @@ -63,13 +63,13 @@ export function MetadataAttributeList ({entities, onDelete}) { {attr.helpText} {attr.defaultValue?.toString()} - + Edit -