[java-shib-metadata] branch main updated: Restore indirected version of PredicateFilterParser.
Scott Cantor
cantor.2 at osu.edu
Wed Jul 6 14:13:06 UTC 2022
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-shib-metadata.
View the commit online:
http://git.shibboleth.net/view/?p=java-shib-metadata.git;a=commit;h=eead653bbe379e348af2f8335e2d5d5b2dee1343
The following commit(s) were added to refs/heads/main by this push:
new eead653bb Restore indirected version of PredicateFilterParser.
eead653bb is described below
commit eead653bbe379e348af2f8335e2d5d5b2dee1343
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Jul 6 10:13:04 2022 -0400
Restore indirected version of PredicateFilterParser.
---
.../spring/metadata/MetadataNamespaceHandler.java | 2 +
.../PredicateFilterDirectionFactoryBean.java | 63 ++++
.../metadata/filter/PredicateFilterParser.java | 336 +++++++++++++++++++++
3 files changed, 401 insertions(+)
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/MetadataNamespaceHandler.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/MetadataNamespaceHandler.java
index ea8ae3801..74807e15c 100644
--- a/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/MetadataNamespaceHandler.java
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/MetadataNamespaceHandler.java
@@ -29,6 +29,7 @@ import net.shibboleth.spring.metadata.filter.EntityRoleFilterParser;
import net.shibboleth.spring.metadata.filter.KeyAuthorityParser;
import net.shibboleth.spring.metadata.filter.NameIDFormatFilterParser;
import net.shibboleth.spring.metadata.filter.NodeProcessingParser;
+import net.shibboleth.spring.metadata.filter.PredicateFilterParser;
import net.shibboleth.spring.metadata.filter.RequiredValidUntilParser;
import net.shibboleth.spring.metadata.filter.SchemaValidationParser;
import net.shibboleth.spring.metadata.filter.SignatureValidationParser;
@@ -63,6 +64,7 @@ public class MetadataNamespaceHandler extends BaseSpringNamespaceHandler {
new LocalDynamicMetadataProviderParser());
// Filters
+ registerBeanDefinitionParser(PredicateFilterParser.TYPE_NAME, new PredicateFilterParser());
registerBeanDefinitionParser(RequiredValidUntilParser.TYPE_NAME, new RequiredValidUntilParser());
registerBeanDefinitionParser(AlgorithmFilterParser.TYPE_NAME, new AlgorithmFilterParser());
registerBeanDefinitionParser(EntityAttributesFilterParser.TYPE_NAME, new EntityAttributesFilterParser());
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/filter/PredicateFilterDirectionFactoryBean.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/filter/PredicateFilterDirectionFactoryBean.java
new file mode 100644
index 000000000..aaf1bf678
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/filter/PredicateFilterDirectionFactoryBean.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.metadata.filter;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.saml.metadata.resolver.filter.impl.PredicateFilter;
+import org.opensaml.saml.metadata.resolver.filter.impl.PredicateFilter.Direction;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+
+/**
+ * Factory bean allow property replacements of the direction going in to a {@link PredicateFilter}.
+ */
+public class PredicateFilterDirectionFactoryBean extends AbstractFactoryBean<PredicateFilter.Direction> {
+
+ /** What we want to set the value from this should be "exclude" or "include".*/
+ @Nullable private final String value;
+
+ /**
+ * Constructor.
+ * @param what the value to set
+ */
+ public PredicateFilterDirectionFactoryBean(@Nullable final String what) {
+ value = what;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Class<?> getObjectType() {
+ return PredicateFilter.Direction.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected Direction createInstance() throws Exception {
+ if (value == null) {
+ throw new BeanCreationException("Predicate filter requires 'direction' attribute");
+ } else if ("exclude".equals(value)) {
+ return PredicateFilter.Direction.EXCLUDE;
+ } else if ("include".equals(value)) {
+ return PredicateFilter.Direction.INCLUDE;
+ } else {
+ throw new BeanCreationException("Predicate filter direction must be 'include' or 'exclude'");
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/filter/PredicateFilterParser.java b/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/filter/PredicateFilterParser.java
new file mode 100644
index 000000000..6507b8467
--- /dev/null
+++ b/shib-metadata-spring/src/main/java/net/shibboleth/spring/metadata/filter/PredicateFilterParser.java
@@ -0,0 +1,336 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.spring.metadata.filter;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.xml.namespace.QName;
+
+import org.opensaml.saml.common.profile.logic.EntityAttributesPredicate;
+import org.opensaml.saml.common.profile.logic.EntityAttributesPredicate.Candidate;
+import org.opensaml.saml.common.profile.logic.EntityGroupNamePredicate;
+import org.opensaml.saml.common.profile.logic.EntityIdPredicate;
+import org.opensaml.saml.metadata.resolver.filter.impl.PredicateFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+import net.shibboleth.ext.spring.util.AbstractCustomBeanDefinitionParser;
+import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.spring.ScriptTypeBeanParser;
+import net.shibboleth.spring.metadata.AbstractMetadataProviderParser;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.logic.PredicateSupport;
+import net.shibboleth.utilities.java.support.logic.ScriptedPredicate;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+/**
+ * Parser for a <Predicate> filter.
+ */
+public class PredicateFilterParser extends AbstractCustomBeanDefinitionParser {
+
+ /** Element name. */
+ @Nonnull public static final QName TYPE_NAME =
+ new QName(AbstractMetadataProviderParser.METADATA_NAMESPACE, "Predicate");
+
+ /** Name of class to attempt to instantiate to handle mapped attribute predicate. */
+ @Nonnull @NotEmpty private static final String MAPPED_PREDICATE_CLASS =
+ "net.shibboleth.idp.saml.profile.logic.MappedEntityAttributesPredicate";
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(PredicateFilterParser.class);
+
+ /** Stores class of the predicate handling the mapped entity attribute feature. */
+ @Nullable private Class<? extends Predicate<?>> mappedPredicateClass;
+
+ /** Constructor. */
+ @SuppressWarnings("unchecked")
+ public PredicateFilterParser() {
+ try {
+ mappedPredicateClass = (Class<? extends Predicate<?>>) Class.forName(MAPPED_PREDICATE_CLASS);
+ } catch (final ClassNotFoundException e) {
+ // Will warn later any time we encounter a relevant setting.
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Class<?> getBeanClass(final Element element) {
+ return PredicateFilter.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doParse(final Element element, final ParserContext parserContext,
+ final BeanDefinitionBuilder builder) {
+
+ if (element.hasAttributeNS(null, "removeEmptyEntitiesDescriptors")) {
+ builder.addPropertyValue("removeEmptyEntitiesDescriptors", SpringSupport.getStringValueAsBoolean(
+ element.getAttributeNS(null, "removeEmptyEntitiesDescriptors")));
+ }
+
+ final BeanDefinitionBuilder directionBuilder =
+ BeanDefinitionBuilder.genericBeanDefinition(PredicateFilterDirectionFactoryBean.class);
+ directionBuilder.addConstructorArgValue(StringSupport.trimOrNull(element.getAttributeNS(null, "direction")));
+ builder.addConstructorArgValue(directionBuilder.getBeanDefinition());
+
+ if (element.hasAttributeNS(null, "conditionRef")) {
+ log.info("Found conditionRef attribute, ignoring embedded Entity/Group/Tag elements");
+ builder.addConstructorArgReference(StringSupport.trimOrNull(element.getAttributeNS(null, "conditionRef")));
+ } else {
+ builder.addConstructorArgValue(parseCustomElements(element));
+ }
+ }
+
+// Checkstyle: CyclomaticComplexity OFF
+ /**
+ * Parser custom element content into a {@link java.util.function.Predicate} to pass to the filter constructor.
+ *
+ * @param element root element to parse
+ *
+ * @return the bean definition of the Predicate to install
+ */
+ @Nonnull public BeanDefinition parseCustomElements(@Nonnull final Element element) {
+
+ // Track which predicates have to be built.
+ final BeanDefinitionBuilder entityIdPredicateBuilder = parseEntityPredicate(element);
+ final BeanDefinitionBuilder groupPredicateBuilder = parseGroupPredicate(element);
+ final BeanDefinitionBuilder tagPredicateBuilder = parseTagPredicate(element);
+ final BeanDefinitionBuilder mappedTagPredicateBuilder = parseMappedTagPredicate(element);
+ final BeanDefinitionBuilder scriptPredicateBuilder = parseScripts(element);
+
+ int count = 0;
+ if (entityIdPredicateBuilder != null) {
+ count++;
+ }
+ if (groupPredicateBuilder != null) {
+ count++;
+ }
+ if (tagPredicateBuilder != null) {
+ count++;
+ }
+ if (mappedTagPredicateBuilder != null) {
+ count++;
+ }
+ if (scriptPredicateBuilder != null) {
+ count++;
+ }
+
+ if (count == 0) {
+ throw new BeanCreationException("No Entity, Group, Tag, or ConditionScript element found");
+ } else if (count == 1) {
+ if (entityIdPredicateBuilder != null) {
+ return entityIdPredicateBuilder.getBeanDefinition();
+ } else if (groupPredicateBuilder != null) {
+ return groupPredicateBuilder.getBeanDefinition();
+ } else if (tagPredicateBuilder != null) {
+ return tagPredicateBuilder.getBeanDefinition();
+ } else if (mappedTagPredicateBuilder != null) {
+ return mappedTagPredicateBuilder.getBeanDefinition();
+ } else {
+ return scriptPredicateBuilder.getBeanDefinition();
+ }
+ } else {
+ final BeanDefinitionBuilder orBuilder =
+ BeanDefinitionBuilder.rootBeanDefinition(PredicateSupport.class, "or");
+ final ManagedList<BeanDefinition> managedList = new ManagedList<>(count);
+ if (entityIdPredicateBuilder != null) {
+ managedList.add(entityIdPredicateBuilder.getBeanDefinition());
+ }
+ if (groupPredicateBuilder != null) {
+ managedList.add(groupPredicateBuilder.getBeanDefinition());
+ }
+ if (tagPredicateBuilder != null) {
+ managedList.add(tagPredicateBuilder.getBeanDefinition());
+ }
+ if (mappedTagPredicateBuilder != null) {
+ managedList.add(mappedTagPredicateBuilder.getBeanDefinition());
+ }
+ if (scriptPredicateBuilder != null) {
+ managedList.add(scriptPredicateBuilder.getBeanDefinition());
+ }
+ orBuilder.addConstructorArgValue(managedList);
+ return orBuilder.getBeanDefinition();
+ }
+ }
+
+// Checkstyle: CyclomaticComplexity ON
+
+ /**
+ * Parse Entity elements into a builder for an {@link EntityIdPredicate}.
+ *
+ * @param element root element to parse under
+ *
+ * @return builder for the predicate, or null if none needed
+ */
+ @Nullable public BeanDefinitionBuilder parseEntityPredicate(@Nonnull final Element element) {
+ final List<Element> entityList =
+ ElementSupport.getChildElementsByTagNameNS(element, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+ "Entity");
+ if (!entityList.isEmpty()) {
+ final ManagedList<String> managedEntityList = SpringSupport.getElementTextContentAsManagedList(entityList);
+ final BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(EntityIdPredicate.class);
+ builder.addConstructorArgValue(managedEntityList);
+ return builder;
+ }
+
+ return null;
+ }
+
+ /**
+ * Parse Group elements into a builder for an {@link EntityGroupNamePredicate}.
+ *
+ * @param element root element to parse under
+ *
+ * @return builder for the predicate, or null if none needed
+ */
+ @Nullable public BeanDefinitionBuilder parseGroupPredicate(@Nonnull final Element element) {
+
+ final List<Element> groupList =
+ ElementSupport.getChildElementsByTagNameNS(element, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+ "Group");
+ if (!groupList.isEmpty()) {
+ final ManagedList<String> managedGroupList = SpringSupport.getElementTextContentAsManagedList(groupList);
+ final BeanDefinitionBuilder builder =
+ BeanDefinitionBuilder.genericBeanDefinition(EntityGroupNamePredicate.class);
+ builder.addConstructorArgValue(managedGroupList);
+ return builder;
+ }
+
+ return null;
+ }
+
+ /**
+ * Parse Tag elements into a builder for an {@link EntityAttributesPredicate}.
+ *
+ * @param element root element to parse under
+ *
+ * @return builder for the predicate, or null if none needed
+ */
+ @Nullable public BeanDefinitionBuilder parseTagPredicate(@Nonnull final Element element) {
+ final List<Element> tagList =
+ ElementSupport.getChildElementsByTagNameNS(element, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+ "Tag");
+ if (!tagList.isEmpty()) {
+ final ManagedList<BeanDefinition> managedTagList = new ManagedList<>(tagList.size());
+ for (final Element tag : tagList) {
+ final BeanDefinitionBuilder tagBuilder = BeanDefinitionBuilder.genericBeanDefinition(Candidate.class);
+ tagBuilder.addConstructorArgValue(StringSupport.trimOrNull(tag.getAttributeNS(null, "name")));
+ tagBuilder.addConstructorArgValue(StringSupport.trimOrNull(tag.getAttributeNS(null, "nameFormat")));
+ final List<Element> valueList =
+ ElementSupport.getChildElementsByTagNameNS(tag,
+ AbstractMetadataProviderParser.METADATA_NAMESPACE, "Value");
+ if (!valueList.isEmpty()) {
+ final ManagedList<String> managedValueList =
+ SpringSupport.getElementTextContentAsManagedList(valueList);
+ tagBuilder.addPropertyValue("values", managedValueList);
+ }
+ managedTagList.add(tagBuilder.getBeanDefinition());
+ }
+ final BeanDefinitionBuilder builder =
+ BeanDefinitionBuilder.genericBeanDefinition(EntityAttributesPredicate.class);
+ builder.addConstructorArgValue(managedTagList);
+ builder.addConstructorArgValue(SpringSupport.getStringValueAsBoolean(element.getAttributeNS(null, "trim")));
+ return builder;
+ }
+
+ return null;
+ }
+
+ /**
+ * Parse MappedTag elements into a builder for the relevant predicate class.
+ *
+ * @param element root element to parse under
+ *
+ * @return builder for the predicate, or null if none needed
+ */
+ @Nullable public BeanDefinitionBuilder parseMappedTagPredicate(@Nonnull final Element element) {
+
+ final List<Element> tagList =
+ ElementSupport.getChildElementsByTagNameNS(element, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+ "MappedTag");
+ if (!tagList.isEmpty()) {
+
+ if (mappedPredicateClass == null) {
+ log.warn("Ignoring MappedTag element(s) due to class instantiation failure at startup");
+ return null;
+ }
+
+ final ManagedList<BeanDefinition> managedTagList = new ManagedList<>(tagList.size());
+ for (final Element tag : tagList) {
+ final BeanDefinitionBuilder tagBuilder = BeanDefinitionBuilder.genericBeanDefinition(Candidate.class);
+ tagBuilder.addConstructorArgValue(StringSupport.trimOrNull(tag.getAttributeNS(null, "name")));
+ final List<Element> valueList =
+ ElementSupport.getChildElementsByTagNameNS(tag,
+ AbstractMetadataProviderParser.METADATA_NAMESPACE, "Value");
+ if (!valueList.isEmpty()) {
+ final ManagedList<String> managedValueList =
+ SpringSupport.getElementTextContentAsManagedList(valueList);
+ tagBuilder.addPropertyValue("values", managedValueList);
+ }
+ managedTagList.add(tagBuilder.getBeanDefinition());
+ }
+ final BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(mappedPredicateClass);
+ builder.addConstructorArgValue(managedTagList);
+ builder.addConstructorArgValue(StringSupport.trimOrNull(element.getAttributeNS(null, "trim")));
+ return builder;
+ }
+
+ return null;
+ }
+
+ /**
+ * Parse ConditionScript elements into a builder, wrapped in an OR as necessary.
+ *
+ * @param element root element to parse under
+ *
+ * @return builder for the predicate, or null if none needed
+ */
+ @Nullable public BeanDefinitionBuilder parseScripts(@Nonnull final Element element) {
+ final List<Element> scriptList =
+ ElementSupport.getChildElementsByTagNameNS(element, AbstractMetadataProviderParser.METADATA_NAMESPACE,
+ "ConditionScript");
+ if (scriptList.isEmpty()) {
+ return null;
+ } else if (scriptList.size() == 1) {
+ return ScriptTypeBeanParser.parseScriptType(ScriptedPredicate.class, scriptList.get(0));
+ } else {
+ final BeanDefinitionBuilder orBuilder =
+ BeanDefinitionBuilder.rootBeanDefinition(PredicateSupport.class, "or");
+ final ManagedList<BeanDefinition> managedList = new ManagedList<>(scriptList.size());
+ for (final Element e : scriptList) {
+ managedList.add(ScriptTypeBeanParser.parseScriptType(ScriptedPredicate.class, e).getBeanDefinition());
+ }
+ orBuilder.addConstructorArgValue(managedList);
+ return orBuilder;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected boolean shouldGenerateId() {
+ return true;
+ }
+
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list