Added exception annotation, missing exception factories.
authorScott Cantor <cantor.2@osu.edu>
Tue, 29 Mar 2005 02:21:52 +0000 (02:21 +0000)
committerScott Cantor <cantor.2@osu.edu>
Tue, 29 Mar 2005 02:21:52 +0000 (02:21 +0000)
shib/ShibConfig.cpp
shib/shib.h

index 18107f9..2f38a6f 100644 (file)
@@ -72,9 +72,12 @@ using namespace shibboleth;
 using namespace log4cpp;
 using namespace std;
 
+
+SAML_EXCEPTION_FACTORY(ResourceAccessException);
 SAML_EXCEPTION_FACTORY(MetadataException);
 SAML_EXCEPTION_FACTORY(CredentialException);
 SAML_EXCEPTION_FACTORY(InvalidHandleException);
+SAML_EXCEPTION_FACTORY(InvalidSessionException);
 
 namespace {
     ShibConfig g_config;
@@ -98,9 +101,11 @@ extern "C" unsigned long openssl_thread_id(void)
 
 bool ShibConfig::init()
 {
+    REGISTER_EXCEPTION_FACTORY(ResourceAccessException);
     REGISTER_EXCEPTION_FACTORY(MetadataException);
     REGISTER_EXCEPTION_FACTORY(CredentialException);
     REGISTER_EXCEPTION_FACTORY(InvalidHandleException);
+    REGISTER_EXCEPTION_FACTORY(InvalidSessionException);
 
     // Set up OpenSSL locking.
        for (int i=0; i<CRYPTO_num_locks(); i++)
@@ -142,3 +147,81 @@ void shibboleth::log_openssl()
         code=ERR_get_error_line_data(&file,&line,&data,&flags);
     }
 }
