X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fmetadata%2Fimpl%2FDiscoverableMetadataProvider.cpp;h=a2d89bbafb2751203e796bbaf83ccf78949ecc75;hb=42edb0e4431f15cfe5adc16e267d7809070772c3;hp=fafce2383026b733cf941a48a8fd8b7497c644f5;hpb=957a15ca26870e578bfe58016ef8b2ebf1c77669;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp b/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp index fafce23..a2d89bb 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. */ /** @@ -27,11 +31,14 @@ #include #include +#include +#include #include #include using namespace opensaml::saml2md; using namespace xmltooling; +using namespace boost; using namespace std; DiscoverableMetadataProvider::DiscoverableMetadataProvider(const DOMElement* e) : MetadataProvider(e), m_legacyOrgNames(false) @@ -46,12 +53,11 @@ DiscoverableMetadataProvider::~DiscoverableMetadataProvider() void DiscoverableMetadataProvider::generateFeed() { + m_feed.erase(); bool first = true; - m_feed = "["; const XMLObject* object = getMetadata(); - disco(m_feed, dynamic_cast(object), first); - disco(m_feed, dynamic_cast(object), first); - m_feed += "\n]"; + discoGroup(m_feed, dynamic_cast(object), first); + discoEntity(m_feed, dynamic_cast(object), first); SAMLConfig::getConfig().generateRandomBytes(m_feedTag, 4); m_feedTag = SAMLArtifact::toHex(m_feedTag); @@ -62,12 +68,53 @@ string DiscoverableMetadataProvider::getCacheTag() const return m_feedTag; } -ostream& DiscoverableMetadataProvider::outputFeed(ostream& os) const +void DiscoverableMetadataProvider::outputFeed(ostream& os, bool& first, bool wrapArray) const { - return os << m_feed; + if (wrapArray) + os << '['; + if (!m_feed.empty()) { + if (first) + first = false; + else + os << ",\n"; + os << m_feed; + } + if (wrapArray) + os << "\n]"; } -void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* entity, bool& first) const +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::discoEntity(string& s, const EntityDescriptor* entity, bool& first) const { time_t now = time(nullptr); if (entity && entity->isValid(now)) { @@ -80,12 +127,13 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti else s += ','; s += "\n{\n \"entityID\": \""; - s += entityid.get(); + 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 (indirect_iterator::const_iterator> idp = make_indirect_iterator(idps.begin()); + !extFound && idp != make_indirect_iterator(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) { @@ -93,13 +141,14 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti 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()) + for (indirect_iterator::const_iterator> dispname = make_indirect_iterator(dispnames.begin()); + dispname != make_indirect_iterator(dispnames.end()); ++dispname) { + if (dispname.base() != dispnames.begin()) s += ','; - auto_arrayptr val(toUTF8((*dispname)->getName())); - auto_ptr_char lang((*dispname)->getLang()); + auto_arrayptr val(toUTF8(dispname->getName())); + auto_ptr_char lang(dispname->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -110,13 +159,32 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti 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()) + for (indirect_iterator::const_iterator> desc = make_indirect_iterator(descs.begin()); + desc != make_indirect_iterator(descs.end()); ++desc) { + if (desc.base() != 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 (indirect_iterator::const_iterator> words = make_indirect_iterator(keywords.begin()); + words != make_indirect_iterator(keywords.end()); ++words) { + if (words.base() != keywords.begin()) s += ','; - auto_arrayptr val(toUTF8((*desc)->getDescription())); - auto_ptr_char lang((*desc)->getLang()); + auto_arrayptr val(toUTF8(words->getValues())); + auto_ptr_char lang(words->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -127,13 +195,14 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti 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()) + for (indirect_iterator::const_iterator> infurl = make_indirect_iterator(infurls.begin()); + infurl != make_indirect_iterator(infurls.end()); ++infurl) { + if (infurl.base() != infurls.begin()) s += ','; - auto_ptr_char val((*infurl)->getURL()); - auto_ptr_char lang((*infurl)->getLang()); + auto_ptr_char val(infurl->getURL()); + auto_ptr_char lang(infurl->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -144,13 +213,14 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti 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()) + for (indirect_iterator::const_iterator> priv = make_indirect_iterator(privs.begin()); + priv != make_indirect_iterator(privs.end()); ++priv) { + if (priv.base() != privs.begin()) s += ','; - auto_ptr_char val((*priv)->getURL()); - auto_ptr_char lang((*priv)->getLang()); + auto_ptr_char val(priv->getURL()); + auto_ptr_char lang(priv->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -161,24 +231,25 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti 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()) + for (indirect_iterator::const_iterator> logo = make_indirect_iterator(logos.begin()); + logo != make_indirect_iterator(logos.end()); ++logo) { + if (logo.base() != logos.begin()) s += ','; s += "\n {\n"; - auto_ptr_char val((*logo)->getURL()); + auto_ptr_char val(logo->getURL()); s += " \"value\": \""; - s += val.get(); + json_safe(s, val.get()); ostringstream ht; - ht << (*logo)->getHeight().second; + ht << logo->getHeight().second; s += "\",\n \"height\": \""; s += ht.str(); - ht.clear(); - ht << (*logo)->getWidth().second; + ostringstream wt; + wt << logo->getWidth().second; s += "\",\n \"width\": \""; - s += ht.str(); + s += wt.str(); s += '\"'; - if ((*logo)->getLang()) { - auto_ptr_char lang((*logo)->getLang()); + if (logo->getLang()) { + auto_ptr_char lang(logo->getLang()); s += ",\n \"lang\": \""; s += lang.get(); s += '\"'; @@ -194,9 +265,10 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti 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(); + for (indirect_iterator::const_iterator> idp = make_indirect_iterator(idps.begin()); + !org && idp != make_indirect_iterator(idps.end()); ++idp) { + if (idp->isValid(now)) + org = idp->getOrganization(); } if (!org) org = entity->getOrganization(); @@ -204,13 +276,14 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti 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()) + for (indirect_iterator::const_iterator> dispname = make_indirect_iterator(odns.begin()); + dispname != make_indirect_iterator(odns.end()); ++dispname) { + if (dispname.base() != odns.begin()) s += ','; - auto_arrayptr val(toUTF8((*dispname)->getName())); - auto_ptr_char lang((*dispname)->getLang()); + auto_arrayptr val(toUTF8(dispname->getName())); + auto_ptr_char lang(dispname->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -226,15 +299,16 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti } } -void DiscoverableMetadataProvider::disco(string& s, const EntitiesDescriptor* group, bool& first) const +void DiscoverableMetadataProvider::discoGroup(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); + for_each( + group->getEntitiesDescriptors().begin(), group->getEntitiesDescriptors().end(), + boost::bind(&DiscoverableMetadataProvider::discoGroup, this, boost::ref(s), _1, boost::ref(first)) + ); + for_each( + group->getEntityDescriptors().begin(), group->getEntityDescriptors().end(), + boost::bind(&DiscoverableMetadataProvider::discoEntity, this, boost::ref(s), _1, boost::ref(first)) + ); } }