attribute/ExtensibleAttribute.h \
attribute/NameIDAttribute.h \
attribute/ScopedAttribute.h \
- attribute/SimpleAttribute.h
+ attribute/SimpleAttribute.h \
+ attribute/XMLAttribute.h
attrfiltinclude_HEADERS = \
attribute/filtering/AttributeFilter.h \
attribute/NameIDFromScopedAttributeDecoder.cpp \
attribute/ScopedAttributeDecoder.cpp \
attribute/StringAttributeDecoder.cpp \
+ attribute/XMLAttributeDecoder.cpp \
attribute/filtering/impl/AttributeFilter.cpp \
attribute/filtering/impl/ChainingAttributeFilter.cpp \
attribute/filtering/impl/XMLAttributeFilter.cpp \
#include "attribute/ScopedAttribute.h"
#include "attribute/NameIDAttribute.h"
#include "attribute/ExtensibleAttribute.h"
+#include "attribute/XMLAttribute.h"
#include "util/SPConstants.h"
+#include <xercesc/util/Base64.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
using namespace shibsp;
return new ExtensibleAttribute(in);
}
+ SHIBSP_DLLLOCAL Attribute* XMLAttributeFactory(DDF& in) {
+ return new XMLAttribute(in);
+ }
+
#ifndef SHIBSP_LITE
SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory StringAttributeDecoderFactory;
SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory ScopedAttributeDecoderFactory;
SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory NameIDFromScopedAttributeDecoderFactory;
SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory KeyInfoAttributeDecoderFactory;
SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory DOMAttributeDecoderFactory;
+ SHIBSP_DLLLOCAL PluginManager<AttributeDecoder,xmltooling::QName,const DOMElement*>::Factory XMLAttributeDecoderFactory;
static const XMLCh _StringAttributeDecoder[] = UNICODE_LITERAL_22(S,t,r,i,n,g,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh _ScopedAttributeDecoder[] = UNICODE_LITERAL_22(S,c,o,p,e,d,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh _NameIDFromScopedAttributeDecoder[] = UNICODE_LITERAL_32(N,a,m,e,I,D,F,r,o,m,S,c,o,p,e,d,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh _KeyInfoAttributeDecoder[] =UNICODE_LITERAL_23(K,e,y,I,n,f,o,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh _DOMAttributeDecoder[] = UNICODE_LITERAL_19(D,O,M,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
+ static const XMLCh _XMLAttributeDecoder[] = UNICODE_LITERAL_19(X,M,L,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
static const XMLCh caseSensitive[] = UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
static const XMLCh internal[] = UNICODE_LITERAL_8(i,n,t,e,r,n,a,l);
xmltooling::QName shibsp::NameIDFromScopedAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _NameIDFromScopedAttributeDecoder);
xmltooling::QName shibsp::KeyInfoAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _KeyInfoAttributeDecoder);
xmltooling::QName shibsp::DOMAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _DOMAttributeDecoder);
+xmltooling::QName shibsp::XMLAttributeDecoderType(shibspconstants::SHIB2ATTRIBUTEMAP_NS, _XMLAttributeDecoder);
void shibsp::registerAttributeDecoders()
{
conf.AttributeDecoderManager.registerFactory(NameIDFromScopedAttributeDecoderType, NameIDFromScopedAttributeDecoderFactory);
conf.AttributeDecoderManager.registerFactory(KeyInfoAttributeDecoderType, KeyInfoAttributeDecoderFactory);
conf.AttributeDecoderManager.registerFactory(DOMAttributeDecoderType, DOMAttributeDecoderFactory);
+ conf.AttributeDecoderManager.registerFactory(XMLAttributeDecoderType, XMLAttributeDecoderFactory);
}
AttributeDecoder::AttributeDecoder(const DOMElement *e) : m_caseSensitive(true), m_internal(false)
Attribute::registerFactory("Scoped", ScopedAttributeFactory);
Attribute::registerFactory("NameID", NameIDAttributeFactory);
Attribute::registerFactory("Extensible", ExtensibleAttributeFactory);
+ Attribute::registerFactory("XML", XMLAttributeFactory);
}
map<string,Attribute::AttributeFactory*> Attribute::m_factoryMap;
throw AttributeException("No registered factory for Attribute of type ($1).", params(1,in.name()));
return (i->second)(in);
}
+
+const vector<string>& XMLAttribute::getSerializedValues() const
+{
+ xsecsize_t len;
+ XMLByte *pos, *pos2;\r
+ if (m_serialized.empty()) {
+ for (vector<string>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) {
+ XMLByte* enc = Base64::encode(reinterpret_cast<const XMLByte*>(i->data()), i->size(), &len);
+ if (enc) {
+ for (pos=enc, pos2=enc; *pos2; pos2++)\r
+ if (isgraph(*pos2))\r
+ *pos++=*pos2;\r
+ *pos=0;\r
+ m_serialized.push_back(reinterpret_cast<char*>(enc));
+#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE
+ XMLString::release(&enc);
+#else
+ XMLString::release((char**)&enc);
+#endif
+ }
+ }
+ }
+ return Attribute::getSerializedValues();
+}
/** Decodes arbitrary DOM information into an ExtensibleAttribute. */
extern SHIBSP_API xmltooling::QName DOMAttributeDecoderType;
+ /** Decodes arbitrary XML into an XMLAttribute. */
+ extern SHIBSP_API xmltooling::QName XMLAttributeDecoderType;
+
/** Registers built-in AttributeDecoders into the runtime. */
void registerAttributeDecoders();
};
--- /dev/null
+/*
+ * Copyright 2009 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file shibsp/attribute/XMLAttribute.h
+ *
+ * An Attribute whose values are serialized XML.
+ */
+
+#ifndef __shibsp_xmlattr_h__
+#define __shibsp_xmlattr_h__
+
+#include <shibsp/attribute/Attribute.h>
+
+namespace shibsp {
+
+ /**
+ * An Attribute whose values are serialized XML.
+ */
+ class SHIBSP_API XMLAttribute : public Attribute
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param ids array with primary identifier in first position, followed by any aliases
+ */
+ XMLAttribute(const std::vector<std::string>& ids) : Attribute(ids) {}
+
+ /**
+ * Constructs based on a remoted XMLAttribute.
+ *
+ * @param in input object containing marshalled XMLAttribute
+ */
+ XMLAttribute(DDF& in) : Attribute(in) {
+ DDF val = in.first().first();
+ while (val.string()) {
+ m_values.push_back(val.string());
+ val = in.first().next();
+ }
+ }
+
+ virtual ~XMLAttribute() {}
+
+ /**
+ * Returns the set of values encoded as XML.
+ *
+ * @return a mutable vector of the values
+ */
+ std::vector<std::string>& getValues() {
+ return m_values;
+ }
+
+ /**
+ * Returns the set of values encoded as XML.
+ *
+ * @return an immutable vector of the values
+ */
+ const std::vector<std::string>& getValues() const {
+ return m_values;
+ }
+
+ size_t valueCount() const {
+ return m_values.size();
+ }
+
+ void clearSerializedValues() {
+ m_serialized.clear();
+ }
+
+ const char* getString(size_t index) const {
+ return m_values[index].c_str();
+ }
+
+ void removeValue(size_t index) {
+ Attribute::removeValue(index);
+ if (index < m_values.size())
+ m_values.erase(m_values.begin() + index);
+ }
+
+ const std::vector<std::string>& getSerializedValues() const;
+
+ DDF marshall() const {
+ DDF ddf = Attribute::marshall();
+ ddf.name("XML");
+ DDF vlist = ddf.first();
+ for (std::vector<std::string>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i)
+ vlist.add(DDF(NULL).string(i->c_str()));
+ return ddf;
+ }
+
+ private:
+ std::vector<std::string> m_values;
+ };
+
+};
+
+#endif /* __shibsp_xmlattr_h__ */
--- /dev/null
+/*\r
+ * Copyright 2009 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
+ * XMLAttributeDecoder.cpp\r
+ *\r
+ * Decodes arbitrary XML into an XMLAttribute.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "attribute/AttributeDecoder.h"\r
+#include "attribute/XMLAttribute.h"\r
+\r
+#include <saml/saml1/core/Assertions.h>\r
+#include <saml/saml2/core/Assertions.h>\r
+#include <xmltooling/util/XMLHelper.h>\r
+\r
+using namespace shibsp;\r
+using namespace opensaml;\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+namespace shibsp {\r
+ class SHIBSP_DLLLOCAL XMLAttributeDecoder : virtual public AttributeDecoder\r
+ {\r
+ public:\r
+ XMLAttributeDecoder(const DOMElement* e) : AttributeDecoder(e) {}\r
+ ~XMLAttributeDecoder() {}\r
+\r
+ Attribute* decode(\r
+ const vector<string>& ids, const XMLObject* xmlObject, const char* assertingParty=NULL, const char* relyingParty=NULL\r
+ ) const;\r
+\r
+ private:\r
+ DDF convert(DOMElement* e, bool nameit=true) const;\r
+ auto_ptr_char m_formatter;\r
+ map<pair<xstring,xstring>,string> m_tagMap;\r
+ };\r
+\r
+ AttributeDecoder* SHIBSP_DLLLOCAL XMLAttributeDecoderFactory(const DOMElement* const & e)\r
+ {\r
+ return new XMLAttributeDecoder(e);\r
+ }\r
+};\r
+\r
+\r
+Attribute* XMLAttributeDecoder::decode(\r
+ const vector<string>& ids, const XMLObject* xmlObject, const char* assertingParty, const char* relyingParty\r
+ ) const\r
+{\r
+ if (!xmlObject)\r
+ return NULL;\r
+\r
+ Category& log = Category::getInstance(SHIBSP_LOGCAT".AttributeDecoder.XML");\r
+\r
+ auto_ptr<XMLAttribute> attr(new XMLAttribute(ids));\r
+ vector<string>& dest = attr->getValues();\r
+\r
+ // Handle any non-Attribute object directly.\r
+ if (!xmlObject || !XMLString::equals(saml1::Attribute::LOCAL_NAME, xmlObject->getElementQName().getLocalPart())) {\r
+ DOMElement* e = xmlObject->getDOM();\r
+ if (e) {\r
+ if (log.isDebugEnabled()) {\r
+ log.debug(\r
+ "decoding XMLAttribute (%s) from XMLObject (%s)",\r
+ ids.front().c_str(),\r
+ (xmlObject->getSchemaType() ? xmlObject->getSchemaType()->toString() : xmlObject->getElementQName().toString()).c_str()\r
+ );\r
+ }\r
+ dest.push_back(string());\r
+ XMLHelper::serialize(e, dest.back());\r
+ }\r
+ else {\r
+ log.warn("skipping XMLObject without a backing DOM");\r
+ }\r
+ return dest.empty() ? NULL : _decode(attr.release());\r
+ }\r
+\r
+ vector<XMLObject*>::const_iterator v,stop;\r
+\r
+ const saml2::Attribute* saml2attr = dynamic_cast<const 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(\r
+ "decoding XMLAttribute (%s) from SAML 2 Attribute (%s) with %lu value(s)",\r
+ ids.front().c_str(), n.get() ? n.get() : "unnamed", values.size()\r
+ );\r
+ }\r
+ }\r
+ else {\r
+ const saml1::Attribute* saml1attr = dynamic_cast<const saml1::Attribute*>(xmlObject);\r
+ if (saml1attr) {\r
+ const vector<XMLObject*>& values = saml1attr->getAttributeValues();\r
+ v = values.begin();\r
+ stop = values.end();\r
+ if (log.isDebugEnabled()) {\r
+ auto_ptr_char n(saml1attr->getAttributeName());\r
+ log.debug(\r
+ "decoding XMLAttribute (%s) from SAML 1 Attribute (%s) with %lu value(s)",\r
+ ids.front().c_str(), n.get() ? n.get() : "unnamed", values.size()\r
+ );\r
+ }\r
+ }\r
+ else {\r
+ log.warn("XMLObject type not recognized by XMLAttributeDecoder, no values returned");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ for (; v!=stop; ++v) {\r
+ DOMElement* e = (*v)->getDOM();\r
+ if (e) {\r
+ dest.push_back(string());\r
+ XMLHelper::serialize(e, dest.back());\r
+ }\r
+ else\r
+ log.warn("skipping AttributeValue without a backing DOM");\r
+ }\r
+\r
+ return dest.empty() ? NULL : _decode(attr.release());\r
+}\r
RelativePath=".\attribute\SimpleAttribute.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\XMLAttribute.h"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="handler"\r
RelativePath=".\attribute\StringAttributeDecoder.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\XMLAttributeDecoder.cpp"\r
+ >\r
+ </File>\r
<Filter\r
Name="resolver"\r
>\r
RelativePath=".\attribute\SimpleAttribute.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\attribute\XMLAttribute.h"\r
+ >\r
+ </File>\r
<Filter\r
Name="resolver"\r
>\r