b652ee096c80aed6bb7a80a1611dc1bc0a705b99
[shibboleth/cpp-sp.git] / shibsp / attribute / StringAttributeDecoder.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  * StringAttributeDecoder.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 <saml/saml1/core/Assertions.h>\r
28 #include <saml/saml2/core/Assertions.h>\r
29 \r
30 using namespace shibsp;\r
31 using namespace opensaml::saml1;\r
32 using namespace opensaml::saml2;\r
33 using namespace xmltooling;\r
34 using namespace std;\r
35 \r
36 namespace shibsp {\r
37     class SHIBSP_DLLLOCAL StringAttributeDecoder : virtual public AttributeDecoder\r
38     {\r
39     public:\r
40         StringAttributeDecoder(const DOMElement* e) : AttributeDecoder(e) {}\r
41         ~StringAttributeDecoder() {}\r
42 \r
43         shibsp::Attribute* decode(\r
44             const char* id, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
45             ) const;\r
46     };\r
47 \r
48     AttributeDecoder* SHIBSP_DLLLOCAL StringAttributeDecoderFactory(const DOMElement* const & e)\r
49     {\r
50         return new StringAttributeDecoder(e);\r
51     }\r
52 };\r
53 \r
54 shibsp::Attribute* StringAttributeDecoder::decode(\r
55     const char* id, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
56     ) const\r
57 {\r
58     char* val;\r
59     auto_ptr<SimpleAttribute> simple(new SimpleAttribute(id));\r
60     simple->setCaseSensitive(m_caseSensitive);\r
61     vector<string>& dest = simple->getValues();\r
62     vector<XMLObject*>::const_iterator v,stop;\r
63 \r
64     Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder");\r
65 \r
66     if (xmlObject && XMLString::equals(opensaml::saml1::Attribute::LOCAL_NAME,xmlObject->getElementQName().getLocalPart())) {\r
67         const opensaml::saml2::Attribute* saml2attr = dynamic_cast<const opensaml::saml2::Attribute*>(xmlObject);\r
68         if (saml2attr) {\r
69             const vector<XMLObject*>& values = saml2attr->getAttributeValues();\r
70             v = values.begin();\r
71             stop = values.end();\r
72             if (log.isDebugEnabled()) {\r
73                 auto_ptr_char n(saml2attr->getName());\r
74                 log.debug("decoding SimpleAttribute (%s) from SAML 2 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
75             }\r
76         }\r
77         else {\r
78             const opensaml::saml1::Attribute* saml1attr = dynamic_cast<const opensaml::saml1::Attribute*>(xmlObject);\r
79             if (saml1attr) {\r
80                 const vector<XMLObject*>& values = saml1attr->getAttributeValues();\r
81                 v = values.begin();\r
82                 stop = values.end();\r
83                 if (log.isDebugEnabled()) {\r
84                     auto_ptr_char n(saml1attr->getAttributeName());\r
85                     log.debug("decoding SimpleAttribute (%s) from SAML 1 Attribute (%s) with %lu value(s)", id, n.get() ? n.get() : "unnamed", values.size());\r
86                 }\r
87             }\r
88             else {\r
89                 log.warn("XMLObject type not recognized by StringAttributeDecoder, no values returned");\r
90                 return NULL;\r
91             }\r
92         }\r
93 \r
94         for (; v!=stop; ++v) {\r
95             if (!(*v)->hasChildren()) {\r
96                 val = toUTF8((*v)->getTextContent());\r
97                 if (val && *val)\r
98                     dest.push_back(val);\r
99                 else\r
100                     log.warn("skipping empty AttributeValue");\r
101                 delete[] val;\r
102             }\r
103             else {\r
104                 log.warn("skipping complex AttributeValue");\r
105             }\r
106         }\r
107 \r
108         return dest.empty() ? NULL : simple.release();\r
109     }\r
110 \r
111     const NameID* saml2name = dynamic_cast<const NameID*>(xmlObject);\r
112     if (saml2name) {\r
113         if (log.isDebugEnabled()) {\r
114             auto_ptr_char f(saml2name->getFormat());\r
115             log.debug("decoding SimpleAttribute (%s) from SAML 2 NameID with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
116         }\r
117         val = toUTF8(saml2name->getName());\r
118     }\r
119     else {\r
120         const NameIdentifier* saml1name = dynamic_cast<const NameIdentifier*>(xmlObject);\r
121         if (saml1name) {\r
122             if (log.isDebugEnabled()) {\r
123                 auto_ptr_char f(saml1name->getFormat());\r
124                 log.debug("decoding SimpleAttribute (%s) from SAML 1 NameIdentifier with Format (%s)", id, f.get() ? f.get() : "unspecified");\r
125             }\r
126             val = toUTF8(saml1name->getName());\r
127         }\r
128         else {\r
129             log.warn("XMLObject type not recognized by StringAttributeDecoder, no values returned");\r
130             return NULL;\r
131         }\r
132     }\r
133 \r
134     if (val && *val)\r
135         dest.push_back(val);\r
136     else\r
137         log.warn("ignoring empty NameID");\r
138     delete[] val;\r
139     return dest.empty() ? NULL : simple.release();\r
140 }\r