978f78db1c9e65866d4dc628ae5d4955eadb2d3f
[shibboleth/cpp-sp.git] / shibsp / attribute / NameIDAttribute.cpp
1 /*
2  *  Copyright 2009 Internet2
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * NameIDAttribute.cpp
19  *
20  * An Attribute whose values are derived from or mappable to a SAML NameID.
21  */
22
23 #include "internal.h"
24 #include "attribute/NameIDAttribute.h"
25
26 #include <xmltooling/exceptions.h>
27
28 using namespace shibsp;
29 using namespace xmltooling;
30 using namespace std;
31
32 namespace shibsp {
33     SHIBSP_DLLLOCAL Attribute* NameIDAttributeFactory(DDF& in) {
34         return new NameIDAttribute(in);
35     }
36 };
37
38 NameIDAttribute::NameIDAttribute(const vector<string>& ids, const char* formatter) : Attribute(ids), m_formatter(formatter)
39 {
40 }
41
42 NameIDAttribute::NameIDAttribute(DDF& in) : Attribute(in)
43 {
44     DDF val = in["_formatter"];
45     if (val.isstring())
46         m_formatter = val.string();
47     else
48         m_formatter = DEFAULT_NAMEID_FORMATTER;
49     const char* pch;
50     val = in.first().first();
51     while (val.name()) {
52         m_values.push_back(Value());
53         Value& v = m_values.back();
54         v.m_Name = val.name();
55         pch = val["Format"].string();
56         if (pch)
57             v.m_Format = pch;
58         pch = val["NameQualifier"].string();
59         if (pch)
60             v.m_NameQualifier = pch;
61         pch = val["SPNameQualifier"].string();
62         if (pch)
63             v.m_SPNameQualifier = pch;
64         pch = val["SPProvidedID"].string();
65         if (pch)
66             v.m_SPProvidedID = pch;
67         val = in.first().next();
68     }
69 }
70
71 NameIDAttribute::~NameIDAttribute()
72 {
73 }
74
75 vector<NameIDAttribute::Value>& NameIDAttribute::getValues()
76 {
77     return m_values;
78 }
79
80 const vector<NameIDAttribute::Value>& NameIDAttribute::getValues() const
81 {
82     return m_values;
83 }
84
85 size_t NameIDAttribute::valueCount() const
86 {
87     return m_values.size();
88 }
89
90 void NameIDAttribute::clearSerializedValues()
91 {
92     m_serialized.clear();
93 }
94
95 const char* NameIDAttribute::getString(size_t index) const
96 {
97     return m_values[index].m_Name.c_str();
98 }
99
100 const char* NameIDAttribute::getScope(size_t index) const
101 {
102     return m_values[index].m_NameQualifier.c_str();
103 }
104
105 void NameIDAttribute::removeValue(size_t index)
106 {
107     Attribute::removeValue(index);
108     if (index < m_values.size())
109         m_values.erase(m_values.begin() + index);
110 }
111
112 const vector<string>& NameIDAttribute::getSerializedValues() const
113 {
114     if (m_serialized.empty()) {
115         for (vector<Value>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) {
116             // This is kind of a hack, but it's a good way to reuse some code.
117             XMLToolingException e(
118                 m_formatter,
119                 namedparams(
120                     5,
121                     "Name", i->m_Name.c_str(),
122                     "Format", i->m_Format.c_str(),
123                     "NameQualifier", i->m_NameQualifier.c_str(),
124                     "SPNameQualifier", i->m_SPNameQualifier.c_str(),
125                     "SPProvidedID", i->m_SPProvidedID.c_str()
126                     )
127                 );
128             m_serialized.push_back(e.what());
129         }
130     }
131     return Attribute::getSerializedValues();
132 }
133
134 DDF NameIDAttribute::marshall() const
135 {
136     DDF ddf = Attribute::marshall();
137     ddf.name("NameID");
138     ddf.addmember("_formatter").string(m_formatter.c_str());
139     DDF vlist = ddf.first();
140     for (vector<Value>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) {
141         DDF val = DDF(i->m_Name.c_str()).structure();
142         if (!i->m_Format.empty())
143             val.addmember("Format").string(i->m_Format.c_str());
144         if (!i->m_NameQualifier.empty())
145             val.addmember("NameQualifier").string(i->m_NameQualifier.c_str());
146         if (!i->m_SPNameQualifier.empty())
147             val.addmember("SPNameQualifier").string(i->m_SPNameQualifier.c_str());
148         if (!i->m_SPProvidedID.empty())
149             val.addmember("SPProvidedID").string(i->m_SPProvidedID.c_str());
150         vlist.add(val);
151     }
152     return ddf;
153 }