AAP implementation, refactoring of simple attribute classes.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Mon, 23 Dec 2002 06:20:39 +0000 (06:20 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Mon, 23 Dec 2002 06:20:39 +0000 (06:20 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@245 cb58f699-b61c-0410-a6fe-9272a202ed29

13 files changed:
eduPerson/AAP.cpp [new file with mode: 0644]
eduPerson/AffiliationAttribute.cpp
eduPerson/Constants.cpp
eduPerson/EPPNAttribute.cpp
eduPerson/EntitlementAttribute.cpp
eduPerson/Makefile.am
eduPerson/PrimaryAffiliationAttribute.cpp
eduPerson/ScopedAttribute.cpp
eduPerson/SimpleAttribute.cpp [new file with mode: 0644]
eduPerson/eduPerson.cpp
eduPerson/eduPerson.dsp
eduPerson/eduPerson.h
eduPerson/internal.h [new file with mode: 0644]

diff --git a/eduPerson/AAP.cpp b/eduPerson/AAP.cpp
new file mode 100644 (file)
index 0000000..09257cd
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* AAP.cpp - XML AAP implementation
+
+   Scott Cantor
+   12/21/02
+
+   $History:$
+*/
+
+#include "internal.h"
+
+#include <xercesc/framework/URLInputSource.hpp>
+#include <xercesc/util/regx/RegularExpression.hpp>
+
+AAP::AAP(const char* uri)
+{
+    NDC ndc("AAP");
+    Category& log=Category::getInstance("eduPerson.AAP");
+
+    saml::XML::Parser p;
+    DOMDocument* doc=NULL;
+       try
+    {
+        static XMLCh base[]={chLatin_f, chLatin_i, chLatin_l, chLatin_e, chColon, chForwardSlash, chForwardSlash, chForwardSlash, chNull};
+        URLInputSource src(base,uri);
+        Wrapper4InputSource dsrc(&src,false);
+               doc=p.parse(dsrc);
+
+        log.infoStream() << "Loaded and parsed AAP (" << uri << ")" << CategoryStream::ENDLINE;
+
+               DOMElement* e = doc->getDocumentElement();
+        if (XMLString::compareString(XML::EDUPERSON_NS,e->getNamespaceURI()) ||
+            XMLString::compareString(XML::Literals::AttributeAcceptancePolicy,e->getLocalName()))
+        {
+                       log.error("Construction requires a valid AAP file: (edu:AttributeAcceptancePolicy as root element)");
+                       throw MalformedException("Construction requires a valid site file: (edu:AttributeAcceptancePolicy as root element)");
+               }
+
+               // Loop over the AttributeRule elements.
+        DOMNodeList* nlist = e->getElementsByTagNameNS(XML::EDUPERSON_NS,XML::Literals::AttributeRule);
+               for (int i=0; nlist && i<nlist->getLength(); i++)
+        {
+            // Insert an empty rule, then get a reference to it.
+            m_attrMap[static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,XML::Literals::Name)]=AttributeRule();
+            AttributeRule& arule=m_attrMap[static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,XML::Literals::Name)];
+
+            // Check for an AnySite rule.
+                       DOMNode* anysite = nlist->item(i)->getFirstChild();
+                       while (anysite && anysite->getNodeType()!=DOMNode::ELEMENT_NODE)
+            {
+                               anysite = anysite->getNextSibling();
+                               continue;
+                       }
+
+            if (anysite && !XMLString::compareString(XML::EDUPERSON_NS,static_cast<DOMElement*>(anysite)->getNamespaceURI()) &&
+                !XMLString::compareString(XML::Literals::AnySite,static_cast<DOMElement*>(anysite)->getLocalName()))
+            {
+                // Process each Value element.
+                DOMNodeList* vlist = static_cast<DOMElement*>(anysite)->getElementsByTagNameNS(XML::EDUPERSON_NS,XML::Literals::Value);
+                for (int j=0; vlist && j<vlist->getLength(); j++)
+                {
+                    DOMElement* ve=static_cast<DOMElement*>(vlist->item(j));
+                    DOMNode* valnode=ve->getFirstChild();
+                    if (valnode && valnode->getNodeType()==DOMNode::TEXT_NODE)
+                    {
+                        if (!XMLString::compareString(XML::Literals::literal,ve->getAttributeNS(NULL,XML::Literals::Type)))
+                            arule.m_anySiteRule.push_back(
+                                pair<AttributeRule::value_type,xstring>(AttributeRule::literal,valnode->getNodeValue())
+                                );
+                        else if (!XMLString::compareString(XML::Literals::regexp,ve->getAttributeNS(NULL,XML::Literals::Type)))
+                            arule.m_anySiteRule.push_back(
+                                pair<AttributeRule::value_type,xstring>(AttributeRule::regexp,valnode->getNodeValue())
+                                );
+                        else if (!XMLString::compareString(XML::Literals::xpath,ve->getAttributeNS(NULL,XML::Literals::Type)))
+                            arule.m_anySiteRule.push_back(
+                                pair<AttributeRule::value_type,xstring>(AttributeRule::xpath,valnode->getNodeValue())
+                                );
+                    }
+                }
+            }
+
+            // Loop over the SiteRule elements.
+            DOMNodeList* slist = e->getElementsByTagNameNS(XML::EDUPERSON_NS,XML::Literals::SiteRule);
+                   for (int k=0; slist && k<slist->getLength(); k++)
+            {
+                arule.m_siteMap[static_cast<DOMElement*>(slist->item(k))->getAttributeNS(NULL,XML::Literals::Name)]=AttributeRule::SiteRule();
+                AttributeRule::SiteRule& srule=arule.m_siteMap[static_cast<DOMElement*>(slist->item(k))->getAttributeNS(NULL,XML::Literals::Name)];
+
+                // Process each Value element.
+                DOMNodeList* vlist = static_cast<DOMElement*>(anysite)->getElementsByTagNameNS(XML::EDUPERSON_NS,XML::Literals::Value);
+                for (int j=0; vlist && j<vlist->getLength(); j++)
+                {
+                    DOMElement* ve=static_cast<DOMElement*>(vlist->item(j));
+                    DOMNode* valnode=ve->getFirstChild();
+                    if (valnode && valnode->getNodeType()==DOMNode::TEXT_NODE)
+                    {
+                        if (!XMLString::compareString(XML::Literals::literal,ve->getAttributeNS(NULL,XML::Literals::Type)))
+                            srule.push_back(
+                                pair<AttributeRule::value_type,xstring>(AttributeRule::literal,valnode->getNodeValue())
+                                );
+                        else if (!XMLString::compareString(XML::Literals::regexp,ve->getAttributeNS(NULL,XML::Literals::Type)))
+                            srule.push_back(
+                                pair<AttributeRule::value_type,xstring>(AttributeRule::regexp,valnode->getNodeValue())
+                                );
+                        else if (!XMLString::compareString(XML::Literals::xpath,ve->getAttributeNS(NULL,XML::Literals::Type)))
+                            srule.push_back(
+                                pair<AttributeRule::value_type,xstring>(AttributeRule::xpath,valnode->getNodeValue())
+                                );
+                    }
+                }
+            }
+               }
+    }
+    catch (SAMLException& e)
+    {
+        log.errorStream() << "XML error while parsing AAP: " << e.what() << CategoryStream::ENDLINE;
+        if (doc)
+            doc->release();
+               throw;
+       }
+    catch (...)
+    {
+               log.error("Unexpected error while parsing AAP");
+        if (doc)
+            doc->release();
+               throw;
+    }
+
+}
+
+bool AAP::accept(const XMLCh* name, const XMLCh* originSite, DOMElement* e)
+{
+    NDC ndc("accept");
+    log4cpp::Category& log=log4cpp::Category::getInstance("eduPerson.AAP");
+
+    map<xstring,AttributeRule>::const_iterator arule=m_attrMap.find(name);
+    if (arule==m_attrMap.end())
+    {
+        log.warn("attribute not found in AAP, any value is rejected");
+        return false;
+    }
+
+    // Don't currently support non-simple content models...
+    DOMNode* n=e->getFirstChild();
+    if (!n || n->getNodeType()!=DOMNode::TEXT_NODE)
+    {
+        log.warn("implementation does not support complex attribute values");
+        return false;
+    }
+
+    for (AttributeRule::SiteRule::const_iterator i=arule->second.m_anySiteRule.begin(); i!=arule->second.m_anySiteRule.end(); i++)
+    {
+        if (i->first==AttributeRule::literal && i->second==n->getNodeValue())
+            return true;
+        else if (i->first==AttributeRule::regexp)
+        {
+            try
+            {
+                RegularExpression re(i->second.c_str());
+                if (re.matches(n->getNodeValue()))
+                    return true;
+            }
+            catch (XMLException& ex)
+            {
+                auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
+                log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
+                    << log4cpp::CategoryStream::ENDLINE;
+            }
+        }
+        else
+            log.warn("implementation does not support XPath value rules");
+    }
+
+    map<xstring,AttributeRule::SiteRule>::const_iterator srule=arule->second.m_siteMap.find(originSite);
+    if (srule==arule->second.m_siteMap.end())
+    {
+        log.warn("site not found in attribute ruleset, any value is rejected");
+        return false;
+    }
+
+    for (AttributeRule::SiteRule::const_iterator j=srule->second.begin(); j!=srule->second.end(); j++)
+    {
+        if (j->first==AttributeRule::literal && j->second==n->getNodeValue())
+            return true;
+        else if (j->first==AttributeRule::regexp)
+        {
+            try
+            {
+                RegularExpression re(j->second.c_str());
+                if (re.matches(n->getNodeValue()))
+                    return true;
+            }
+            catch (XMLException& ex)
+            {
+                auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
+                log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
+                    << log4cpp::CategoryStream::ENDLINE;
+            }
+        }
+        else
+            log.warn("implementation does not support XPath value rules");
+    }
+
+    log.warn("attribute value could not be validated by AAP, rejecting it");
+    return false;
+}
index 66934a0..f3419b4 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define EDUPERSON_EXPORTS __declspec(dllexport)
-#endif
-
-#include <log4cpp/Category.hh>
-
-#include "../shib/shib.h"
-#include "eduPerson.h"
-using namespace saml;
-using namespace shibboleth;
-using namespace eduPerson;
-using namespace std;
-
-#define SAML_log (*reinterpret_cast<log4cpp::Category*>(m_log))
+#include "internal.h"
 
 AffiliationAttribute::AffiliationAttribute(const XMLCh* defaultScope, long lifetime,
                                            const Iterator<const XMLCh*>& scopes,
index 44ab07d..70cd7ef 100644 (file)
@@ -76,6 +76,41 @@ const XMLCh eduPerson::XML::EDUPERSON_SCHEMA_ID[] = // eduPerson.xsd
 const XMLCh eduPerson::XML::Literals::anyURI[]=
 { chLatin_a, chLatin_n, chLatin_y, chLatin_U, chLatin_R, chLatin_I, chNull };
 
+const XMLCh eduPerson::XML::Literals::AnySite[]=
+{ chLatin_A, chLatin_n, chLatin_y, chLatin_S, chLatin_i, chLatin_t, chLatin_e, chNull };
+
+const XMLCh eduPerson::XML::Literals::AttributeAcceptancePolicy[] =
+{ chLatin_A, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e,
+  chLatin_A, chLatin_c, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chLatin_a, chLatin_n, chLatin_c, chLatin_e,
+  chLatin_P, chLatin_o, chLatin_l, chLatin_i, chLatin_c, chLatin_y, chNull
+};
+
+const XMLCh eduPerson::XML::Literals::AttributeRule[] =
+{ chLatin_A, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e,
+  chLatin_R, chLatin_u, chLatin_l, chLatin_e, chNull
+};
+
+const XMLCh eduPerson::XML::Literals::Name[]=
+{ chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull };
+
+const XMLCh eduPerson::XML::Literals::SiteRule[] =
+{ chLatin_S, chLatin_i, chLatin_t, chLatin_e, chLatin_R, chLatin_u, chLatin_l, chLatin_e, chNull };
+
+const XMLCh eduPerson::XML::Literals::Type[]=
+{ chLatin_T, chLatin_y, chLatin_p, chLatin_e, chNull };
+
+const XMLCh eduPerson::XML::Literals::Value[] =
+{ chLatin_V, chLatin_a, chLatin_l, chLatin_u, chLatin_e, chNull };
+
+const XMLCh eduPerson::XML::Literals::literal[] =
+{ chLatin_l, chLatin_i, chLatin_t, chLatin_e, chLatin_r, chLatin_a, chLatin_l, chNull };
+
+const XMLCh eduPerson::XML::Literals::regexp[] =
+{ chLatin_r, chLatin_e, chLatin_g, chLatin_e, chLatin_x, chLatin_p, chNull };
+
+const XMLCh eduPerson::XML::Literals::xpath[] =
+{ chLatin_x, chLatin_p, chLatin_a, chLatin_t, chLatin_h, chNull };
+
 const XMLCh eduPerson::XML::Literals::faculty[] =
 { chLatin_f, chLatin_a, chLatin_c, chLatin_u, chLatin_l, chLatin_t, chLatin_y, chNull };
 
index 0918879..743f258 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define EDUPERSON_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
 
-#include <log4cpp/Category.hh>
-
-#include "../shib/shib.h"
-#include "eduPerson.h"
-using namespace saml;
-using namespace shibboleth;
-using namespace eduPerson;
-using namespace std;
-
-#define SAML_log (*reinterpret_cast<log4cpp::Category*>(m_log))
 
 EPPNAttribute::EPPNAttribute(const XMLCh* defaultScope, long lifetime, const XMLCh* scope, const XMLCh* value)
     : ScopedAttribute(eduPerson::Constants::EDUPERSON_PRINCIPAL_NAME,
index 46fa4ec..45e45cf 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define EDUPERSON_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
 
-#include <log4cpp/Category.hh>
 #include <xercesc/util/XMLUri.hpp>
 
-#include "../shib/shib.h"
-#include "eduPerson.h"
-using namespace saml;
-using namespace shibboleth;
-using namespace eduPerson;
-using namespace std;
-
-#define SAML_log (*reinterpret_cast<log4cpp::Category*>(m_log))
 
 EntitlementAttribute::EntitlementAttribute(long lifetime, const Iterator<const XMLCh*>& values)
-    : SAMLAttribute(eduPerson::Constants::EDUPERSON_ENTITLEMENT,
-                    shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,NULL,lifetime,values)
+    : SimpleAttribute(eduPerson::Constants::EDUPERSON_ENTITLEMENT,
+                      shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,NULL,lifetime,values)
 {
     m_type=new saml::QName(saml::XML::XSD_NS,eduPerson::XML::Literals::anyURI);
 }
 
-EntitlementAttribute::EntitlementAttribute(DOMElement* e) : SAMLAttribute(e) {}
+EntitlementAttribute::EntitlementAttribute(DOMElement* e) : SimpleAttribute(e) {}
 
 EntitlementAttribute::~EntitlementAttribute() {}
 
index 341dce0..cf0f724 100644 (file)
@@ -6,17 +6,20 @@ lib_LTLIBRARIES = libeduPerson.la
 
 libeduPersondir = $(includedir)/eduPerson
 libeduPerson_HEADERS = eduPerson.h
+noinst_HEADERS = internal.h
 
 libeduPerson_la_LIBADD = $(top_builddir)/shib/libshib.la $(top_builddir)/shib-target/libshib-target.la
 
 libeduPerson_la_SOURCES = \
                     eduPerson.cpp \
                     Constants.cpp \
+                    AAP.cpp \
                     AffiliationAttribute.cpp \
                     EPPNAttribute.cpp \
                     EntitlementAttribute.cpp \
                     PrimaryAffiliationAttribute.cpp \
-                    ScopedAttribute.cpp
+                    ScopedAttribute.cpp \
+                    SimpleAttribute.cpp
 
 # this is different from the project version
 # http://sources.redhat.com/autobook/autobook/autobook_91.html
index 259898b..3d7a8a8 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define EDUPERSON_EXPORTS __declspec(dllexport)
-#endif
-
-#include <log4cpp/Category.hh>
-
-#include "../shib/shib.h"
-#include "eduPerson.h"
-using namespace saml;
-using namespace shibboleth;
-using namespace eduPerson;
-using namespace std;
-
-#define SAML_log (*reinterpret_cast<log4cpp::Category*>(m_log))
+#include "internal.h"
 
 PrimaryAffiliationAttribute::PrimaryAffiliationAttribute(const XMLCh* defaultScope, long lifetime, const XMLCh* scope, const XMLCh* value)
     : ScopedAttribute(eduPerson::Constants::EDUPERSON_PRIMARY_AFFILIATION,
index 9fb8145..ad88e2e 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define EDUPERSON_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
 
-#include "../shib/shib.h"
-#include "eduPerson.h"
-
-#include <log4cpp/Category.hh>
 #include <xercesc/util/regx/RegularExpression.hpp>
 
-using namespace saml;
-using namespace shibboleth;
-using namespace eduPerson;
-using namespace std;
-
 ScopedAttribute::ScopedAttribute(const XMLCh* name, const XMLCh* ns, const XMLCh* defaultScope,
                                  const saml::QName* type, long lifetime,
                                  const saml::Iterator<const XMLCh*>& scopes,
@@ -137,8 +126,7 @@ bool ScopedAttribute::accept(DOMElement* e) const
             {
                 auto_ptr<char> tmp(XMLString::transcode(ex.getMessage()));
                 NDC ndc("accept");
-                log4cpp::Category& log=log4cpp::Category::getInstance("eduPerson.ScopedAttribute");
-                log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
+                SAML_log.errorStream() << "caught exception while parsing regular expression: " << tmp.get()
                     << log4cpp::CategoryStream::ENDLINE;
                 return false;
             }
@@ -148,11 +136,10 @@ bool ScopedAttribute::accept(DOMElement* e) const
     }
 
     NDC ndc("accept");
-    log4cpp::Category& log=log4cpp::Category::getInstance("eduPerson.ScopedAttribute");
-    if (log.isWarnEnabled())
+    if (SAML_log.isWarnEnabled())
     {
         auto_ptr<char> tmp(XMLString::transcode(this_scope));
-        log.warn("rejecting value with scope of %s",tmp.get());
+        SAML_log.warn("rejecting value with scope of %s",tmp.get());
     }
     return false;
 }
diff --git a/eduPerson/SimpleAttribute.cpp b/eduPerson/SimpleAttribute.cpp
new file mode 100644 (file)
index 0000000..37b9b5c
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* SimpleAttribute.cpp - simple attribute implementation with AAP-support
+
+   Scott Cantor
+   12/19/02
+
+   $History:$
+*/
+
+#include "internal.h"
+
+SimpleAttribute::SimpleAttribute(const XMLCh* name, const XMLCh* ns, const saml::QName* type, long lifetime,
+                                 const Iterator<const XMLCh*>& values)
+    : SAMLAttribute(name,ns,type,lifetime,values) {}
+
+SimpleAttribute::SimpleAttribute(DOMElement* e) : SAMLAttribute(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,"SimpleAttribute() can't find saml:NameIdentifier in enclosing statement");
+    m_originSite=static_cast<DOMElement*>(nlist->item(0))->getAttributeNS(NULL,L(NameQualifier));
+}
+
+SimpleAttribute::~SimpleAttribute() {}
+
+SAMLObject* SimpleAttribute::clone() const
+{
+    SimpleAttribute* dest=new SimpleAttribute(m_name,m_namespace,m_type,m_lifetime);
+    dest->m_values.assign(m_values.begin(),m_values.end());
+    return dest;
+}
+
+bool SimpleAttribute::accept(DOMElement* e) const
+{
+    if (g_AAP)
+        return g_AAP->accept(m_name,m_originSite.c_str(),e);
+    return true;
+}
index c0a187b..87a6a22 100644 (file)
    9/1/02
 */
 
-#ifdef WIN32
-# define EDUPERSON_EXPORTS __declspec(dllexport)
-#endif
-
 #define EDUPERSON_INSTANTIATE
 
-#include "../shib/shib.h"
-#include "../shib-target/shib-target.h"
-#include "eduPerson.h"
-
-using namespace std;
-using namespace saml;
-using namespace shibboleth;
-using namespace shibtarget;
-using namespace eduPerson;
+#include "internal.h"
 
 #ifdef WIN32
 
@@ -109,18 +97,38 @@ extern "C" SAMLAttribute* SimpleFactory(DOMElement* e)
 }
 
 namespace {
-    ShibINI* ini=NULL;
+    ShibINI* g_ShibINI=NULL;
 }
 
