Improve consistency of cache API methods.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Mon, 26 Nov 2007 18:57:10 +0000 (18:57 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Mon, 26 Nov 2007 18:57:10 +0000 (18:57 +0000)
Move advanced "back-channel" methods to an Ex subinterface.

git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2638 cb58f699-b61c-0410-a6fe-9272a202ed29

15 files changed:
adfs/adfs.cpp
shibsp/AbstractSPRequest.cpp
shibsp/Makefile.am
shibsp/SessionCache.h
shibsp/SessionCacheEx.h [new file with mode: 0644]
shibsp/handler/impl/AssertionLookup.cpp
shibsp/handler/impl/LocalLogoutInitiator.cpp
shibsp/handler/impl/SAML1Consumer.cpp
shibsp/handler/impl/SAML2Consumer.cpp
shibsp/handler/impl/SAML2Logout.cpp
shibsp/handler/impl/SAML2LogoutInitiator.cpp
shibsp/handler/impl/SAML2NameIDMgmt.cpp
shibsp/impl/StorageServiceSessionCache.cpp
shibsp/shibsp-lite.vcproj
shibsp/shibsp.vcproj

index 98c905e..34e47a0 100644 (file)
@@ -634,10 +634,10 @@ void ADFSConsumer::implementProtocol(
     }
 
     application.getServiceProvider().getSessionCache()->insert(
-        now + lifetime.second,
         application,
         httpRequest,
         httpResponse,
+        now + lifetime.second,
         policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL,
         m_protocol.get(),
         nameid.get(),
@@ -802,12 +802,12 @@ pair<bool,long> ADFSLogout::run(SPRequest& request, bool isHandler) const
     }
 
     // Best effort on back channel and to remove the user agent's session.
-    string session_id = app.getServiceProvider().getSessionCache()->active(request, app);
+    string session_id = app.getServiceProvider().getSessionCache()->active(app, request);
     if (!session_id.empty()) {
         vector<string> sessions(1,session_id);
         notifyBackChannel(app, request.getRequestURL(), sessions, false);
         try {
-            app.getServiceProvider().getSessionCache()->remove(request, &request, app);
+            app.getServiceProvider().getSessionCache()->remove(app, request, &request);
         }
         catch (exception& ex) {
             m_log.error("error removing session (%s): %s", session_id.c_str(), ex.what());
index d76b910..e7de1cd 100644 (file)
@@ -99,7 +99,7 @@ Session* AbstractSPRequest::getSession(bool checkTimeout, bool ignoreAddress, bo
 
     // The cache will either silently pass a session or NULL back, or throw an exception out.
     Session* session = getServiceProvider().getSessionCache()->find(
-        *this, getApplication(), ignoreAddress ? NULL : getRemoteAddr().c_str(), checkTimeout ? &timeout : NULL
+        getApplication(), *this, ignoreAddress ? NULL : getRemoteAddr().c_str(), checkTimeout ? &timeout : NULL
         );
     if (cache)
         m_session = session;
index 57a8206..ae4df5b 100644 (file)
@@ -37,6 +37,7 @@ libshibspinclude_HEADERS = \
        RequestMapper.h \
        ServiceProvider.h \
        SessionCache.h \
+       SessionCacheEx.h \
        SPConfig.h \
        SPRequest.h \
        TransactionLog.h \
index 21a1ea6..18910bd 100644 (file)
@@ -37,6 +37,14 @@ namespace shibsp {
     class SHIBSP_API Application;
     class SHIBSP_API Attribute;
 
+    /**
+     * Encapsulates access to a user's security session.
+     *
+     * <p>The SessionCache does not itself require locking to manage
+     * concurrency, but access to each Session is generally exclusive
+     * or at least controlled, and the caller must unlock a Session
+     * to dispose of it.
+     */
     class SHIBSP_API Session : public virtual xmltooling::Lockable
     {
         MAKE_NONCOPYABLE(Session);
@@ -206,10 +214,10 @@ namespace shibsp {
          * 
          * <p>The SSO tokens and Attributes remain owned by the caller and are copied by the cache.
          * 
-         * @param expires           expiration time of session
          * @param application       reference to Application that owns the Session
          * @param httpRequest       request that initiated session
          * @param httpResponse      current response to client
+         * @param expires           expiration time of session
          * @param issuer            issuing metadata of assertion issuer, if known
          * @param protocol          protocol family used to initiate the session
          * @param nameid            principal identifier, normalized to SAML 2, if any
@@ -221,10 +229,10 @@ namespace shibsp {
          * @param attributes        optional array of resolved Attributes to cache with session
          */
         virtual void insert(
-            time_t expires,
             const Application& application,
             const xmltooling::HTTPRequest& httpRequest,
             xmltooling::HTTPResponse& httpResponse,
+            time_t expires,
             const opensaml::saml2md::EntityDescriptor* issuer=NULL,
             const XMLCh* protocol=NULL,
             const opensaml::saml2::NameID* nameid=NULL,
@@ -237,47 +245,21 @@ namespace shibsp {
             )=0;
 
         /**
-         * Returns active sessions that match particular parameters and records the logout
-         * to prevent race conditions.
-         *
-         * <p>On exit, the mapping between these sessions and the associated information MAY be
-         * removed by the cache, so subsequent calls to this method may not return anything.
-         *
-         * <p>Until logout expiration, any attempt to create a session with the same parameters
-         * will be blocked by the cache.
-         * 
-         * @param issuer        source of session(s)
-         * @param nameid        name identifier associated with the session(s) to terminate
-         * @param indexes       indexes of sessions, or NULL for all sessions associated with other parameters
-         * @param expires       logout expiration
-         * @param application   reference to Application that owns the session(s)
-         * @param sessions      on exit, contains the IDs of the matching sessions found
-         */
-        virtual std::vector<std::string>::size_type logout(
-            const opensaml::saml2md::EntityDescriptor* issuer,
-            const opensaml::saml2::NameID& nameid,
-            const std::set<std::string>* indexes,
-            time_t expires,
-            const Application& application,
-            std::vector<std::string>& sessions
-            )=0;
-
-        /**
          * Determines whether the Session bound to a client request matches a set of input criteria.
          * 
+         * @param application   reference to Application that owns the Session
          * @param request       request in which to locate Session
          * @param issuer        required source of session(s)
          * @param nameid        required name identifier
          * @param indexes       session indexes
-         * @param application   reference to Application that owns the Session
          * @return  true iff the Session exists and matches the input criteria
          */
         virtual bool matches(
+            const Application& application,
             const xmltooling::HTTPRequest& request,
             const opensaml::saml2md::EntityDescriptor* issuer,
             const opensaml::saml2::NameID& nameid,
-            const std::set<std::string>* indexes,
-            const Application& application
+            const std::set<std::string>* indexes
             )=0;
 
         /**
@@ -289,27 +271,11 @@ namespace shibsp {
         /**
          * Returns the ID of the session bound to the specified client request, if possible.
          * 
-         * @param request       request from client containing session, or a reference to it
          * @param application   reference to Application that owns the Session
+         * @param request       request from client containing session, or a reference to it
          * @return  ID of session, if any known, or an empty string
          */
-        virtual std::string active(const xmltooling::HTTPRequest& request, const Application& application) const=0;
-
-        /**
-         * Locates an existing session by ID.
-         * 
-         * <p>If the client address is supplied, then a check will be performed against
-         * the address recorded in the record.
-         * 
-         * @param key           session key
-         * @param application   reference to Application that owns the Session
-         * @param client_addr   network address of client (if known)
-         * @param timeout       inactivity timeout to enforce (0 for none, NULL to bypass check/update of last access)
-         * @return  pointer to locked Session, or NULL
-         */
-        virtual Session* find(
-            const char* key, const Application& application, const char* client_addr=NULL, time_t* timeout=NULL
-            )=0;
+        virtual std::string active(const Application& application, const xmltooling::HTTPRequest& request)=0;
 
         /**
          * Locates an existing session bound to a request.
@@ -317,32 +283,24 @@ namespace shibsp {
          * <p>If the client address is supplied, then a check will be performed against
          * the address recorded in the record.
          * 
-         * @param request       request from client containing session, or a reference to it
          * @param application   reference to Application that owns the Session
+         * @param request       request from client containing session, or a reference to it
          * @param client_addr   network address of client (if known)
          * @param timeout       inactivity timeout to enforce (0 for none, NULL to bypass check/update of last access)
          * @return  pointer to locked Session, or NULL
          */
         virtual Session* find(
-            const xmltooling::HTTPRequest& request, const Application& application, const char* client_addr=NULL, time_t* timeout=NULL
+            const Application& application, const xmltooling::HTTPRequest& request, const char* client_addr=NULL, time_t* timeout=NULL
             )=0;
 
         /**
-         * Deletes an existing session.
-         * 
-         * @param key           session key
-         * @param application   reference to Application that owns the Session
-         */
-        virtual void remove(const char* key, const Application& application)=0;
-
-        /**
          * Deletes an existing session bound to a request.
          * 
+         * @param application   reference to Application that owns the Session
          * @param request       request from client containing session, or a reference to it
          * @param response      optional response to client enabling removal of session or reference
-         * @param application   reference to Application that owns the Session
          */
-        virtual void remove(const xmltooling::HTTPRequest& request, xmltooling::HTTPResponse* response, const Application& application)=0;
+        virtual void remove(const Application& application, const xmltooling::HTTPRequest& request, xmltooling::HTTPResponse* response=NULL)=0;
     };
 
     /** SessionCache implementation backed by a StorageService. */
diff --git a/shibsp/SessionCacheEx.h b/shibsp/SessionCacheEx.h
new file mode 100644 (file)
index 0000000..b71f568
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * 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
+ *
+ *     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.
+ */
+
+/**
+ * @file shibsp/SessionCacheEx.h
+ * 
+ * Extended SessionCache API with additional capabilities
+ */
+
+#ifndef __shibsp_sessioncacheex_h__
+#define __shibsp_sessioncacheex_h__
+
+#include <shibsp/SessionCache.h>
+
+namespace shibsp {
+
+    /**
+     * Extended SessionCache API with additional capabilities
+     */
+    class SHIBSP_API SessionCacheEx : public SessionCache
+    {
+    protected:
+        SessionCacheEx() {}
+    public:
+        virtual ~SessionCacheEx() {}
+        
+#ifndef SHIBSP_LITE
+        /**
+         * Returns active sessions that match particular parameters and records the logout
+         * to prevent race conditions.
+         *
+         * <p>On exit, the mapping between these sessions and the associated information MAY be
+         * removed by the cache, so subsequent calls to this method may not return anything.
+         *
+         * <p>Until logout expiration, any attempt to create a session with the same parameters
+         * will be blocked by the cache.
+         * 
+         * @param application   reference to Application that owns the session(s)
+         * @param issuer        source of session(s)
+         * @param nameid        name identifier associated with the session(s) to terminate
+         * @param indexes       indexes of sessions, or NULL for all sessions associated with other parameters
+         * @param expires       logout expiration
+         * @param sessions      on exit, contains the IDs of the matching sessions found
+         */
+        virtual std::vector<std::string>::size_type logout(
+            const Application& application,
+            const opensaml::saml2md::EntityDescriptor* issuer,
+            const opensaml::saml2::NameID& nameid,
+            const std::set<std::string>* indexes,
+            time_t expires,
+            std::vector<std::string>& sessions
+            )=0;
+#endif
+
+        /**
+         * Locates an existing session by ID.
+         * 
+         * <p>If the client address is supplied, then a check will be performed against
+         * the address recorded in the record.
+         * 
+         * @param application   reference to Application that owns the Session
+         * @param key           session key
+         * @param client_addr   network address of client (if known)
+         * @param timeout       inactivity timeout to enforce (0 for none, NULL to bypass check/update of last access)
+         * @return  pointer to locked Session, or NULL
+         */
+        virtual Session* find(const Application& application, const char* key, const char* client_addr=NULL, time_t* timeout=NULL)=0;
+
+        /**
+         * Deletes an existing session.
+         * 
+         * @param application   reference to Application that owns the Session
+         * @param key           session key
+         */
+        virtual void remove(const Application& application, const char* key)=0;
+    };
+};
+
+#endif /* __shibsp_sessioncacheex_h__ */
index 11ac325..8ae7e10 100644 (file)
@@ -24,7 +24,7 @@
 #include "Application.h"
 #include "exceptions.h"
 #include "ServiceProvider.h"
-#include "SessionCache.h"
+#include "SessionCacheEx.h"
 #include "handler/AbstractHandler.h"
 #include "handler/RemotedHandler.h"
 #include "util/SPConstants.h"
@@ -176,8 +176,14 @@ pair<bool,long> AssertionLookup::processMessage(const Application& application,
 
     m_log.debug("processing assertion lookup request (session: %s, assertion: %s)", key, ID);
 
+    SessionCacheEx* cache = dynamic_cast<SessionCacheEx*>(application.getServiceProvider().getSessionCache());
+    if (!cache) {
+        m_log.error("session cache does not support extended API");
+        throw FatalProfileException("Session cache does not support assertion lookup.");
+    }
+
     // The cache will either silently pass a session or NULL back, or throw an exception out.
-    Session* session = application.getServiceProvider().getSessionCache()->find(httpRequest, application);
+    Session* session = cache->find(application, ID);
     if (!session) {
         m_log.error("valid session (%s) not found for assertion lookup", key);
         throw FatalProfileException("Session key not found.");
index c75bc87..8faaa71 100644 (file)
@@ -98,15 +98,15 @@ pair<bool,long> LocalLogoutInitiator::run(SPRequest& request, bool isHandler) co
         return ret;
 
     const Application& app = request.getApplication();
-    string session_id = app.getServiceProvider().getSessionCache()->active(request, app);
+    string session_id = app.getServiceProvider().getSessionCache()->active(app, request);
     if (!session_id.empty()) {
         // Do back channel notification.
         vector<string> sessions(1, session_id);
         if (!notifyBackChannel(app, request.getRequestURL(), sessions, true)) {
-            app.getServiceProvider().getSessionCache()->remove(request, &request, app);
+            app.getServiceProvider().getSessionCache()->remove(app, request, &request);
             return sendLogoutPage(app, request, true, "Partial logout failure.");
         }
-        request.getServiceProvider().getSessionCache()->remove(request, &request, app);
+        request.getServiceProvider().getSessionCache()->remove(app, request, &request);
     }
 
     return sendLogoutPage(app, request, true, "Logout was successful.");
index 893b84a..367b687 100644 (file)
@@ -273,10 +273,10 @@ void SAML1Consumer::implementProtocol(
     tokens.insert(tokens.end(), badtokens.begin(), badtokens.end());
 
     application.getServiceProvider().getSessionCache()->insert(
-        now + lifetime.second,
         application,
         httpRequest,
         httpResponse,
+        now + lifetime.second,
         policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL,
         (!response->getMinorVersion().first || response->getMinorVersion().second==1) ?
             samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM,
index 2045185..e171ad4 100644 (file)
@@ -381,10 +381,10 @@ void SAML2Consumer::implementProtocol(
         tokens.insert(tokens.end(), badtokens.begin(), badtokens.end());
 
         application.getServiceProvider().getSessionCache()->insert(
-            sessionExp,
             application,
             httpRequest,
             httpResponse,
+            sessionExp,
             policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL,
             samlconstants::SAML20P_NS,
             ssoName,
index 1c6feb3..9dbedd9 100644 (file)
@@ -29,7 +29,7 @@
 #include "util/SPConstants.h"
 
 #ifndef SHIBSP_LITE
-# include "SessionCache.h"
+# include "SessionCacheEx.h"
 # include "security/SecurityPolicy.h"
 # include "util/TemplateParameters.h"
 # include <fstream>
@@ -253,13 +253,14 @@ pair<bool,long> SAML2Logout::doRequest(const Application& application, const HTT
 #ifndef SHIBSP_LITE
     // First capture the active session ID.
     SessionCache* cache = application.getServiceProvider().getSessionCache();
-    string session_id = cache->active(request, application);
+    SessionCacheEx* cacheex = dynamic_cast<SessionCacheEx*>(cache);
+    string session_id = cache->active(application, request);
 
     if (!strcmp(request.getMethod(),"GET") && request.getParameter("notifying")) {
         // This is returning from a front-channel notification, so we have to do the back-channel and then
         // respond. To do that, we need state from the original request.
         if (!request.getParameter("entityID")) {
-            cache->remove(request, &response, application);
+            cache->remove(application, request, &response);
             throw FatalProfileException("Application notification loop did not return entityID for LogoutResponse.");
         }
 
@@ -269,7 +270,7 @@ pair<bool,long> SAML2Logout::doRequest(const Application& application, const HTT
             vector<string> sessions(1,session_id);
             worked1 = notifyBackChannel(application, request.getRequestURL(), sessions, false);
             try {
-                cache->remove(request, &response, application);
+                cache->remove(application, request, &response);
                 worked2 = true;
             }
             catch (exception& ex) {
@@ -413,7 +414,7 @@ pair<bool,long> SAML2Logout::doRequest(const Application& application, const HTT
         // For a front-channel LogoutRequest, we have to match the information in the request
         // against the current session.
         if (!session_id.empty()) {
-            if (!cache->matches(request, entity, *nameid, &indexes, application)) {
+            if (!cache->matches(application, request, entity, *nameid, &indexes)) {
                 return sendResponse(
                     logoutRequest->getID(),
                     StatusCode::REQUESTER, StatusCode::REQUEST_DENIED, "Active session did not match logout request.",
@@ -430,14 +431,21 @@ pair<bool,long> SAML2Logout::doRequest(const Application& application, const HTT
         // Now we perform "logout" by finding the matching sessions.
         vector<string> sessions;
         try {
-            time_t expires = logoutRequest->getNotOnOrAfter() ? logoutRequest->getNotOnOrAfterEpoch() : 0;
-            cache->logout(entity, *nameid, &indexes, expires, application, sessions);
-
-            // Now we actually terminate everything except for the active session,
-            // if this is front-channel, for notification purposes.
-            for (vector<string>::const_iterator sit = sessions.begin(); sit != sessions.end(); ++sit)
-                if (*sit != session_id)
-                    cache->remove(sit->c_str(), application);   // using the ID-based removal operation
+            if (cacheex) {
+                time_t expires = logoutRequest->getNotOnOrAfter() ? logoutRequest->getNotOnOrAfterEpoch() : 0;
+                cacheex->logout(application, entity, *nameid, &indexes, expires, sessions);
+
+                // Now we actually terminate everything except for the active session,
+                // if this is front-channel, for notification purposes.
+                for (vector<string>::const_iterator sit = sessions.begin(); sit != sessions.end(); ++sit)
+                    if (*sit != session_id)
+                        cacheex->remove(application, sit->c_str());   // using the ID-based removal operation
+            }
+            else {
+                m_log.warn("session cache does not support extended API, can't implement indirect logout of sessions");
+                if (!session_id.empty())
+                    sessions.push_back(session_id);
+            }
         }
         catch (exception& ex) {
             m_log.error("error while logging out matching sessions: %s", ex.what());
@@ -474,7 +482,7 @@ pair<bool,long> SAML2Logout::doRequest(const Application& application, const HTT
         if (!session_id.empty()) {
             // One last session to yoink...
             try {
-                cache->remove(request, &response, application);
+                cache->remove(application, request, &response);
                 worked2 = true;
             }
             catch (exception& ex) {
index b68c44f..b4db0c0 100644 (file)
@@ -240,7 +240,7 @@ void SAML2LogoutInitiator::receive(DDF& in, ostream& out)
     
     Session* session = NULL;
     try {
-         session = app->getServiceProvider().getSessionCache()->find(*req.get(), *app, NULL, NULL);
+         session = app->getServiceProvider().getSessionCache()->find(*app, *req.get(), NULL, NULL);
     }
     catch (exception& ex) {
         m_log.error("error accessing current session: %s", ex.what());
@@ -257,7 +257,7 @@ void SAML2LogoutInitiator::receive(DDF& in, ostream& out)
         else {
              m_log.error("no NameID or issuing entityID found in session");
              session->unlock();
-             app->getServiceProvider().getSessionCache()->remove(*req.get(), resp.get(), *app);
+             app->getServiceProvider().getSessionCache()->remove(*app, *req.get(), resp.get());
         }
     }
     out << ret;
@@ -274,7 +274,7 @@ pair<bool,long> SAML2LogoutInitiator::doRequest(
     vector<string> sessions(1, session->getID());
     if (!notifyBackChannel(application, httpRequest.getRequestURL(), sessions, false)) {
         session->unlock();
-        application.getServiceProvider().getSessionCache()->remove(httpRequest, &httpResponse, application);
+        application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
         return sendLogoutPage(application, httpResponse, true, "Partial logout failure.");
     }
 
@@ -354,7 +354,7 @@ pair<bool,long> SAML2LogoutInitiator::doRequest(
             if (session) {
                 session->unlock();
                 session = NULL;
-                application.getServiceProvider().getSessionCache()->remove(httpRequest, &httpResponse, application);
+                application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
             }
             return ret;
         }
@@ -374,13 +374,13 @@ pair<bool,long> SAML2LogoutInitiator::doRequest(
     if (session) {
         session->unlock();
         session = NULL;
-        application.getServiceProvider().getSessionCache()->remove(httpRequest, &httpResponse, application);
+        application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
     }
 
     return ret;
 #else
     session->unlock();
-    application.getServiceProvider().getSessionCache()->remove(httpRequest, &httpResponse, application);
+    application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
     throw ConfigurationException("Cannot perform logout using lite version of shibsp library.");
 #endif
 }
index 3d5e69d..08435ed 100644 (file)
@@ -272,7 +272,7 @@ pair<bool,long> SAML2NameIDMgmt::doRequest(
         // Message from IdP to change or terminate a NameID.
 
         // If this is front-channel, we have to have a session_id to use already.
-        string session_id = cache->active(request, application);
+        string session_id = cache->active(application, request);
         if (m_decoder->isUserAgentPresent() && session_id.empty()) {
             m_log.error("no active session");
             return sendResponse(
@@ -334,7 +334,7 @@ pair<bool,long> SAML2NameIDMgmt::doRequest(
         // against the current session.
         EntityDescriptor* entity = policy.getIssuerMetadata() ? dynamic_cast<EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL;
         if (!session_id.empty()) {
-            if (!cache->matches(request, entity, *nameid, NULL, application)) {
+            if (!cache->matches(application, request, entity, *nameid, NULL)) {
                 return sendResponse(
                     mgmtRequest->getID(),
                     StatusCode::REQUESTER, StatusCode::REQUEST_DENIED, "Active session did not match NameID mgmt request.",
index 843a37d..cb26b1f 100644 (file)
@@ -32,7 +32,7 @@
 #include "Application.h"
 #include "exceptions.h"
 #include "ServiceProvider.h"
-#include "SessionCache.h"
+#include "SessionCacheEx.h"
 #include "TransactionLog.h"
 #include "attribute/Attribute.h"
 #include "remoting/ListenerService.h"
@@ -59,7 +59,7 @@ using namespace std;
 namespace shibsp {
 
     class StoredSession;
-    class SSCache : public SessionCache
+    class SSCache : public SessionCacheEx
 #ifndef SHIBSP_LITE
         ,public virtual Remoted
 #endif
@@ -72,10 +72,10 @@ namespace shibsp {
         void receive(DDF& in, ostream& out);
 
         void insert(
-            time_t expires,
             const Application& application,
             const HTTPRequest& httpRequest,
             HTTPResponse& httpResponse,
+            time_t expires,
             const saml2md::EntityDescriptor* issuer=NULL,
             const XMLCh* protocol=NULL,
             const saml2::NameID* nameid=NULL,
@@ -87,45 +87,45 @@ namespace shibsp {
             const vector<Attribute*>* attributes=NULL
             );
         vector<string>::size_type logout(
+            const Application& application,
             const saml2md::EntityDescriptor* issuer,
             const saml2::NameID& nameid,
             const set<string>* indexes,
             time_t expires,
-            const Application& application,
             vector<string>& sessions
             );
         bool matches(
+            const Application& application,
             const xmltooling::HTTPRequest& request,
             const saml2md::EntityDescriptor* issuer,
             const saml2::NameID& nameid,
-            const set<string>* indexes,
-            const Application& application
+            const set<string>* indexes
             );
 #endif
-        Session* find(const char* key, const Application& application, const char* client_addr=NULL, time_t* timeout=NULL);
-        void remove(const char* key, const Application& application);
+        Session* find(const Application& application, const char* key, const char* client_addr=NULL, time_t* timeout=NULL);
+        void remove(const Application& application, const char* key);
         void test();
 
-        string active(const xmltooling::HTTPRequest& request, const Application& application) const {
+        string active(const Application& application, const xmltooling::HTTPRequest& request) {
             pair<string,const char*> shib_cookie = application.getCookieNameProps("_shibsession_");
             const char* session_id = request.getCookie(shib_cookie.first.c_str());
             return (session_id ? session_id : "");
         }
 
-        Session* find(const HTTPRequest& request, const Application& application, const char* client_addr=NULL, time_t* timeout=NULL) {
-            string id = active(request, application);
+        Session* find(const Application& application, const HTTPRequest& request, const char* client_addr=NULL, time_t* timeout=NULL) {
+            string id = active(application, request);
             if (!id.empty())
-                return find(id.c_str(), application, client_addr, timeout);
+                return find(application, id.c_str(), client_addr, timeout);
             return NULL;
         }
 
-        void remove(const HTTPRequest& request, HTTPResponse* response, const Application& application) {
+        void remove(const Application& application, const HTTPRequest& request, HTTPResponse* response=NULL) {
             pair<string,const char*> shib_cookie = application.getCookieNameProps("_shibsession_");
             const char* session_id = request.getCookie(shib_cookie.first.c_str());
             if (session_id && *session_id) {
                 if (response)
                     response->setCookie(shib_cookie.first.c_str(), shib_cookie.second);
-                remove(session_id, application);
+                remove(application, session_id);
             }
         }
 
@@ -826,10 +826,10 @@ void SSCache::insert(const char* key, time_t expires, const char* name, const ch
 }
 
 void SSCache::insert(
-    time_t expires,
     const Application& application,
     const HTTPRequest& httpRequest,
     HTTPResponse& httpResponse,
+    time_t expires,
     const saml2md::EntityDescriptor* issuer,
     const XMLCh* protocol,
     const saml2::NameID* nameid,
@@ -1008,22 +1008,22 @@ void SSCache::insert(
     }
 
     pair<string,const char*> shib_cookie = application.getCookieNameProps("_shibsession_");
-    string k(key.get());\r
+    string k(key.get());
     k += shib_cookie.second;
     httpResponse.setCookie(shib_cookie.first.c_str(), k.c_str());
 }
 
 bool SSCache::matches(
+    const Application& application,
     const xmltooling::HTTPRequest& request,
     const saml2md::EntityDescriptor* issuer,
     const saml2::NameID& nameid,
-    const set<string>* indexes,
-    const Application& application
+    const set<string>* indexes
     )
 {
     auto_ptr_char entityID(issuer ? issuer->getEntityID() : NULL);
     try {
-        Session* session = find(request, application);
+        Session* session = find(application, request);
         if (session) {
             Locker locker(session, false);
             if (XMLString::equals(session->getEntityID(), entityID.get()) && session->getNameID() &&
@@ -1039,11 +1039,11 @@ bool SSCache::matches(
 }
 
 vector<string>::size_type SSCache::logout(
+    const Application& application,
     const saml2md::EntityDescriptor* issuer,
     const saml2::NameID& nameid,
     const set<string>* indexes,
     time_t expires,
-    const Application& application,
     vector<string>& sessionsKilled
     )
 {
@@ -1107,12 +1107,12 @@ vector<string>::size_type SSCache::logout(
             ver = m_storage->updateText("Logout", name.get(), lout.str().c_str(), max(expires, oldexp), ver);
             if (ver <= 0) {
                 // Out of sync, or went missing, so retry.
-                return logout(issuer, nameid, indexes, expires, application, sessionsKilled);
+                return logout(application, issuer, nameid, indexes, expires, sessionsKilled);
             }
         }
         else if (!m_storage->createText("Logout", name.get(), lout.str().c_str(), expires)) {
             // Hit a dup, so just retry, hopefully hitting the other branch.
-            return logout(issuer, nameid, indexes, expires, application, sessionsKilled);
+            return logout(application, issuer, nameid, indexes, expires, sessionsKilled);
         }
 
         obj.destroy();
@@ -1139,7 +1139,7 @@ vector<string>::size_type SSCache::logout(
                 // Fetch the session for comparison.
                 Session* session = NULL;
                 try {
-                    session = find(key.string(), application);
+                    session = find(application, key.string());
                 }
                 catch (exception& ex) {
                     m_log.error("error locating session (%s): %s", key.string(), ex.what());
@@ -1236,7 +1236,7 @@ bool SSCache::stronglyMatches(const XMLCh* idp, const XMLCh* sp, const saml2::Na
 
 #endif
 
-Session* SSCache::find(const char* key, const Application& application, const char* client_addr, time_t* timeout)
+Session* SSCache::find(const Application& application, const char* key, const char* client_addr, time_t* timeout)
 {
 #ifdef _DEBUG
     xmltooling::NDC ndc("find");
@@ -1324,7 +1324,7 @@ Session* SSCache::find(const char* key, const Application& application, const ch
             
             if (timeout && *timeout > 0 && now - lastAccess >= *timeout) {
                 m_log.info("session timed out (ID: %s)", key);
-                remove(key, application);
+                remove(application, key);
                 RetryableProfileException ex("Your session has expired, and you must re-authenticate.");
                 const char* eid = obj["entity_id"].string();
                 if (!eid) {
@@ -1386,14 +1386,14 @@ Session* SSCache::find(const char* key, const Application& application, const ch
     }
     catch (...) {
         session->unlock();
-        remove(key, application);
+        remove(application, key);
         throw;
     }
     
     return session;
 }
 
-void SSCache::remove(const char* key, const Application& application)
+void SSCache::remove(const Application& application, const char* key)
 {
 #ifdef _DEBUG
     xmltooling::NDC ndc("remove");
@@ -1581,7 +1581,7 @@ void SSCache::receive(DDF& in, ostream& out)
                     
             if (timeout > 0 && now - lastAccess >= timeout) {
                 m_log.info("session timed out (ID: %s)", key);
-                remove(key,*app);
+                remove(*app, key);
                 throw RetryableProfileException("Your session has expired, and you must re-authenticate.");
             } 
 
@@ -1657,7 +1657,7 @@ void SSCache::receive(DDF& in, ostream& out)
         if (!app)
             throw ConfigurationException("Application not found, check configuration?");
 
-        remove(key,*app);
+        remove(*app, key);
         DDF ret(NULL);
         DDFJanitor jan(ret);
         out << ret;
index c6b35c1..498c712 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\SessionCacheEx.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\SPConfig.h"\r
                                >\r
                        </File>\r
index cd3ce30..86c852e 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\SessionCacheEx.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\SPConfig.h"\r
                                >\r
                        </File>\r