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