Renamed 2.0 source files to fix automake collision.
[shibboleth/cpp-opensaml.git] / saml / saml2 / core / impl / Assertions20SchemaValidators.cpp
diff --git a/saml/saml2/core/impl/Assertions20SchemaValidators.cpp b/saml/saml2/core/impl/Assertions20SchemaValidators.cpp
new file mode 100644 (file)
index 0000000..e839e69
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+*  Copyright 2001-2006 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.
+ */
+
+/**
+ * AssertionsSchemaValidators.cpp
+ * 
+ * Schema-based validators for SAML 2.0 Assertions classes
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "saml2/core/Assertions.h"
+
+using namespace opensaml::saml2;
+using namespace opensaml;
+using namespace xmltooling;
+using namespace std;
+
+namespace opensaml {
+    namespace saml2 {
+        
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,Action);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,AssertionIDRef);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,AssertionURIRef);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,Audience);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,AuthnContextClassRef);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,AuthnContextDeclRef);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,AuthenticatingAuthority);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,NameIDType);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,NameID);
+        XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,Issuer);
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AudienceRestriction);
+            XMLOBJECTVALIDATOR_NONEMPTY(AudienceRestriction,Audience);
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,ProxyRestriction);
+            if (ptr->getAudiences().empty()) {
+                XMLOBJECTVALIDATOR_REQUIRE(ProxyRestriction,Count);
+            }
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Conditions);
+            if (!ptr->hasChildren()) {
+                XMLOBJECTVALIDATOR_ONEOF(Conditions,NotBefore,NotOnOrAfter);
+            }
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,KeyInfoConfirmationDataType);
+            XMLOBJECTVALIDATOR_NONEMPTY(KeyInfoConfirmationDataType,KeyInfo);
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,SubjectConfirmation);
+            XMLOBJECTVALIDATOR_REQUIRE(SubjectConfirmation,Method);
+            int count=0;
+            if (ptr->getBaseID())
+                count++;
+            if (ptr->getNameID())
+                count++;
+            //if (ptr->getEncryptedID())
+                //count++;
+            if (count > 1)
+                throw ValidationException("SubjectConfirmation cannot contain multiple identifier elements.");
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Subject);
+            int count=0;
+            if (ptr->getBaseID())
+                count++;
+            if (ptr->getNameID())
+                count++;
+            //if (ptr->getEncryptedID())
+                //count++;
+            if (count > 1)
+                throw ValidationException("Subject cannot contain multiple identifier elements.");
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,SubjectLocality);
+            XMLOBJECTVALIDATOR_ONEOF(SubjectLocality,Address,DNSName);
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AuthnContext);
+            if (!ptr->getAuthnContextClassRef()) {
+                XMLOBJECTVALIDATOR_ONLYONEOF(AuthnContext,AuthnContextDeclRef,AuthnContextDecl);
+            }
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AuthnStatement);
+            XMLOBJECTVALIDATOR_REQUIRE(AuthnStatement,AuthnInstant);
+            XMLOBJECTVALIDATOR_REQUIRE(AuthnStatement,AuthnContext);
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Evidence);
+            if (!ptr->hasChildren())
+                throw ValidationException("Evidence must have at least one child element.");
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AuthzDecisionStatement);
+            XMLOBJECTVALIDATOR_REQUIRE(AuthzDecisionStatement,Resource);
+            XMLOBJECTVALIDATOR_REQUIRE(AuthzDecisionStatement,Decision);
+            if (!XMLString::equals(ptr->getDecision(),AuthzDecisionStatement::DECISION_PERMIT) &&
+                !XMLString::equals(ptr->getDecision(),AuthzDecisionStatement::DECISION_DENY) &&
+                !XMLString::equals(ptr->getDecision(),AuthzDecisionStatement::DECISION_INDETERMINATE))
+                throw ValidationException("Decision must be one of Deny, Permit, or Indeterminate.");
+            XMLOBJECTVALIDATOR_NONEMPTY(AuthzDecisionStatement,Action);
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Attribute);
+            XMLOBJECTVALIDATOR_REQUIRE(Attribute,Name);
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AttributeStatement);
+            XMLOBJECTVALIDATOR_NONEMPTY(AttributeStatement,Attribute);
+        END_XMLOBJECTVALIDATOR;
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Assertion);
+            XMLOBJECTVALIDATOR_REQUIRE(Assertion,Version);
+            XMLOBJECTVALIDATOR_REQUIRE(Assertion,ID);
+            XMLOBJECTVALIDATOR_REQUIRE(Assertion,IssueInstant);
+            XMLOBJECTVALIDATOR_REQUIRE(Assertion,Issuer);
+            if ((!ptr->getAuthnStatements().empty() ||
+                !ptr->getAttributeStatements().empty() ||
+                !ptr->getAuthzDecisionStatements().empty()) && !ptr->getSubject())
+                throw ValidationException("Assertion with standard statements must have a Subject.");
+        END_XMLOBJECTVALIDATOR;
+
+        class SAML_DLLLOCAL checkWildcardNS {
+        public:
+            void operator()(const XMLObject* xmlObject) const {
+                const XMLCh* ns=xmlObject->getElementQName().getNamespaceURI();
+                if (XMLString::equals(ns,SAMLConstants::SAML20_NS) || !ns || !*ns) {
+                    throw ValidationException(
+                        "Object contains an illegal extension child element ($1).",
+                        params(1,xmlObject->getElementQName().toString().c_str())
+                        );
+                }
+            }
+        };
+
+        BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Advice);
+            const vector<XMLObject*>& anys=ptr->getOthers();
+            for_each(anys.begin(),anys.end(),checkWildcardNS());
+        END_XMLOBJECTVALIDATOR;
+
+    };
+};
+
+#define REGISTER_ELEMENT(cname) \
+    q=QName(SAMLConstants::SAML20_NS,cname::LOCAL_NAME); \
+    XMLObjectBuilder::registerBuilder(q,new cname##Builder()); \
+    Validator::registerValidator(q,new cname##SchemaValidator())
+    
+#define REGISTER_TYPE(cname) \
+    q=QName(SAMLConstants::SAML20_NS,cname::TYPE_NAME); \
+    XMLObjectBuilder::registerBuilder(q,new cname##Builder()); \
+    Validator::registerValidator(q,new cname##SchemaValidator())
+
+#define REGISTER_ELEMENT_NOVAL(cname) \
+    q=QName(SAMLConstants::SAML20_NS,cname::LOCAL_NAME); \
+    XMLObjectBuilder::registerBuilder(q,new cname##Builder());
+    
+#define REGISTER_TYPE_NOVAL(cname) \
+    q=QName(SAMLConstants::SAML20_NS,cname::TYPE_NAME); \
+    XMLObjectBuilder::registerBuilder(q,new cname##Builder());
+
+void opensaml::saml2::registerAssertionClasses() {
+    QName q;
+    REGISTER_ELEMENT(Action);
+    REGISTER_ELEMENT(Advice);
+    REGISTER_ELEMENT(Assertion);
+    REGISTER_ELEMENT(AssertionIDRef);
+    REGISTER_ELEMENT(AssertionURIRef);
+    REGISTER_ELEMENT(Attribute);
+    REGISTER_ELEMENT(AttributeStatement);
+    REGISTER_ELEMENT_NOVAL(AttributeValue);
+    REGISTER_ELEMENT(Audience);
+    REGISTER_ELEMENT(AudienceRestriction);
+    REGISTER_ELEMENT(AuthenticatingAuthority);
+    REGISTER_ELEMENT(AuthnContext);
+    REGISTER_ELEMENT(AuthnContextClassRef);
+    REGISTER_ELEMENT_NOVAL(AuthnContextDecl);
+    REGISTER_ELEMENT(AuthnContextDeclRef);
+    REGISTER_ELEMENT(AuthnStatement);
+    REGISTER_ELEMENT(AuthzDecisionStatement);
+    REGISTER_ELEMENT(Conditions);
+    REGISTER_ELEMENT(Evidence);
+    REGISTER_ELEMENT(Issuer);
+    REGISTER_ELEMENT(NameID);
+    REGISTER_ELEMENT_NOVAL(OneTimeUse);
+    REGISTER_ELEMENT(ProxyRestriction);
+    REGISTER_ELEMENT(Subject);
+    REGISTER_ELEMENT(SubjectConfirmation);
+    REGISTER_ELEMENT_NOVAL(SubjectConfirmationData);
+    REGISTER_ELEMENT(SubjectLocality);
+    REGISTER_TYPE(Action);
+    REGISTER_TYPE(Advice);
+    REGISTER_TYPE(Assertion);
+    REGISTER_TYPE(Attribute);
+    REGISTER_TYPE(AttributeStatement);
+    REGISTER_TYPE(AudienceRestriction);
+    REGISTER_TYPE(AuthnContext);
+    REGISTER_TYPE(AuthnStatement);
+    REGISTER_TYPE(AuthzDecisionStatement);
+    REGISTER_TYPE(Conditions);
+    REGISTER_TYPE(Evidence);
+    REGISTER_TYPE(KeyInfoConfirmationDataType);
+    REGISTER_TYPE(NameIDType);
+    REGISTER_TYPE_NOVAL(OneTimeUse);
+    REGISTER_TYPE(ProxyRestriction);
+    REGISTER_TYPE(Subject);
+    REGISTER_TYPE(SubjectConfirmation);
+    REGISTER_TYPE(SubjectLocality);
+}