/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.oozie.server;


import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import org.apache.hadoop.conf.Configuration;
import org.apache.oozie.service.ConfigurationService;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Objects;

/**
 * Factory that is used to configure SSL settings for the Oozie server.
 */
class SSLServerConnectorFactory {
    private static final Logger LOG = LoggerFactory.getLogger(SSLServerConnectorFactory.class);
    public static final String OOZIE_HTTPS_KEYSTORE_PASS = "oozie.https.keystore.pass";
    public static final String OOZIE_HTTPS_KEYSTORE_FILE = "oozie.https.keystore.file";
    public static final String OOZIE_HTTPS_KEYSTORE_TYPE = "oozie.https.keystore.type";
    public static final String OOZIE_HTTPS_EXCLUDE_PROTOCOLS = "oozie.https.exclude.protocols";
    public static final String OOZIE_HTTPS_INCLUDE_PROTOCOLS = "oozie.https.include.protocols";
    public static final String OOZIE_HTTPS_INCLUDE_CIPHER_SUITES = "oozie.https.include.cipher.suites";
    public static final String OOZIE_HTTPS_EXCLUDE_CIPHER_SUITES = "oozie.https.exclude.cipher.suites";
    public static final String OOZIE_HSTS_MAX_AGE_SECONDS = "oozie.hsts.max.age.seconds";
    @VisibleForTesting
    static final long OOZIE_DEFAULT_HSTS_MAX_AGE = 31536000;

    private SslContextFactory.Server sslContextFactory;
    private Configuration conf;

    @Inject
    public SSLServerConnectorFactory(final SslContextFactory.Server sslContextFactory) {
        this.sslContextFactory = Objects.requireNonNull(sslContextFactory,  "sslContextFactory is null");
    }

    /**
     *  Construct a ServerConnector object with SSL settings
     *
     *  @param oozieHttpsPort Oozie HTTPS port
     *  @param conf Oozie configuration
     *  @param server jetty Server which the connector is attached to
     *
     *  @return ServerConnector
    */
    public ServerConnector createSecureServerConnector(int oozieHttpsPort, Configuration conf, Server server) {
        this.conf = Objects.requireNonNull(conf, "conf is null");
        Objects.requireNonNull(server, "server is null");
        Preconditions.checkState(oozieHttpsPort >= 1 && oozieHttpsPort <= 65535,
                String.format("Invalid port number specified: \'%d\'. It should be between 1 and 65535.", oozieHttpsPort));

        setIncludeProtocols();
        setExcludeProtocols();

        setIncludeCipherSuites();
        setExludeCipherSuites();

        setKeyStoreFile();
        setKeyStoreType();
        setKeystorePass();

        HttpConfiguration httpsConfiguration = getHttpsConfiguration();
        ServerConnector secureServerConnector = new ServerConnector(server,
                new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
                new HttpConnectionFactory(httpsConfiguration));

        secureServerConnector.setPort(oozieHttpsPort);

        LOG.info(String.format("Secure server connector created, listening on port %d", oozieHttpsPort));
        return secureServerConnector;
    }

    private void setExludeCipherSuites() {
        String excludeCipherList = conf.get(OOZIE_HTTPS_EXCLUDE_CIPHER_SUITES);
        String[] excludeCipherSuites = excludeCipherList.split(",");
        sslContextFactory.setExcludeCipherSuites(excludeCipherSuites);

        LOG.info(String.format("SSL context - excluding cipher suites: %s",
                Arrays.toString(excludeCipherSuites).replaceAll("[\r\n]","")));
    }

    private void setIncludeCipherSuites() {
        String includeCipherList = conf.get(OOZIE_HTTPS_INCLUDE_CIPHER_SUITES);
        if (includeCipherList == null || includeCipherList.isEmpty()) {
            return;
        }

        String[] includeCipherSuites = includeCipherList.split(",");
        sslContextFactory.setIncludeCipherSuites(includeCipherSuites);

        LOG.info(String.format("SSL context - including cipher suites: %s",
                Arrays.toString(includeCipherSuites).replaceAll("[\r\n]","")));
    }

    private void setIncludeProtocols() {
        String enabledProtocolsList = conf.get(OOZIE_HTTPS_INCLUDE_PROTOCOLS);
        String[] enabledProtocols = enabledProtocolsList.split(",");
        sslContextFactory.setIncludeProtocols(enabledProtocols);

        LOG.info(String.format("SSL context - including protocols: %s",
                Arrays.toString(enabledProtocols).replaceAll("[\r\n]","")));
    }

    private void setExcludeProtocols() {
        String excludedProtocolsList = conf.get(OOZIE_HTTPS_EXCLUDE_PROTOCOLS);
        if (excludedProtocolsList == null || excludedProtocolsList.isEmpty()) {
            return;
        }
        String[] excludedProtocols = excludedProtocolsList.split(",");
        sslContextFactory.setExcludeProtocols(excludedProtocols);
        LOG.info(String.format("SSL context - excluding protocols: %s",
                Arrays.toString(excludedProtocols).replaceAll("[\r\n]","")));
    }

    private void setKeystorePass() {
        String keystorePass = ConfigurationService.getPassword(conf, OOZIE_HTTPS_KEYSTORE_PASS);
        Objects.requireNonNull(keystorePass, "keystorePass is null");
        sslContextFactory.setKeyStorePassword(keystorePass);
    }

    private void setKeyStoreFile() {
        String keystoreFile = conf.get(OOZIE_HTTPS_KEYSTORE_FILE);
        Objects.requireNonNull(keystoreFile, "keystoreFile is null");
        sslContextFactory.setKeyStorePath(keystoreFile);
    }

    private void setKeyStoreType() {
        String keyStoreType = conf.get(OOZIE_HTTPS_KEYSTORE_TYPE);
        if(keyStoreType != null) {
            sslContextFactory.setKeyStoreType(keyStoreType);
        }
    }

    private HttpConfiguration getHttpsConfiguration() {
        HttpConfiguration https = new HttpConfigurationWrapper(conf).getDefaultHttpConfiguration();
        https.setSecureScheme("https");
        long htsMaxAgeSeconds = conf.getLong(OOZIE_HSTS_MAX_AGE_SECONDS, OOZIE_DEFAULT_HSTS_MAX_AGE);
        boolean sniHostCheck = true;
        boolean stsIncludeSubdomains = false;
        https.addCustomizer(new SecureRequestCustomizer(sniHostCheck, htsMaxAgeSeconds, stsIncludeSubdomains));
        return https;
    }
}
