-namespace {
- void disco(string& s, const EntityDescriptor* entity) {
- if (entity) {
- const vector<IDPSSODescriptor*>& idps = entity->getIDPSSODescriptors();
- if (!idps.empty()) {
- auto_ptr_char entityid(entity->getEntityID());
- // Open a struct and output id: entityID.
- s += "{\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 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 ]";
+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()
+{
+}
+
+void DiscoverableMetadataProvider::generateFeed()
+{
+ bool first = true;
+ const XMLObject* object = getMetadata();
+ disco(m_feed, dynamic_cast<const EntitiesDescriptor*>(object), first);
+ disco(m_feed, dynamic_cast<const EntityDescriptor*>(object), first);
+
+ SAMLConfig::getConfig().generateRandomBytes(m_feedTag, 4);
+ m_feedTag = SAMLArtifact::toHex(m_feedTag);
+}
+
+string DiscoverableMetadataProvider::getCacheTag() const
+{
+ return m_feedTag;
+}
+
+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<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\": \"";
+ json_safe(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\": \"";
+ json_safe(s, val.get());
+ s += "\",\n \"lang\": \"";
+ s += lang.get();
+ s += "\"\n }";