// 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.

#include "kudu/server/webserver_options.h"

#include <cstdlib>
#include <ostream>
#include <string>

#include <gflags/gflags.h>
#include <glog/logging.h>

#include "kudu/gutil/macros.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/security/security_flags.h"
#include "kudu/util/flag_tags.h"
#include "kudu/util/flag_validators.h"

using std::string;

namespace kudu {

static std::string GetDefaultDocumentRoot();

} // namespace kudu

// Flags defining web server behavior. The class implementation should
// not use these directly, but rather access them via WebserverOptions.
// This makes it easier to instantiate web servers with different options
// within a single unit test.
DEFINE_string(webserver_interface, "",
    "Interface to start the embedded webserver on. If blank, the webserver "
    "binds to 0.0.0.0");
TAG_FLAG(webserver_interface, advanced);

DEFINE_string(webserver_advertised_addresses, "",
              "Comma-separated list of addresses to advertise externally for "
              "HTTP(S) connections. Ephemeral ports (i.e. port 0) are not "
              "allowed. This should be configured when the locally bound "
              "webserver address specified in --webserver_interface and "
              "--webserver_port are not externally resolvable, for example, if "
              "Kudu is deployed in a container.");
TAG_FLAG(webserver_advertised_addresses, advanced);

DEFINE_string(webserver_doc_root, kudu::GetDefaultDocumentRoot(),
    "Files under <webserver_doc_root> are accessible via the embedded "
    "webserver. Defaults to $KUDU_HOME/www, or if $KUDU_HOME is not set, "
    "disables the document root");
TAG_FLAG(webserver_doc_root, advanced);

DEFINE_bool(webserver_enable_doc_root, true,
    "If true, webserver may serve static files from the webserver_doc_root");
TAG_FLAG(webserver_enable_doc_root, advanced);

// TLS/SSL configuration.
DEFINE_string(webserver_certificate_file, "",
    "The location of the embedded webserver's TLS/SSL certificate file, in PEM "
    "format. If empty, webserver TLS/SSL support is not enabled. "
    "If --webserver_private_key_file is set, this option must be set as well.");
TAG_FLAG(webserver_certificate_file, stable);

DEFINE_string(webserver_private_key_file, "",
    "The full path to the private key used as a counterpart to the public key "
    "contained in --webserver_certificate_file. This flag must be set if "
    "the --webserver_certificate_file flag is set.");
TAG_FLAG(webserver_private_key_file, sensitive);
TAG_FLAG(webserver_private_key_file, stable);

DEFINE_string(webserver_private_key_password_cmd, "",
    "A Unix command whose output returns the password to decrypt the private "
    "key of the webserver's certificate pointed to by the "
    "--webserver_private_key_file flag. If the PEM key file is not "
    "password-protected, this flag does not need to be set. Trailing "
    "whitespace will be trimmed before it is used to decrypt the private key");
TAG_FLAG(webserver_private_key_password_cmd, sensitive);
TAG_FLAG(webserver_private_key_password_cmd, stable);

DEFINE_string(webserver_authentication_domain, "",
    "Domain used for the authentication by the embedded webserver");

DEFINE_string(webserver_password_file, "",
    "Location of .htpasswd file containing user names and hashed "
    "passwords for the authentication performed by the embedded webserver "
    "(NOTE: for better protection, consider configuring SPNEGO using the "
    "--webserver_require_spnego flag)");
TAG_FLAG(webserver_password_file, sensitive);

DEFINE_int32(webserver_num_worker_threads, 50,
             "Maximum number of threads to start for handling webserver requests");
TAG_FLAG(webserver_num_worker_threads, advanced);

DEFINE_int32(webserver_port, 0,
             "Port to bind to for the webserver");
TAG_FLAG(webserver_port, stable);

DEFINE_string(webserver_tls_ciphers,
              // See security/tls_context.cc for origin of this list.
              kudu::security::SecurityDefaults::kDefaultTlsCiphers,
              "The cipher suite preferences to use for webserver HTTPS connections. "
              "Uses the OpenSSL cipher preference list format. See man (1) ciphers "
              "for more information.");
TAG_FLAG(webserver_tls_ciphers, advanced);

DEFINE_string(webserver_tls_min_protocol, kudu::security::SecurityDefaults::kDefaultTlsMinVersion,
              "The minimum protocol version to allow when for webserver HTTPS "
              "connections. May be one of 'TLSv1', 'TLSv1.1', or 'TLSv1.2'.");
TAG_FLAG(webserver_tls_min_protocol, advanced);

DEFINE_bool(webserver_require_spnego, false,
            "Require connections to the webserver to authenticate via Kerberos "
            "using SPNEGO.");
TAG_FLAG(webserver_require_spnego, stable);

namespace kudu {

static bool ValidateTlsFlags() {
  bool has_cert = !FLAGS_webserver_certificate_file.empty();
  bool has_key = !FLAGS_webserver_private_key_file.empty();
  bool has_passwd = !FLAGS_webserver_private_key_password_cmd.empty();

  if (has_key != has_cert) {
    LOG(ERROR) << "--webserver_certificate_file and --webserver_private_key_file "
                  "must be set as a group; i.e. either set all or none of them.";
    return false;
  }
  if (has_passwd && !has_key) {
    LOG(ERROR) << "--webserver_private_key_password_cmd may not be set without "
                  "--webserver_private_key_file";
    return false;
  }

  return true;
}
GROUP_FLAG_VALIDATOR(webserver_tls_options, ValidateTlsFlags);

// Returns KUDU_HOME if set, otherwise we won't serve any static files.
static string GetDefaultDocumentRoot() {
  char* kudu_home = getenv("KUDU_HOME");
  // Empty document root means don't serve static files
  return kudu_home ? strings::Substitute("$0/www", kudu_home) : "";
}

WebserverOptions::WebserverOptions()
    : bind_interface(FLAGS_webserver_interface),
      webserver_advertised_addresses(FLAGS_webserver_advertised_addresses),
      port(FLAGS_webserver_port),
      doc_root(FLAGS_webserver_doc_root),
      enable_doc_root(FLAGS_webserver_enable_doc_root),
      certificate_file(FLAGS_webserver_certificate_file),
      private_key_file(FLAGS_webserver_private_key_file),
      private_key_password_cmd(FLAGS_webserver_private_key_password_cmd),
      authentication_domain(FLAGS_webserver_authentication_domain),
      password_file(FLAGS_webserver_password_file),
      tls_ciphers(FLAGS_webserver_tls_ciphers),
      tls_min_protocol(FLAGS_webserver_tls_min_protocol),
      num_worker_threads(FLAGS_webserver_num_worker_threads),
      require_spnego(FLAGS_webserver_require_spnego) {
}

} // namespace kudu
