package au.gov.dto.dibp.appointments.config;

import au.gov.dto.dibp.appointments.initializer.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.servlet.http.HttpSessionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Configuration
@ComponentScan(basePackages = "au.gov.dto.dibp.appointments")
public class AppConfig {
    private static final Logger LOG = LoggerFactory.getLogger(AppConfig.class);

    @Bean
    public ServletContextInitializer noSessionTrackingServletContextInitializer() {
        return servletContext -> servletContext.setSessionTrackingModes(Collections.emptySet());
    }

    @Bean
    @Order(1)
    public FilterRegistrationBean dosFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        DoSFilter dosFilter = new DoSFilter();
        registration.setFilter(dosFilter);
        registration.addInitParameter("enabled", "true");
        registration.addInitParameter("insertHeaders", "false");
        registration.addInitParameter("ipWhitelist", getIpWhitelist());
        registration.addInitParameter("managedAttr", "true");  // allow filter to be managed via JMX
        registration.addInitParameter("remotePort", "false");
        registration.addInitParameter("trackSessions", "false");
        registration.addUrlPatterns("/*");
        return registration;
    }

    private String getIpWhitelist() {
        List<String> ipWhitelist = new ArrayList<>();
        String ipAddressOrCidrRange;
        for (int i = 1; StringUtils.isNotBlank(ipAddressOrCidrRange = System.getenv("IP_WHITELIST_" + i)); i++) {
            LOG.info("Adding IP address or range=[{}] to DoSFilter whitelist", ipAddressOrCidrRange);
            ipWhitelist.add(ipAddressOrCidrRange);
        }
        String[] ipWhitelistArray = ipWhitelist.toArray(new String[ipWhitelist.size()]);
        return String.join(",", ipWhitelistArray);
    }

    @Bean
    @Order(2)
    public FilterRegistrationBean httpsFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new HttpsOnlyFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }

    @Bean
    @Order(3)
    public FilterRegistrationBean logClientIdFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new LogClientIdFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }

    @Bean
    @Order(4)
    public FilterRegistrationBean reuqestLoggingFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new RequestLoggingFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }

    @Bean
    public FilterRegistrationBean noHttpSessionFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new NoHttpSessionFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }

    @Bean
    public ServletListenerRegistrationBean<HttpSessionListener> sessionCreatedListener() {
        ServletListenerRegistrationBean<HttpSessionListener> listenerRegistrationBean = new ServletListenerRegistrationBean<>();
        listenerRegistrationBean.setListener(new HttpSessionCreatedListener());
        return listenerRegistrationBean;
    }
}

@@ -91,111 +91,662 @@
 zer.
-*;%0Aimport org.apache.commons.lang3.StringUtils;%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory
+DoSFilter;%0Aimport au.gov.dto.dibp.appointments.initializer.HttpsOnlyFilter;%0Aimport au.gov.dto.dibp.appointments.initializer.LogClientIdFilter;%0Aimport au.gov.dto.dibp.appointments.initializer.NoHttpSessionFilter;%0Aimport au.gov.dto.dibp.appointments.initializer.RequestLoggingFilter;%0Aimport org.apache.commons.lang3.StringUtils;%0Aimport org.eclipse.jetty.server.Connector;%0Aimport org.eclipse.jetty.server.HttpConnectionFactory;%0Aimport org.eclipse.jetty.server.Server;%0Aimport org.eclipse.jetty.server.ServerConnector;%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0Aimport org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer
 ;%0Aim
@@ -966,32 +966,203 @@
 gistrationBean;%0A
+import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;%0Aimport org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;%0A
 import org.sprin
@@ -1872,32 +1872,942 @@
 ySet());%0A    %7D%0A%0A
+    @Bean%0A    public EmbeddedServletContainerCustomizer disableServerHeader() %7B%0A        return container -%3E %7B%0A            if (container instanceof JettyEmbeddedServletContainerFactory) %7B%0A                ((JettyEmbeddedServletContainerFactory) container).addServerCustomizers(new JettyServerCustomizer() %7B%0A                    @Override%0A                    public void customize(Server server) %7B%0A                        for (Connector connector : server.getConnectors()) %7B%0A                            if (connector instanceof ServerConnector) %7B%0A                                HttpConnectionFactory connectionFactory = connector.getConnectionFactory(HttpConnectionFactory.class);%0A                                connectionFactory.getHttpConfiguration().setSendServerVersion(false);%0A                            %7D%0A                        %7D%0A                    %7D%0A                %7D);%0A            %7D%0A        %7D;%0A    %7D%0A%0A
     @Bean%0A    @O

Disable Server header