1e41c3765bdf362e63a90870faf2ce8f86f809a5
[shibboleth/cpp-sp.git] / shibsp / attribute / resolver / impl / AuthnAuthorityAttributeExtractor.cpp
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * DelegationAttributeExtractor.cpp
23  *
24  * AttributeExtractor for DelegationRestriction information.
25  */
26
27 #include "internal.h"
28 #include "Application.h"
29 #include "ServiceProvider.h"
30 #include "attribute/SimpleAttribute.h"
31 #include "attribute/resolver/AttributeExtractor.h"
32
33 #include <saml/saml2/core/Assertions.h>
34 #include <saml/saml2/metadata/Metadata.h>
35 #include <xmltooling/util/XMLHelper.h>
36 #include <xercesc/util/XMLUniDefs.hpp>
37
38 using namespace shibsp;
39 using namespace opensaml::saml2;
40 using namespace opensaml::saml2md;
41 using namespace opensaml;
42 using namespace xmltooling;
43 using namespace std;
44
45 namespace shibsp {
46
47 #if defined (_MSC_VER)
48     #pragma warning( push )
49     #pragma warning( disable : 4250 )
50 #endif
51
52     class AuthnAuthorityExtractor : public AttributeExtractor
53     {
54     public:
55         AuthnAuthorityExtractor(const DOMElement* e);
56         ~AuthnAuthorityExtractor() {}
57
58         Lockable* lock() {
59             return this;
60         }
61
62         void unlock() {
63         }
64
65         void extractAttributes(
66             const Application& application,
67             const RoleDescriptor* issuer,
68             const XMLObject& xmlObject,
69             vector<shibsp::Attribute*>& attributes
70             ) const;
71
72         void getAttributeIds(std::vector<std::string>& attributes) const {
73             attributes.push_back(m_attributeId);
74         }
75
76     private:
77         string m_attributeId;
78     };
79
80 #if defined (_MSC_VER)
81     #pragma warning( pop )
82 #endif
83
84     AttributeExtractor* SHIBSP_DLLLOCAL AuthnAuthorityAttributeExtractorFactory(const DOMElement* const & e)
85     {
86         return new AuthnAuthorityExtractor(e);
87     }
88
89     static const XMLCh attributeId[] =  UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,d);
90 };
91
92 AuthnAuthorityExtractor::AuthnAuthorityExtractor(const DOMElement* e)
93     : m_attributeId(XMLHelper::getAttrString(e, "AuthenticatingAuthority", attributeId))
94 {
95 }
96
97 void AuthnAuthorityExtractor::extractAttributes(
98     const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<shibsp::Attribute*>& attributes
99     ) const
100 {
101     const saml2::Assertion* assertion = dynamic_cast<const saml2::Assertion*>(&xmlObject);
102     if (!assertion || assertion->getAuthnStatements().empty())
103         return;
104
105     auto_ptr<SimpleAttribute> attr(new SimpleAttribute(vector<string>(1,m_attributeId)));
106
107     const vector<AuthnStatement*>& statements = assertion->getAuthnStatements();
108     for (vector<AuthnStatement*>::const_iterator s = statements.begin(); s != statements.end(); ++s) {
109
110         if (!(*s)->getAuthnContext() || (*s)->getAuthnContext()->getAuthenticatingAuthoritys().empty())
111             continue;
112
113         const vector<AuthenticatingAuthority*>& authorities =
114             const_cast<const AuthnContext*>((*s)->getAuthnContext())->getAuthenticatingAuthoritys();
115         for (vector<AuthenticatingAuthority*>::const_iterator a = authorities.begin(); a != authorities.end(); ++a) {
116             const XMLCh* n = (*a)->getID();
117             if (n && *n) {
118                 auto_ptr_char temp(n);
119                 attr->getValues().push_back(temp.get());
120             }
121         }
122
123         if (attr->valueCount() > 0) {
124             attributes.push_back(attr.release());
125             return;
126         }
127     }
128 }