X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=shibsp%2Fattribute%2Fresolver%2Fimpl%2FChainingAttributeResolver.cpp;h=d4227f9a977a6d6c6cc56ffad121084c4a5f5e62;hb=c51bfd77603cf0ddb0b5e374c35586a8435895d6;hp=f2ef8373e08aad32a52e25caae1145c47a9ee17d;hpb=85fe3cf344513c8a1e11dfdff63d602af82d35d3;p=shibboleth%2Fcpp-sp.git diff --git a/shibsp/attribute/resolver/impl/ChainingAttributeResolver.cpp b/shibsp/attribute/resolver/impl/ChainingAttributeResolver.cpp index f2ef837..d4227f9 100644 --- a/shibsp/attribute/resolver/impl/ChainingAttributeResolver.cpp +++ b/shibsp/attribute/resolver/impl/ChainingAttributeResolver.cpp @@ -1,134 +1,247 @@ -/* - * 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 #include using namespace shibsp; using namespace opensaml::saml2; using namespace opensaml::saml2md; using namespace xmltooling; -using namespace log4cpp; +using namespace boost; using namespace std; namespace shibsp { struct SHIBSP_DLLLOCAL ChainingContext : public ResolutionContext { + ChainingContext( + 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 + ) : 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_request(nullptr), m_issuer(nullptr), m_protocol(nullptr), m_nameid(nullptr), + m_authclass(nullptr), m_authdecl(nullptr), m_session(&session) { + } + ~ChainingContext() { - for_each(m_contexts.begin(), m_contexts.end(), xmltooling::cleanup()); - for_each(m_attributes.begin(), m_attributes.end(), cleanup_pair()); - for_each(m_assertions.begin(), m_assertions.end(), xmltooling::cleanup()); + for_each(m_ownedAttributes.begin(), m_ownedAttributes.end(), xmltooling::cleanup()); + for_each(m_ownedAssertions.begin(), m_ownedAssertions.end(), xmltooling::cleanup()); } - multimap& getResolvedAttributes() { - return m_attributes; + vector& getResolvedAttributes() { + return m_ownedAttributes; } vector& getResolvedAssertions() { - return m_assertions; + return m_ownedAssertions; } - vector m_contexts; - multimap m_attributes; - vector m_assertions; + vector m_ownedAttributes; + vector m_ownedAssertions; + + const Application& m_app; + const GenericRequest* m_request; + const EntityDescriptor* m_issuer; + const XMLCh* m_protocol; + const NameID* m_nameid; + const XMLCh* m_authclass; + const XMLCh* m_authdecl; + vector m_tokens; + vector m_attributes; + + const Session* m_session; }; class SHIBSP_DLLLOCAL ChainingAttributeResolver : public AttributeResolver { public: ChainingAttributeResolver(const DOMElement* e); - virtual ~ChainingAttributeResolver() { - for_each(m_resolvers.begin(), m_resolvers.end(), xmltooling::cleanup()); - } - + virtual ~ChainingAttributeResolver() {} + Lockable* lock() { - for_each(m_resolvers.begin(), m_resolvers.end(), mem_fun(&AttributeResolver::lock)); return this; } void unlock() { - for_each(m_resolvers.begin(), m_resolvers.end(), mem_fun(&AttributeResolver::unlock)); } - + ResolutionContext* createResolutionContext( const Application& application, const EntityDescriptor* issuer, - const NameID* nameid, - const char* authncontext_class=NULL, - const char* authncontext_decl=NULL, - const vector* tokens=NULL, - const multimap* attributes=NULL + 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 { - auto_ptr chain(new ChainingContext()); - for (vector::const_iterator i=m_resolvers.begin(); i!=m_resolvers.end(); ++i) - chain->m_contexts.push_back( - (*i)->createResolutionContext(application, issuer, nameid, authncontext_class, authncontext_decl, tokens, attributes) - ); - return chain.release(); + // 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, request, issuer, protocol, nameid, authncontext_class, authncontext_decl, tokens, attributes); } ResolutionContext* createResolutionContext(const Application& application, const Session& session) const { - auto_ptr chain(new ChainingContext()); - for (vector::const_iterator i=m_resolvers.begin(); i!=m_resolvers.end(); ++i) - chain->m_contexts.push_back((*i)->createResolutionContext(application, session)); - return chain.release(); + return new ChainingContext(application, session); } void resolveAttributes(ResolutionContext& ctx) const; + void getAttributeIds(vector& attributes) const { + 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() ); } @@ -140,12 +253,31 @@ ChainingAttributeResolver::ChainingAttributeResolver(const DOMElement* e) void ChainingAttributeResolver::resolveAttributes(ResolutionContext& ctx) const { ChainingContext& chain = dynamic_cast(ctx); - vector::iterator ictx = chain.m_contexts.begin(); - for (vector::const_iterator i=m_resolvers.begin(); i!=m_resolvers.end(); ++i, ++ictx) { - (*i)->resolveAttributes(*(*ictx)); - chain.getResolvedAttributes().insert((*ictx)->getResolvedAttributes().begin(), (*ictx)->getResolvedAttributes().end()); - (*ictx)->getResolvedAttributes().clear(); - chain.getResolvedAssertions().insert(chain.getResolvedAssertions().end(), (*ictx)->getResolvedAssertions().begin(), (*ictx)->getResolvedAssertions().end()); - (*ictx)->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() + ); + } } }