NameID decoder.
authorScott Cantor <cantor.2@osu.edu>
Sun, 18 Feb 2007 23:06:21 +0000 (23:06 +0000)
committerScott Cantor <cantor.2@osu.edu>
Sun, 18 Feb 2007 23:06:21 +0000 (23:06 +0000)
shibsp/Makefile.am
shibsp/attribute/Attribute.cpp
shibsp/attribute/NameIDAttribute.h
shibsp/attribute/NameIDAttributeDecoder.cpp [new file with mode: 0644]
shibsp/attribute/ScopedAttribute.h
shibsp/attribute/ScopedAttributeDecoder.cpp
shibsp/attribute/SimpleAttributeDecoder.cpp
shibsp/shibsp.vcproj

index 8ca36c5..85a5bf5 100644 (file)
@@ -74,6 +74,7 @@ libshibsp_la_SOURCES = \
        SessionCache.cpp \
        SPConfig.cpp \
        attribute/Attribute.cpp \
+       attribute/NameIDAttributeDecoder.cpp \
        attribute/SimpleAttributeDecoder.cpp \
        attribute/ScopedAttributeDecoder.cpp \
        binding/impl/SOAPClient.cpp \
index d6df740..cda7400 100644 (file)
@@ -48,7 +48,7 @@ namespace shibsp {
     
     SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,const DOMElement*>::Factory SimpleAttributeDecoderFactory;
     SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,const DOMElement*>::Factory ScopedAttributeDecoderFactory;
-    //SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,const DOMElement*>::Factory NameIDAttributeDecoderFactory;
+    SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,const DOMElement*>::Factory NameIDAttributeDecoderFactory;
 };
 
 void shibsp::registerAttributeDecoders()
@@ -56,15 +56,15 @@ void shibsp::registerAttributeDecoders()
     SPConfig& conf = SPConfig::getConfig();
     conf.AttributeDecoderManager.registerFactory(SIMPLE_ATTRIBUTE_DECODER, SimpleAttributeDecoderFactory);
     conf.AttributeDecoderManager.registerFactory(SCOPED_ATTRIBUTE_DECODER, ScopedAttributeDecoderFactory);
-    //conf.AttributeDecoderManager.registerFactory(NAMEID_ATTRIBUTE_DECODER, NameIDAttributeDecoderFactory);
+    conf.AttributeDecoderManager.registerFactory(NAMEID_ATTRIBUTE_DECODER, NameIDAttributeDecoderFactory);
 }
 
 void shibsp::registerAttributeFactories()
 {
     Attribute::registerFactory("", SimpleAttributeFactory);
-    Attribute::registerFactory("simple", SimpleAttributeFactory);
-    Attribute::registerFactory("scoped", ScopedAttributeFactory);
-    Attribute::registerFactory("nameid", NameIDAttributeFactory);
+    Attribute::registerFactory("Simple", SimpleAttributeFactory);
+    Attribute::registerFactory("Scoped", ScopedAttributeFactory);
+    Attribute::registerFactory("NameID", NameIDAttributeFactory);
 }
 
 std::map<std::string,Attribute::AttributeFactory*> Attribute::m_factoryMap;
