From: Scott Cantor Date: Wed, 1 Feb 2012 17:25:52 +0000 (+0000) Subject: Refactor contact handling X-Git-Tag: 2.5.0~41 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=commitdiff_plain;h=3cbec746823d9c409f7caf3f4c6f5d69fac67333 Refactor contact handling --- diff --git a/saml/SAMLConfig.cpp b/saml/SAMLConfig.cpp index 298e84b..e0ff16c 100644 --- a/saml/SAMLConfig.cpp +++ b/saml/SAMLConfig.cpp @@ -68,6 +68,7 @@ #include #include #include +#include using namespace opensaml; using namespace xmlsignature; @@ -190,6 +191,9 @@ bool SAMLInternalConfig::init(bool initXMLTooling) registerMessageDecoders(); registerSecurityPolicyRules(); + m_contactPriority.push_back(saml2md::ContactPerson::CONTACT_SUPPORT); + m_contactPriority.push_back(saml2md::ContactPerson::CONTACT_TECHNICAL); + log.info("%s library initialization complete", PACKAGE_STRING); ++m_initCount; return true; @@ -264,6 +268,40 @@ string SAMLInternalConfig::hashSHA1(const char* s, bool toHex) return SecurityHelper::doHash("SHA1", s, strlen(s), toHex); } +void SAMLInternalConfig::setContactPriority(const XMLCh* contactTypes) +{ + const XMLCh* ctype; + m_contactPriority.clear(); + XMLStringTokenizer tokens(contactTypes); + while (tokens.hasMoreTokens()) { + ctype = tokens.nextToken(); + if (ctype && *ctype) + m_contactPriority.push_back(ctype); + } +} + +using namespace saml2md; + +const ContactPerson* SAMLInternalConfig::getContactPerson(const EntityDescriptor& entity) const +{ + for (vector::const_iterator ctype = m_contactPriority.begin(); ctype != m_contactPriority.end(); ++ctype) { + const ContactPerson* cp = find_if(entity.getContactPersons(), *ctype == lambda::bind(&ContactPerson::getContactType, _1)); + if (cp) + return cp; + } + return nullptr; +} + +const ContactPerson* SAMLInternalConfig::getContactPerson(const RoleDescriptor& role) const +{ + for (vector::const_iterator ctype = m_contactPriority.begin(); ctype != m_contactPriority.end(); ++ctype) { + const ContactPerson* cp = find_if(role.getContactPersons(), *ctype == lambda::bind(&ContactPerson::getContactType, _1)); + if (cp) + return cp; + } + return getContactPerson(*(dynamic_cast(role.getParent()))); +} + SignableObject::SignableObject() { } @@ -296,9 +334,6 @@ Status::~Status() { } -using namespace saml2p; -using namespace saml2md; - void opensaml::annotateException(XMLToolingException* e, const EntityDescriptor* entity, const Status* status, bool rethrow) { time_t now = time(nullptr); @@ -324,30 +359,32 @@ void opensaml::annotateException(XMLToolingException* e, const RoleDescriptor* r auto_ptr_char id(dynamic_cast(role->getParent())->getEntityID()); e->addProperty("entityID",id.get()); - const vector& contacts=role->getContactPersons(); - for (vector::const_iterator c=contacts.begin(); c!=contacts.end(); ++c) { - const XMLCh* ctype=(*c)->getContactType(); - if (ctype && (XMLString::equals(ctype,ContactPerson::CONTACT_SUPPORT) - || XMLString::equals(ctype,ContactPerson::CONTACT_TECHNICAL))) { - GivenName* fname=(*c)->getGivenName(); - SurName* lname=(*c)->getSurName(); - auto_ptr_char first(fname ? fname->getName() : nullptr); - auto_ptr_char last(lname ? lname->getName() : nullptr); - if (first.get() && last.get()) { - string contact=string(first.get()) + ' ' + last.get(); - e->addProperty("contactName",contact.c_str()); - } - else if (first.get()) - e->addProperty("contactName",first.get()); - else if (last.get()) - e->addProperty("contactName",last.get()); - const vector& emails=const_cast(*c)->getEmailAddresss(); - if (!emails.empty()) { - auto_ptr_char email(emails.front()->getAddress()); - if (email.get()) - e->addProperty("contactEmail",email.get()); + const ContactPerson* cp = SAMLConfig::getConfig().getContactPerson(*role); + if (cp) { + GivenName* fname = cp->getGivenName(); + SurName* lname = cp->getSurName(); + auto_ptr_char first(fname ? fname->getName() : nullptr); + auto_ptr_char last(lname ? lname->getName() : nullptr); + if (first.get() && last.get()) { + string contact=string(first.get()) + ' ' + last.get(); + e->addProperty("contactName", contact.c_str()); + } + else if (first.get()) + e->addProperty("contactName", first.get()); + else if (last.get()) + e->addProperty("contactName", last.get()); + const vector& emails=cp->getEmailAddresss(); + if (!emails.empty()) { + auto_ptr_char email(emails.front()->getAddress()); + if (email.get()) { + if (strstr(email.get(), "mailto:") == email.get()) { + e->addProperty("contactEmail", email.get()); + } + else { + string addr = string("mailto:") + email.get(); + e->addProperty("contactEmail", addr.c_str()); + } } - break; } } diff --git a/saml/SAMLConfig.h b/saml/SAMLConfig.h index c1548f4..4944abb 100644 --- a/saml/SAMLConfig.h +++ b/saml/SAMLConfig.h @@ -46,8 +46,11 @@ namespace opensaml { class SAML_API SecurityPolicyRule; namespace saml2md { + class SAML_API ContactPerson; + class SAML_API EntityDescriptor; class SAML_API MetadataProvider; class SAML_API MetadataFilter; + class SAML_API RoleDescriptor; }; #if defined (_MSC_VER) @@ -147,6 +150,29 @@ namespace opensaml { */ virtual std::string hashSHA1(const char* s, bool toHex=false)=0; + /** + * Sets the order of contact types to use in annotating exceptions with contact information. + * + * @param contactTypes whitespace-delimited list of contact types + */ + virtual void setContactPriority(const XMLCh* contactTypes)=0; + + /** + * Returns the appropriate contact to use for the entity. + * + * @param entity the entity to search + * @return a contact to use, or nullptr + */ + virtual const saml2md::ContactPerson* getContactPerson(const saml2md::EntityDescriptor& entity) const=0; + + /** + * Returns the appropriate contact to use for the role. + * + * @param entity the role to search + * @return a contact to use, or nullptr + */ + virtual const saml2md::ContactPerson* getContactPerson(const saml2md::RoleDescriptor& role) const=0; + /** Manages factories for MessageDecoder plugins. */ xmltooling::PluginManager< MessageDecoder,std::string,std::pair > MessageDecoderManager; diff --git a/saml/internal.h b/saml/internal.h index 6c5320d..774f7fe 100644 --- a/saml/internal.h +++ b/saml/internal.h @@ -45,7 +45,9 @@ #include "SAMLConfig.h" #include +#include #include +#include using namespace xercesc; @@ -109,10 +111,14 @@ namespace opensaml { void generateRandomBytes(std::string& buf, unsigned int len); XMLCh* generateIdentifier(); std::string hashSHA1(const char* data, bool toHex=false); + void setContactPriority(const XMLCh*); + const saml2md::ContactPerson* getContactPerson(const saml2md::EntityDescriptor&) const; + const saml2md::ContactPerson* getContactPerson(const saml2md::RoleDescriptor&) const; private: int m_initCount; boost::scoped_ptr m_lock; + std::vector m_contactPriority; }; /// @endcond