#include "bmcweb_authorizer_singleton.h"

#include <array>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <string>
#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>

#include "gmi/machine_identity.pb.h"
#include "one/network_interfaces.pb.h"
#include "one/offline_node_entities.pb.h"
#include "one/resolved_entities.pb.h"
#include "one/public_offline_node_entities.h"
#include "absl/base/no_destructor.h"
#include "absl/container/flat_hash_set.h"
#include "absl/log/log.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/substitute.h"
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "authorizer_enums.h"
#include "redfish_v1.pb.h"
#include "grpc/grpc_security_constants.h"
#include "grpcpp/security/auth_context.h"
#include "grpcpp/support/status.h"
#include "grpcpp/support/string_ref.h"
#include "nlohmann/json.hpp"
#include "config_parser.h"
#include "oauth_utils.h"
#include "redfish_authorizer.h"
#include "redfish_privileges.h"
#include "zatar/certificate_metadata.h"

namespace milotic::authz {

namespace {

using ::ecclesia::Operation;
using ::ecclesia::ResourceEntity;
using ::milotic::redfish::CertificateMetadata;
using ::milotic::redfish::CertificateMetadataParser;
using ::production_msv::node_entities::ReadOfflineNodeEntityInformation;
using ::production_msv::node_entities_proto::NetworkInterface;
using ::production_msv::node_entities_proto::OfflineNodeEntityInformation;
using ::production_msv::node_entities_proto::ResolvedNodeEntity;
using ::security_prodid::GoogleMachineIdentityProto;

}  // namespace

BmcWebAuthorizerSingleton& BmcWebAuthorizerSingleton::Initialize(
    const AuthorizerOptions& options, std::string_view oauth_key_path) {
  static absl::NoDestructor<BmcWebAuthorizerSingleton> singleton(
      options, oauth_key_path);

  return *singleton;
}

void BmcWebAuthorizerSingleton::ReloadRedfishAuthorizer(
    const std::string& configuration_path) {
  redfish_authorizer_.ReloadConfiguration(configuration_path);
}

BmcWebAuthorizerSingleton& BmcWebAuthorizerSingleton::GetInstance() {
  return Initialize(/*options=*/{}, /*oauth_key_path=*/"");
}

BmcWebAuthorizerSingleton::BmcWebAuthorizerSingleton(
    const AuthorizerOptions& options, std::string_view oauth_key_path)
    : tlbmc_trust_bundle_install_module_is_enabled_(
          options.tlbmc_trust_bundle_install_module_is_enabled),
      gmi_path_(options.google_machine_identity_path),
      oauth_key_path_(oauth_key_path),
      offline_node_entity_path_(options.offline_node_entities_path),
      redfish_authorizer_(options) {
  ReloadConfiguration();
}

void BmcWebAuthorizerSingleton::ReloadGmiPaths(std::string_view gmi_path) {
  gmi_path_ = gmi_path;
}

void BmcWebAuthorizerSingleton::ReloadConfiguration() {
  LOG(WARNING) << "Reload configuration started..";
  redfish_authorizer_.ReloadConfiguration();
  std::string primary_fqdn = ReadPrimaryFqdnFromGmi();
  SetPrimaryFqdn(primary_fqdn);
  SetOauthKey(ReadOauthKeyFromFile());
  SetInterfaceFqdns(ReadDomainNameFromOfflineNodeEntity(primary_fqdn));
  LOG(WARNING) << "Reload configuration done.";
}

grpc::Status BmcWebAuthorizerSingleton::RecordNewSubscription(
    const PeerSpiffeIdentity& peer) {
  if (absl::Status status = redfish_authorizer_.RecordNewSubscription(peer);
      !status.ok()) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED, status.ToString());
  }
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::RecordNewUnsubscription(
    const PeerSpiffeIdentity& peer) {
  if (absl::Status status = redfish_authorizer_.RecordNewUnsubscription(peer);
      !status.ok()) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED, status.ToString());
  }
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::Authorize(
    std::string_view uri, boost::beast::http::verb verb,
    const RequestState& request_state) const {
  if (!request_state.peer_authenticated) {
    if (request_state.with_trust_bundle) {
      return grpc::Status(
          grpc::StatusCode::UNAUTHENTICATED,
          "Peer must be authenticated if BMC has trust bundle!");
    }
    if (tlbmc_trust_bundle_install_module_is_enabled_) {
      return RecoveryAuthorizeForBloom(uri, verb);
    }

    return AuthorizeWithoutTrustBundle(uri, verb);
  }

  return AuthorizeWithTrustBundle(uri, verb, request_state);
}

