using namespace log4cpp;
using namespace std;
+void ScopedAttribute::valueToDOM(unsigned int index, DOMElement* e) const
+{
+ SAMLAttribute::valueToDOM(index,e);
+ e->setAttributeNS(NULL,SHIB_L(Scope),m_scopes[index]);
+}
ScopedAttribute::ScopedAttribute(const XMLCh* name, const XMLCh* ns, long lifetime,
const saml::Iterator<const XMLCh*>& scopes,
const saml::Iterator<const XMLCh*>& values)
- : SimpleAttribute(name,ns,lifetime,values)
+ : SAMLAttribute(name,ns,NULL,lifetime,values)
{
if (scopes.size()!=values.size())
throw MalformedException(SAMLException::RESPONDER,"ScopedAttribute() requires the number of scopes to equal the number of values");
while (scopes.hasNext())
- m_values.push_back(scopes.next());
+ m_scopes.push_back(XMLString::replicate(scopes.next()));
}
-ScopedAttribute::ScopedAttribute(DOMElement* e) : SimpleAttribute(e) {}
-
-ScopedAttribute::~ScopedAttribute() {}
-
-bool ScopedAttribute::addValue(DOMElement* e)
+ScopedAttribute::ScopedAttribute(DOMElement* e) : SAMLAttribute(e)
{
- static XMLCh empty[] = {chNull};
- if (SAMLAttribute::addValue(e))
+ // Default scope comes from subject.
+ DOMNodeList* nlist=
+ static_cast<DOMElement*>(e->getParentNode())->getElementsByTagNameNS(saml::XML::SAML_NS,L(NameIdentifier));
+ if (!nlist || nlist->getLength() != 1)
+ throw MalformedException(SAMLException::RESPONDER,"ScopedAttribute() can't find saml:NameIdentifier in enclosing statement");
+ m_originSite=static_cast<DOMElement*>(nlist->item(0))->getAttributeNS(NULL,L(NameQualifier));
+
+ e=saml::XML::getFirstChildElement(e,saml::XML::SAML_NS,L(AttributeValue));
+ while (e)
{
- DOMAttr* scope=e->getAttributeNodeNS(NULL,Scope);
- m_scopes.push_back(scope ? scope->getNodeValue() : empty);
- return true;
+ DOMAttr* scope=e->getAttributeNodeNS(NULL,SHIB_L(Scope));
+ m_scopes.push_back(scope ? scope->getNodeValue() : &chNull);
+ e=saml::XML::getNextSiblingElement(e,saml::XML::SAML_NS,L(AttributeValue));
}
- return false;
}
-bool ScopedAttribute::accept(DOMElement* e) const
+ScopedAttribute::~ScopedAttribute()
{
- OriginSiteMapper mapper;
- Iterator<pair<xstring,bool> > domains=mapper.getSecurityDomains(m_originSite.c_str());
- const XMLCh* this_scope=NULL;
- DOMAttr* scope=e->getAttributeNodeNS(NULL,Scope);
- if (scope)
- this_scope=scope->getNodeValue();
- if (!this_scope || !*this_scope)
- this_scope=m_originSite.c_str();
-
- while (domains.hasNext())
+ if (m_bOwnStrings)
{
- const pair<xstring,bool>& p=domains.next();
- if (p.second)
+ for (vector<const XMLCh*>::iterator i=m_scopes.begin(); i!=m_scopes.end(); i++)
{
- try
- {
- RegularExpression re(p.first.c_str());
- if (re.matches(this_scope))
- return true;
- }
- catch (XMLException& ex)
- {
- auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
- NDC ndc("accept");
- Category& log=Category::getInstance(SHIB_LOGCAT".ScopedAttribute");
- log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
- << CategoryStream::ENDLINE;
- return false;
- }
+ XMLCh* p = const_cast<XMLCh*>(*i);
+ XMLString::release(&p);
}
- else if (p.first==this_scope)
- return true;
}
- NDC ndc("accept");
- Category& log=Category::getInstance(SHIB_LOGCAT".ScopedAttribute");
- if (log.isWarnEnabled())
+ // We always own any scoped values we've built.
+ for (vector<const XMLCh*>::iterator i=m_scopedValues.begin(); i!=m_scopedValues.end(); i++)
{
- auto_ptr<char> tmp(XMLString::transcode(this_scope));
- log.warn("rejecting value with scope of %s",tmp.get());
+ XMLCh* p = const_cast<XMLCh*>(*i);
+ XMLString::release(&p);
}
- return false;
}
-Iterator<xstring> ScopedAttribute::getValues() const
+Iterator<const XMLCh*> ScopedAttribute::getValues() const
{
+ static XMLCh at[]={chAt, chNull};
+
if (m_scopedValues.empty())
{
- vector<xstring>::const_iterator j=m_scopes.begin();
- for (vector<xstring>::const_iterator i=m_values.begin(); i!=m_values.end(); i++, j++)
- m_scopedValues.push_back((*i) + chAt + (!j->empty() ? (*j) : m_originSite));
+ vector<const XMLCh*>::const_iterator j=m_scopes.begin();
+ for (vector<const XMLCh*>::const_iterator i=m_values.begin(); i!=m_values.end(); i++, j++)
+ {
+ const XMLCh* scope=((*j) ? (*j) : m_originSite);
+ XMLCh* temp=new XMLCh[XMLString::stringLen(*i) + XMLString::stringLen(scope) + 2];
+ temp[0]=chNull;
+ XMLString::catString(temp,*i);
+ XMLString::catString(temp,at);
+ XMLString::catString(temp,scope);
+ m_scopedValues.push_back(temp);
+ }
}
- return Iterator<xstring>(m_scopedValues);
+ return m_scopedValues;
}
Iterator<string> ScopedAttribute::getSingleByteValues() const
getValues();
if (m_sbValues.empty())
{
- for (vector<xstring>::const_iterator i=m_scopedValues.begin(); i!=m_scopedValues.end(); i++)
+ for (vector<const XMLCh*>::const_iterator i=m_scopedValues.begin(); i!=m_scopedValues.end(); i++)
{
- auto_ptr<char> temp(XMLString::transcode(i->c_str()));
+ auto_ptr<char> temp(toUTF8(*i));
if (temp.get())
m_sbValues.push_back(temp.get());
}
return Iterator<string>(m_sbValues);
}
-SAMLObject* ScopedAttribute::clone() const
+void ScopedAttribute::setValues(const Iterator<const XMLCh*>& values)
{
- ScopedAttribute* dest=new ScopedAttribute(m_name,m_namespace,m_lifetime);
- dest->m_values.assign(m_values.begin(),m_values.end());
- dest->m_scopes.assign(m_scopes.begin(),m_scopes.end());
- return dest;
+ throw SAMLException("unsupported operation");
}
-DOMNode* ScopedAttribute::toDOM(DOMDocument* doc,bool xmlns) const
+void ScopedAttribute::addValue(const XMLCh* value)
{
- SimpleAttribute::toDOM(doc,xmlns);
+ throw SAMLException("unsupported operation");
+}
- int i=0;
- DOMNode* n=m_root->getFirstChild();
- while (n)
- {
- if (n->getNodeType()==DOMNode::ELEMENT_NODE)
- {
- static_cast<DOMElement*>(n)->setAttributeNS(NULL,Scope,
- (!m_scopes[i].empty() ? m_scopes[i].c_str() : m_originSite.c_str()));
- i++;
- }
- n=n->getNextSibling();
+void ScopedAttribute::removeValue(unsigned int index)
+{
+ SAMLAttribute::removeValue(index);
+
+ if (m_bOwnStrings) {
+ XMLCh* p=const_cast<XMLCh*>(m_scopes[index]);
+ XMLString::release(&p);
}
-
- return m_root;
+ m_scopes.erase(m_scopes.begin()+index);
}
-const XMLCh ScopedAttribute::Scope[] = { chLatin_S, chLatin_c, chLatin_o, chLatin_p, chLatin_e, chNull };
+SAMLObject* ScopedAttribute::clone() const
+{
+ return new ScopedAttribute(m_name,m_namespace,m_lifetime,m_scopes,m_values);
+}