+
+void shibboleth::annotateException(SAMLException& e, const IEntityDescriptor* entity, bool rethrow)
+{
+    if (entity) {
+        auto_ptr_char id(entity->getId());
+        e.addProperty("providerId",id.get());
+        Iterator<const IRoleDescriptor*> roles=entity->getRoleDescriptors();
+        while (roles.hasNext()) {
+            const IRoleDescriptor* role=roles.next();
+            if (role->isValid()) {
+                const char* temp=role->getErrorURL();
+                if (temp) {
+                    e.addProperty("errorURL",temp);
+                    break;
+                }
+            }
+        }
+
+        Iterator<const IContactPerson*> i=entity->getContactPersons();
+        while (i.hasNext()) {
+            const IContactPerson* c=i.next();
+            if ((c->getType()==IContactPerson::technical || c->getType()==IContactPerson::support)) {
+                const char* fname=c->getGivenName();
+                const char* lname=c->getSurName();
+                if (fname && lname) {
+                    string contact=string(fname) + ' ' + lname;
+                    e.addProperty("contactName",contact.c_str());
+                }
+                else if (fname)
+                    e.addProperty("contactName",fname);
+                else if (lname)
+                    e.addProperty("contactName",lname);
+                Iterator<string> emails=c->getEmailAddresses();
+                if (emails.hasNext())
+                    e.addProperty("contactEmail",emails.next().c_str());
+                break;
+            }
+        }
+    }
+    
+    if (rethrow)
+        throw e;
+}
+
+void shibboleth::annotateException(saml::SAMLException& e, const IRoleDescriptor* role, bool rethrow)
+{
+    if (role) {
+        auto_ptr_char id(role->getEntityDescriptor()->getId());
+        e.addProperty("providerId",id.get());
+        const char* temp=role->getErrorURL();
+        if (role->getErrorURL())
+            e.addProperty("errorURL",role->getErrorURL());
+
+        Iterator<const IContactPerson*> i=role->getContactPersons();
+        while (i.hasNext()) {
+            const IContactPerson* c=i.next();
+            if ((c->getType()==IContactPerson::technical || c->getType()==IContactPerson::support)) {
+                const char* fname=c->getGivenName();
+                const char* lname=c->getSurName();
+                if (fname && lname) {
+                    string contact=string(fname) + ' ' + lname;
+                    e.addProperty("contactName",contact.c_str());
+                }
+                else if (fname)
+                    e.addProperty("contactName",fname);
+                else if (lname)
+                    e.addProperty("contactName",lname);
+                Iterator<string> emails=c->getEmailAddresses();
+                if (emails.hasNext())
+                    e.addProperty("contactEmail",emails.next().c_str());
+                break;
+            }
+        }
+    }
+    
+    if (rethrow)
+        throw e;
+}
index c909b1e..b60542a 100644 (file)
 
 namespace shibboleth
 {
-    #define DECLARE_SHIB_EXCEPTION(name,base) \
-        class SHIB_EXPORTS name : public saml::base \
-        { \
-        public: \
-            name(const char* msg, const saml::params& p=saml::params(), const saml::Iterator<saml::QName>& codes=EMPTY(saml::QName), DOMElement* detail=NULL) \
-                : saml::base(msg,p,codes,detail) {RTTI(name);} \
-            name(const char* msg, const saml::namedparams& p, const saml::Iterator<saml::QName>& codes=EMPTY(saml::QName), DOMElement* detail=NULL) \
-                : saml::base(msg,p,codes,detail) {RTTI(name);} \
-            name(const std::string& msg, const saml::params& p=saml::params(), const saml::Iterator<saml::QName>& codes=EMPTY(saml::QName), DOMElement* detail=NULL) \
-                : saml::base(msg,p,codes,detail) {RTTI(name);} \
-            name(const std::string& msg, const saml::namedparams& p, const saml::Iterator<saml::QName>& codes=EMPTY(saml::QName), DOMElement* detail=NULL) \
-                : saml::base(msg,p,codes,detail) {RTTI(name);} \
-            name(const saml::QName& code, const char* msg, const saml::params& p=saml::params(), DOMElement* detail=NULL) \
-                : saml::base(code,msg,p,detail) {RTTI(name);} \
-            name(const saml::QName& code, const char* msg, const saml::namedparams& p, DOMElement* detail=NULL) \
-                : saml::base(code,msg,p,detail) {RTTI(name);} \
-            name(const saml::QName& code, const std::string& msg, const saml::params& p=saml::params(), DOMElement* detail=NULL) \
-                : saml::base(code,msg,p,detail) {RTTI(name);} \
-            name(const saml::QName& code, const std::string& msg, const saml::namedparams& p, DOMElement* detail=NULL) \
-                : saml::base(code,msg,p,detail) {RTTI(name);} \
-            name(HRESULT code, const char* msg, const saml::params& p=saml::params(), DOMElement* detail=NULL) \
-                : saml::base(code,msg,p,detail) {RTTI(name);} \
-            name(HRESULT code, const char* msg, const saml::namedparams& p, DOMElement* detail=NULL) \
-                : saml::base(code,msg,p,detail) {RTTI(name);} \
-            name(HRESULT code, const std::string& msg, const saml::params& p=saml::params(), DOMElement* detail=NULL) \
-                : saml::base(code,msg,p,detail) {RTTI(name);} \
-            name(HRESULT code, const std::string& msg, const saml::namedparams& p, DOMElement* detail=NULL) \
-                : saml::base(code,msg,p,detail) {RTTI(name);} \
-            name(DOMElement* e) : saml::base(e) {RTTI(name);} \
-            name(std::istream& in) : saml::base(in) {RTTI(name);} \
-            virtual ~name() throw () {} \
-        }
-
-    DECLARE_SHIB_EXCEPTION(MetadataException,SAMLException);
-    DECLARE_SHIB_EXCEPTION(CredentialException,SAMLException);
-    DECLARE_SHIB_EXCEPTION(InvalidHandleException,RetryableProfileException);
+    DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,ResourceAccessException,SAMLException);
+    DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,MetadataException,SAMLException);
+    DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,CredentialException,SAMLException);
+    DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,InvalidHandleException,RetryableProfileException);
+    DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,InvalidSessionException,RetryableProfileException);
 
     // Metadata abstract interfaces, based on SAML 2.0
     
@@ -498,7 +467,6 @@ namespace shibboleth
 
         virtual void setVersion(int major, int minor);
         virtual saml::SAMLBrowserProfile::BrowserProfileResponse receive(
-            XMLCh** pIssuer,
             const char* packet,
             const XMLCh* recipient,
             int supportedProfiles,
@@ -603,6 +571,17 @@ namespace shibboleth
         time_t m_filestamp;
         RWLock* m_lock;
     };
+
+    /* These helpers attach metadata-derived information as exception properties and then
+     * rethrow the object. The following properties are attached, when possible:
+     * 
+     *  providerId          The unique ID of the entity
+     *  errorURL            The error support URL of the entity or role
+     *  contactName         A formatted support or technical contact name
+     *  contactEmail        A contact email address
+     */
+    SHIB_EXPORTS void annotateException(saml::SAMLException& e, const IEntityDescriptor* entity, bool rethrow=true);
+    SHIB_EXPORTS void annotateException(saml::SAMLException& e, const IRoleDescriptor* role, bool rethrow=true);
 }
 
 #endif