From: Scott Cantor Date: Mon, 26 Jul 2010 21:08:35 +0000 (+0000) Subject: Allow for default RequestMap, relax constraint on root applicationId. X-Git-Tag: 2.4RC1~88 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;ds=sidebyside;h=926fc8dc99fc125be98c79abf0e7803382eb8112;p=shibboleth%2Fcpp-sp.git Allow for default RequestMap, relax constraint on root applicationId. --- diff --git a/configs/example-shibboleth2.xml b/configs/example-shibboleth2.xml index e826ad9..eb3df67 100644 --- a/configs/example-shibboleth2.xml +++ b/configs/example-shibboleth2.xml @@ -58,7 +58,7 @@ - + - diff --git a/configs/shibboleth2.xml b/configs/shibboleth2.xml index b363666..643fb3f 100644 --- a/configs/shibboleth2.xml +++ b/configs/shibboleth2.xml @@ -11,7 +11,7 @@ - + - diff --git a/configs/win-shibboleth2.xml b/configs/win-shibboleth2.xml index 89316ed..63ab25b 100644 --- a/configs/win-shibboleth2.xml +++ b/configs/win-shibboleth2.xml @@ -31,7 +31,7 @@ - + - diff --git a/schemas/shibboleth-2.0-native-sp-config.xsd b/schemas/shibboleth-2.0-native-sp-config.xsd index f12e353..10f4024 100644 --- a/schemas/shibboleth-2.0-native-sp-config.xsd +++ b/schemas/shibboleth-2.0-native-sp-config.xsd @@ -220,6 +220,7 @@ + @@ -264,7 +265,6 @@ - @@ -295,7 +295,6 @@ - @@ -314,7 +313,6 @@ - @@ -332,7 +330,6 @@ - @@ -347,7 +344,6 @@ - diff --git a/shibsp/AbstractSPRequest.cpp b/shibsp/AbstractSPRequest.cpp index 5fefc01..eb1ced4 100644 --- a/shibsp/AbstractSPRequest.cpp +++ b/shibsp/AbstractSPRequest.cpp @@ -97,7 +97,7 @@ const Application& AbstractSPRequest::getApplication() const // Now find the application from the URL settings m_app=m_sp->getApplication(getRequestSettings().first->getString("applicationId").second); if (!m_app) - throw ConfigurationException("Unable to map request to ApplicationOverride settings, check configuration."); + throw ConfigurationException("Unable to map non-default applicationId to an ApplicationOverride, check configuration."); } return *m_app; } diff --git a/shibsp/Application.cpp b/shibsp/Application.cpp index b54e5d5..439cd73 100644 --- a/shibsp/Application.cpp +++ b/shibsp/Application.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009 Internet2 + * Copyright 2001-2010 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,8 @@ const ServiceProvider& Application::getServiceProvider() const const char* Application::getId() const { - return getString("id").second; + pair ret = getString("id"); + return ret.first ? ret.second : "default"; } pair Application::getCookieNameProps(const char* prefix, time_t* lifetime) const diff --git a/shibsp/ServiceProvider.cpp b/shibsp/ServiceProvider.cpp index 9c2487b..538fb2c 100644 --- a/shibsp/ServiceProvider.cpp +++ b/shibsp/ServiceProvider.cpp @@ -63,7 +63,7 @@ namespace shibsp { // Strictly for error handling, detect a nullptr application and point at the default. if (!app) - app = request.getServiceProvider().getApplication("default"); + app = request.getServiceProvider().getApplication(nullptr); const PropertySet* props=app->getPropertySet("Errors"); diff --git a/shibsp/ServiceProvider.h b/shibsp/ServiceProvider.h index 15658fe..3bb95ca 100644 --- a/shibsp/ServiceProvider.h +++ b/shibsp/ServiceProvider.h @@ -155,7 +155,7 @@ namespace shibsp { /** * Returns an Application instance matching the specified ID. * - * @param applicationId the ID of the application + * @param applicationId the ID of the application, or nullptr for the default * @return pointer to the application, or nullptr */ virtual const Application* getApplication(const char* applicationId) const=0; diff --git a/shibsp/impl/XMLRequestMapper.cpp b/shibsp/impl/XMLRequestMapper.cpp index fbef292..593afe3 100644 --- a/shibsp/impl/XMLRequestMapper.cpp +++ b/shibsp/impl/XMLRequestMapper.cpp @@ -35,6 +35,7 @@ #include #include +using shibspconstants::SHIB2SPCONFIG_NS; using namespace shibsp; using namespace xmltooling; using namespace std; @@ -469,10 +470,20 @@ XMLRequestMapperImpl::XMLRequestMapperImpl(const DOMElement* e, Category& log) : #ifdef _DEBUG xmltooling::NDC ndc("XMLRequestMapperImpl"); #endif + static const XMLCh _default[] = UNICODE_LITERAL_7(d,e,f,a,u,l,t); + static const XMLCh _id[] = UNICODE_LITERAL_2(i,d); + static const XMLCh _RequestMap[] = UNICODE_LITERAL_10(R,e,q,u,e,s,t,M,a,p); + + if (!XMLHelper::isNodeNamed(e, SHIB2SPCONFIG_NS, _RequestMap)) + throw ConfigurationException("XML RequestMapper requires conf:RequestMap at root of configuration."); // Load the property set. load(e,nullptr,this); + // Inject "default" app ID if not explicit. + if (!getString("applicationId").first) + setProperty("applicationId", "default"); + // Load any AccessControl provider. loadACL(e,log); diff --git a/shibsp/impl/XMLServiceProvider.cpp b/shibsp/impl/XMLServiceProvider.cpp index 5b73168..db279c2 100644 --- a/shibsp/impl/XMLServiceProvider.cpp +++ b/shibsp/impl/XMLServiceProvider.cpp @@ -377,7 +377,7 @@ namespace { } const Application* getApplication(const char* applicationId) const { - map::const_iterator i=m_impl->m_appmap.find(applicationId); + map::const_iterator i=m_impl->m_appmap.find(applicationId ? applicationId : "default"); return (i!=m_impl->m_appmap.end()) ? i->second : nullptr; } @@ -427,6 +427,7 @@ namespace { #pragma warning( pop ) #endif + static const XMLCh applicationId[] = UNICODE_LITERAL_13(a,p,p,l,i,c,a,t,i,o,n,I,d); static const XMLCh ApplicationOverride[] = UNICODE_LITERAL_19(A,p,p,l,i,c,a,t,i,o,n,O,v,e,r,r,i,d,e); static const XMLCh ApplicationDefaults[] = UNICODE_LITERAL_19(A,p,p,l,i,c,a,t,i,o,n,D,e,f,a,u,l,t,s); static const XMLCh _ArtifactMap[] = UNICODE_LITERAL_11(A,r,t,i,f,a,c,t,M,a,p); @@ -439,6 +440,7 @@ namespace { static const XMLCh Binding[] = UNICODE_LITERAL_7(B,i,n,d,i,n,g); static const XMLCh Channel[]= UNICODE_LITERAL_7(C,h,a,n,n,e,l); static const XMLCh _CredentialResolver[] = UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r); + static const XMLCh _default[] = UNICODE_LITERAL_7(d,e,f,a,u,l,t); static const XMLCh _Extensions[] = UNICODE_LITERAL_10(E,x,t,e,n,s,i,o,n,s); static const XMLCh _fatal[] = UNICODE_LITERAL_5(f,a,t,a,l); static const XMLCh _Handler[] = UNICODE_LITERAL_7(H,a,n,d,l,e,r); @@ -459,6 +461,7 @@ namespace { static const XMLCh RelyingParty[] = UNICODE_LITERAL_12(R,e,l,y,i,n,g,P,a,r,t,y); static const XMLCh _ReplayCache[] = UNICODE_LITERAL_11(R,e,p,l,a,y,C,a,c,h,e); static const XMLCh _RequestMapper[] = UNICODE_LITERAL_13(R,e,q,u,e,s,t,M,a,p,p,e,r); + static const XMLCh RequestMap[] = UNICODE_LITERAL_10(R,e,q,u,e,s,t,M,a,p); static const XMLCh SecurityPolicies[] = UNICODE_LITERAL_16(S,e,c,u,r,i,t,y,P,o,l,i,c,i,e,s); static const XMLCh SecurityPolicyProvider[] = UNICODE_LITERAL_22(S,e,c,u,r,i,t,y,P,o,l,i,c,y,P,r,o,v,i,d,e,r); static const XMLCh _SessionCache[] = UNICODE_LITERAL_12(S,e,s,s,i,o,n,C,a,c,h,e); @@ -509,7 +512,7 @@ XMLApplication::XMLApplication( XMLToolingConfig& xmlConf=XMLToolingConfig::getConfig(); #endif - // This used to be an actual hash, but now it's just a hex-encode to avoid xmlsec. + // This used to be an actual hash, but now it's just a hex-encode to avoid xmlsec dependency. static char DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; string tohash=getId(); tohash+=getString("entityID").second; @@ -1503,8 +1506,12 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o } } if (!m_requestMapper) { - log.fatal("can't build RequestMapper, missing conf:RequestMapper element?"); - throw ConfigurationException("Can't build RequestMapper, missing conf:RequestMapper element?"); + log.info("no RequestMapper specified, using 'Native' plugin with empty/default map"); + child = e->getOwnerDocument()->createElementNS(nullptr, _RequestMapper); + DOMElement* mapperDummy = e->getOwnerDocument()->createElementNS(shibspconstants::SHIB2SPCONFIG_NS, RequestMap); + mapperDummy->setAttributeNS(nullptr, applicationId, _default); + child->appendChild(mapperDummy); + m_requestMapper = conf.RequestMapperManager.newPlugin(NATIVE_REQUEST_MAPPER, child); } } @@ -1564,7 +1571,7 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o } #endif - // Load the default application. This actually has a fixed ID of "default". ;-) + // Load the default application. child = XMLHelper::getLastChildElement(e, ApplicationDefaults); if (!child) { log.fatal("can't build default Application object, missing conf:ApplicationDefaults element?"); diff --git a/shibsp/util/DOMPropertySet.cpp b/shibsp/util/DOMPropertySet.cpp index 12155fc..2c7f64b 100644 --- a/shibsp/util/DOMPropertySet.cpp +++ b/shibsp/util/DOMPropertySet.cpp @@ -255,3 +255,21 @@ const PropertySet* DOMPropertySet::getPropertySet(const char* name, const char* return (i!=m_nested.end()) ? i->second : (m_parent ? m_parent->getPropertySet(name,ns) : nullptr); } + +bool DOMPropertySet::setProperty(const char* name, const char* val, const char* ns) +{ + string propname = ns ? (string("{") + ns + "}" + name) : name; + + // Erase existing property. + if (m_map.count(propname) > 0) { + XMLString::release(&m_map[propname].first); + m_map.erase(propname); + } + + char* dup = XMLString::replicate(val); + auto_ptr_XMLCh widedup(val); + m_injected.push_back(widedup.get()); + m_map[propname] = make_pair(dup, m_injected.back().c_str()); + + return true; +} diff --git a/shibsp/util/DOMPropertySet.h b/shibsp/util/DOMPropertySet.h index 24e11fc..8d41e14 100644 --- a/shibsp/util/DOMPropertySet.h +++ b/shibsp/util/DOMPropertySet.h @@ -65,11 +65,23 @@ namespace shibsp { const std::map* remapper=nullptr ); + protected: + /** + * Post-load injection of a property, for use by subclasses. + * + * @param name property name + * @param val property value + * @param ns property namespace + * @return true iff the property was successfully set + */ + bool setProperty(const char* name, const char* val, const char* ns=nullptr); + private: const PropertySet* m_parent; const xercesc::DOMElement* m_root; std::map > m_map; std::map m_nested; + std::vector m_injected; }; };