001/*
002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.http.security.pipeline;
017
018import de.cuioss.http.security.config.SecurityConfiguration;
019import de.cuioss.http.security.core.HttpSecurityValidator;
020import de.cuioss.http.security.core.ValidationType;
021import de.cuioss.http.security.monitoring.SecurityEventCounter;
022
023import java.util.Objects;
024
025/**
026 * Factory class for creating HTTP security validation pipelines.
027 *
028 * <p>This factory provides centralized creation of all HTTP security validation pipelines
029 * with consistent configuration and monitoring. It ensures proper pipeline selection
030 * based on the type of HTTP component being validated and provides convenient factory
031 * methods for common use cases.</p>
032 *
033 * <h3>Design Principles</h3>
034 * <ul>
035 *   <li><strong>Centralized Creation</strong> - Single point for pipeline instantiation</li>
036 *   <li><strong>Type Safety</strong> - Compile-time verification of pipeline types</li>
037 *   <li><strong>Configuration Consistency</strong> - Ensures all pipelines use same config</li>
038 *   <li><strong>Monitoring Integration</strong> - Unified event tracking across pipelines</li>
039 * </ul>
040 *
041 * <h3>Supported Pipeline Types</h3>
042 * <ul>
043 *   <li><strong>URL Path Validation</strong> - For URL path segments and components</li>
044 *   <li><strong>URL Parameter Validation</strong> - For query parameter values</li>
045 *   <li><strong>HTTP Header Validation</strong> - For header names and values</li>
046 * </ul>
047 *
048 * <h3>Usage Examples</h3>
049 * <pre>
050 * SecurityConfiguration config = SecurityConfiguration.defaults();
051 * SecurityEventCounter counter = new SecurityEventCounter();
052 *
053 * // Create specific pipeline types
054 * HttpSecurityValidator pathValidator = PipelineFactory.createUrlPathPipeline(config, counter);
055 * HttpSecurityValidator paramValidator = PipelineFactory.createUrlParameterPipeline(config, counter);
056 * HttpSecurityValidator headerNameValidator = PipelineFactory.createHeaderNamePipeline(config, counter);
057 * HttpSecurityValidator headerValueValidator = PipelineFactory.createHeaderValuePipeline(config, counter);
058 *
059 * // Generic factory method based on validation type
060 * HttpSecurityValidator validator = PipelineFactory.createPipeline(ValidationType.URL_PATH, config, counter);
061 * </pre>
062 *
063 * <h3>Factory Method Benefits</h3>
064 * <ul>
065 *   <li><strong>Type Safety</strong> - Prevents incorrect ValidationType for header pipelines</li>
066 *   <li><strong>Simplified API</strong> - Clear method names for common use cases</li>
067 *   <li><strong>Future Extensibility</strong> - Easy to add new pipeline types</li>
068 *   <li><strong>Configuration Validation</strong> - Ensures proper pipeline setup</li>
069 * </ul>
070 *
071 * <h3>Thread Safety</h3>
072 * <p>This factory class is stateless and thread-safe. All factory methods can be called
073 * concurrently from multiple threads. The created pipelines are also thread-safe and
074 * immutable.</p>
075 *
076 * Implements: Task P5 from HTTP verification specification
077 *
078 * @since 1.0
079 */
080public final class PipelineFactory {
081
082    /**
083     * Private constructor to prevent instantiation of utility class.
084     */
085    private PipelineFactory() {
086        // Utility class
087    }
088
089    /**
090     * Creates a URL path validation pipeline for validating URL path components.
091     *
092     * <p>This pipeline validates URL path segments for security threats including:</p>
093     * <ul>
094     *   <li>Path traversal attacks (../)</li>
095     *   <li>Directory escape attempts</li>
096     *   <li>Encoded path traversal patterns</li>
097     *   <li>Suspicious path patterns</li>
098     *   <li>Invalid URL encoding</li>
099     * </ul>
100     *
101     * @param config The security configuration to use
102     * @param eventCounter The event counter for tracking security violations
103     * @return A configured URL path validation pipeline
104     * @throws NullPointerException if config or eventCounter is null
105     */
106    public static HttpSecurityValidator createUrlPathPipeline(
107            SecurityConfiguration config, SecurityEventCounter eventCounter) {
108        return new URLPathValidationPipeline(config, eventCounter);
109    }
110
111    /**
112     * Creates a URL parameter validation pipeline for validating query parameter values.
113     *
114     * <p>This pipeline validates URL parameter values for HTTP-layer security threats including:</p>
115     * <ul>
116     *   <li>XSS attack patterns</li>
117     *   <li>Path traversal attempts</li>
118     *   <li>Invalid URL encoding</li>
119     *   <li>Parameter-based attacks</li>
120     *   <li>Character encoding attacks</li>
121     * </ul>
122     *
123     * @param config The security configuration to use
124     * @param eventCounter The event counter for tracking security violations
125     * @return A configured URL parameter validation pipeline
126     * @throws NullPointerException if config or eventCounter is null
127     */
128    public static HttpSecurityValidator createUrlParameterPipeline(
129            SecurityConfiguration config, SecurityEventCounter eventCounter) {
130        return new URLParameterValidationPipeline(config, eventCounter);
131    }
132
133    /**
134     * Creates a URL parameter name validation pipeline.
135     *
136     * <p>This pipeline validates URL parameter names (query string keys) for:</p>
137     * <ul>
138     *   <li>Invalid characters in parameter names</li>
139     *   <li>Parameter name length limits</li>
140     *   <li>Encoding and normalization issues</li>
141     *   <li>Injection attempts</li>
142     * </ul>
143     *
144     * <p>Parameter names have stricter validation than parameter values since they
145     * typically map to internal field names or database columns.</p>
146     *
147     * @param config The security configuration to use
148     * @param eventCounter The event counter for tracking security violations
149     * @return A configured URL parameter name validation pipeline
150     * @throws NullPointerException if config or eventCounter is null
151     */
152    public static HttpSecurityValidator createParameterNamePipeline(
153            SecurityConfiguration config, SecurityEventCounter eventCounter) {
154        // Parameter names use similar validation to parameter values but with stricter character requirements
155        // They typically should not contain special characters that could be used for injection
156        return new URLParameterValidationPipeline(config, eventCounter);
157    }
158
159    /**
160     * Creates an HTTP header name validation pipeline.
161     *
162     * <p>This pipeline validates HTTP header names according to RFC 7230 specifications
163     * and checks for:</p>
164     * <ul>
165     *   <li>Invalid header name characters</li>
166     *   <li>Header injection attempts</li>
167     *   <li>CRLF injection patterns</li>
168     *   <li>Suspicious header names</li>
169     * </ul>
170     *
171     * @param config The security configuration to use
172     * @param eventCounter The event counter for tracking security violations
173     * @return A configured HTTP header name validation pipeline
174     * @throws NullPointerException if config or eventCounter is null
175     */
176    public static HttpSecurityValidator createHeaderNamePipeline(
177            SecurityConfiguration config, SecurityEventCounter eventCounter) {
178        return new HTTPHeaderValidationPipeline(config, eventCounter, ValidationType.HEADER_NAME);
179    }
180
181    /**
182     * Creates an HTTP header value validation pipeline.
183     *
184     * <p>This pipeline validates HTTP header values according to RFC 7230 specifications
185     * and checks for:</p>
186     * <ul>
187     *   <li>Invalid header value characters</li>
188     *   <li>Header injection attempts</li>
189     *   <li>CRLF injection patterns</li>
190     *   <li>Malicious header content</li>
191     * </ul>
192     *
193     * @param config The security configuration to use
194     * @param eventCounter The event counter for tracking security violations
195     * @return A configured HTTP header value validation pipeline
196     * @throws NullPointerException if config or eventCounter is null
197     */
198    public static HttpSecurityValidator createHeaderValuePipeline(
199            SecurityConfiguration config, SecurityEventCounter eventCounter) {
200        return new HTTPHeaderValidationPipeline(config, eventCounter, ValidationType.HEADER_VALUE);
201    }
202
203
204    /**
205     * Generic factory method that creates the appropriate validation pipeline
206     * based on the specified validation type.
207     *
208     * <p>This method provides a unified interface for creating any type of validation
209     * pipeline. It's particularly useful when the pipeline type is determined at runtime.</p>
210     *
211     * <h3>Supported Validation Types</h3>
212     * <ul>
213     *   <li><strong>URL_PATH</strong> - Creates URLPathValidationPipeline</li>
214     *   <li><strong>PARAMETER_VALUE</strong> - Creates URLParameterValidationPipeline</li>
215     *   <li><strong>HEADER_NAME</strong> - Creates HTTPHeaderValidationPipeline for names</li>
216     *   <li><strong>HEADER_VALUE</strong> - Creates HTTPHeaderValidationPipeline for values</li>
217     * </ul>
218     *
219     * @param validationType The type of validation pipeline to create
220     * @param config The security configuration to use
221     * @param eventCounter The event counter for tracking security violations
222     * @return A configured validation pipeline of the appropriate type
223     * @throws NullPointerException if any parameter is null
224     * @throws IllegalArgumentException if validationType is not supported or invalid
225     */
226    public static HttpSecurityValidator createPipeline(
227            ValidationType validationType, SecurityConfiguration config, SecurityEventCounter eventCounter) {
228
229        Objects.requireNonNull(validationType, "ValidationType must not be null");
230        Objects.requireNonNull(config, "Config must not be null");
231        Objects.requireNonNull(eventCounter, "EventCounter must not be null");
232
233        return switch (validationType) {
234            case URL_PATH -> createUrlPathPipeline(config, eventCounter);
235            case PARAMETER_VALUE -> createUrlParameterPipeline(config, eventCounter);
236            case HEADER_NAME -> createHeaderNamePipeline(config, eventCounter);
237            case HEADER_VALUE -> createHeaderValuePipeline(config, eventCounter);
238            case PARAMETER_NAME -> createParameterNamePipeline(config, eventCounter);
239            case BODY -> throw new IllegalArgumentException(
240                    "BODY validation pipeline has been removed. HTTP body content validation should be handled at application layer.");
241            case COOKIE_NAME, COOKIE_VALUE -> throw new IllegalArgumentException(
242                    """
243                    Cookie validation pipelines are not yet implemented. \
244                    Supported types: URL_PATH, PARAMETER_VALUE, HEADER_NAME, HEADER_VALUE""");
245        };
246    }
247
248    /**
249     * Creates multiple validation pipelines for common HTTP component validation scenarios.
250     *
251     * <p>This convenience method creates a set of commonly used pipelines with shared
252     * configuration and monitoring. This is useful for applications that need to validate
253     * multiple types of HTTP components.</p>
254     *
255     * @param config The security configuration to use for all pipelines
256     * @param eventCounter The event counter for tracking security violations across all pipelines
257     * @return A {@link PipelineSet} containing commonly used validation pipelines
258     * @throws NullPointerException if config or eventCounter is null
259     */
260    public static PipelineSet createCommonPipelines(SecurityConfiguration config, SecurityEventCounter eventCounter) {
261        Objects.requireNonNull(config, "Config must not be null");
262        Objects.requireNonNull(eventCounter, "EventCounter must not be null");
263
264        return new PipelineSet(
265                createUrlPathPipeline(config, eventCounter),
266                createUrlParameterPipeline(config, eventCounter),
267                createHeaderNamePipeline(config, eventCounter),
268                createHeaderValuePipeline(config, eventCounter)
269        );
270    }
271
272    /**
273     * A record containing commonly used HTTP validation pipelines.
274     *
275     * <p>This immutable record provides convenient access to all the main pipeline types
276     * with consistent configuration and monitoring.</p>
277     *
278     * @param urlPathPipeline Pipeline for validating URL path components
279     * @param urlParameterPipeline Pipeline for validating URL parameter values
280     * @param headerNamePipeline Pipeline for validating HTTP header names
281     * @param headerValuePipeline Pipeline for validating HTTP header values
282     */
283    public record PipelineSet(
284    HttpSecurityValidator urlPathPipeline,
285    HttpSecurityValidator urlParameterPipeline,
286    HttpSecurityValidator headerNamePipeline,
287    HttpSecurityValidator headerValuePipeline
288    ) {
289        public PipelineSet {
290            Objects.requireNonNull(urlPathPipeline, "urlPathPipeline must not be null");
291            Objects.requireNonNull(urlParameterPipeline, "urlParameterPipeline must not be null");
292            Objects.requireNonNull(headerNamePipeline, "headerNamePipeline must not be null");
293            Objects.requireNonNull(headerValuePipeline, "headerValuePipeline must not be null");
294        }
295    }
296}