index 832c087..39f2f13 100644 (file)
@@ -135,7 +135,7 @@ namespace shibsp {
     
         DDF marshall() const {
             DDF ddf = Attribute::marshall();
-            ddf.name("nameid");
+            ddf.name("NameID");
             DDF vlist = ddf.first();
             for (std::vector<Value>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) {
                 DDF val = DDF(i->m_Name.c_str()).structure();
diff --git a/shibsp/attribute/NameIDAttributeDecoder.cpp b/shibsp/attribute/NameIDAttributeDecoder.cpp
new file mode 100644 (file)
index 0000000..c4885b1
--- /dev/null
@@ -0,0 +1,200 @@
+/*\r
+ *  Copyright 2001-2007 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * NameIDAttributeDecoder.cpp\r
+ * \r
+ * Decodes SAML into NameIDAttributes\r
+ */\r
+\r
+#include "internal.h"\r
+#include "attribute/AttributeDecoder.h"\r
+#include "attribute/NameIDAttribute.h"\r
+\r
+#include <log4cpp/Category.hh>\r
+#include <saml/saml1/core/Assertions.h>\r
+#include <saml/saml2/core/Assertions.h>\r
+\r
+using namespace shibsp;\r
+using namespace opensaml::saml1;\r
+using namespace opensaml::saml2;\r
+using namespace xmltooling;\r
+using namespace log4cpp;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+    static XMLCh formatter[] = UNICODE_LITERAL_9(f,o,r,m,a,t,t,e,r);\r
+\r
+    class SHIBSP_DLLLOCAL NameIDAttributeDecoder : virtual public AttributeDecoder\r
+    {\r
+    public:\r
+        NameIDAttributeDecoder(const DOMElement* e) : m_formatter(e ? e->getAttributeNS(NULL,formatter) : NULL) {}\r
+        ~NameIDAttributeDecoder() {}\r
+\r
+        shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
+\r
+    private:\r
+        void extract(const NameID* n, vector<NameIDAttribute::Value>& dest) const;\r
+        void extract(const NameIdentifier* n, vector<NameIDAttribute::Value>& dest) const;\r
+        auto_ptr_char m_formatter;\r
+    };\r
+\r
+    AttributeDecoder* SHIBSP_DLLLOCAL NameIDAttributeDecoderFactory(const DOMElement* const & e)\r
+    {\r
+        return new NameIDAttributeDecoder(e);\r
+    }\r
+};\r
+\r
+shibsp::Attribute* NameIDAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
+{\r
+    auto_ptr<NameIDAttribute> nameid(\r
+        new NameIDAttribute(id, (m_formatter.get() && *m_formatter.get()) ? m_formatter.get() : DEFAULT_NAMEID_FORMATTER)\r
+        );\r
+    vector<NameIDAttribute::Value>& dest = nameid->getValues();\r
+    vector<XMLObject*>::const_iterator v,stop;\r
+\r
+    Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder");\r
+    \r
+    if (xmlObject && XMLString::equals(opensaml::saml1::Attribute::LOCAL_NAME,xmlObject->getElementQName().getLocalPart())) {\r
+        const opensaml::saml2::Attribute* saml2attr = dynamic_cast<const opensaml::saml2::Attribute*>(xmlObject);\r
+        if (saml2attr) {\r
+            const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+            v = values.begin();\r
+            stop = values.end();\r
+            if (log.isDebugEnabled()) {\r
+                auto_ptr_char n(saml2attr->getName());\r
+                log.debug("decoding NameIDAttribute (%s) from SAML 2 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
+            }\r
+        }\r
+        else {\r
+            const opensaml::saml1::Attribute* saml1attr = dynamic_cast<const opensaml::saml1::Attribute*>(xmlObject);\r
+            if (saml1attr) {\r
+                const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
+                v = values.begin();\r
+                stop = values.end();\r
+                if (log.isDebugEnabled()) {\r
+                    auto_ptr_char n(saml1attr->getAttributeName());\r
+                    log.debug("decoding NameIDAttribute (%s) from SAML 1 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
+                }\r
+            }\r
+            else {\r
+                log.warn("XMLObject type not recognized by NameIDAttributeDecoder, no values returned");\r
+                return NULL;\r
+            }\r
+        }\r
+\r
+        for (; v!=stop; ++v) {\r
+            const NameID* n2 = dynamic_cast<const NameID*>(*v);\r
+            if (n2)\r
+                extract(n2, dest);\r
+            else {\r
+                const NameIdentifier* n1=dynamic_cast<const NameIdentifier*>(*v);\r
+                if (n1)\r
+                    extract(n1, dest);\r
+                else if ((*v)->hasChildren()) {\r
+                    const list<XMLObject*>& values = (*v)->getOrderedChildren();\r
+                    for (list<XMLObject*>::const_iterator vv = values.begin(); vv!=values.end(); ++vv) {\r
+                        if (n2=dynamic_cast<const NameID*>(*vv))\r
+                            extract(n2, dest);\r
+                        else if (n1=dynamic_cast<const NameIdentifier*>(*vv))\r
+                            extract(n1, dest);\r
+                        else\r
+                            log.warn("skipping AttributeValue without a recognizable NameID/NameIdentifier");\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        return dest.empty() ? NULL : nameid.release();\r
+    }\r
+\r
+    const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);\r
+    if (saml2name) {\r
+        if (log.isDebugEnabled()) {\r
+            auto_ptr_char f(saml2name->getFormat());\r
+            log.debug("decoding NameIDAttribute (%s) from SAML 2 NameID with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
+        }\r
+        extract(saml2name, dest);\r
+    }\r
+    else {\r
+        const NameIdentifier* saml1name = dynamic_cast<const NameIdentifier*>(xmlObject);\r
+        if (saml1name) {\r
+            if (log.isDebugEnabled()) {\r
+                auto_ptr_char f(saml1name->getFormat());\r
+                log.debug("decoding NameIDAttribute (%s) from SAML 1 NameIdentifier with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
+            }\r
+            extract(saml1name, dest);\r
+        }\r
+        else {\r
+            log.warn("XMLObject type not recognized by NameIDAttributeDecoder, no values returned");\r
+            return NULL;\r
+        }\r
+    }\r
+\r
+    return dest.empty() ? NULL : nameid.release();\r
+}\r
+\r
+void NameIDAttributeDecoder::extract(const NameID* n, vector<NameIDAttribute::Value>& dest) const\r
+{\r
+    char* name = toUTF8(n->getName());\r
+    if (name && *name) {\r
+        dest.push_back(NameIDAttribute::Value());\r
+        NameIDAttribute::Value& val = dest.back();\r
+        val.m_Name = name;\r
+        char* str = toUTF8(n->getFormat());\r
+        if (str) {\r
+            val.m_Format = str;\r
+            delete[] str;\r
+        }\r
+        str = toUTF8(n->getNameQualifier());\r
+        if (str) {\r
+            val.m_NameQualifier = str;\r
+            delete[] str;\r
+        }\r
+        str = toUTF8(n->getSPNameQualifier());\r
+        if (str) {\r
+            val.m_SPNameQualifier = str;\r
+            delete[] str;\r
+        }\r
+        str = toUTF8(n->getSPProvidedID());\r
+        if (str) {\r
+            val.m_SPProvidedID = str;\r
+            delete[] str;\r
+        }\r
+    }\r
+    delete[] name;\r
+}\r
+\r
+void NameIDAttributeDecoder::extract(const NameIdentifier* n, vector<NameIDAttribute::Value>& dest) const\r
+{\r
+    char* name = toUTF8(n->getName());\r
+    if (name && *name) {\r
+        dest.push_back(NameIDAttribute::Value());\r
+        NameIDAttribute::Value& val = dest.back();\r
+        val.m_Name = name;\r
+        char* str = toUTF8(n->getFormat());\r
+        if (str) {\r
+            val.m_Format = str;\r
+            delete[] str;\r
+        }\r
+        str = toUTF8(n->getNameQualifier());\r
+        if (str) {\r
+            val.m_NameQualifier = str;\r
+            delete[] str;\r
+        }\r
+    }\r
+    delete[] name;\r
+}\r
index 2156f2a..0e73c86 100644 (file)
@@ -100,7 +100,7 @@ namespace shibsp {
 
         DDF marshall() const {
             DDF ddf = Attribute::marshall();
-            ddf.name("scoped");
+            ddf.name("Scoped");
             if (!m_caseSensitive)
                 ddf.addmember("case_insensitive");
             DDF vlist = ddf.first();
index 8bab5ec..a412d64 100644 (file)
@@ -36,7 +36,7 @@ using namespace log4cpp;
 using namespace std;\r
 \r
 namespace shibsp {\r
-    class ScopedAttributeDecoder : virtual public AttributeDecoder\r
+    class SHIBSP_DLLLOCAL ScopedAttributeDecoder : virtual public AttributeDecoder\r
     {\r
     public:\r
         ScopedAttributeDecoder(const DOMElement* e) {}\r
index f199b1f..0dfc6c8 100644 (file)
@@ -36,7 +36,7 @@ using namespace log4cpp;
 using namespace std;\r
 \r
 namespace shibsp {\r
-    class SimpleAttributeDecoder : virtual public AttributeDecoder\r
+    class SHIBSP_DLLLOCAL SimpleAttributeDecoder : virtual public AttributeDecoder\r
     {\r
     public:\r
         SimpleAttributeDecoder(const DOMElement* e) {}\r
index 72cf763..f4b68a1 100644 (file)
                                        >\r
                                </File>\r
                                <File\r
+                                       RelativePath=".\attribute\NameIDAttributeDecoder.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath=".\attribute\ScopedAttributeDecoder.cpp"\r
                                        >\r
                                </File>\r