From 0f3c25302b5938c77530b5779732e94d535e5ef9 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 21 Oct 2010 21:00:48 +0000 Subject: [PATCH] Add legacy option for fallback to OrgDisplayName, use UTF-8 for names. --- saml/saml2/metadata/DiscoverableMetadataProvider.h | 21 +- .../metadata/impl/DiscoverableMetadataProvider.cpp | 316 ++++++++++++--------- saml/saml2/metadata/impl/XMLMetadataProvider.cpp | 2 +- 3 files changed, 196 insertions(+), 143 deletions(-) diff --git a/saml/saml2/metadata/DiscoverableMetadataProvider.h b/saml/saml2/metadata/DiscoverableMetadataProvider.h index a9bdb5a..daa78fe 100644 --- a/saml/saml2/metadata/DiscoverableMetadataProvider.h +++ b/saml/saml2/metadata/DiscoverableMetadataProvider.h @@ -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: + * + *
+ *
legacyOrgNames
+ *
true iff IdPs without a UIInfo extension should + * be identified using <md:OrganizationDisplayName>
+ *
+ * + * @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) diff --git a/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp b/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp index 1e3a9bc..634caf6 100644 --- a/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp @@ -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& 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::const_iterator idp = idps.begin(); idp != idps.end(); ++idp) { - if ((*idp)->getExtensions()) { - const vector& exts = const_cast((*idp)->getExtensions())->getUnknownXMLObjects(); - for (vector::const_iterator ext = exts.begin(); ext != exts.end(); ++ext) { - const UIInfo* info = dynamic_cast(*ext); - if (info) { - const vector& dispnames = info->getDisplayNames(); - if (!dispnames.empty()) { - s += ",\n \"DisplayNames\": ["; - for (vector::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& descs = info->getDescriptions(); - if (!descs.empty()) { - s += ",\n \"Descriptions\": ["; - for (vector::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& infurls = info->getInformationURLs(); - if (!infurls.empty()) { - s += ",\n \"InformationURLs\": ["; - for (vector::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& privs = info->getPrivacyStatementURLs(); - if (!privs.empty()) { - s += ",\n \"PrivacyStatementURLs\": ["; - for (vector::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& logos = info->getLogos(); - if (!logos.empty()) { - s += ",\n \"Logos\": ["; - for (vector::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& groups = group->getEntitiesDescriptors(); - for (vector::const_iterator i = groups.begin(); i != groups.end(); ++i) - disco(s, *i, first); - - const vector& sites = group->getEntityDescriptors(); - for (vector::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& 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::const_iterator idp = idps.begin(); !extFound && idp != idps.end(); ++idp) { + if ((*idp)->isValid(now) && (*idp)->getExtensions()) { + const vector& exts = const_cast((*idp)->getExtensions())->getUnknownXMLObjects(); + for (vector::const_iterator ext = exts.begin(); !extFound && ext != exts.end(); ++ext) { + const UIInfo* info = dynamic_cast(*ext); + if (info) { + extFound = true; + const vector& dispnames = info->getDisplayNames(); + if (!dispnames.empty()) { + s += ",\n \"DisplayNames\": ["; + for (vector::const_iterator dispname = dispnames.begin(); dispname != dispnames.end(); ++dispname) { + if (dispname != dispnames.begin()) + s += ','; + auto_arrayptr 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& descs = info->getDescriptions(); + if (!descs.empty()) { + s += ",\n \"Descriptions\": ["; + for (vector::const_iterator desc = descs.begin(); desc != descs.end(); ++desc) { + if (desc != descs.begin()) + s += ','; + auto_arrayptr 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& infurls = info->getInformationURLs(); + if (!infurls.empty()) { + s += ",\n \"InformationURLs\": ["; + for (vector::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& privs = info->getPrivacyStatementURLs(); + if (!privs.empty()) { + s += ",\n \"PrivacyStatementURLs\": ["; + for (vector::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& logos = info->getLogos(); + if (!logos.empty()) { + s += ",\n \"Logos\": ["; + for (vector::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::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& odns = org->getOrganizationDisplayNames(); + if (!odns.empty()) { + s += ",\n \"DisplayNames\": ["; + for (vector::const_iterator dispname = odns.begin(); dispname != odns.end(); ++dispname) { + if (dispname != odns.begin()) + s += ','; + auto_arrayptr 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& groups = group->getEntitiesDescriptors(); + for (vector::const_iterator i = groups.begin(); i != groups.end(); ++i) + disco(s, *i, first); + + const vector& sites = group->getEntityDescriptors(); + for (vector::const_iterator j = sites.begin(); j != sites.end(); ++j) + disco(s, *j, first); + } +} diff --git a/saml/saml2/metadata/impl/XMLMetadataProvider.cpp b/saml/saml2/metadata/impl/XMLMetadataProvider.cpp index 3d88264..2f410bd 100644 --- a/saml/saml2/metadata/impl/XMLMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/XMLMetadataProvider.cpp @@ -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)), -- 2.1.4