+EDUPERSON_EXPORTS AAP* eduPerson::g_AAP=NULL;
+
 extern "C" EDUPERSON_EXPORTS int saml_extension_init(void* context)
 {
-    ini=reinterpret_cast<shibtarget::ShibINI*>(context);
-    if (ini)
+    // Register extension schema and attribute factories.
+    saml::XML::registerSchema(eduPerson::XML::EDUPERSON_NS,eduPerson::XML::EDUPERSON_SCHEMA_ID);
+
+    SAMLAttribute::regFactory(eduPerson::Constants::EDUPERSON_PRINCIPAL_NAME,
+                              shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,
+                              &EPPNFactory);
+    SAMLAttribute::regFactory(eduPerson::Constants::EDUPERSON_AFFILIATION,
+                              shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,
+                              &AffiliationFactory);
+    SAMLAttribute::regFactory(eduPerson::Constants::EDUPERSON_PRIMARY_AFFILIATION,
+                              shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,
+                              &PrimaryAffiliationFactory);
+    SAMLAttribute::regFactory(eduPerson::Constants::EDUPERSON_ENTITLEMENT,
+                              shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,
+                              &EntitlementFactory);
+
+    g_ShibINI=reinterpret_cast<shibtarget::ShibINI*>(context);
+
+    // Register additional attributes and create AAP object.
+    if (g_ShibINI)
     {
-        ShibINI::Iterator* i=ini->tag_iterator("attributes");
+        ShibINI::Iterator* i=g_ShibINI->tag_iterator("attributes");
         for (const string* attrname=i->begin(); attrname; attrname=i->next())
         {
-            const string& factory=ini->get("attributes",*attrname);
+            const string& factory=g_ShibINI->get("attributes",*attrname);
             if (factory=="scoped")
             {
                 auto_ptr<XMLCh> temp(XMLString::transcode(attrname->c_str()));
@@ -136,23 +144,21 @@ extern "C" EDUPERSON_EXPORTS int saml_extension_init(void* context)
                     &SimpleFactory);
             }
         }
-    }
 
