\r
#include <ctime>\r
#include <sstream>\r
-#include <log4cpp/Category.hh>\r
#include <xmltooling/XMLToolingConfig.h>\r
#include <xmltooling/util/DateTime.h>\r
#include <xmltooling/util/NDC.h>\r
\r
using namespace shibsp;\r
using namespace xmltooling;\r
-using namespace log4cpp;\r
using namespace std;\r
\r
namespace shibsp {\r
~RemotedSession() {\r
delete m_lock;\r
m_obj.destroy();\r
- for_each(m_attributes.begin(), m_attributes.end(), cleanup_pair<string,Attribute>());\r
+ for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<Attribute>());\r
}\r
\r
Lockable* lock() {\r
m_lock->unlock();\r
}\r
\r
+ const char* getID() const {\r
+ return m_obj.name();\r
+ }\r
const char* getApplicationID() const {\r
return m_obj["application_id"].string();\r
}\r
const char* getEntityID() const {\r
return m_obj["entity_id"].string();\r
}\r
+ const char* getProtocol() const {\r
+ return m_obj["protocol"].string();\r
+ }\r
const char* getAuthnInstant() const {\r
return m_obj["authn_instant"].string();\r
}\r
const char* getAuthnContextDeclRef() const {\r
return m_obj["authncontext_decl"].string();\r
}\r
- const multimap<string,Attribute*>& getAttributes() const {\r
+ const vector<Attribute*>& getAttributes() const {\r
if (m_attributes.empty())\r
unmarshallAttributes();\r
return m_attributes;\r
}\r
+ const multimap<string,const Attribute*>& getIndexedAttributes() const {\r
+ if (m_attributeIndex.empty()) {\r
+ if (m_attributes.empty())\r
+ unmarshallAttributes();\r
+ for (vector<Attribute*>::const_iterator a = m_attributes.begin(); a != m_attributes.end(); ++a) {\r
+ const vector<string>& aliases = (*a)->getAliases();\r
+ for (vector<string>::const_iterator alias = aliases.begin(); alias != aliases.end(); ++alias)\r
+ m_attributeIndex.insert(make_pair(*alias, *a));\r
+ }\r
+ }\r
+ return m_attributeIndex;\r
+ }\r
const vector<const char*>& getAssertionIDs() const {\r
if (m_ids.empty()) {\r
DDF ids = m_obj["assertions"];\r
\r
int m_version;\r
mutable DDF m_obj;\r
- mutable multimap<string,Attribute*> m_attributes;\r
+ mutable vector<Attribute*> m_attributes;\r
+ mutable multimap<string,const Attribute*> m_attributeIndex;\r
mutable vector<const char*> m_ids;\r
time_t m_expires,m_lastAccess;\r
RemotedCache* m_cache;\r
~RemotedCache();\r
\r
Session* find(const char* key, const Application& application, const char* client_addr=NULL, time_t* timeout=NULL);\r
- void remove(const char* key, const Application& application, const char* client_addr);\r
+ void remove(const char* key, const Application& application);\r
\r
void cleanup();\r
\r
while (!attr.isnull()) {\r
try {\r
attribute = Attribute::unmarshall(attr);\r
- m_attributes.insert(make_pair(attribute->getId(),attribute));\r
+ m_attributes.push_back(attribute);\r
if (m_cache->m_log.isDebugEnabled())\r
m_cache->m_log.debug("unmarshalled attribute (ID: %s) with %d value%s",\r
attribute->getId(), attr.first().integer(), attr.first().integer()!=1 ? "s" : "");\r
// Basic expiration?\r
time_t now = time(NULL);\r
if (now > m_expires) {\r
- m_cache->m_log.info("session expired (ID: %s)", m_obj.name());\r
+ m_cache->m_log.info("session expired (ID: %s)", getID());\r
throw opensaml::RetryableProfileException("Your session has expired, and you must re-authenticate.");\r
}\r
\r
DDF in("touch::"REMOTED_SESSION_CACHE"::SessionCache"), out;\r
DDFJanitor jin(in);\r
in.structure();\r
- in.addmember("key").string(m_obj.name());\r
+ in.addmember("key").string(getID());\r
in.addmember("version").integer(m_obj["version"].integer());\r
if (*timeout) {\r
// On 64-bit Windows, time_t doesn't fit in a long, so I'm using ISO timestamps. \r
if (out.isstruct()) {\r
// We got an updated record back.\r
m_ids.clear();\r
- for_each(m_attributes.begin(), m_attributes.end(), cleanup_const_pair<string,Attribute>());\r
+ for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<Attribute>());\r
m_attributes.clear();\r
+ m_attributeIndex.clear();\r
m_obj.destroy();\r
m_obj = out;\r
}\r
}\r
\r
RemotedCache::RemotedCache(const DOMElement* e)\r
- : SessionCache(e), m_log(Category::getInstance(SHIBSP_LOGCAT".SessionCache")), m_root(e), m_lock(NULL), shutdown(false)\r
+ : SessionCache(e, 900), m_log(Category::getInstance(SHIBSP_LOGCAT".SessionCache")), m_root(e), m_lock(NULL), shutdown(false)\r
{\r
if (!SPConfig::getConfig().getServiceProvider()->getListenerService())\r
throw ConfigurationException("RemotedCacheService requires a ListenerService, but none available.");\r
DDFJanitor jin(in);\r
in.structure();\r
in.addmember("key").string(key);\r
+ in.addmember("application_id").string(application.getId());\r
if (timeout && *timeout) {\r
// On 64-bit Windows, time_t doesn't fit in a long, so I'm using ISO timestamps. \r
#ifndef HAVE_GMTIME_R\r
}\r
catch (...) {\r
session->unlock();\r
- remove(key, application, client_addr);\r
+ remove(key, application);\r
throw;\r
}\r
\r
return session;\r
}\r
\r
-void RemotedCache::remove(const char* key, const Application& application, const char* client_addr)\r
+void RemotedCache::remove(const char* key, const Application& application)\r
{\r
// Take care of local copy.\r
dormant(key);\r
in.structure();\r
in.addmember("key").string(key);\r
in.addmember("application_id").string(application.getId());\r
- in.addmember("client_addr").string(client_addr);\r
\r
DDF out = application.getServiceProvider().getListenerService()->send(in);\r
out.destroy();\r