Boost changes
[shibboleth/cpp-opensaml.git] / saml / saml2 / metadata / impl / BlacklistMetadataFilter.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  * BlacklistMetadataFilter.cpp
23  * 
24  * Removes blacklisted entities from a metadata instance
25  */
26
27 #include "internal.h"
28 #include "saml2/metadata/Metadata.h"
29 #include "saml2/metadata/MetadataFilter.h"
30
31 #include <xmltooling/logging.h>
32 #include <xmltooling/util/NDC.h>
33
34 using namespace opensaml::saml2md;
35 using namespace xmltooling::logging;
36 using namespace xmltooling;
37 using namespace std;
38
39 namespace opensaml {
40     namespace saml2md {
41                 
42         class SAML_DLLLOCAL BlacklistMetadataFilter : public MetadataFilter
43         {
44         public:
45             BlacklistMetadataFilter(const DOMElement* e);
46             ~BlacklistMetadataFilter() {}
47             
48             const char* getId() const { return BLACKLIST_METADATA_FILTER; }
49             void doFilter(XMLObject& xmlObject) const;
50
51         private:
52             void doFilter(EntitiesDescriptor& entities) const;
53             
54             bool found(const XMLCh* id) const {
55                 if (!id)
56                     return false;
57                 return m_set.count(id)==1;
58             }
59
60             set<xstring> m_set;
61         }; 
62
63         MetadataFilter* SAML_DLLLOCAL BlacklistMetadataFilterFactory(const DOMElement* const & e)
64         {
65             return new BlacklistMetadataFilter(e);
66         }
67
68     };
69 };
70
71 static const XMLCh Exclude[] =  UNICODE_LITERAL_7(E,x,c,l,u,d,e);
72
73 BlacklistMetadataFilter::BlacklistMetadataFilter(const DOMElement* e)
74 {
75     e = XMLHelper::getFirstChildElement(e);
76     while (e) {
77         if (XMLString::equals(e->getLocalName(), Exclude) && e->hasChildNodes()) {
78             m_set.insert(e->getFirstChild()->getTextContent());
79         }
80         e = XMLHelper::getNextSiblingElement(e);
81     }
82 }
83
84 void BlacklistMetadataFilter::doFilter(XMLObject& xmlObject) const
85 {
86 #ifdef _DEBUG
87     NDC ndc("doFilter");
88 #endif
89     
90     try {
91         EntitiesDescriptor& entities = dynamic_cast<EntitiesDescriptor&>(xmlObject);
92         if (found(entities.getName()))
93             throw MetadataFilterException("BlacklistMetadataFilter instructed to filter the root/only group in the metadata.");
94         doFilter(entities);
95         return;
96     }
97     catch (bad_cast&) {
98     }
99
100     try {
101         EntityDescriptor& entity = dynamic_cast<EntityDescriptor&>(xmlObject);
102         if (found(entity.getEntityID()))
103             throw MetadataFilterException("BlacklistMetadataFilter instructed to filter the root/only entity in the metadata.");
104         return;
105     }
106     catch (bad_cast&) {
107     }
108      
109     throw MetadataFilterException("BlacklistMetadataFilter was given an improper metadata instance to filter.");
110 }
111
112 void BlacklistMetadataFilter::doFilter(EntitiesDescriptor& entities) const
113 {
114     Category& log=Category::getInstance(SAML_LOGCAT".MetadataFilter.Blacklist");
115     
116     VectorOf(EntityDescriptor) v=entities.getEntityDescriptors();
117     for (VectorOf(EntityDescriptor)::size_type i=0; i<v.size(); ) {
118         const XMLCh* id=v[i]->getEntityID();
119         if (found(id)) {
120             auto_ptr_char id2(id);
121             log.info("filtering out blacklisted entity (%s)", id2.get());
122             v.erase(v.begin() + i);
123         }
124         else {
125             i++;
126         }
127     }
128     
129     VectorOf(EntitiesDescriptor) w=entities.getEntitiesDescriptors();
130     for (VectorOf(EntitiesDescriptor)::size_type j=0; j<w.size(); ) {
131         const XMLCh* name=w[j]->getName();
132         if (found(name)) {
133             auto_ptr_char name2(name);
134             log.info("filtering out blacklisted group (%s)", name2.get());
135             w.erase(w.begin() + j);
136         }
137         else {
138             doFilter(*(w[j]));
139             j++;
140         }
141     }
142 }