-    // Register extension schema and attribute factories.
-    saml::XML::registerSchema(eduPerson::XML::EDUPERSON_NS,eduPerson::XML::EDUPERSON_SCHEMA_ID);
+        if (g_ShibINI->exists(SHIBTARGET_GENERAL,"aap-uri"))
+        {
+            const string& uri=g_ShibINI->get(SHIBTARGET_GENERAL,"aap-uri");
+            try
+            {
+                g_AAP=new AAP(uri.c_str());
+            }
+            catch(...)
+            {
+                return -1;
+            }
+        }
+    }
 
-    SAMLAttribute::regFactory(eduPerson::Constants::EDUPERSON_PRINCIPAL_NAME,
-                              shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,
-                              &EPPNFactory);
-    SAMLAttribute::regFactory(eduPerson::Constants::EDUPERSON_AFFILIATION,
-                              shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,
-                              &AffiliationFactory);
-    SAMLAttribute::regFactory(eduPerson::Constants::EDUPERSON_PRIMARY_AFFILIATION,
-                              shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,
-                              &PrimaryAffiliationFactory);
-    SAMLAttribute::regFactory(eduPerson::Constants::EDUPERSON_ENTITLEMENT,
-                              shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,
-                              &EntitlementFactory);
     return 0;
 }
 
