First set of logout base classes and non-building draft of SP-initiated logout.
[shibboleth/cpp-sp.git] / shibsp / impl / XMLServiceProvider.cpp
index 2c1e147..5f14445 100644 (file)
@@ -129,7 +129,7 @@ namespace {
             return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;
         }
 #endif
-        string getLogoutNotification(const HTTPRequest& request, bool front, unsigned int index) const;
+        string getNotificationURL(const HTTPRequest& request, bool front, unsigned int index) const;
 
         const set<string>& getRemoteUserAttributeIds() const {
             return (m_remoteUsers.empty() && m_base) ? m_base->getRemoteUserAttributeIds() : m_remoteUsers;
@@ -387,10 +387,11 @@ namespace {
     static const XMLCh Listener[] =             UNICODE_LITERAL_8(L,i,s,t,e,n,e,r);
     static const XMLCh Location[] =             UNICODE_LITERAL_8(L,o,c,a,t,i,o,n);
     static const XMLCh logger[] =               UNICODE_LITERAL_6(l,o,g,g,e,r);
+    static const XMLCh _LogoutInitiator[] =     UNICODE_LITERAL_15(L,o,g,o,u,t,I,n,i,t,i,a,t,o,r);
     static const XMLCh _ManageNameIDService[] = UNICODE_LITERAL_19(M,a,n,a,g,e,N,a,m,e,I,D,S,e,r,v,i,c,e);
     static const XMLCh MemoryListener[] =       UNICODE_LITERAL_14(M,e,m,o,r,y,L,i,s,t,e,n,e,r);
     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 NotifyOnLogout[] =       UNICODE_LITERAL_14(N,o,t,i,f,y,O,n,L,o,g,o,u,t);
+    static const XMLCh Notify[] =               UNICODE_LITERAL_6(N,o,t,i,f,y);
     static const XMLCh OutOfProcess[] =         UNICODE_LITERAL_12(O,u,t,O,f,P,r,o,c,e,s,s);
     static const XMLCh _path[] =                UNICODE_LITERAL_4(p,a,t,h);
     static const XMLCh Policy[] =               UNICODE_LITERAL_6(P,o,l,i,c,y);
@@ -594,6 +595,15 @@ XMLApplication::XMLApplication(
                             m_sessionInitDefault=sihandler;
                     }
                 }
+                else if (XMLString::equals(child->getLocalName(),_LogoutInitiator)) {
+                    auto_ptr_char type(child->getAttributeNS(NULL,_type));
+                    if (!type.get() || !*(type.get())) {
+                        log.warn("LogoutInitiator element has no type attribute, skipping it...");
+                        child = XMLHelper::getNextSiblingElement(child);
+                        continue;
+                    }
+                    handler=conf.LogoutInitiatorManager.newPlugin(type.get(),make_pair(child, getId()));
+                }
                 else if (XMLString::equals(child->getLocalName(),_ArtifactResolutionService)) {
                     auto_ptr_char bindprop(child->getAttributeNS(NULL,Binding));
                     if (!bindprop.get() || !*(bindprop.get())) {
@@ -660,8 +670,8 @@ XMLApplication::XMLApplication(
             child = XMLHelper::getNextSiblingElement(child);
         }
 
-        // Logout notification.
-        DOMNodeList* nlist=e->getElementsByTagNameNS(shibspconstants::SHIB2SPCONFIG_NS,NotifyOnLogout);
+        // Notification.
+        DOMNodeList* nlist=e->getElementsByTagNameNS(shibspconstants::SHIB2SPCONFIG_NS,Notify);
         for (XMLSize_t i=0; nlist && i<nlist->getLength(); i++) {
             if (nlist->item(i)->getParentNode()->isSameNode(e)) {
                 const XMLCh* channel = static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,Channel);
@@ -878,12 +888,13 @@ short XMLApplication::acceptNode(const DOMNode* node) const
     const XMLCh* name=node->getLocalName();
     if (XMLString::equals(name,_Application) ||
         XMLString::equals(name,_Audience) ||
-        XMLString::equals(name,NotifyOnLogout) ||
+        XMLString::equals(name,Notify) ||
         XMLString::equals(name,_AssertionConsumerService) ||
         XMLString::equals(name,_ArtifactResolutionService) ||
-        XMLString::equals(name,_SingleLogoutService) ||
+        XMLString::equals(name,_LogoutInitiator) ||
         XMLString::equals(name,_ManageNameIDService) ||
         XMLString::equals(name,_SessionInitiator) ||
+        XMLString::equals(name,_SingleLogoutService) ||
         XMLString::equals(name,DefaultRelyingParty) ||
         XMLString::equals(name,RelyingParty) ||
         XMLString::equals(name,_MetadataProvider) ||
@@ -937,11 +948,11 @@ const PropertySet* XMLApplication::getRelyingParty(const EntityDescriptor* provi
 
 #endif
 
-string XMLApplication::getLogoutNotification(const HTTPRequest& request, bool front, unsigned int index) const
+string XMLApplication::getNotificationURL(const HTTPRequest& request, bool front, unsigned int index) const
 {
     const vector<string>& locs = front ? m_frontLogout : m_backLogout;
     if (locs.empty())
-        return m_base ? m_base->getLogoutNotification(request, front, index) : string();
+        return m_base ? m_base->getNotificationURL(request, front, index) : string();
     else if (index >= locs.size())
         return string();
 
@@ -958,7 +969,7 @@ string XMLApplication::getLogoutNotification(const HTTPRequest& request, bool fr
     // Should never happen...
     if (!handler || (*handler!='/' && strncmp(handler,"http:",5) && strncmp(handler,"https:",6)))
         throw ConfigurationException(
-            "Invalid Location property ($1) in logout notification for Application ($2)",
+            "Invalid Location property ($1) in Notify element for Application ($2)",
             params(2, handler ? handler : "null", getId())
             );