grpc::Status BmcWebAuthorizerSingleton::AuthorizeWithTrustBundle(
    std::string_view uri, boost::beast::http::verb verb,
    const RequestState& request_state) const {
  Operation operation = BoostVerbToOperation(verb);
  RedfishPrivileges peer_privileges =
      RedfishPrivileges(request_state.peer_privileges);
  if (!redfish_authorizer_.IsPeerAuthorized(uri, operation, peer_privileges)) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED,
                        "Client doesn't have enough permissions: " +
                            peer_privileges.GetDebugString());
  }
  return grpc::Status::OK;
}

Operation BmcWebAuthorizerSingleton::BoostVerbToOperation(
    boost::beast::http::verb verb) {
  switch (verb) {
    case boost::beast::http::verb::get:
      return Operation::kGet;
    case boost::beast::http::verb::post:
      return Operation::kPost;
    case boost::beast::http::verb::delete_:
      return Operation::kDelete;
    case boost::beast::http::verb::put:
      return Operation::kPut;
    case boost::beast::http::verb::patch:
      return Operation::kPatch;
    case boost::beast::http::verb::head:
      return Operation::kHead;
    default:
      return Operation::kUndefined;
  }
}

grpc::Status BmcWebAuthorizerSingleton::AuthorizeWithoutTrustBundle(
    std::string_view uri, boost::beast::http::verb verb) const {
  constexpr std::array<std::pair<ResourceEntity, boost::beast::http::verb>, 10>
      kRecoveryOperations = {
          std::pair<ResourceEntity, boost::beast::http::verb>{
              ResourceEntity::kServiceRoot, boost::beast::http::verb::get},
          {ResourceEntity::kChassisCollection, boost::beast::http::verb::get},
          {ResourceEntity::kChassis, boost::beast::http::verb::get},
          {ResourceEntity::kActionInfo, boost::beast::http::verb::get},
          {ResourceEntity::kChassis, boost::beast::http::verb::post},
          {ResourceEntity::kComputerSystem, boost::beast::http::verb::get},
          {ResourceEntity::kComputerSystemCollection,
           boost::beast::http::verb::get},
          {ResourceEntity::kComputerSystem, boost::beast::http::verb::post},
          {ResourceEntity::kManagerCollection, boost::beast::http::verb::get},
          {ResourceEntity::kManager, boost::beast::http::verb::get},
      };
  ResourceEntity entity = GetEntityTypeFromRedfishUri(uri);
  bool authorized = false;
  for (auto const& [allowed_entity, allowed_verb] : kRecoveryOperations) {
    if (entity == allowed_entity && verb == allowed_verb) {
      authorized = true;
      break;
    }
  }

  // Specifically hardcode the Manager.Reset operation to be allowed.
  if (uri == "/redfish/v1/Managers/bmc/Actions/Manager.Reset" &&
      verb == boost::beast::http::verb::post) {
    authorized = true;
  }

  if (!authorized) {
    return grpc::Status(
        grpc::StatusCode::PERMISSION_DENIED,
        "Without trust bundle, only recovery operations are allowed");
  }

  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::RecoveryAuthorizeForBloom(
    std::string_view uri, boost::beast::http::verb verb) const {
  // allowlist during trust bundle installation
  static const absl::NoDestructor<absl::flat_hash_set<
      std::pair<std::string_view, boost::beast::http::verb>>>
      kAllowedEndpoints({
          {"/redfish/v1/CertificateService", boost::beast::http::verb::get},
          {"/redfish/v1/CertificateService/ReplaceCertificateActionInfo",
           boost::beast::http::verb::get},
          {"/redfish/v1/CertificateService/Actions/"
           "CertificateService.ReplaceCertificate",
           boost::beast::http::verb::post},
      });

  if (kAllowedEndpoints->contains({uri, verb})) {
    return grpc::Status::OK;
  }

  return grpc::Status(
      grpc::StatusCode::PERMISSION_DENIED,
      "Please install your client *CA* certificate as trust bundle first.");
}

grpc::Status BmcWebAuthorizerSingleton::GetPeerRoleFromAuthContext(
    const grpc::AuthContext& context, std::string& peer_role) const {
  PeerSpiffeIdentity peer_identity;
  if (grpc::Status status =
          GetPeerIdentityFromAuthContext(context, peer_identity);
      !status.ok()) {
    peer_role.clear();
    return status;
  }
  peer_role = redfish_authorizer_.GetPeerRedfishRole(peer_identity);
  if (peer_role.empty()) {
    return grpc::Status(
        grpc::StatusCode::PERMISSION_DENIED,
        absl::StrCat(
            "Peer role is not specified in the auth config: peer_identity=",
            peer_identity.spiffe_id));
  }
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::GetPrivilegesViaOAuth(
    const grpc::AuthContext& context, const std::string& token,
    std::unordered_set<std::string>& peer_privileges) const {
  PeerSpiffeIdentity peer_identity;
  if (grpc::Status status =
          GetPeerIdentityFromAuthContext(context, peer_identity);
      !status.ok()) {
    return status;
  }

  std::string redfish_role;
  constexpr const char* kExpectedIssuer = "BMC Local Authorization Server";
  if (grpc::Status status = VerifyAndExtractRoleFromToken(
          token, GetOauthKey(), GenerateOAuthSubject(peer_identity),
          GetPrimaryFqdn(), kExpectedIssuer, redfish_role);
      !status.ok()) {
    return status;
  }

  peer_privileges = redfish_authorizer_.GetRedfishPrivileges(redfish_role);
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::GetPrivilegesViaMTls(
    const grpc::AuthContext& context,
    std::unordered_set<std::string>& peer_privileges) const {
  PeerSpiffeIdentity peer_identity;
  if (grpc::Status status =
          GetPeerIdentityFromAuthContext(context, peer_identity);
      !status.ok()) {
    return status;
  }
  LOG(INFO) << "Peer identity: " << peer_identity.spiffe_id;
  peer_privileges = redfish_authorizer_.GetPeerRedfishPrivileges(peer_identity);
  return grpc::Status::OK;
}

std::string BmcWebAuthorizerSingleton::ReadPrimaryFqdnFromGmi() const {
  std::ifstream gmi_file(gmi_path_);
  if (!gmi_file.is_open()) {
    LOG(WARNING) << "GMI file at '" << gmi_path_ << "' is missing." << '\n';
    return "";
  }
  GoogleMachineIdentityProto gmi;
  if (!gmi.ParseFromIstream(&gmi_file)) {
    std::cerr << "GMI parsing failed at '" << gmi_path_ << "'" << '\n';
    return "";
  }
  return gmi.fqdn();
}

std::string BmcWebAuthorizerSingleton::ReadOauthKeyFromFile() const {
  std::ifstream oauth_key_file(oauth_key_path_);
  if (!oauth_key_file.is_open()) {
    LOG(WARNING) << "OAuth key file at '" << oauth_key_path_ << "' is missing."
                 << '\n';
    return "";
  }
  std::string oauth_key = {std::istreambuf_iterator<char>(oauth_key_file),
                           std::istreambuf_iterator<char>()};
  return oauth_key;
}

std::vector<std::string>
BmcWebAuthorizerSingleton::ReadDomainNameFromOfflineNodeEntity(
    std::string_view primary_fqdn) const {
  std::ifstream offline_node_entity_file(offline_node_entity_path_);
  std::vector<std::string> interface_fqdns;
  if (!offline_node_entity_file.is_open()) {
    LOG(WARNING) << "Offline Node Entity file at '" << offline_node_entity_path_
                 << "' is missing." << '\n';
    return interface_fqdns;
  }
  absl::StatusOr<OfflineNodeEntityInformation> one =
      ReadOfflineNodeEntityInformation(offline_node_entity_path_);
  if (!one.ok()) {
    LOG(WARNING) << "Could not read offline node entities information: "
                 << one.status().message();
    return interface_fqdns;
  }
  for (const std::pair<const std::string, ResolvedNodeEntity>& entity :
       (*one).resolved_config().entities()) {
    if (absl::StrCat(entity.second.hostname(), ".prod.google.com") !=
        primary_fqdn)
      continue;
    for (const NetworkInterface& intf :
         entity.second.network_interfaces().network_interface()) {
      interface_fqdns.push_back(intf.hostname() + ".prod.google.com");
    }
    break;
  }
  return interface_fqdns;
}

uint64_t BmcWebAuthorizerSingleton::GetSampleRateLimit(
    const std::string& peer_role) const {
  return redfish_authorizer_.GetSampleRateLimit(peer_role);
}

std::string BmcWebAuthorizerSingleton::GetAnycastAddress(
    const std::string& peer_role) const {
  return redfish_authorizer_.GetAnycastAddress(peer_role);
}

ResourceEntity BmcWebAuthorizerSingleton::GetEntityTypeFromRedfishUri(
    std::string_view uri) const {
  return redfish_authorizer_.GetEntityTypeFromRedfishUri(uri);
}

std::size_t BmcWebAuthorizerSingleton::GetNodeIndexInPatternArray(
    std::string_view uri) const {
  return redfish_authorizer_.GetNodeIndexInPatternArray(uri);
}

nlohmann::json BmcWebAuthorizerSingleton::GetRedfishPrivilegeRegistry() const {
  return redfish_authorizer_.GetRedfishPrivilegeRegistry();
}

bool BmcWebAuthorizerSingleton::IsBasePrivilegeRegistryFound() const {
  nlohmann::json config_json = redfish_authorizer_.ParseAuthConfig();

  if (config_json.empty()) {
    return false;
  }

  std::string base_privilege_registry_path =
      redfish_authorizer_.FindBasePrivilegeRegistryPath(config_json);

  return !base_privilege_registry_path.empty();
}

void BmcWebAuthorizerSingleton::SetBasePrivilegesFolder(
    std::string_view base_privileges_folder) {
  redfish_authorizer_.SetBasePrivilegesFolder(base_privileges_folder);
}

grpc::Status BmcWebAuthorizerSingleton::GetPeerIdentityFromAuthContext(
    const grpc::AuthContext& context, PeerSpiffeIdentity& peer_identity) {
  if (!context.IsPeerAuthenticated()) {
    return grpc::Status(grpc::StatusCode::UNAUTHENTICATED,
                        "Peer is unauthenticated");
  }
  if (context.GetPeerIdentityPropertyName() != GRPC_X509_SAN_PROPERTY_NAME) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED,
                        "Peer identity isn't X.509 SAN");
  }
  for (const grpc::string_ref& val : context.GetPeerIdentity()) {
    std::string_view str(val.data(), val.size());
    // As per SPIFFE specification, SPIFFE schema and trust domain are case
    // insensitive.
    // https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#24-spiffe-id-parsing
    if (absl::StartsWithIgnoreCase(str, "spiffe://")) {
      peer_identity.spiffe_id = str;
    } else if (absl::EndsWith(str, ".prod.google.com")) {
      peer_identity.fqdn = str;
    }
  }
  return grpc::Status::OK;
}

grpc::Status BmcWebAuthorizerSingleton::CheckTarget(
    const grpc::AuthContext& grpc_context,
    const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata,
    const ::redfish::v1::Request& request) const {
  PeerSpiffeIdentity peer_identity;
  if (grpc::Status status =
          GetPeerIdentityFromAuthContext(grpc_context, peer_identity);
      !status.ok()) {
    return status;
  }

  CertificateMetadata peer_metadata;
  if (absl::Status status = metadata_parser_.GetContextAndRoleFromSpiffe(
          peer_identity.spiffe_id, peer_metadata.context, peer_metadata.role);
      !status.ok()) {
    return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, status.ToString());
  }

  // If the service (BMCWeb) has a legitimate GMI, and peer is not a node (e.g.,
  // it's a Borg job), check that the intended recipient of the request matches
  // the identity in the certificate. This is to prevent redirect attacks in
  // powercycle trust model, where clients never verify server.
  std::string primary_fqdn = GetPrimaryFqdn();
  if (primary_fqdn.empty()) {
    LOG(WARNING) << "Can't parse primary fqdn. GMI is probably broken.";
    return grpc::Status::OK;
  }
  if (peer_metadata.context == CertificateMetadataParser::kCaContextNode) {
    return grpc::Status::OK;
  }

  std::string host;
  for (auto const& [key, val] : request.headers()) {
    // Both field name of the Authorization header and the token type are case
    // insensitive
    // References
    // https://www.rfc-editor.org/rfc/rfc7230#section-3.2
    // https://www.rfc-editor.org/rfc/rfc6749#section-5.1
    if (absl::EqualsIgnoreCase(key, "Host")) {
      host = val;
    }
  }

  // To keep backward compatibility, extract host from metadata as well if it's
  // not in headers.
  if (host.empty()) {
    auto it = client_metadata.find("target");
    if (it != client_metadata.end()) {
      host = {it->second.data(), it->second.length()};
    }
  }

  // DNS should be case insensitive
  // Reference: https://www.rfc-editor.org/rfc/rfc4343
  if (absl::EqualsIgnoreCase(host, primary_fqdn)) {
    return grpc::Status::OK;
  }

  // We could have multiple FQDNs on BMC and they can be different from the
  // hostname. Matching any of them should pass the validation
  for (const std::string& fqdn : GetInterfaceFqdns()) {
    if (absl::EqualsIgnoreCase(host, fqdn)) {
      return grpc::Status::OK;
    }
  }

  return grpc::Status(
      grpc::StatusCode::PERMISSION_DENIED,
      absl::Substitute(
          "Unauthorized user: request target doesn't match server; request's "
          "host header='$0'; BMC's primary FQDN='$1'; BMC's interface "
          "FQDNs='$2'",
          host, primary_fqdn, absl::StrJoin(GetInterfaceFqdns(), " ")));
}

}  // namespace milotic::authz