@@ -167,12 +173,14 @@ extern "C" EDUPERSON_EXPORTS void saml_extension_term()
     SAMLAttribute::unregFactory(eduPerson::Constants::EDUPERSON_ENTITLEMENT,
                                 shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI);
 
-    if (ini)
+    if (g_ShibINI)
     {
-        ShibINI::Iterator* i=ini->tag_iterator("attributes");
+        delete g_AAP;
+
+        ShibINI::Iterator* i=g_ShibINI->tag_iterator("attributes");
         for (const string* attrname=i->begin(); attrname; attrname=i->next())
         {
-            const string& factory=ini->get("attributes",*attrname);
+            const string& factory=g_ShibINI->get("attributes",*attrname);
             if (factory=="scoped")
             {
                 auto_ptr<XMLCh> temp(XMLString::transcode(attrname->c_str()));
index 3f7d8c7..9a0f009 100644 (file)
@@ -43,7 +43,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EDUPERSON_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "." /I ".." /I "C:\curl\include" /I "C:\xerces-c\include" /I "..\..\..\opensaml\c" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "." /I ".." /I "..\oncrpc" /I "C:\boost" /I "C:\curl\include" /I "C:\xerces-c\include" /I "..\..\..\opensaml\c" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -69,7 +69,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EDUPERSON_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "." /I ".." /I "C:\curl\include" /I "C:\xerces-c\include" /I "C:\log4cpp\include" /I "..\..\..\opensaml\c" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "C:\log4cpp\include" /I "." /I ".." /I "..\oncrpc" /I "C:\boost" /I "C:\curl\include" /I "C:\xerces-c\include" /I "..\..\..\opensaml\c" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -119,5 +119,9 @@ SOURCE=.\PrimaryAffiliationAttribute.cpp
 
 SOURCE=.\ScopedAttribute.cpp
 # End Source File
+# Begin Source File
+
+SOURCE=.\SimpleAttribute.cpp
+# End Source File
 # End Target
 # End Project
index 96d33b4..f668db4 100644 (file)
 
 namespace eduPerson
 {
+    class EDUPERSON_EXPORTS SimpleAttribute : public saml::SAMLAttribute
+    {
+    public:
+        SimpleAttribute(const XMLCh* name, const XMLCh* ns, const saml::QName* type=NULL, long lifetime=0,
+                        const saml::Iterator<const XMLCh*>& values=saml::Iterator<const XMLCh*>());
+        SimpleAttribute(DOMElement* e);
+        virtual saml::SAMLObject* clone() const;
+        virtual ~SimpleAttribute();
+
+    protected:
+        virtual bool accept(DOMElement* e) const;
+
+    private:
+        saml::xstring m_originSite;
+    };
+
     class EDUPERSON_EXPORTS ScopedAttribute : public saml::SAMLAttribute
     {
     public:
@@ -135,7 +151,7 @@ namespace eduPerson
         virtual bool addValue(DOMElement* e);
     };
 
-    class EDUPERSON_EXPORTS EntitlementAttribute : public saml::SAMLAttribute
+    class EDUPERSON_EXPORTS EntitlementAttribute : public SimpleAttribute
     {
     public:
         EntitlementAttribute(long lifetime=0, const saml::Iterator<const XMLCh*>& values=saml::Iterator<const XMLCh*>());
@@ -147,6 +163,26 @@ namespace eduPerson
         virtual bool addValue(DOMElement* e);
     };
 
+    class EDUPERSON_EXPORTS AAP
+    {
+    public:
+        AAP(const char* uri);
+        bool accept(const XMLCh* name, const XMLCh* originSite, DOMElement* e);
+
+    private:
+        struct AttributeRule
+        {
+            enum value_type { literal, regexp, xpath };
+            typedef std::vector<std::pair<value_type,saml::xstring> > SiteRule;
+            SiteRule m_anySiteRule;
+            std::map<saml::xstring,SiteRule> m_siteMap;
+        };
+
+        std::map<saml::xstring,AttributeRule> m_attrMap;
+    };
+
+    extern EDUPERSON_EXPORTS AAP* g_AAP;
+
     struct EDUPERSON_EXPORTS XML
     {
         static const XMLCh EDUPERSON_NS[];
@@ -155,6 +191,19 @@ namespace eduPerson
         struct EDUPERSON_EXPORTS Literals
         {
             static const XMLCh anyURI[];
+            
+            static const XMLCh AnySite[];
+            static const XMLCh AttributeAcceptancePolicy[];
+            static const XMLCh AttributeRule[];
+            static const XMLCh Name[];
+            static const XMLCh SiteRule[];
+            static const XMLCh Type[];
+            static const XMLCh Value[];
+
+            static const XMLCh literal[];
+            static const XMLCh regexp[];
+            static const XMLCh xpath[];
+
             static const XMLCh faculty[];
             static const XMLCh student[];
             static const XMLCh staff[];
diff --git a/eduPerson/internal.h b/eduPerson/internal.h
new file mode 100644 (file)
index 0000000..dd7f170
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * The OpenSAML License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of OpenSAML nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact opensaml@opensaml.org
+ *
+ * Products derived from this software may not be called OpenSAML, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may OpenSAML appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* internal.h - internally visible classes
+
+   Scott Cantor
+   9/6/02
+
+   $History:$
+*/
+
+#ifndef __eduPerson_internal_h__
+#define __eduPerson_internal_h__
+
+#ifdef WIN32
+# define EDUPERSON_EXPORTS __declspec(dllexport)
+#endif
+
+// eventually we might be able to support autoconf via cygwin...
+#if defined (_MSC_VER) || defined(__BORLANDC__)
+# include "config_win32.h"
+#else
+# include "config.h"
+#endif
+
+#include "../shib/shib.h"
+#include "../shib-target/shib-target.h"
+#include "eduPerson.h"
+
+#include <log4cpp/Category.hh>
+
+using namespace std;
+using namespace saml;
+using namespace shibboleth;
+using namespace shibtarget;
+using namespace eduPerson;
+using namespace log4cpp;
+
+#define SAML_log (*reinterpret_cast<log4cpp::Category*>(m_log))
+
+#endif