//
//
// Copyright 2019 gRPC authors.
//
// Licensed 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 <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "upb/mem/arena.hpp"

#include <grpc/grpc_security_constants.h>
#include <grpc/support/log.h>
#include <grpcpp/security/alts_context.h>
#include <grpcpp/security/alts_util.h>
#include <grpcpp/security/auth_context.h>
#include <grpcpp/support/status.h>
#include <grpcpp/support/string_ref.h>

#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
#include "src/proto/grpc/gcp/altscontext.upb.h"

namespace grpc {
namespace experimental {

std::unique_ptr<AltsContext> GetAltsContextFromAuthContext(
    const std::shared_ptr<const AuthContext>& auth_context) {
  if (auth_context == nullptr) {
    gpr_log(GPR_ERROR, "auth_context is nullptr.");
    return nullptr;
  }
  std::vector<string_ref> ctx_vector =
      auth_context->FindPropertyValues(TSI_ALTS_CONTEXT);
  if (ctx_vector.size() != 1) {
    gpr_log(GPR_ERROR, "contains zero or more than one ALTS context.");
    return nullptr;
  }
  upb::Arena context_arena;
  grpc_gcp_AltsContext* ctx = grpc_gcp_AltsContext_parse(
      ctx_vector[0].data(), ctx_vector[0].size(), context_arena.ptr());
  if (ctx == nullptr) {
    gpr_log(GPR_ERROR, "fails to parse ALTS context.");
    return nullptr;
  }
  if (grpc_gcp_AltsContext_security_level(ctx) < GRPC_SECURITY_MIN ||
      grpc_gcp_AltsContext_security_level(ctx) > GRPC_SECURITY_MAX) {
    gpr_log(GPR_ERROR, "security_level is invalid.");
    return nullptr;
  }
  return std::make_unique<AltsContext>(AltsContext(ctx));
}

grpc::Status AltsClientAuthzCheck(
    const std::shared_ptr<const AuthContext>& auth_context,
    const std::vector<std::string>& expected_service_accounts) {
  std::unique_ptr<AltsContext> alts_ctx =
      GetAltsContextFromAuthContext(auth_context);
  if (alts_ctx == nullptr) {
    return grpc::Status(grpc::StatusCode::PERMISSION_DENIED,
                        "fails to parse ALTS context.");
  }
  if (std::find(expected_service_accounts.begin(),
                expected_service_accounts.end(),
                alts_ctx->peer_service_account()) !=
      expected_service_accounts.end()) {
    return grpc::Status::OK;
  }
  return grpc::Status(
      grpc::StatusCode::PERMISSION_DENIED,
      "client " + alts_ctx->peer_service_account() + " is not authorized.");
}

}  // namespace experimental
}  // namespace grpc
