f199b1f44622cca5ce7e62921cc5658d2c810f89
[shibboleth/sp.git] / shibsp / attribute / SimpleAttributeDecoder.cpp
1 /*\r
2  *  Copyright 2001-2007 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * SimpleAttributeDecoder.cpp\r
19  * \r
20  * Decodes SAML into SimpleAttributes\r
21  */\r
22 \r
23 #include "internal.h"\r
24 #include "attribute/AttributeDecoder.h"\r
25 #include "attribute/SimpleAttribute.h"\r
26 \r
27 #include <log4cpp/Category.hh>\r
28 #include <saml/saml1/core/Assertions.h>\r
29 #include <saml/saml2/core/Assertions.h>\r
30 \r
31 using namespace shibsp;\r
32 using namespace opensaml::saml1;\r
33 using namespace opensaml::saml2;\r
34 using namespace xmltooling;\r
35 using namespace log4cpp;\r
36 using namespace std;\r
37 \r
38 namespace shibsp {\r
39     class SimpleAttributeDecoder : virtual public AttributeDecoder\r
40     {\r
41     public:\r
42         SimpleAttributeDecoder(const DOMElement* e) {}\r
43         ~SimpleAttributeDecoder() {}\r
44 \r
45         shibsp::Attribute* decode(const char* id, const XMLObject* xmlObject) const;\r
46     };\r
47 \r
48     AttributeDecoder* SHIBSP_DLLLOCAL SimpleAttributeDecoderFactory(const DOMElement* const & e)\r
49     {\r
50         return new SimpleAttributeDecoder(e);\r
51     }\r
52 };\r
53 \r
54 shibsp::Attribute* SimpleAttributeDecoder::decode(const char* id, const XMLObject* xmlObject) const\r
55 {\r
56     char* val;\r
57     auto_ptr<SimpleAttribute> simple(new SimpleAttribute(id));\r
58     vector<string>& dest = simple->getValues();\r
59     vector<XMLObject*>::const_iterator v,stop;\r
60 \r
61     Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder");\r
62 \r
63     if (xmlObject && XMLString::equals(opensaml::saml1::Attribute::LOCAL_NAME,xmlObject->getElementQName().getLocalPart())) {\r
64         const opensaml::saml2::Attribute* saml2attr = dynamic_cast<const opensaml::saml2::Attribute*>(xmlObject);\r
65         if (saml2attr) {\r
66             const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
67             v = values.begin();\r
68             stop = values.end();\r
69             if (log.isDebugEnabled()) {\r
70                 auto_ptr_char n(saml2attr->getName());\r
71                 log.debug("decoding SimpleAttribute (%s) from SAML 2 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
72             }\r
73         }\r
74         else {\r
75             const opensaml::saml1::Attribute* saml1attr = dynamic_cast<const opensaml::saml1::Attribute*>(xmlObject);\r
76             if (saml1attr) {\r
77                 const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
78                 v = values.begin();\r
79                 stop = values.end();\r
80                 if (log.isDebugEnabled()) {\r
81                     auto_ptr_char n(saml1attr->getAttributeName());\r
82                     log.debug("decoding SimpleAttribute (%s) from SAML 1 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
83                 }\r
84             }\r
85             else {\r
86                 log.warn("XMLObject type not recognized by SimpleAttributeDecoder, no values returned");\r
87                 return NULL;\r
88             }\r
89         }\r
90 \r
91         for (; v!=stop; ++v) {\r
92             if (!(*v)->hasChildren()) {\r
93                 val = toUTF8((*v)->getTextContent());\r
94                 if (val && *val)\r
95                     dest.push_back(val);\r
96                 else\r
97                     log.warn("skipping empty AttributeValue");\r
98                 delete[] val;\r
99             }\r
100             else {\r
101                 log.warn("skipping complex AttributeValue");\r
102             }\r
103         }\r
104 \r
105         return dest.empty() ? NULL : simple.release();\r
106     }\r
107 \r
108     const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);\r
109     if (saml2name) {\r
110         if (log.isDebugEnabled()) {\r
111             auto_ptr_char f(saml2name->getFormat());\r
112             log.debug("decoding SimpleAttribute (%s) from SAML 2 NameID with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
113         }\r
114         val = toUTF8(saml2name->getName());\r
115     }\r
116     else {\r
117         const NameIdentifier* saml1name = dynamic_cast<const NameIdentifier*>(xmlObject);\r
118         if (saml1name) {\r
119             if (log.isDebugEnabled()) {\r
120                 auto_ptr_char f(saml1name->getFormat());\r
121                 log.debug("decoding SimpleAttribute (%s) from SAML 1 NameIdentifier with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
122             }\r
123             val = toUTF8(saml1name->getName());\r
124         }\r
125         else {\r
126             log.warn("XMLObject type not recognized by SimpleAttributeDecoder, no values returned");\r
127             return NULL;\r
128         }\r
129     }\r
130 \r
131     if (val && *val)\r
132         dest.push_back(val);\r
133     else\r
134         log.warn("ignoring empty NameID");\r
135     delete[] val;\r
136     return dest.empty() ? NULL : simple.release();\r
137 }\r