1 /*
2  * Zed Attack Proxy (ZAP) and its related class files.
3  *
4  * ZAP is an HTTP/HTTPS proxy for assessing web application security.
5  *
6  * Copyright 2019 The ZAP Development Team
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 package org.zaproxy.zap.extension.ascan.filters.impl;
21 
22 import java.util.Collection;
23 import java.util.LinkedHashSet;
24 import java.util.Objects;
25 import java.util.Set;
26 import java.util.function.BiPredicate;
27 import org.parosproxy.paros.Constant;
28 import org.zaproxy.zap.extension.ascan.filters.FilterCriteria;
29 import org.zaproxy.zap.extension.ascan.filters.FilterResult;
30 import org.zaproxy.zap.extension.ascan.filters.ScanFilter;
31 
32 /**
33  * Abstract ScanFilter for handling generic filter usecases.
34  *
35  * @author KSASAN preetkaran20@gmail.com
36  * @since 2.9.0
37  */
38 public abstract class AbstractGenericScanFilter<T, V> implements ScanFilter {
39 
40     public static final String INCLUDE_FILTER_CRITERIA_MESSAGE_KEY =
41             "scan.filter.filtercriteria.include";
42     public static final String EXCLUDE_FILTER_CRITERIA_MESSAGE_KEY =
43             "scan.filter.filtercriteria.exclude";
44 
45     private final BiPredicate<Collection<T>, V> matcher;
46 
47     private FilterCriteria filterCriteria = FilterCriteria.INCLUDE;
48 
49     private Collection<T> filterData = new LinkedHashSet<>();
50 
AbstractGenericScanFilter()51     public AbstractGenericScanFilter() {
52         this((filterData, value) -> filterData.contains((Object) value));
53     }
54 
AbstractGenericScanFilter(BiPredicate<Collection<T>, V> matcher)55     public AbstractGenericScanFilter(BiPredicate<Collection<T>, V> matcher) {
56         this.matcher = matcher;
57     }
58 
getFilterType()59     public abstract String getFilterType();
60 
getFilterCriteria()61     public FilterCriteria getFilterCriteria() {
62         return filterCriteria;
63     }
64 
setFilterCriteria(FilterCriteria filterCriteria)65     public void setFilterCriteria(FilterCriteria filterCriteria) {
66         Objects.requireNonNull(filterCriteria);
67         this.filterCriteria = filterCriteria;
68     }
69 
getFilterData()70     public Collection<T> getFilterData() {
71         return filterData;
72     }
73 
setFilterData(Collection<T> filterData)74     public void setFilterData(Collection<T> filterData) {
75         Objects.requireNonNull(filterData);
76         this.filterData = filterData;
77     }
78 
isFiltered(Collection<V> values)79     protected FilterResult isFiltered(Collection<V> values) {
80         Objects.requireNonNull(values);
81 
82         if (filterData.isEmpty()) {
83             return FilterResult.NOT_FILTERED;
84         }
85 
86         FilterCriteria filterCriteria = this.getFilterCriteria();
87         switch (filterCriteria) {
88             case INCLUDE:
89                 if (values.stream().anyMatch(value -> matcher.test(filterData, value))) {
90                     return FilterResult.NOT_FILTERED;
91                 }
92 
93                 return new FilterResult(
94                         Constant.messages.getString(
95                                 INCLUDE_FILTER_CRITERIA_MESSAGE_KEY,
96                                 this.getFilterType(),
97                                 filterData));
98             case EXCLUDE:
99                 for (V value : values) {
100                     if (matcher.test(filterData, value)) {
101                         return new FilterResult(
102                                 Constant.messages.getString(
103                                         EXCLUDE_FILTER_CRITERIA_MESSAGE_KEY,
104                                         this.getFilterType(),
105                                         "[" + value + "]"));
106                     }
107                 }
108                 return FilterResult.NOT_FILTERED;
109             default:
110                 return FilterResult.NOT_FILTERED;
111         }
112     }
113 
isFiltered(V value)114     protected FilterResult isFiltered(V value) {
115         Objects.requireNonNull(value);
116         Set<V> nodeValues = new LinkedHashSet<>();
117         nodeValues.add(value);
118         return this.isFiltered(nodeValues);
119     }
120 }
121