From 9f9783497033d5377b1dbc58e776024ab2bb9724 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Tue, 31 Jan 2012 16:51:28 +0000 Subject: [PATCH] Add Status base class. --- saml/Assertion.h | 16 +-------- saml/RootObject.h | 52 +++++++++++++++++++++++++++++ saml/SAMLConfig.cpp | 20 +++++++---- saml/exceptions.h | 10 +++--- saml/saml1/binding/impl/SAML1SOAPClient.cpp | 4 +-- saml/saml1/core/Protocols.h | 2 +- saml/saml1/core/impl/ProtocolsImpl.cpp | 18 ++++++++++ saml/saml2/binding/impl/SAML2SOAPClient.cpp | 2 +- saml/saml2/core/Protocols.h | 2 +- saml/saml2/core/impl/Protocols20Impl.cpp | 15 +++++++++ samltest/saml2/binding/SAML2ArtifactTest.h | 2 +- 11 files changed, 111 insertions(+), 32 deletions(-) diff --git a/saml/Assertion.h b/saml/Assertion.h index 2f1d147..5172dbd 100644 --- a/saml/Assertion.h +++ b/saml/Assertion.h @@ -29,20 +29,6 @@ #include -namespace opensaml { - - /** - * Base class for SAML assertions. - * Currently just a marker interface. - */ - class SAML_API Assertion : public virtual RootObject - { - public: - virtual ~Assertion(); - protected: - Assertion(); - }; - -}; +// Moved declaration into RootObject.h header. #endif /* __saml_assertion_h__ */ diff --git a/saml/RootObject.h b/saml/RootObject.h index 5db45cd..4c50b45 100644 --- a/saml/RootObject.h +++ b/saml/RootObject.h @@ -69,6 +69,58 @@ namespace opensaml { RootObject(); }; + /** + * Base class for SAML assertions. + * Currently just a marker interface. + */ + class SAML_API Assertion : public virtual RootObject + { + public: + virtual ~Assertion(); + protected: + Assertion(); + }; + + /** + * Base class for SAML status codes. + */ + class SAML_API Status : public virtual xmltooling::XMLObject + { + public: + virtual ~Status(); + + /** + * Returns a string representation of the top-level status code. + * + * @return string representation of top-level status code + */ + virtual const XMLCh* getTopStatus() const=0; + + /** + * Returns a string representation of the second-level status code, if any. + * + * @return string representation of second-level status code, or nullptr + */ + virtual const XMLCh* getSubStatus() const=0; + + /** + * Returns true iff status information beyond the second level exists. + * + * @return indicator of three or more status codes + */ + virtual bool hasAdditionalStatus() const=0; + + /** + * Returns the message contained in the status, if any. + * + * @return status message, or nullptr + */ + virtual const XMLCh* getMessage() const=0; + + protected: + Status(); + }; + }; #endif /* __saml_root_h__ */ diff --git a/saml/SAMLConfig.cpp b/saml/SAMLConfig.cpp index 5efbb59..298e84b 100644 --- a/saml/SAMLConfig.cpp +++ b/saml/SAMLConfig.cpp @@ -288,6 +288,14 @@ Assertion::~Assertion() { } +Status::Status() +{ +} + +Status::~Status() +{ +} + using namespace saml2p; using namespace saml2md; @@ -348,18 +356,18 @@ void opensaml::annotateException(XMLToolingException* e, const RoleDescriptor* r e->addProperty("errorURL",eurl.get()); } } - + if (status) { - auto_ptr_char sc(status->getStatusCode() ? status->getStatusCode()->getValue() : nullptr); + auto_ptr_char sc(status->getTopStatus()); if (sc.get() && *sc.get()) e->addProperty("statusCode", sc.get()); - if (status->getStatusCode()->getStatusCode()) { - auto_ptr_char sc2(status->getStatusCode()->getStatusCode()->getValue()); + if (status->getSubStatus()) { + auto_ptr_char sc2(status->getSubStatus()); if (sc2.get() && *sc.get()) e->addProperty("statusCode2", sc2.get()); } - if (status->getStatusMessage()) { - auto_ptr_char msg(status->getStatusMessage()->getMessage()); + if (status->getMessage()) { + auto_ptr_char msg(status->getMessage()); if (msg.get() && *msg.get()) e->addProperty("statusMessage", msg.get()); } diff --git a/saml/exceptions.h b/saml/exceptions.h index 7048c55..c01a512 100644 --- a/saml/exceptions.h +++ b/saml/exceptions.h @@ -32,9 +32,8 @@ namespace opensaml { - namespace saml2p { - class SAML_API Status; - }; + class SAML_API Status; + namespace saml2md { class SAML_API EntityDescriptor; class SAML_API RoleDescriptor; @@ -68,7 +67,7 @@ namespace opensaml { void SAML_API annotateException( xmltooling::XMLToolingException* e, const saml2md::EntityDescriptor* entity, - const saml2p::Status* status=nullptr, + const Status* status=nullptr, bool rethrow=true ); @@ -93,9 +92,10 @@ namespace opensaml { void SAML_API annotateException( xmltooling::XMLToolingException* e, const saml2md::RoleDescriptor* role, - const saml2p::Status* status=nullptr, + const Status* status=nullptr, bool rethrow=true ); + }; #endif /* __saml_exceptions_h__ */ diff --git a/saml/saml1/binding/impl/SAML1SOAPClient.cpp b/saml/saml1/binding/impl/SAML1SOAPClient.cpp index 513eb7e..0e23b88 100644 --- a/saml/saml1/binding/impl/SAML1SOAPClient.cpp +++ b/saml/saml1/binding/impl/SAML1SOAPClient.cpp @@ -92,7 +92,7 @@ Response* SAML1SOAPClient::receiveSAML() if (code && *code != StatusCode::SUCCESS && handleError(*status)) { BindingException ex("SAML Response contained an error."); if (m_soaper.getPolicy().getIssuerMetadata()) - annotateException(&ex, m_soaper.getPolicy().getIssuerMetadata()); // throws it + annotateException(&ex, m_soaper.getPolicy().getIssuerMetadata(), status); // throws it else ex.raise(); } @@ -114,7 +114,7 @@ Response* SAML1SOAPClient::receiveSAML() return nullptr; } -bool SAML1SOAPClient::handleError(const Status& status) +bool SAML1SOAPClient::handleError(const saml1p::Status& status) { const xmltooling::QName* code = status.getStatusCode() ? status.getStatusCode()->getValue() : nullptr; auto_ptr_char str((status.getStatusMessage() ? status.getStatusMessage()->getMessage() : nullptr)); diff --git a/saml/saml1/core/Protocols.h b/saml/saml1/core/Protocols.h index 8258bb3..6f44fa9 100644 --- a/saml/saml1/core/Protocols.h +++ b/saml/saml1/core/Protocols.h @@ -141,7 +141,7 @@ namespace opensaml { static const XMLCh TYPE_NAME[]; END_XMLOBJECT; - BEGIN_XMLOBJECT(SAML_API,Status,xmltooling::XMLObject,SAML 1.x Status element); + BEGIN_XMLOBJECT(SAML_API,Status,opensaml::Status,SAML 1.x Status element); DECL_TYPED_CHILD(StatusCode); DECL_TYPED_CHILD(StatusMessage); DECL_TYPED_CHILD(StatusDetail); diff --git a/saml/saml1/core/impl/ProtocolsImpl.cpp b/saml/saml1/core/impl/ProtocolsImpl.cpp index a28a905..684c1e2 100644 --- a/saml/saml1/core/impl/ProtocolsImpl.cpp +++ b/saml/saml1/core/impl/ProtocolsImpl.cpp @@ -641,6 +641,24 @@ namespace opensaml { IMPL_TYPED_CHILD(StatusMessage); IMPL_TYPED_CHILD(StatusDetail); + // Base class methods. + const XMLCh* getTopStatus() const { + const xmltooling::QName* code = getStatusCode() ? getStatusCode()->getValue() : nullptr; + return code ? code->getLocalPart() : nullptr; + } + const XMLCh* getSubStatus() const { + const StatusCode* sc = getStatusCode() ? getStatusCode()->getStatusCode() : nullptr; + if (sc) + return sc->getValue() ? sc->getValue()->getLocalPart() : nullptr; + return nullptr; + } + bool hasAdditionalStatus() const { + return (getStatusCode() && getStatusCode()->getStatusCode() && getStatusCode()->getStatusCode()->getStatusCode()); + } + const XMLCh* getMessage() const { + return getStatusMessage() ? getStatusMessage()->getMessage() : nullptr; + } + protected: void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { PROC_TYPED_CHILD(StatusCode,SAML1P_NS,false); diff --git a/saml/saml2/binding/impl/SAML2SOAPClient.cpp b/saml/saml2/binding/impl/SAML2SOAPClient.cpp index a9c78f2..d010275 100644 --- a/saml/saml2/binding/impl/SAML2SOAPClient.cpp +++ b/saml/saml2/binding/impl/SAML2SOAPClient.cpp @@ -119,7 +119,7 @@ StatusResponseType* SAML2SOAPClient::receiveSAML() return nullptr; } -bool SAML2SOAPClient::handleError(const Status& status) +bool SAML2SOAPClient::handleError(const saml2p::Status& status) { auto_ptr_char code((status.getStatusCode() ? status.getStatusCode()->getValue() : nullptr)); auto_ptr_char str((status.getStatusMessage() ? status.getStatusMessage()->getMessage() : nullptr)); diff --git a/saml/saml2/core/Protocols.h b/saml/saml2/core/Protocols.h index d634165..f487295 100644 --- a/saml/saml2/core/Protocols.h +++ b/saml/saml2/core/Protocols.h @@ -135,7 +135,7 @@ namespace opensaml { static const XMLCh TYPE_NAME[]; END_XMLOBJECT; - BEGIN_XMLOBJECT(SAML_API,Status,xmltooling::XMLObject,SAML 2.0 Status element); + BEGIN_XMLOBJECT(SAML_API,Status,opensaml::Status,SAML 2.0 Status element); DECL_TYPED_CHILD(StatusCode); DECL_TYPED_CHILD(StatusMessage); DECL_TYPED_CHILD(StatusDetail); diff --git a/saml/saml2/core/impl/Protocols20Impl.cpp b/saml/saml2/core/impl/Protocols20Impl.cpp index 6ce1c3a..bfd4d82 100644 --- a/saml/saml2/core/impl/Protocols20Impl.cpp +++ b/saml/saml2/core/impl/Protocols20Impl.cpp @@ -222,6 +222,21 @@ namespace opensaml { IMPL_TYPED_CHILD(StatusMessage); IMPL_TYPED_CHILD(StatusDetail); + // Base class methods. + const XMLCh* getTopStatus() const { + return getStatusCode() ? getStatusCode()->getValue() : nullptr; + } + const XMLCh* getSubStatus() const { + const StatusCode* sc = getStatusCode() ? getStatusCode()->getStatusCode() : nullptr; + return sc ? sc->getValue() : nullptr; + } + bool hasAdditionalStatus() const { + return (getStatusCode() && getStatusCode()->getStatusCode() && getStatusCode()->getStatusCode()->getStatusCode()); + } + const XMLCh* getMessage() const { + return getStatusMessage() ? getStatusMessage()->getMessage() : nullptr; + } + protected: void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { PROC_TYPED_CHILD(StatusCode,SAML20P_NS,false); diff --git a/samltest/saml2/binding/SAML2ArtifactTest.h b/samltest/saml2/binding/SAML2ArtifactTest.h index 0996ce9..df162e7 100644 --- a/samltest/saml2/binding/SAML2ArtifactTest.h +++ b/samltest/saml2/binding/SAML2ArtifactTest.h @@ -142,7 +142,7 @@ public: auto_ptr response(ArtifactResponseBuilder::buildArtifactResponse()); response->setPayload(payload); - Status* status = StatusBuilder::buildStatus(); + saml2p::Status* status = StatusBuilder::buildStatus(); response->setStatus(status); StatusCode* sc = StatusCodeBuilder::buildStatusCode(); status->setStatusCode(sc); -- 2.1.4