// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jdisc.http.ssl.impl;

import com.yahoo.component.AbstractComponent;
import com.yahoo.jdisc.http.ssl.SslContextFactoryProvider;
import com.yahoo.security.tls.ConfigFileBasedTlsContext;
import com.yahoo.security.tls.TlsContext;
import com.yahoo.security.tls.TransportSecurityUtils;
import org.eclipse.jetty.util.ssl.SslContextFactory;

/**
 * The default implementation of {@link SslContextFactoryProvider} to be injected into connectors without explicit ssl configuration
 *
 * @author bjorncs
 */
public class DefaultSslContextFactoryProvider extends AbstractComponent implements SslContextFactoryProvider {

    private final SslContextFactoryProvider instance = TransportSecurityUtils.getConfigFile()
            .map(configFile -> (SslContextFactoryProvider) new StaticTlsContextBasedProvider(
                    new ConfigFileBasedTlsContext(configFile, TransportSecurityUtils.getInsecureAuthorizationMode())))
            .orElseGet(ThrowingSslContextFactoryProvider::new);

    @Override
    public SslContextFactory getInstance(String containerId, int port) {
        return instance.getInstance(containerId, port);
    }

    @Override
    public void deconstruct() {
        instance.close();
    }

    private static class ThrowingSslContextFactoryProvider implements SslContextFactoryProvider {
        @Override
        public SslContextFactory getInstance(String containerId, int port) {
            throw new UnsupportedOperationException();
        }
    }

    private static class StaticTlsContextBasedProvider extends TlsContextBasedProvider {
        final TlsContext tlsContext;

        StaticTlsContextBasedProvider(TlsContext tlsContext) {
            this.tlsContext = tlsContext;
        }

        @Override
        protected TlsContext getTlsContext(String containerId, int port) {
            return tlsContext;
        }
    }
}
@@ -167,41 +167,119 @@
 com.
-yahoo.component.AbstractComponent
+google.inject.Inject;%0Aimport com.yahoo.component.AbstractComponent;%0Aimport com.yahoo.jdisc.http.ConnectorConfig
 ;%0Aim
@@ -384,32 +384,82 @@
 asedTlsContext;%0A
+import com.yahoo.security.tls.PeerAuthentication;%0A
 import com.yahoo
@@ -592,16 +592,44 @@
 ctory;%0A%0A
+import java.nio.file.Path;%0A%0A
 /**%0A * T
@@ -756,16 +756,17 @@
 guration
+.
 %0A *%0A * @
@@ -948,16 +948,131 @@
 instance
+;%0A%0A    @Inject%0A    public DefaultSslContextFactoryProvider(ConnectorConfig connectorConfig) %7B%0A        this.instance
  = Trans
@@ -1117,16 +1117,20 @@
         
+   
+ 
 .map(con
@@ -1144,75 +1144,320 @@
  -%3E 
-(SslContextFactoryProvider) new StaticTlsContextBasedProvider(%0A    
+createTlsContextBasedProvider(connectorConfig, configFile))%0A                .orElseGet(ThrowingSslContextFactoryProvider::new);%0A    %7D%0A%0A    private static SslContextFactoryProvider createTlsContextBasedProvider(ConnectorConfig connectorConfig, Path configFile) %7B%0A        return new StaticTlsContextBasedProvider(%0A
     
@@ -1498,16 +1498,41 @@
 Context(
+%0A                        
 configFi
@@ -1592,75 +1592,552 @@
 de()
+, getPeerAuthenticationMode(connectorConfig
 )))
+;
 %0A    
+%7D%0A%0A
     
-    .orElseGet(ThrowingSslContextFactoryProvider::new);
+/**%0A     * Allows white-listing of user provided uri paths.%0A     * JDisc will delegate the enforcement of peer authentication from the TLS to the HTTP layer if %7B@link ConnectorConfig.TlsClientAuthEnforcer#enable()%7D is true.%0A     */%0A    private static PeerAuthentication getPeerAuthenticationMode(ConnectorConfig connectorConfig) %7B%0A        return connectorConfig.tlsClientAuthEnforcer().enable()%0A                ? PeerAuthentication.WANT%0A                : PeerAuthentication.NEED;%0A    %7D
 %0A%0A  

Allow whitelisting of uri paths in combination with implicit ssl connector