X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fmetadata%2Fimpl%2FDiscoverableMetadataProvider.cpp;h=ce5950b7c50bf00d98850b91685055ef917b5eb8;hb=f1208cd2f514700244816377443c4951dc22c848;hp=9998e2f1ae1d54f8093297683c0e5afa9b247423;hpb=4f4d6afe8ddda8c4ec806df6c301497e03f20daa;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp b/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp index 9998e2f..ce5950b 100644 --- a/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp @@ -1,17 +1,21 @@ -/* - * Copyright 2010 Internet2 +/** + * 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. * - * Licensed 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 + * 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 + * 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. + * 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. */ /** @@ -26,6 +30,7 @@ #include "saml2/metadata/DiscoverableMetadataProvider.h" #include +#include #include #include @@ -33,144 +38,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 += ",\n"; - s += "{\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 dn((*dispname)->getName()); - auto_ptr_char lang((*dispname)->getLang()); - s += "\n {\n \"value\": \""; - s += dn.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 d((*desc)->getDescription()); - auto_ptr_char lang((*desc)->getLang()); - s += "\n {\n \"value\": \""; - s += d.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 iu((*infurl)->getURL()); - auto_ptr_char lang((*infurl)->getLang()); - s += "\n {\n \"value\": \""; - s += iu.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 pu((*priv)->getURL()); - auto_ptr_char lang((*priv)->getLang()); - s += "\n {\n \"value\": \""; - s += pu.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 imgsrc((*logo)->getURL()); - s += " \"value\": \""; - s += imgsrc.get(); - s += "\",\n \"height\": \""; - s += (*logo)->getHeight().second; - s += "\",\n \"width\": \""; - s += (*logo)->getWidth().second; - 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) : MetadataProvider(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() @@ -179,12 +50,11 @@ DiscoverableMetadataProvider::~DiscoverableMetadataProvider() void DiscoverableMetadataProvider::generateFeed() { + m_feed.erase(); bool first = true; - m_feed = "[\n"; const XMLObject* object = getMetadata(); disco(m_feed, dynamic_cast(object), first); disco(m_feed, dynamic_cast(object), first); - m_feed += "\n]\n"; SAMLConfig::getConfig().generateRandomBytes(m_feedTag, 4); m_feedTag = SAMLArtifact::toHex(m_feedTag); @@ -195,7 +65,237 @@ string DiscoverableMetadataProvider::getCacheTag() const return m_feedTag; } -ostream& DiscoverableMetadataProvider::outputFeed(ostream& os) const +void DiscoverableMetadataProvider::outputFeed(ostream& os, bool& first, bool wrapArray) const +{ + if (wrapArray) + os << '['; + if (!m_feed.empty()) { + if (first) + first = false; + else + os << ",\n"; + os << m_feed; + } + if (wrapArray) + os << "\n]"; +} + +static string& json_safe(string& s, const char* buf) +{ + for (; *buf; ++buf) { + switch (*buf) { + case '\\': + case '"': + s += '\\'; + s += *buf; + break; + case '\b': + s += "\\b"; + break; + case '\t': + s += "\\t"; + break; + case '\n': + s += "\\n"; + break; + case '\f': + s += "\\f"; + break; + case '\r': + s += "\\r"; + break; + default: + s += *buf; + } + } + return s; +} + +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\": \""; + json_safe(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\": \""; + json_safe(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\": \""; + json_safe(s, val.get()); + s += "\",\n \"lang\": \""; + s += lang.get(); + s += "\"\n }"; + } + s += "\n ]"; + } + + const vector& keywords = info->getKeywordss(); + if (!keywords.empty()) { + s += ",\n \"Keywords\": ["; + for (vector::const_iterator words = keywords.begin(); words != keywords.end(); ++words) { + if (words != keywords.begin()) + s += ','; + auto_arrayptr val(toUTF8((*words)->getValues())); + auto_ptr_char lang((*words)->getLang()); + s += "\n {\n \"value\": \""; + json_safe(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\": \""; + json_safe(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\": \""; + json_safe(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\": \""; + json_safe(s, val.get()); + ostringstream ht; + ht << (*logo)->getHeight().second; + s += "\",\n \"height\": \""; + s += ht.str(); + ostringstream wt; + wt << (*logo)->getWidth().second; + s += "\",\n \"width\": \""; + s += wt.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\": \""; + json_safe(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 { - return os << m_feed; + 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); + } }