X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-sp.git;a=blobdiff_plain;f=shibsp%2Fattribute%2Fresolver%2Fimpl%2FChainingAttributeResolver.cpp;h=39ee3747cf7a625b932582cbfbbe148c69573cae;hp=e819e90ad4b9c37680ab61981f1d944be2db4d0a;hb=f0cab28136e0758f7bf7c60581d714f5f5dbbf08;hpb=4df1b856e188b7853ea8f5c7f100e73765e6cba4 diff --git a/shibsp/attribute/resolver/impl/ChainingAttributeResolver.cpp b/shibsp/attribute/resolver/impl/ChainingAttributeResolver.cpp index e819e90..39ee374 100644 --- a/shibsp/attribute/resolver/impl/ChainingAttributeResolver.cpp +++ b/shibsp/attribute/resolver/impl/ChainingAttributeResolver.cpp @@ -1,39 +1,47 @@ -/* - * Copyright 2001-2007 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/** + * Licensed to the University Corporation for Advanced Internet + * Development, Inc. (UCAID) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * UCAID licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the + * License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. */ /** * ChainingAttributeResolver.cpp - * + * * Chains together multiple AttributeResolver plugins. */ #include "internal.h" +#include "exceptions.h" #include "Application.h" #include "ServiceProvider.h" #include "attribute/Attribute.h" #include "attribute/resolver/AttributeResolver.h" #include "attribute/resolver/ResolutionContext.h" +#include #include +#include #include using namespace shibsp; using namespace opensaml::saml2; using namespace opensaml::saml2md; using namespace xmltooling; +using namespace boost; using namespace std; namespace shibsp { @@ -42,6 +50,7 @@ namespace shibsp { { ChainingContext( const Application& application, + const GenericRequest* request, const EntityDescriptor* issuer, const XMLCh* protocol, const NameID* nameid, @@ -49,14 +58,17 @@ namespace shibsp { const XMLCh* authncontext_decl, const vector* tokens, const vector* attributes - ) : m_app(application), m_issuer(issuer), m_protocol(protocol), m_authclass(authncontext_class), m_authdecl(authncontext_decl), m_session(NULL) { + ) : m_app(application), m_request(request), m_issuer(issuer), m_protocol(protocol), m_nameid(nameid), + m_authclass(authncontext_class), m_authdecl(authncontext_decl), m_session(nullptr) { if (tokens) m_tokens.assign(tokens->begin(), tokens->end()); if (attributes) m_attributes.assign(attributes->begin(), attributes->end()); } - ChainingContext(const Application& application, const Session& session) : m_app(application), m_session(&session) { + ChainingContext(const Application& application, const Session& session) + : m_app(application), m_request(nullptr), m_issuer(nullptr), m_protocol(nullptr), m_nameid(nullptr), + m_authclass(nullptr), m_authdecl(nullptr), m_session(&session) { } ~ChainingContext() { @@ -75,6 +87,7 @@ namespace shibsp { vector m_ownedAssertions; const Application& m_app; + const GenericRequest* m_request; const EntityDescriptor* m_issuer; const XMLCh* m_protocol; const NameID* m_nameid; @@ -90,10 +103,8 @@ namespace shibsp { { public: ChainingAttributeResolver(const DOMElement* e); - virtual ~ChainingAttributeResolver() { - for_each(m_resolvers.begin(), m_resolvers.end(), xmltooling::cleanup()); - } - + virtual ~ChainingAttributeResolver() {} + Lockable* lock() { return this; } @@ -104,13 +115,28 @@ namespace shibsp { const Application& application, const EntityDescriptor* issuer, const XMLCh* protocol, - const NameID* nameid, - const XMLCh* authncontext_class=NULL, - const XMLCh* authncontext_decl=NULL, - const vector* tokens=NULL, - const vector* attributes=NULL + const NameID* nameid=nullptr, + const XMLCh* authncontext_class=nullptr, + const XMLCh* authncontext_decl=nullptr, + const vector* tokens=nullptr, + const vector* attributes=nullptr + ) const { + // Make sure new method gets run. + return createResolutionContext(application, nullptr, issuer, protocol, nameid, authncontext_class, authncontext_decl, tokens, attributes); + } + + ResolutionContext* createResolutionContext( + const Application& application, + const GenericRequest* request, + const EntityDescriptor* issuer, + const XMLCh* protocol, + const NameID* nameid=nullptr, + const XMLCh* authncontext_class=nullptr, + const XMLCh* authncontext_decl=nullptr, + const vector* tokens=nullptr, + const vector* attributes=nullptr ) const { - return new ChainingContext(application, issuer, protocol, nameid, authncontext_class, authncontext_decl, tokens, attributes); + return new ChainingContext(application, request, issuer, protocol, nameid, authncontext_class, authncontext_decl, tokens, attributes); } ResolutionContext* createResolutionContext(const Application& application, const Session& session) const { @@ -120,39 +146,102 @@ namespace shibsp { void resolveAttributes(ResolutionContext& ctx) const; void getAttributeIds(vector& attributes) const { - for (vector::const_iterator i=m_resolvers.begin(); i!=m_resolvers.end(); ++i) { - Locker locker(*i); - (*i)->getAttributeIds(attributes); + for (ptr_vector::iterator i = m_resolvers.begin(); i != m_resolvers.end(); ++i) { + Locker locker(&(*i)); + i->getAttributeIds(attributes); } } - + private: - vector m_resolvers; + mutable ptr_vector m_resolvers; }; static const XMLCh _AttributeResolver[] = UNICODE_LITERAL_17(A,t,t,r,i,b,u,t,e,R,e,s,o,l,v,e,r); static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e); - AttributeResolver* SHIBSP_DLLLOCAL ChainingAttributeResolverFactory(const DOMElement* & e) + SHIBSP_DLLLOCAL PluginManager::Factory QueryResolverFactory; + SHIBSP_DLLLOCAL PluginManager::Factory SimpleAggregationResolverFactory; + + AttributeResolver* SHIBSP_DLLLOCAL ChainingResolverFactory(const DOMElement* const & e) { return new ChainingAttributeResolver(e); } }; +void SHIBSP_API shibsp::registerAttributeResolvers() +{ + SPConfig::getConfig().AttributeResolverManager.registerFactory(QUERY_ATTRIBUTE_RESOLVER, QueryResolverFactory); + SPConfig::getConfig().AttributeResolverManager.registerFactory(SIMPLEAGGREGATION_ATTRIBUTE_RESOLVER, SimpleAggregationResolverFactory); + SPConfig::getConfig().AttributeResolverManager.registerFactory(CHAINING_ATTRIBUTE_RESOLVER, ChainingResolverFactory); +} + +ResolutionContext::ResolutionContext() +{ +} + +ResolutionContext::~ResolutionContext() +{ +} + +AttributeResolver::AttributeResolver() +{ +} + +AttributeResolver::~AttributeResolver() +{ +} + +ResolutionContext* AttributeResolver::createResolutionContext( + const Application& application, + const GenericRequest* request, + const EntityDescriptor* issuer, + const XMLCh* protocol, + const NameID* nameid, + const XMLCh* authncontext_class, + const XMLCh* authncontext_decl, + const vector* tokens, + const vector* attributes + ) const +{ + // Default call into deprecated method. + return createResolutionContext(application, issuer, protocol, nameid, authncontext_class, authncontext_decl, tokens, attributes); +} + +ResolutionContext* AttributeResolver::createResolutionContext( + const Application& application, + const EntityDescriptor* issuer, + const XMLCh* protocol, + const NameID* nameid, + const XMLCh* authncontext_class, + const XMLCh* authncontext_decl, + const vector* tokens, + const vector* attributes + ) const +{ + // Default for deprecated method. + throw ConfigurationException("Deprecated method implementation should always be overridden."); +} + + ChainingAttributeResolver::ChainingAttributeResolver(const DOMElement* e) { SPConfig& conf = SPConfig::getConfig(); // Load up the chain of handlers. - e = e ? XMLHelper::getFirstChildElement(e, _AttributeResolver) : NULL; + e = XMLHelper::getFirstChildElement(e, _AttributeResolver); while (e) { - auto_ptr_char type(e->getAttributeNS(NULL,_type)); - if (type.get() && *(type.get())) { + string t(XMLHelper::getAttrString(e, nullptr, _type)); + if (!t.empty()) { try { - m_resolvers.push_back(conf.AttributeResolverManager.newPlugin(type.get(),e)); + Category::getInstance(SHIBSP_LOGCAT ".AttributeResolver." CHAINING_ATTRIBUTE_RESOLVER).info( + "building AttributeResolver of type (%s)...", t.c_str() + ); + auto_ptr np(conf.AttributeResolverManager.newPlugin(t.c_str(), e)); + m_resolvers.push_back(np.get()); + np.release(); } catch (exception& ex) { - Category::getInstance(SHIBSP_LOGCAT".AttributeResolver").error( + Category::getInstance(SHIBSP_LOGCAT ".AttributeResolver." CHAINING_ATTRIBUTE_RESOLVER).error( "caught exception processing embedded AttributeResolver element: %s", ex.what() ); } @@ -164,24 +253,31 @@ ChainingAttributeResolver::ChainingAttributeResolver(const DOMElement* e) void ChainingAttributeResolver::resolveAttributes(ResolutionContext& ctx) const { ChainingContext& chain = dynamic_cast(ctx); - for (vector::const_iterator i=m_resolvers.begin(); i!=m_resolvers.end(); ++i) { - Locker locker(*i); - auto_ptr context( - chain.m_session ? - (*i)->createResolutionContext(chain.m_app, *chain.m_session) : - (*i)->createResolutionContext( - chain.m_app, chain.m_issuer, chain.m_protocol, chain.m_nameid, chain.m_authclass, chain.m_authdecl, &chain.m_tokens, &chain.m_attributes - ) - ); - - (*i)->resolveAttributes(*context.get()); - - chain.m_attributes.insert(chain.m_attributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end()); - chain.m_ownedAttributes.insert(chain.m_attributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end()); - context->getResolvedAttributes().clear(); - - chain.m_tokens.insert(chain.m_tokens.end(), context->getResolvedAssertions().begin(), context->getResolvedAssertions().end()); - chain.m_ownedAssertions.insert(chain.m_ownedAssertions.end(), context->getResolvedAssertions().begin(), context->getResolvedAssertions().end()); - context->getResolvedAssertions().clear(); + for (ptr_vector::iterator i = m_resolvers.begin(); i != m_resolvers.end(); ++i) { + try { + Locker locker(&(*i)); + scoped_ptr context( + chain.m_session ? + i->createResolutionContext(chain.m_app, *chain.m_session) : + i->createResolutionContext( + chain.m_app, chain.m_request, chain.m_issuer, chain.m_protocol, chain.m_nameid, chain.m_authclass, chain.m_authdecl, &chain.m_tokens, &chain.m_attributes + ) + ); + + i->resolveAttributes(*context); + + chain.m_attributes.insert(chain.m_attributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end()); + chain.m_ownedAttributes.insert(chain.m_ownedAttributes.end(), context->getResolvedAttributes().begin(), context->getResolvedAttributes().end()); + context->getResolvedAttributes().clear(); + + chain.m_tokens.insert(chain.m_tokens.end(), context->getResolvedAssertions().begin(), context->getResolvedAssertions().end()); + chain.m_ownedAssertions.insert(chain.m_ownedAssertions.end(), context->getResolvedAssertions().begin(), context->getResolvedAssertions().end()); + context->getResolvedAssertions().clear(); + } + catch (exception& ex) { + Category::getInstance(SHIBSP_LOGCAT ".AttributeResolver." CHAINING_ATTRIBUTE_RESOLVER).error( + "caught exception applying AttributeResolver in chain: %s", ex.what() + ); + } } }