SSPCPP-616 - clean up concatenated string literals
[shibboleth/cpp-sp.git] / shibsp / attribute / resolver / impl / XMLAttributeExtractor.cpp
index be87f09..ffd9108 100644 (file)
@@ -131,7 +131,7 @@ namespace shibsp {
         scoped_ptr<AttributeFilter> m_filter;
         scoped_ptr<MetadataProvider> m_metadata;
         scoped_ptr<TrustEngine> m_trust;
-        bool m_entityAssertions;
+        bool m_entityAssertions,m_metaAttrCaching;
 
         // manages caching of decoded Attributes
         scoped_ptr<RWLock> m_attrLock;
@@ -142,7 +142,9 @@ namespace shibsp {
     class XMLExtractor : public AttributeExtractor, public ReloadableXMLFile
     {
     public:
-        XMLExtractor(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.XML")) {
+        XMLExtractor(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT ".AttributeExtractor.XML")) {
+            if (m_local && m_lock)
+                m_log.warn("attribute mappings are reloadable; be sure to restart web server when adding new attribute IDs");
             background_load();
         }
         ~XMLExtractor() {
@@ -186,25 +188,27 @@ namespace shibsp {
         return new XMLExtractor(e);
     }
 
-    static const XMLCh _aliases[] =             UNICODE_LITERAL_7(a,l,i,a,s,e,s);
-    static const XMLCh _AttributeDecoder[] =    UNICODE_LITERAL_16(A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
-    static const XMLCh _AttributeFilter[] =     UNICODE_LITERAL_15(A,t,t,r,i,b,u,t,e,F,i,l,t,e,r);
-    static const XMLCh Attributes[] =           UNICODE_LITERAL_10(A,t,t,r,i,b,u,t,e,s);
-    static const XMLCh _id[] =                  UNICODE_LITERAL_2(i,d);
-    static const XMLCh isRequested[] =          UNICODE_LITERAL_11(i,s,R,e,q,u,e,s,t,e,d);
-    static const XMLCh _MetadataProvider[] =    UNICODE_LITERAL_16(M,e,t,a,d,a,t,a,P,r,o,v,i,d,e,r);
-    static const XMLCh _name[] =                UNICODE_LITERAL_4(n,a,m,e);
-    static const XMLCh nameFormat[] =           UNICODE_LITERAL_10(n,a,m,e,F,o,r,m,a,t);
-    static const XMLCh metadataPolicyId[] =     UNICODE_LITERAL_16(m,e,t,a,d,a,t,a,P,o,l,i,c,y,I,d);
-    static const XMLCh _TrustEngine[] =         UNICODE_LITERAL_11(T,r,u,s,t,E,n,g,i,n,e);
-    static const XMLCh _type[] =                UNICODE_LITERAL_4(t,y,p,e);
+    static const XMLCh _aliases[] =                 UNICODE_LITERAL_7(a,l,i,a,s,e,s);
+    static const XMLCh _AttributeDecoder[] =        UNICODE_LITERAL_16(A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
+    static const XMLCh _AttributeFilter[] =         UNICODE_LITERAL_15(A,t,t,r,i,b,u,t,e,F,i,l,t,e,r);
+    static const XMLCh Attributes[] =               UNICODE_LITERAL_10(A,t,t,r,i,b,u,t,e,s);
+    static const XMLCh _id[] =                      UNICODE_LITERAL_2(i,d);
+    static const XMLCh isRequested[] =              UNICODE_LITERAL_11(i,s,R,e,q,u,e,s,t,e,d);
+    static const XMLCh _MetadataProvider[] =        UNICODE_LITERAL_16(M,e,t,a,d,a,t,a,P,r,o,v,i,d,e,r);
+    static const XMLCh metadataAttributeCaching[] = UNICODE_LITERAL_24(m,e,t,a,d,a,t,a,A,t,t,r,i,b,u,t,e,C,a,c,h,i,n,g);
+    static const XMLCh metadataPolicyId[] =         UNICODE_LITERAL_16(m,e,t,a,d,a,t,a,P,o,l,i,c,y,I,d);
+    static const XMLCh _name[] =                    UNICODE_LITERAL_4(n,a,m,e);
+    static const XMLCh nameFormat[] =               UNICODE_LITERAL_10(n,a,m,e,F,o,r,m,a,t);
+    static const XMLCh _TrustEngine[] =             UNICODE_LITERAL_11(T,r,u,s,t,E,n,g,i,n,e);
+    static const XMLCh _type[] =                    UNICODE_LITERAL_4(t,y,p,e);
 };
 
 XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log)
     : m_log(log),
         m_document(nullptr),
         m_policyId(XMLHelper::getAttrString(e, nullptr, metadataPolicyId)),
-        m_entityAssertions(true)
+        m_entityAssertions(true),
+        m_metaAttrCaching(XMLHelper::getAttrBool(e, true, metadataAttributeCaching))
 {
 #ifdef _DEBUG
     xmltooling::NDC ndc("XMLExtractorImpl");
@@ -341,8 +345,10 @@ XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log)
 
         name = child->getAttributeNS(nullptr, _aliases);
         if (name && *name) {
+            m_log.warn("attribute mapping rule (%s) uses deprecated aliases feature, consider revising", id.get());
             auto_ptr_char aliases(name);
             string dup(aliases.get());
+            trim(dup);
             set<string> new_aliases;
             split(new_aliases, dup, is_space(), algorithm::token_compress_on);
             set<string>::iterator ru = new_aliases.find("REMOTE_USER");
@@ -350,13 +356,15 @@ XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log)
                 m_log.warn("skipping alias, REMOTE_USER is a reserved name");
                 new_aliases.erase(ru);
             }
+            decl.second.insert(decl.second.end(), new_aliases.begin(), new_aliases.end());
             m_attributeIds.insert(m_attributeIds.end(), new_aliases.begin(), new_aliases.end());
         }
 
         child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
     }
 
-    m_attrLock.reset(RWLock::create());
+    if (m_metaAttrCaching)
+        m_attrLock.reset(RWLock::create());
 }
 
 void XMLExtractorImpl::generateMetadata(SPSSODescriptor& role) const
@@ -573,7 +581,7 @@ void XMLExtractorImpl::extractAttributes(
         map<const ObservableMetadataProvider*,decoded_t>::iterator cacheEntry;
 
         // Check for cached result.
-        if (observable) {
+        if (observable && m_metaAttrCaching) {
             m_attrLock->rdlock();
             cacheEntry = m_decodedMap.find(observable);
             if (cacheEntry == m_decodedMap.end()) {
@@ -987,7 +995,7 @@ void XMLExtractor::extractAttributes(
                 }
             }
             catch (std::exception& ex) {
-                m_log.error("caught exception decrypting Attribute: %s", ex.what());
+                m_log.error("failed to decrypt Attribute: %s", ex.what());
                 return;
             }
         }