Correct eol-style property.
[shibboleth/cpp-opensaml.git] / samltest / saml1 / binding / SAML1ArtifactTest.h
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 #include "binding.h"
18
19 #include <saml/binding/ArtifactMap.h>
20 #include <saml/saml1/core/Assertions.h>
21 #include <saml/saml1/core/Protocols.h>
22 #include <saml/saml1/binding/SAMLArtifactType0001.h>
23 #include <xmltooling/signature/Signature.h>
24 #include <xmltooling/validation/ValidatorSuite.h>
25
26 using namespace opensaml::saml1p;
27 using namespace opensaml::saml1;
28
29 class SAML1ArtifactTest : public CxxTest::TestSuite,
30         public SAMLBindingBaseTestCase, public MessageEncoder::ArtifactGenerator, public MessageDecoder::ArtifactResolver {
31 public:
32     void setUp() {
33         SAMLBindingBaseTestCase::setUp();
34     }
35
36     void tearDown() {
37         SAMLBindingBaseTestCase::tearDown();
38     }
39
40     void testSAML1Artifact() {
41         try {
42             xmltooling::QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
43             SecurityPolicy policy(m_metadata, &idprole, m_trust, false);
44             policy.getRules().assign(m_rules.begin(), m_rules.end());
45
46             // Read message to use from file.
47             string path = data_path + "saml1/binding/SAML1Assertion.xml";
48             ifstream in(path.c_str());
49             DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
50             XercesJanitor<DOMDocument> janitor(doc);
51             auto_ptr<saml1::Assertion> toSend(
52                 dynamic_cast<saml1::Assertion*>(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(),true))
53                 );
54             janitor.release();
55
56             CredentialCriteria cc;
57             cc.setUsage(Credential::SIGNING_CREDENTIAL);
58             Locker clocker(m_creds);
59             const Credential* cred = m_creds->resolve(&cc);
60             TSM_ASSERT("Retrieved credential was null", cred!=NULL);
61
62             // Encode message.
63             auto_ptr<MessageEncoder> encoder(
64                 SAMLConfig::getConfig().MessageEncoderManager.newPlugin(
65                     samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT, pair<const DOMElement*,const XMLCh*>(NULL,NULL)
66                     )
67                 );
68             Locker locker(m_metadata);
69             encoder->encode(
70                 *this,
71                 toSend.get(),
72                 "https://sp.example.org/SAML/SSO",
73                 m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first,
74                 "state",
75                 this,
76                 cred
77                 );
78             toSend.release();
79             
80             // Decode message.
81             string relayState;
82             auto_ptr<MessageDecoder> decoder(
83                 SAMLConfig::getConfig().MessageDecoderManager.newPlugin(
84                     samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT, pair<const DOMElement*,const XMLCh*>(NULL,NULL)
85                     )
86                 );
87             decoder->setArtifactResolver(this);
88             auto_ptr<Response> response(dynamic_cast<Response*>(decoder->decode(relayState,*this,policy)));
89             
90             // Test the results.
91             TSM_ASSERT_EQUALS("TARGET was not the expected result.", relayState, "state");
92             TSM_ASSERT("SAML Response not decoded successfully.", response.get());
93             TSM_ASSERT("Message was not verified.", policy.isAuthenticated());
94             auto_ptr_char entityID(policy.getIssuer()->getName());
95             TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
96             TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
97
98             // Trigger a replay.
99             policy.reset();
100             TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
101         }
102         catch (XMLToolingException& ex) {
103             TS_TRACE(ex.what());
104             throw;
105         }
106     }
107
108     SAMLArtifact* generateSAML1Artifact(const EntityDescriptor* relyingParty) const {
109         return new SAMLArtifactType0001(SAMLConfig::getConfig().hashSHA1("https://idp.example.org/"));
110     }
111     
112     saml2p::SAML2Artifact* generateSAML2Artifact(const EntityDescriptor* relyingParty) const {
113         throw BindingException("Not implemented.");
114     }
115     
116     Response* resolve(
117         const vector<SAMLArtifact*>& artifacts,
118         const IDPSSODescriptor& idpDescriptor,
119         SecurityPolicy& policy
120         ) const {
121         TSM_ASSERT_EQUALS("Too many artifacts.", artifacts.size(), 1);
122         XMLObject* xmlObject =
123             SAMLConfig::getConfig().getArtifactMap()->retrieveContent(artifacts.front(), "https://sp.example.org/");
124         saml1::Assertion* assertion = dynamic_cast<saml1::Assertion*>(xmlObject);
125         TSM_ASSERT("Not an assertion.", assertion!=NULL);
126         auto_ptr<Response> response(ResponseBuilder::buildResponse());
127         response->getAssertions().push_back(assertion);
128         Status* status = StatusBuilder::buildStatus();
129         response->setStatus(status);
130         StatusCode* sc = StatusCodeBuilder::buildStatusCode();
131         status->setStatusCode(sc);
132         sc->setValue(&StatusCode::SUCCESS);
133         response->setSignature(SignatureBuilder::buildSignature());
134         vector<Signature*> sigs(1,response->getSignature());
135         CredentialCriteria cc;
136         cc.setUsage(Credential::SIGNING_CREDENTIAL);
137         Locker clocker(m_creds);
138         const Credential* cred = m_creds->resolve(&cc);
139         TSM_ASSERT("Retrieved credential was null", cred!=NULL);
140         response->marshall((DOMDocument*)NULL,&sigs,cred);
141         SchemaValidators.validate(response.get());
142         policy.evaluate(*(response.get()), this);
143         return response.release();
144     }
145
146     saml2p::ArtifactResponse* resolve(
147         const saml2p::SAML2Artifact& artifact,
148         const SSODescriptorType& ssoDescriptor,
149         SecurityPolicy& policy
150         ) const {
151         throw BindingException("Not implemented.");
152     }
153 };