[cpp-opensaml] branch main updated: CPPOST-118 - Metadata filter for adding UIInfo extensions
Scott Cantor
cantor.2 at osu.edu
Mon Dec 7 15:22:29 UTC 2020
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository cpp-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-opensaml.git;a=commit;h=b627a28d0b270c7c9fd7a47a0b2089b5353f8b81
The following commit(s) were added to refs/heads/main by this push:
new b627a28 CPPOST-118 - Metadata filter for adding UIInfo extensions
b627a28 is described below
commit b627a28d0b270c7c9fd7a47a0b2089b5353f8b81
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Dec 7 10:21:43 2020 -0500
CPPOST-118 - Metadata filter for adding UIInfo extensions
https://issues.shibboleth.net/jira/browse/CPPOST-118
---
Projects/vc15/saml/saml.vcxproj | 1 +
Projects/vc15/saml/saml.vcxproj.filters | 3 +
saml/Makefile.am | 1 +
saml/saml2/metadata/MetadataFilter.h | 3 +
.../impl/EntityAttributesMetadataFilter.cpp | 2 +-
saml/saml2/metadata/impl/MetadataProvider.cpp | 7 +-
saml/saml2/metadata/impl/UIInfoMetadataFilter.cpp | 183 +++++++++++++++++++++
7 files changed, 197 insertions(+), 3 deletions(-)
diff --git a/Projects/vc15/saml/saml.vcxproj b/Projects/vc15/saml/saml.vcxproj
index aa96717..7fe001f 100644
--- a/Projects/vc15/saml/saml.vcxproj
+++ b/Projects/vc15/saml/saml.vcxproj
@@ -202,6 +202,7 @@
<ClCompile Include="..\..\..\saml\saml2\metadata\impl\InlineLogoMetadataFilter.cpp" />
<ClCompile Include="..\..\..\saml\saml2\metadata\impl\NameEntityMatcher.cpp" />
<ClCompile Include="..\..\..\saml\saml2\metadata\impl\RegistrationAuthorityEntityMatcher.cpp" />
+ <ClCompile Include="..\..\..\saml\saml2\metadata\impl\UIInfoMetadataFilter.cpp" />
<ClCompile Include="..\..\..\saml\SAMLConfig.cpp" />
<ClCompile Include="..\..\..\saml\util\CommonDomainCookie.cpp" />
<ClCompile Include="..\..\..\saml\util\SAMLConstants.cpp" />
diff --git a/Projects/vc15/saml/saml.vcxproj.filters b/Projects/vc15/saml/saml.vcxproj.filters
index 4d922ae..a916981 100644
--- a/Projects/vc15/saml/saml.vcxproj.filters
+++ b/Projects/vc15/saml/saml.vcxproj.filters
@@ -369,6 +369,9 @@
<ClCompile Include="..\..\..\saml\saml2\metadata\impl\InlineLogoMetadataFilter.cpp">
<Filter>Source Files\saml2\metadata\impl</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\saml\saml2\metadata\impl\UIInfoMetadataFilter.cpp">
+ <Filter>Source Files\saml2\metadata\impl</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\saml\Assertion.h">
diff --git a/saml/Makefile.am b/saml/Makefile.am
index 048ebdd..d60c0d3 100644
--- a/saml/Makefile.am
+++ b/saml/Makefile.am
@@ -154,6 +154,7 @@ libsaml_la_SOURCES = \
saml2/metadata/impl/InlineLogoMetadataFilter.cpp \
saml2/metadata/impl/RequireValidUntilMetadataFilter.cpp \
saml2/metadata/impl/SignatureMetadataFilter.cpp \
+ saml2/metadata/impl/UIInfoMetadataFilter.cpp \
saml2/metadata/impl/RegistrationAuthorityEntityMatcher.cpp \
saml2/metadata/impl/XMLMetadataProvider.cpp \
saml2/binding/impl/SAML2Artifact.cpp \
diff --git a/saml/saml2/metadata/MetadataFilter.h b/saml/saml2/metadata/MetadataFilter.h
index e1632d8..5f83c70 100644
--- a/saml/saml2/metadata/MetadataFilter.h
+++ b/saml/saml2/metadata/MetadataFilter.h
@@ -138,6 +138,9 @@ namespace opensaml {
/** MetadataFilter that adds EntityAttributes extension. */
#define ENTITYATTR_METADATA_FILTER "EntityAttributes"
+ /** MetadataFilter that adds UIInfo extension. */
+ #define UIINFO_METADATA_FILTER "UIInfo"
+
/** MetadataFilter that removes inline logos from metadata. */
#define INLINELOGO_METADATA_FILTER "InlineLogo"
diff --git a/saml/saml2/metadata/impl/EntityAttributesMetadataFilter.cpp b/saml/saml2/metadata/impl/EntityAttributesMetadataFilter.cpp
index 390d1c7..df19038 100644
--- a/saml/saml2/metadata/impl/EntityAttributesMetadataFilter.cpp
+++ b/saml/saml2/metadata/impl/EntityAttributesMetadataFilter.cpp
@@ -151,7 +151,7 @@ void EntityAttributesMetadataFilter::filterEntity(EntityDescriptor* entity) cons
{
if (!entity->getEntityID())
return;
-
+
pair<applymap_t::const_iterator,applymap_t::const_iterator> tags = m_applyMap.equal_range(entity->getEntityID());
if (tags.first != tags.second) {
EntityAttributes* wrapper = getEntityAttributes(entity);
diff --git a/saml/saml2/metadata/impl/MetadataProvider.cpp b/saml/saml2/metadata/impl/MetadataProvider.cpp
index 0b0e922..b2aa2a6 100644
--- a/saml/saml2/metadata/impl/MetadataProvider.cpp
+++ b/saml/saml2/metadata/impl/MetadataProvider.cpp
@@ -59,6 +59,7 @@ namespace opensaml {
SAML_DLLLOCAL PluginManager<MetadataFilter,string,const DOMElement*>::Factory RequireValidUntilMetadataFilterFactory;
SAML_DLLLOCAL PluginManager<MetadataFilter,string,const DOMElement*>::Factory EntityRoleMetadataFilterFactory;
SAML_DLLLOCAL PluginManager<MetadataFilter,string,const DOMElement*>::Factory EntityAttributesMetadataFilterFactory;
+ SAML_DLLLOCAL PluginManager<MetadataFilter,string,const DOMElement*>::Factory UIInfoMetadataFilterFactory;
};
};
@@ -78,11 +79,13 @@ void SAML_API opensaml::saml2md::registerMetadataFilters()
SAMLConfig::getConfig().MetadataFilterManager.registerFactory(INCLUDE_METADATA_FILTER, IncludeMetadataFilterFactory);
SAMLConfig::getConfig().MetadataFilterManager.registerFactory(INLINELOGO_METADATA_FILTER, InlineLogoMetadataFilterFactory);
SAMLConfig::getConfig().MetadataFilterManager.registerFactory(SIGNATURE_METADATA_FILTER, SignatureMetadataFilterFactory);
+ SAMLConfig::getConfig().MetadataFilterManager.registerFactory(ENTITYROLE_METADATA_FILTER, EntityRoleMetadataFilterFactory);
+ SAMLConfig::getConfig().MetadataFilterManager.registerFactory(ENTITYATTR_METADATA_FILTER, EntityAttributesMetadataFilterFactory);
+ SAMLConfig::getConfig().MetadataFilterManager.registerFactory(UIINFO_METADATA_FILTER, UIInfoMetadataFilterFactory);
+
SAMLConfig::getConfig().MetadataFilterManager.registerFactory(REQUIREVALIDUNTIL_METADATA_FILTER, RequireValidUntilMetadataFilterFactory);
// additional name matching Java code
SAMLConfig::getConfig().MetadataFilterManager.registerFactory("RequiredValidUntil", RequireValidUntilMetadataFilterFactory);
- SAMLConfig::getConfig().MetadataFilterManager.registerFactory(ENTITYROLE_METADATA_FILTER, EntityRoleMetadataFilterFactory);
- SAMLConfig::getConfig().MetadataFilterManager.registerFactory(ENTITYATTR_METADATA_FILTER, EntityAttributesMetadataFilterFactory);
// Deprecated names.
SAMLConfig::getConfig().MetadataFilterManager.registerFactory(BLACKLIST_METADATA_FILTER, ExcludeMetadataFilterFactory);
diff --git a/saml/saml2/metadata/impl/UIInfoMetadataFilter.cpp b/saml/saml2/metadata/impl/UIInfoMetadataFilter.cpp
new file mode 100644
index 0000000..fd0d609
--- /dev/null
+++ b/saml/saml2/metadata/impl/UIInfoMetadataFilter.cpp
@@ -0,0 +1,183 @@
+/**
+ * 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.
+ *
+ * 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.
+ */
+
+/**
+ * UIInfoMetadataFilter.cpp
+ *
+ * Adds UIInfo extension to entities.
+ */
+
+#include "internal.h"
+#include "saml2/metadata/Metadata.h"
+#include "saml2/metadata/MetadataFilter.h"
+
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/casts.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
+#include <xmltooling/logging.h>
+
+using namespace opensaml::saml2;
+using namespace opensaml::saml2md;
+using namespace xmltooling::logging;
+using namespace xmltooling;
+using namespace boost::lambda;
+using namespace boost;
+using namespace std;
+
+namespace opensaml {
+ namespace saml2md {
+
+ class SAML_DLLLOCAL UIInfoMetadataFilter : public MetadataFilter
+ {
+ public:
+ UIInfoMetadataFilter(const DOMElement* e);
+ ~UIInfoMetadataFilter() {}
+
+ const char* getId() const { return UIINFO_METADATA_FILTER; }
+ void doFilter(const MetadataFilterContext* ctx, XMLObject& xmlObject) const;
+
+ private:
+ void filterEntity(EntityDescriptor* entity) const;
+ void filterGroup(EntitiesDescriptor* entities) const;
+ Extensions* getContainer(IDPSSODescriptor* entity) const;
+
+ Category& m_log;
+ bool m_replace;
+ vector< boost::shared_ptr<UIInfo> > m_infos;
+ typedef map<xstring,const UIInfo*> applymap_t;
+ applymap_t m_applyMap;
+ };
+
+ MetadataFilter* SAML_DLLLOCAL UIInfoMetadataFilterFactory(const DOMElement* const & e, bool)
+ {
+ return new UIInfoMetadataFilter(e);
+ }
+
+ static const XMLCh Entity[] = UNICODE_LITERAL_6(E,n,t,i,t,y);
+ static const XMLCh replace[] = UNICODE_LITERAL_7(r,e,p,l,a,c,e);
+ };
+};
+
+
+UIInfoMetadataFilter::UIInfoMetadataFilter(const DOMElement* e)
+ : m_log(Category::getInstance(SAML_LOGCAT".MetadataFilter.UIInfo")),
+ m_replace(XMLHelper::getAttrBool(e, false, replace))
+{
+ // Contains ordered set of UIInfo and Entity elements.
+ // We track each one we find, and then consume an Entity by adding.
+ // a mapping from the Entity to the last-seen UIInfo.
+
+ const UIInfo* lastSeen = nullptr;
+
+ DOMElement* child = XMLHelper::getFirstChildElement(e);
+ while (child) {
+ if (XMLHelper::isNodeNamed(child, samlconstants::SAML20MD_UI_NS, UIInfo::LOCAL_NAME)) {
+ boost::shared_ptr<XMLObject> obj(UIInfoBuilder::buildOneFromElement(child));
+ m_infos.push_back(boost::dynamic_pointer_cast<UIInfo>(obj));
+ lastSeen = m_infos.back().get();
+ }
+ else if (XMLString::equals(child->getLocalName(), Entity)) {
+ const XMLCh* eid = XMLHelper::getTextContent(child);
+ if (eid && *eid && lastSeen) {
+ m_applyMap.insert(applymap_t::value_type(eid, lastSeen));
+ }
+ }
+ else {
+ m_log.warn("ignoring unrecognized element, one of mdui:UIInfo or Entity required");
+ }
+ child = XMLHelper::getNextSiblingElement(child);
+ }
+
+ if (m_applyMap.empty()) {
+ m_log.warn("UIInfo filter has no rules to apply");
+ }
+}
+
+void UIInfoMetadataFilter::doFilter(const MetadataFilterContext*, XMLObject& xmlObject) const
+{
+ if (m_applyMap.empty())
+ return;
+
+ EntitiesDescriptor* group = dynamic_cast<EntitiesDescriptor*>(&xmlObject);
+ if (group) {
+ filterGroup(group);
+ }
+ else {
+ EntityDescriptor* entity = dynamic_cast<EntityDescriptor*>(&xmlObject);
+ if (entity) {
+ filterEntity(entity);
+ }
+ else {
+ throw MetadataFilterException(UIINFO_METADATA_FILTER " MetadataFilter was given an improper metadata instance to filter.");
+ }
+ }
+}
+
+void UIInfoMetadataFilter::filterGroup(EntitiesDescriptor* entities) const
+{
+ const vector<EntityDescriptor*>& v = const_cast<const EntitiesDescriptor*>(entities)->getEntityDescriptors();
+ for_each(v.begin(), v.end(), lambda::bind(&UIInfoMetadataFilter::filterEntity, this, _1));
+
+ const vector<EntitiesDescriptor*>& v2 = const_cast<const EntitiesDescriptor*>(entities)->getEntitiesDescriptors();
+ for_each(v2.begin(), v2.end(), lambda::bind(&UIInfoMetadataFilter::filterGroup, this, _1));
+}
+
+void UIInfoMetadataFilter::filterEntity(EntityDescriptor* entity) const
+{
+ if (!entity->getEntityID())
+ return;
+
+ applymap_t::const_iterator uiinfo = m_applyMap.find(entity->getEntityID());
+ if (uiinfo == m_applyMap.end())
+ return;
+
+ VectorOf(IDPSSODescriptor) roles = entity->getIDPSSODescriptors();
+ for (VectorOf(IDPSSODescriptor)::iterator i = roles.begin(); i != roles.end(); ++i) {
+ Extensions* ext = getContainer(*i);
+ if (ext) {
+ auto_ptr<UIInfo> dup(uiinfo->second->cloneUIInfo());
+ ext->getUnknownXMLObjects().push_back(dup.get());
+ dup.release();
+ }
+ }
+}
+
+Extensions* UIInfoMetadataFilter::getContainer(IDPSSODescriptor* role) const
+{
+ Extensions* exts = role->getExtensions();
+ if (!exts) {
+ role->setExtensions(ExtensionsBuilder::buildExtensions());
+ return role->getExtensions();
+ }
+
+ VectorOf(XMLObject) children = exts->getUnknownXMLObjects();
+ for (VectorOf(XMLObject)::iterator i = children.begin(); i != children.end(); ++i) {
+ if (dynamic_cast<UIInfo*>(*i)) {
+ if (!m_replace)
+ return nullptr;
+ children.erase(i);
+ break;
+ }
+ }
+
+ return exts;
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list