Process attributes when loading sessions.
authorScott Cantor <cantor.2@osu.edu>
Fri, 2 Feb 2007 23:28:48 +0000 (23:28 +0000)
committerScott Cantor <cantor.2@osu.edu>
Fri, 2 Feb 2007 23:28:48 +0000 (23:28 +0000)
shibsp/impl/RemotedSessionCache.cpp
shibsp/impl/StorageServiceSessionCache.cpp

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