Reducing header overuse, non-inlining selected methods (CPPOST-35).
[shibboleth/cpp-opensaml.git] / saml / saml1 / core / impl / ProtocolsSchemaValidators.cpp
1 /*
2 *  Copyright 2001-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  * ProtocolsSchemaValidators.cpp
19  *
20  * Schema-based validators for SAML 1.x Protocols classes
21  */
22
23 #include "internal.h"
24 #include "exceptions.h"
25 #include "saml1/core/Protocols.h"
26
27 #include <xmltooling/validation/Validator.h>
28 #include <xmltooling/validation/ValidatorSuite.h>
29
30 using namespace opensaml::saml1p;
31 using namespace opensaml::saml1;
32 using namespace opensaml;
33 using namespace xmltooling;
34 using namespace std;
35 using samlconstants::SAML1P_NS;
36
37 namespace opensaml {
38     namespace saml1p {
39
40         XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,AssertionArtifact);
41         XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,StatusMessage);
42
43         BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,RespondWith);
44             XMLOBJECTVALIDATOR_REQUIRE(RespondWith,QName);
45         END_XMLOBJECTVALIDATOR;
46
47         BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AuthenticationQuery);
48             XMLOBJECTVALIDATOR_REQUIRE(AuthenticationQuery,AuthenticationMethod);
49             XMLOBJECTVALIDATOR_REQUIRE(AuthenticationQuery,Subject);
50         END_XMLOBJECTVALIDATOR;
51
52         BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AttributeQuery);
53             XMLOBJECTVALIDATOR_REQUIRE(AttributeQuery,Subject);
54         END_XMLOBJECTVALIDATOR;
55
56         BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AuthorizationDecisionQuery);
57             XMLOBJECTVALIDATOR_REQUIRE(AuthorizationDecisionQuery,Subject);
58             XMLOBJECTVALIDATOR_REQUIRE(AuthorizationDecisionQuery,Resource);
59             XMLOBJECTVALIDATOR_NONEMPTY(AuthorizationDecisionQuery,Action);
60         END_XMLOBJECTVALIDATOR;
61
62         BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Request);
63             XMLOBJECTVALIDATOR_REQUIRE(Request,RequestID);
64             XMLOBJECTVALIDATOR_REQUIRE(Request,IssueInstant);
65             pair<bool,int> minor=ptr->getMinorVersion();
66             if (!minor.first)
67                 throw ValidationException("Request must have MinorVersion");
68             int count=0;
69             if (ptr->getQuery()!=NULL)
70                 count++;
71             if (!ptr->getAssertionIDReferences().empty())
72                 count++;
73             if (!ptr->getAssertionArtifacts().empty())
74                 count++;
75             if (count != 1)
76                 throw ValidationException("Request must have either a query, >0 assertion references, or >0 artifacts.");
77         END_XMLOBJECTVALIDATOR;
78
79         BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,StatusCode);
80             XMLOBJECTVALIDATOR_REQUIRE(StatusCode,Value);
81         END_XMLOBJECTVALIDATOR;
82
83         BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Status);
84             XMLOBJECTVALIDATOR_REQUIRE(Status,StatusCode);
85             const xmltooling::QName* value=ptr->getStatusCode()->getValue();
86             if (!value || (*value!=StatusCode::SUCCESS && *value!=StatusCode::REQUESTER &&
87                 *value!=StatusCode::RESPONDER && *value!=StatusCode::VERSIONMISMATCH))
88                 throw ValidationException("Top-level status code not one of the allowable values.");
89         END_XMLOBJECTVALIDATOR;
90
91         BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Response);
92             XMLOBJECTVALIDATOR_REQUIRE(Response,ResponseID);
93             XMLOBJECTVALIDATOR_REQUIRE(Response,IssueInstant);
94             XMLOBJECTVALIDATOR_REQUIRE(Response,Status);
95             pair<bool,int> minor=ptr->getMinorVersion();
96             if (!minor.first)
97                 throw ValidationException("Response must have MinorVersion");
98         END_XMLOBJECTVALIDATOR;
99     };
100 };
101
102 #define REGISTER_ELEMENT(cname) \
103     q=xmltooling::QName(SAML1P_NS,cname::LOCAL_NAME); \
104     XMLObjectBuilder::registerBuilder(q,new cname##Builder()); \
105     SchemaValidators.registerValidator(q,new cname##SchemaValidator())
106
107 #define REGISTER_TYPE(cname) \
108     q=xmltooling::QName(SAML1P_NS,cname::TYPE_NAME); \
109     XMLObjectBuilder::registerBuilder(q,new cname##Builder()); \
110     SchemaValidators.registerValidator(q,new cname##SchemaValidator())
111
112 #define REGISTER_ELEMENT_NOVAL(cname) \
113     q=xmltooling::QName(SAML1P_NS,cname::LOCAL_NAME); \
114     XMLObjectBuilder::registerBuilder(q,new cname##Builder());
115
116 #define REGISTER_TYPE_NOVAL(cname) \
117     q=xmltooling::QName(SAML1P_NS,cname::TYPE_NAME); \
118     XMLObjectBuilder::registerBuilder(q,new cname##Builder());
119
120 void opensaml::saml1p::registerProtocolClasses() {
121     xmltooling::QName q;
122     REGISTER_ELEMENT(AssertionArtifact);
123     REGISTER_ELEMENT(AttributeQuery);
124     REGISTER_ELEMENT(AuthenticationQuery);
125     REGISTER_ELEMENT(AuthorizationDecisionQuery);
126     REGISTER_ELEMENT_NOVAL(Query);
127     REGISTER_ELEMENT(Request);
128     REGISTER_ELEMENT(RespondWith);
129     REGISTER_ELEMENT(Response);
130     REGISTER_ELEMENT(Status);
131     REGISTER_ELEMENT(StatusCode);
132     REGISTER_ELEMENT_NOVAL(StatusDetail);
133     REGISTER_ELEMENT(StatusMessage);
134     REGISTER_TYPE(AttributeQuery);
135     REGISTER_TYPE(AuthenticationQuery);
136     REGISTER_TYPE(AuthorizationDecisionQuery);
137     REGISTER_TYPE(Request);
138     REGISTER_TYPE(Response);
139     REGISTER_TYPE(Status);
140     REGISTER_TYPE(StatusCode);
141     REGISTER_TYPE_NOVAL(StatusDetail);
142 }