Add method to read all properties.
[shibboleth/sp.git] / shibsp / ServiceProvider.cpp
index 48b947a..dd8ce3b 100644 (file)
@@ -61,23 +61,37 @@ namespace shibsp {
         request.setResponseHeader("Expires","01-Jan-1997 12:00:00 GMT");
         request.setResponseHeader("Cache-Control","private,no-store,no-cache");
     
+        // Error templates come from the request's settings or from the Errors property set.
+        pair<bool,const char*> pathname = pair<bool,const char*>(false,NULL);
+        try {
+            RequestMapper::Settings settings = request.getRequestSettings();
+            string pagename(page);
+            pagename += "Error";
+            pathname = settings.first->getString(pagename.c_str());
+        }
+        catch (exception& ex) {
+            request.log(SPRequest::SPError, ex.what());
+        }
+
+        // Nothing for request, so check app properties.
         const PropertySet* props=app ? app->getPropertySet("Errors") : NULL;
-        if (props) {
-            pair<bool,const char*> p=props->getString(page);
-            if (p.first) {
-                ifstream infile(p.second);
-                if (infile) {
-                    tp.setPropertySet(props);
-                    stringstream str;
-                    XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, tp, tp.getRichException());
-                    return request.sendResponse(str);
-                }
-            }
-            else if (!strcmp(page,"access")) {
-                istringstream msg("Access Denied");
-                return request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN);
+        if (!pathname.first && props)
+            pathname=props->getString(page);
+
+        if (pathname.first) {
+            ifstream infile(pathname.second);
+            if (infile) {
+                tp.setPropertySet(props);
+                stringstream str;
+                XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, tp, tp.getRichException());
+                return request.sendResponse(str);
             }
         }
+        
+        if (!strcmp(page,"access")) {
+            istringstream msg("Access Denied");
+            return request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN);
+        }
     
         string errstr = string("sendError could not process error template (") + page + ")";
         request.log(SPRequest::SPError, errstr);
@@ -269,21 +283,27 @@ pair<bool,long> ServiceProvider::doAuthorization(SPRequest& request) const
             }
        
             Locker acllock(settings.second);
-            if (settings.second->authorized(request,session)) {
-                // Let the caller decide how to proceed.
-                request.log(SPRequest::SPDebug, "access control provider granted access");
-                return make_pair(false,0);
-            }
-            else {
-                request.log(SPRequest::SPWarn, "access control provider denied access");
-                TemplateParameters tp;
-                tp.m_map["requestURL"] = targetURL;
-                return make_pair(true,sendError(request, app, "access", tp));
+            switch (settings.second->authorized(request,session)) {
+                case AccessControl::shib_acl_true:
+                    request.log(SPRequest::SPDebug, "access control provider granted access");
+                    return make_pair(true,request.returnOK());
+
+                case AccessControl::shib_acl_false:
+                {
+                    request.log(SPRequest::SPWarn, "access control provider denied access");
+                    TemplateParameters tp;
+                    tp.m_map["requestURL"] = targetURL;
+                    return make_pair(true,sendError(request, app, "access", tp));
+                }
+
+                default:
+                    // Use the "DECLINE" interface to signal we don't know what to do.
+                    return make_pair(true,request.returnDecline());
             }
-            return make_pair(false,0);
         }
-        else
+        else {
             return make_pair(true,request.returnDecline());
+        }
     }
     catch (exception& e) {
         TemplateParameters tp(&e);
@@ -359,8 +379,12 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
             else {
                 const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();
                 string exportName = "Shib-Assertion-00";
-                const char* handlerURL=request.getHandlerURL(targetURL.c_str());
-                string baseURL = string(handlerURL) + exportLocation.second + "?key=" + session->getID() + "&ID=";
+                string baseURL;
+                if (!strncmp(exportLocation.second, "http", 4))
+                    baseURL = exportLocation.second;
+                else
+                    baseURL = string(request.getHandlerURL(targetURL.c_str())) + exportLocation.second;
+                baseURL = baseURL + "?key=" + session->getID() + "&ID=";
                 const vector<const char*>& tokens = session->getAssertionIDs();
                 vector<const char*>::size_type count = 0;
                 for (vector<const char*>::const_iterator tokenids = tokens.begin(); tokenids!=tokens.end(); ++tokenids) {
@@ -376,8 +400,8 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
 
         // Export the attributes.
         bool remoteUserSet = false;
-        const multimap<string,Attribute*>& attributes = session->getAttributes();
-        for (multimap<string,Attribute*>::const_iterator a = attributes.begin(); a!=attributes.end(); ++a) {
+        const multimap<string,const Attribute*>& attributes = session->getIndexedAttributes();
+        for (multimap<string,const Attribute*>::const_iterator a = attributes.begin(); a!=attributes.end(); ++a) {
             const vector<string>& vals = a->second->getSerializedValues();
 
             // See if this needs to be set as the REMOTE_USER value.
@@ -406,7 +430,7 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
             }
             request.setHeader(a->first.c_str(), header.c_str());
         }
-    
+
         return make_pair(false,0);
     }
     catch (exception& e) {