Add legacy option for fallback to OrgDisplayName, use UTF-8 for names.
authorScott Cantor <cantor.2@osu.edu>
Thu, 21 Oct 2010 21:00:48 +0000 (21:00 +0000)
committerScott Cantor <cantor.2@osu.edu>
Thu, 21 Oct 2010 21:00:48 +0000 (21:00 +0000)
saml/saml2/metadata/DiscoverableMetadataProvider.h
saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp
saml/saml2/metadata/impl/XMLMetadataProvider.cpp

index a9bdb5a..daa78fe 100644 (file)
@@ -39,7 +39,20 @@ namespace opensaml {
         class SAML_API DiscoverableMetadataProvider : public virtual MetadataProvider
         {
         protected:
-            DiscoverableMetadataProvider();
+            /**
+             * Constructor.
+             *
+             * If a DOM is supplied, the following XML content is supported:
+             *
+             * <dl>
+             *   <dt>legacyOrgNames</dt>
+             *   <dd>true iff IdPs without a UIInfo extension should
+             *      be identified using &lt;md:OrganizationDisplayName&gt;</dd>
+             * </dl>
+             *
+             * @param e DOM to supply configuration for provider
+             */
+            DiscoverableMetadataProvider(const xercesc::DOMElement* e=nullptr);
             
             /**
              * Generates a JSON feed of IdP discovery information for the current metadata.
@@ -73,6 +86,12 @@ namespace opensaml {
 
             /** ETag for feed. */
             mutable std::string m_feedTag;
+
+        private:
+            void disco(std::string& s, const EntityDescriptor* entity, bool& first) const;
+            void disco(std::string& s, const EntitiesDescriptor* group, bool& first) const;
+
+            bool m_legacyOrgNames;
         };
 
 #if defined (_MSC_VER)
index 1e3a9bc..634caf6 100644 (file)
@@ -34,148 +34,10 @@ using namespace opensaml::saml2md;
 using namespace xmltooling;
 using namespace std;
 
-namespace {
-    void disco(string& s, const EntityDescriptor* entity, bool& first) {
-        if (entity) {
-            const vector<IDPSSODescriptor*>& idps = entity->getIDPSSODescriptors();
-            if (!idps.empty()) {
-                auto_ptr_char entityid(entity->getEntityID());
-                // Open a struct and output id: entityID.
-                if (first)
-                    first = false;
-                else
-                    s += ',';
-                s += "\n{\n \"entityID\": \"";
-                s += entityid.get();
-                s += '\"';
-                for (vector<IDPSSODescriptor*>::const_iterator idp = idps.begin(); idp != idps.end(); ++idp) {
-                    if ((*idp)->getExtensions()) {
-                        const vector<XMLObject*>& exts =  const_cast<const Extensions*>((*idp)->getExtensions())->getUnknownXMLObjects();
-                        for (vector<XMLObject*>::const_iterator ext = exts.begin(); ext != exts.end(); ++ext) {
-                            const UIInfo* info = dynamic_cast<UIInfo*>(*ext);
-                            if (info) {
-                                const vector<DisplayName*>& dispnames = info->getDisplayNames();
-                                if (!dispnames.empty()) {
-                                    s += ",\n \"DisplayNames\": [";
-                                    for (vector<DisplayName*>::const_iterator dispname = dispnames.begin(); dispname != dispnames.end(); ++dispname) {
-                                        if (dispname != dispnames.begin())
-                                            s += ',';
-                                        auto_ptr_char val((*dispname)->getName());
-                                        auto_ptr_char lang((*dispname)->getLang());
-                                        s += "\n  {\n  \"value\": \"";
-                                        s += val.get();
-                                        s += "\",\n  \"lang\": \"";
-                                        s += lang.get();
-                                        s += "\"\n  }";
-                                    }
-                                    s += "\n ]";
-                                }
-
-                                const vector<Description*>& descs = info->getDescriptions();
-                                if (!descs.empty()) {
-                                    s += ",\n \"Descriptions\": [";
-                                    for (vector<Description*>::const_iterator desc = descs.begin(); desc != descs.end(); ++desc) {
-                                        if (desc != descs.begin())
-                                            s += ',';
-                                        auto_ptr_char val((*desc)->getDescription());
-                                        auto_ptr_char lang((*desc)->getLang());
-                                        s += "\n  {\n  \"value\": \"";
-                                        s += val.get();
-                                        s += "\",\n  \"lang\": \"";
-                                        s += lang.get();
-                                        s += "\"\n  }";
-                                    }
-                                    s += "\n ]";
-                                }
-
-                                const vector<InformationURL*>& infurls = info->getInformationURLs();
-                                if (!infurls.empty()) {
-                                    s += ",\n \"InformationURLs\": [";
-                                    for (vector<InformationURL*>::const_iterator infurl = infurls.begin(); infurl != infurls.end(); ++infurl) {
-                                        if (infurl != infurls.begin())
-                                            s += ',';
-                                        auto_ptr_char val((*infurl)->getURL());
-                                        auto_ptr_char lang((*infurl)->getLang());
-                                        s += "\n  {\n  \"value\": \"";
-                                        s += val.get();
-                                        s += "\",\n  \"lang\": \"";
-                                        s += lang.get();
-                                        s += "\"\n  }";
-                                    }
-                                    s += "\n ]";
-                                }
-
-                                const vector<PrivacyStatementURL*>& privs = info->getPrivacyStatementURLs();
-                                if (!privs.empty()) {
-                                    s += ",\n \"PrivacyStatementURLs\": [";
-                                    for (vector<PrivacyStatementURL*>::const_iterator priv = privs.begin(); priv != privs.end(); ++priv) {
-                                        if (priv != privs.begin())
-                                            s += ',';
-                                        auto_ptr_char val((*priv)->getURL());
-                                        auto_ptr_char lang((*priv)->getLang());
-                                        s += "\n  {\n  \"value\": \"";
-                                        s += val.get();
-                                        s += "\",\n  \"lang\": \"";
-                                        s += lang.get();
-                                        s += "\"\n  }";
-                                    }
-                                    s += "\n ]";
-                                }
-
-                                const vector<Logo*>& logos = info->getLogos();
-                                if (!logos.empty()) {
-                                    s += ",\n \"Logos\": [";
-                                    for (vector<Logo*>::const_iterator logo = logos.begin(); logo != logos.end(); ++logo) {
-                                        if (logo != logos.begin())
-                                            s += ',';
-                                        s += "\n  {\n";
-                                        auto_ptr_char val((*logo)->getURL());
-                                        s += "  \"value\": \"";
-                                        s += val.get();
-                                        ostringstream ht;
-                                        ht << (*logo)->getHeight().second;
-                                        s += "\",\n  \"height\": \"";
-                                        s += ht.str();
-                                        ht.clear();
-                                        ht << (*logo)->getWidth().second;
-                                        s += "\",\n  \"width\": \"";
-                                        s += ht.str();
-                                        s += '\"';
-                                        if ((*logo)->getLang()) {
-                                            auto_ptr_char lang((*logo)->getLang());
-                                            s += ",\n  \"lang\": \"";
-                                            s += lang.get();
-                                            s += '\"';
-                                        }
-                                        s += "\n  }";
-                                    }
-                                    s += "\n ]";
-                                }
-                            }
-                        }
-                    }
-                }
-                // Close the struct;
-                s += "\n}";
-            }
-        }
-    }
-
-    void disco(string& s, const EntitiesDescriptor* group, bool& first) {
-        if (group) {
-            const vector<EntitiesDescriptor*>& groups = group->getEntitiesDescriptors();
-            for (vector<EntitiesDescriptor*>::const_iterator i = groups.begin(); i != groups.end(); ++i)
-                disco(s, *i, first);
-
-            const vector<EntityDescriptor*>& sites = group->getEntityDescriptors();
-            for (vector<EntityDescriptor*>::const_iterator j = sites.begin(); j != sites.end(); ++j)
-                disco(s, *j, first);
-        }
-    }
-}
-
-DiscoverableMetadataProvider::DiscoverableMetadataProvider()
+DiscoverableMetadataProvider::DiscoverableMetadataProvider(const DOMElement* e) : m_legacyOrgNames(false)
 {
+    static const XMLCh legacyOrgNames[] = UNICODE_LITERAL_14(l,e,g,a,c,y,O,r,g,N,a,m,e,s);
+    m_legacyOrgNames = XMLHelper::getAttrBool(e, false, legacyOrgNames);
 }
 
 DiscoverableMetadataProvider::~DiscoverableMetadataProvider()
@@ -204,3 +66,175 @@ ostream& DiscoverableMetadataProvider::outputFeed(ostream& os) const
 {
     return os << m_feed;
 }
+
+void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* entity, bool& first) const
+{
+    time_t now = time(nullptr);
+    if (entity && entity->isValid(now)) {
+        const vector<IDPSSODescriptor*>& idps = entity->getIDPSSODescriptors();
+        if (!idps.empty()) {
+            auto_ptr_char entityid(entity->getEntityID());
+            // Open a struct and output id: entityID.
+            if (first)
+                first = false;
+            else
+                s += ',';
+            s += "\n{\n \"entityID\": \"";
+            s += entityid.get();
+            s += '\"';
+            bool extFound = false;
+            for (vector<IDPSSODescriptor*>::const_iterator idp = idps.begin(); !extFound && idp != idps.end(); ++idp) {
+                if ((*idp)->isValid(now) && (*idp)->getExtensions()) {
+                    const vector<XMLObject*>& exts =  const_cast<const Extensions*>((*idp)->getExtensions())->getUnknownXMLObjects();
+                    for (vector<XMLObject*>::const_iterator ext = exts.begin(); !extFound && ext != exts.end(); ++ext) {
+                        const UIInfo* info = dynamic_cast<UIInfo*>(*ext);
+                        if (info) {
+                            extFound = true;
+                            const vector<DisplayName*>& dispnames = info->getDisplayNames();
+                            if (!dispnames.empty()) {
+                                s += ",\n \"DisplayNames\": [";
+                                for (vector<DisplayName*>::const_iterator dispname = dispnames.begin(); dispname != dispnames.end(); ++dispname) {
+                                    if (dispname != dispnames.begin())
+                                        s += ',';
+                                    auto_arrayptr<char> val(toUTF8((*dispname)->getName()));
+                                    auto_ptr_char lang((*dispname)->getLang());
+                                    s += "\n  {\n  \"value\": \"";
+                                    s += val.get();
+                                    s += "\",\n  \"lang\": \"";
+                                    s += lang.get();
+                                    s += "\"\n  }";
+                                }
+                                s += "\n ]";
+                            }
+
+                            const vector<Description*>& descs = info->getDescriptions();
+                            if (!descs.empty()) {
+                                s += ",\n \"Descriptions\": [";
+                                for (vector<Description*>::const_iterator desc = descs.begin(); desc != descs.end(); ++desc) {
+                                    if (desc != descs.begin())
+                                        s += ',';
+                                    auto_arrayptr<char> val(toUTF8((*desc)->getDescription()));
+                                    auto_ptr_char lang((*desc)->getLang());
+                                    s += "\n  {\n  \"value\": \"";
+                                    s += val.get();
+                                    s += "\",\n  \"lang\": \"";
+                                    s += lang.get();
+                                    s += "\"\n  }";
+                                }
+                                s += "\n ]";
+                            }
+
+                            const vector<InformationURL*>& infurls = info->getInformationURLs();
+                            if (!infurls.empty()) {
+                                s += ",\n \"InformationURLs\": [";
+                                for (vector<InformationURL*>::const_iterator infurl = infurls.begin(); infurl != infurls.end(); ++infurl) {
+                                    if (infurl != infurls.begin())
+                                        s += ',';
+                                    auto_ptr_char val((*infurl)->getURL());
+                                    auto_ptr_char lang((*infurl)->getLang());
+                                    s += "\n  {\n  \"value\": \"";
+                                    s += val.get();
+                                    s += "\",\n  \"lang\": \"";
+                                    s += lang.get();
+                                    s += "\"\n  }";
+                                }
+                                s += "\n ]";
+                            }
+
+                            const vector<PrivacyStatementURL*>& privs = info->getPrivacyStatementURLs();
+                            if (!privs.empty()) {
+                                s += ",\n \"PrivacyStatementURLs\": [";
+                                for (vector<PrivacyStatementURL*>::const_iterator priv = privs.begin(); priv != privs.end(); ++priv) {
+                                    if (priv != privs.begin())
+                                        s += ',';
+                                    auto_ptr_char val((*priv)->getURL());
+                                    auto_ptr_char lang((*priv)->getLang());
+                                    s += "\n  {\n  \"value\": \"";
+                                    s += val.get();
+                                    s += "\",\n  \"lang\": \"";
+                                    s += lang.get();
+                                    s += "\"\n  }";
+                                }
+                                s += "\n ]";
+                            }
+
+                            const vector<Logo*>& logos = info->getLogos();
+                            if (!logos.empty()) {
+                                s += ",\n \"Logos\": [";
+                                for (vector<Logo*>::const_iterator logo = logos.begin(); logo != logos.end(); ++logo) {
+                                    if (logo != logos.begin())
+                                        s += ',';
+                                    s += "\n  {\n";
+                                    auto_ptr_char val((*logo)->getURL());
+                                    s += "  \"value\": \"";
+                                    s += val.get();
+                                    ostringstream ht;
+                                    ht << (*logo)->getHeight().second;
+                                    s += "\",\n  \"height\": \"";
+                                    s += ht.str();
+                                    ht.clear();
+                                    ht << (*logo)->getWidth().second;
+                                    s += "\",\n  \"width\": \"";
+                                    s += ht.str();
+                                    s += '\"';
+                                    if ((*logo)->getLang()) {
+                                        auto_ptr_char lang((*logo)->getLang());
+                                        s += ",\n  \"lang\": \"";
+                                        s += lang.get();
+                                        s += '\"';
+                                    }
+                                    s += "\n  }";
+                                }
+                                s += "\n ]";
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (m_legacyOrgNames && !extFound) {
+                const Organization* org = nullptr;
+                for (vector<IDPSSODescriptor*>::const_iterator idp = idps.begin(); !org && idp != idps.end(); ++idp) {
+                    if ((*idp)->isValid(now))
+                        org = (*idp)->getOrganization();
+                }
+                if (!org)
+                    org = entity->getOrganization();
+                if (org) {
+                    const vector<OrganizationDisplayName*>& odns = org->getOrganizationDisplayNames();
+                    if (!odns.empty()) {
+                        s += ",\n \"DisplayNames\": [";
+                        for (vector<OrganizationDisplayName*>::const_iterator dispname = odns.begin(); dispname != odns.end(); ++dispname) {
+                            if (dispname != odns.begin())
+                                s += ',';
+                            auto_arrayptr<char> val(toUTF8((*dispname)->getName()));
+                            auto_ptr_char lang((*dispname)->getLang());
+                            s += "\n  {\n  \"value\": \"";
+                            s += val.get();
+                            s += "\",\n  \"lang\": \"";
+                            s += lang.get();
+                            s += "\"\n  }";
+                        }
+                        s += "\n ]";
+                    }
+                }
+            }
+
+            // Close the struct;
+            s += "\n}";
+        }
+    }
+}
+
+void DiscoverableMetadataProvider::disco(string& s, const EntitiesDescriptor* group, bool& first) const
+{
+    if (group) {
+        const vector<EntitiesDescriptor*>& groups = group->getEntitiesDescriptors();
+        for (vector<EntitiesDescriptor*>::const_iterator i = groups.begin(); i != groups.end(); ++i)
+            disco(s, *i, first);
+
+        const vector<EntityDescriptor*>& sites = group->getEntityDescriptors();
+        for (vector<EntityDescriptor*>::const_iterator j = sites.begin(); j != sites.end(); ++j)
+            disco(s, *j, first);
+    }
+}
index 3d88264..2f410bd 100644 (file)
@@ -107,7 +107,7 @@ namespace opensaml {
 #endif
 
 XMLMetadataProvider::XMLMetadataProvider(const DOMElement* e)
-    : AbstractMetadataProvider(e), ReloadableXMLFile(e, Category::getInstance(SAML_LOGCAT".MetadataProvider.XML"), false),
+    : AbstractMetadataProvider(e), DiscoverableMetadataProvider(e), ReloadableXMLFile(e, Category::getInstance(SAML_LOGCAT".MetadataProvider.XML"), false),
         m_object(nullptr), m_discoveryFeed(XMLHelper::getAttrBool(e, true, discoveryFeed)),
         m_refreshDelayFactor(0.75), m_backoffFactor(1),
         m_minRefreshDelay(XMLHelper::getAttrInt(e, 600, minRefreshDelay)),