From ac506eaca28306b06fd4f736b0404534532ec631 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Fri, 2 Feb 2007 23:28:48 +0000 Subject: [PATCH] Process attributes when loading sessions. --- shibsp/impl/RemotedSessionCache.cpp | 56 ++++++++++++++++++++++-------- shibsp/impl/StorageServiceSessionCache.cpp | 49 ++++++++++++++++++++------ 2 files changed, 81 insertions(+), 24 deletions(-) diff --git a/shibsp/impl/RemotedSessionCache.cpp b/shibsp/impl/RemotedSessionCache.cpp index c3353f3..639636e 100644 --- a/shibsp/impl/RemotedSessionCache.cpp +++ b/shibsp/impl/RemotedSessionCache.cpp @@ -56,7 +56,7 @@ namespace shibsp { if (!nameid) throw FatalProfileException("NameID missing from remotely cached session."); - // Parse and bind the document into an XMLObject. + // Parse and bind the NameID into an XMLObject. istringstream instr(nameid); DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(instr); XercesJanitor janitor(doc); @@ -64,7 +64,14 @@ namespace shibsp { n->unmarshall(doc->getDocumentElement(), true); janitor.release(); - // TODO: Process attributes... + try { + DDF attrs = m_obj["attributes"]; + unmarshallAttributes(attrs); + } + catch (...) { + for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup()); + throw; + } auto_ptr_XMLCh exp(m_obj["expires"].string()); if (exp.get()) { @@ -134,7 +141,7 @@ namespace shibsp { throw ConfigurationException("addAttributes method not implemented by this session cache plugin."); } void addAssertion(RootObject* assertion) { - throw ConfigurationException("addAttributes method not implemented by this session cache plugin."); + throw ConfigurationException("addAssertion method not implemented by this session cache plugin."); } time_t expires() const { return m_expires; } @@ -142,6 +149,8 @@ namespace shibsp { void validate(const Application& application, const char* client_addr, time_t timeout, bool local=true); private: + void unmarshallAttributes(DDF& in); + string m_appId; int m_version; mutable DDF m_obj; @@ -197,6 +206,24 @@ namespace shibsp { } } +void RemotedSession::unmarshallAttributes(DDF& in) +{ + DDF attr = in.first(); + while (!attr.isnull()) { + try { + m_attributes.push_back(Attribute::unmarshall(attr)); + if (m_cache->m_log.isDebugEnabled()) + m_cache->m_log.debug("unmarshalled attribute (ID: %s) with %d value%s", + attr.first().name(), attr.first().integer(), attr.first().integer()!=1 ? "s" : ""); + } + catch (AttributeException& ex) { + const char* id = attr.first().name(); + m_cache->m_log.error("error unmarshalling attribute (ID: %s): %s", id ? id : "none", ex.what()); + } + attr = attr.next(); + } +} + const RootObject* RemotedSession::getAssertion(const char* id) const { map::const_iterator i = m_tokens.find(id); @@ -280,22 +307,23 @@ void RemotedSession::validate(const Application& application, const char* client try { out=SPConfig::getConfig().getServiceProvider()->getListenerService()->send(in); - if (out.isstruct()) { - // We got an updated record back. - m_ids.clear(); - for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup()); - m_attributes.clear(); - m_obj.destroy(); - m_obj = out; - - // TODO: handle attributes - } } catch (...) { out.destroy(); throw; } - + + if (out.isstruct()) { + // We got an updated record back. + m_ids.clear(); + for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup()); + m_attributes.clear(); + m_obj.destroy(); + m_obj = out; + DDF attrs = m_obj["attributes"]; + unmarshallAttributes(attrs); + } + m_lastAccess = now; } diff --git a/shibsp/impl/StorageServiceSessionCache.cpp b/shibsp/impl/StorageServiceSessionCache.cpp index 3531909..f8aeac3 100644 --- a/shibsp/impl/StorageServiceSessionCache.cpp +++ b/shibsp/impl/StorageServiceSessionCache.cpp @@ -72,7 +72,14 @@ namespace shibsp { n->unmarshall(doc->getDocumentElement(), true); janitor.release(); - // TODO: Process attributes... + try { + DDF attrs = m_obj["attributes"]; + unmarshallAttributes(attrs); + } + catch (...) { + for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup()); + throw; + } m_nameid = n.release(); } @@ -126,6 +133,8 @@ namespace shibsp { void addAssertion(RootObject* assertion); private: + void unmarshallAttributes(DDF& in); + string m_appId; DDF m_obj; saml2::NameID* m_nameid; @@ -179,6 +188,24 @@ StoredSession::~StoredSession() for_each(m_tokens.begin(), m_tokens.end(), xmltooling::cleanup_pair()); } +void StoredSession::unmarshallAttributes(DDF& in) +{ + DDF attr = in.first(); + while (!attr.isnull()) { + try { + m_attributes.push_back(Attribute::unmarshall(attr)); + if (m_cache->m_log.isDebugEnabled()) + m_cache->m_log.debug("unmarshalled attribute (ID: %s) with %d value%s", + attr.first().name(), attr.first().integer(), attr.first().integer()!=1 ? "s" : ""); + } + catch (AttributeException& ex) { + const char* id = attr.first().name(); + m_cache->m_log.error("error unmarshalling attribute (ID: %s): %s", id ? id : "none", ex.what()); + } + attr = attr.next(); + } +} + void StoredSession::addAttributes(const vector& attributes) { #ifdef _DEBUG @@ -223,8 +250,8 @@ void StoredSession::addAttributes(const vector& attributes) m_cache->m_log.warn("storage service indicates the record is out of sync, updating with a fresh copy..."); ver = m_cache->m_storage->readText(m_appId.c_str(), m_obj.name(), &record, NULL); if (!ver) { - m_cache->m_log.error("updateText failed on StorageService for session (%s)", m_obj.name()); - throw IOException("Unable to update stored session."); + m_cache->m_log.error("readText failed on StorageService for session (%s)", m_obj.name()); + throw IOException("Unable to read back stored session."); } // Reset object. @@ -232,14 +259,15 @@ void StoredSession::addAttributes(const vector& attributes) istringstream in(record); in >> newobj; - m_obj.destroy(); m_ids.clear(); for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup()); m_attributes.clear(); newobj["version"].integer(ver); + m_obj.destroy(); m_obj = newobj; - // TODO: handle attributes - + DDF attrs = m_obj["attributes"]; + unmarshallAttributes(attrs); + ver = -1; } } while (ver < 0); // negative indicates a sync issue so we retry @@ -331,8 +359,8 @@ void StoredSession::addAssertion(RootObject* assertion) m_cache->m_log.warn("storage service indicates the record is out of sync, updating with a fresh copy..."); ver = m_cache->m_storage->readText(m_appId.c_str(), m_obj.name(), &record, NULL); if (!ver) { - m_cache->m_log.error("updateText failed on StorageService for session (%s)", m_obj.name()); - throw IOException("Unable to update stored session."); + m_cache->m_log.error("readText failed on StorageService for session (%s)", m_obj.name()); + throw IOException("Unable to read back stored session."); } // Reset object. @@ -340,13 +368,14 @@ void StoredSession::addAssertion(RootObject* assertion) istringstream in(record); in >> newobj; - m_obj.destroy(); m_ids.clear(); for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup()); m_attributes.clear(); newobj["version"].integer(ver); + m_obj.destroy(); m_obj = newobj; - // TODO: handle attributes + DDF attrs = m_obj["attributes"]; + unmarshallAttributes(attrs); ver = -1; } -- 2.1.4