// 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.
//
// Copied from Impala and adapted to Kudu.

#include "kudu/util/jwt-util.h"

#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

#include <glog/logging.h>
#include <gtest/gtest.h>
#include <jwt-cpp/jwt.h>
#include <jwt-cpp/traits/kazuho-picojson/defaults.h>
#include <jwt-cpp/traits/kazuho-picojson/traits.h>

#include "kudu/gutil/strings/substitute.h"
#include "kudu/server/webserver.h"
#include "kudu/server/webserver_options.h"
#include "kudu/util/countdown_latch.h"
#include "kudu/util/env.h"
#include "kudu/util/jwt-util-internal.h"
#include "kudu/util/jwt_test_certs.h"
#include "kudu/util/mini_oidc.h"
#include "kudu/util/net/sockaddr.h"
#include "kudu/util/scoped_cleanup.h"
#include "kudu/util/slice.h"
#include "kudu/util/status.h"
#include "kudu/util/test_macros.h"
#include "kudu/util/web_callback_registry.h"

namespace kudu {

using std::string;
using std::unique_ptr;
using std::unordered_map;
using std::vector;
using strings::Substitute;
using kudu::MiniOidc;

/// Utility class for creating a file that will be automatically deleted upon test
/// completion.
class TempTestDataFile {
 public:
  // Creates a temporary file with the specified contents.
  explicit TempTestDataFile(const std::string& contents);

  /// Returns the absolute path to the file.
  const std::string& Filename() const { return name_; }

 private:
  std::string name_;
  std::unique_ptr<WritableFile> tmp_file_;
};

TempTestDataFile::TempTestDataFile(const std::string& contents)
  : name_("/tmp/jwks_XXXXXX") {
  string created_filename;
  WritableFileOptions opts;
  opts.is_sensitive = false;
  Status status;
  status = Env::Default()->NewTempWritableFile(opts, &name_[0], &created_filename, &tmp_file_);
  if (!status.ok()) {
    std::cerr << Substitute("Error creating temp file: $0", created_filename);
  }

  status = WriteStringToFile(Env::Default(), contents, created_filename);
  if (!status.ok()) {
    std::cerr << Substitute("Error writing contents to temp file: $0", created_filename);
  }

  name_ = created_filename;
}

TEST(JwtUtilTest, LoadJwksFile) {
  // Load JWKS from file.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS256",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_FALSE(jwks->IsEmpty());
  ASSERT_EQ(2, jwks->GetRSAPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupRSAPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ("rs256", key1->get_algorithm());
  ASSERT_EQ(kRsaPubKeyPem, key1->get_key());

  std::string non_existing_kid("public:c424b67b-fe28-45d7-b015-f79da5-xxxxx");
  const JWTPublicKey* key3 = jwks->LookupRSAPublicKey(non_existing_kid);
  ASSERT_FALSE(key3 != nullptr);
}

TEST(JwtUtilTest, LoadInvalidJwksFiles) {
  // JWK without kid.
  std::unique_ptr<TempTestDataFile> jwks_file(new TempTestDataFile(
      "{"
      "  \"keys\": ["
      "    {"
      "      \"use\": \"sig\","
      "      \"kty\": \"RSA\","
      "      \"alg\": \"RS256\","
      "      \"n\": \"sttddbg-_yjXzcFpbMJB1fIFam9lQBeXWbTqzJwbuFbspHMsRowa8FaPw\","
      "      \"e\": \"AQAB\""
      "    }"
      "  ]"
      "}"));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file->Filename());
  ASSERT_FALSE(status.ok());
  ASSERT_STR_CONTAINS(status.ToString(), "parsing key #0")
      << " Actual error: " << status.ToString();
  ASSERT_STR_CONTAINS(status.ToString(), "'kid' property is required")
      << "actual error: " << status.ToString();

  // Invalid JSON format, missing "]" and "}".
  jwks_file.reset(new TempTestDataFile(
      "{"
      "  \"keys\": ["
      "    {"
      "      \"use\": \"sig\","
      "      \"kty\": \"RSA\","
      "      \"kid\": \"public:c424b67b-fe28-45d7-b015-f79da50b5b21\","
      "      \"alg\": \"RS256\","
      "      \"n\": \"sttddbg-_yjXzcFpbMJB1fIFam9lQBeXWbTqzJwbuFbspHMsRowa8FaPw\","
      "      \"e\": \"AQAB\""
      "}"));
  status = jwt_helper.Init(jwks_file->Filename());
  ASSERT_FALSE(status.ok());
  ASSERT_STR_CONTAINS(status.ToString(), "Missing a comma or ']' after an array element")
      << " Actual error: " << status.ToString();

  // JWKS with empty key id.
  jwks_file.reset(new TempTestDataFile(
      Substitute(kJwksRsaFileFormat, "", "RS256", kRsaPubKeyJwkN, kRsaPubKeyJwkE,
          "", "RS256", kRsaInvalidPubKeyJwkN, kRsaPubKeyJwkE)));
  status = jwt_helper.Init(jwks_file->Filename());
  ASSERT_FALSE(status.ok());
  ASSERT_STR_CONTAINS(status.ToString(), "parsing key #0")
      << " Actual error: " << status.ToString();
  ASSERT_STR_CONTAINS(status.ToString(), "'kid' property must be a non-empty string")
      << " Actual error: " << status.ToString();

  // JWKS with empty key value.
  jwks_file.reset(new TempTestDataFile(
      Substitute(kJwksRsaFileFormat, kKid1, "RS256", "", "", kKid2, "RS256", "", "")));
  status = jwt_helper.Init(jwks_file->Filename());
  ASSERT_FALSE(status.ok());
  ASSERT_STR_CONTAINS(status.ToString(), "parsing key #0")
      << " Actual error: " << status.ToString();
  ASSERT_STR_CONTAINS(status.ToString(), "'n' and 'e' properties must be a non-empty string")
      << " Actual error: " << status.ToString();
}

TEST(JwtUtilTest, VerifyJwtHS256) {
  // Cryptographic algorithm: HS256.
  // SharedSecret (Generated for MAC key (Base64 encoded)).
  string shared_secret = "Yx57JSBzhGFDgDj19CabRpH/+kiaKqI6UZI6lDunQKw=";
  TempTestDataFile jwks_file(
      Substitute(kJwksHsFileFormat, kKid1, "HS256", shared_secret));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  EXPECT_OK(status);
  ASSERT_EQ(1, jwks->GetHSKeyNum());

  const JWTPublicKey* key1 = jwks->LookupHSKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(key1->get_key(), shared_secret);

  // Create a JWT token and sign it with HS256.
  auto token = jwt::create()
                   .set_issuer("auth0")
                   .set_type("JWS")
                   .set_algorithm("HS256")
                   .set_key_id(kKid1)
                   .set_payload_claim("username", picojson::value("kudu"))
                   .sign(jwt::algorithm::hs256(shared_secret));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtHS384) {
  // Cryptographic algorithm: HS384.
  // SharedSecret (Generated for MAC key (Base64 encoded)).
  string shared_secret =
      "TlqmKRc2PNQJXTC3Go7eAadwPxA7x9byyXCi5I8tSvxrE77tYbuF5pfZAyswrkou";
  TempTestDataFile jwks_file(
      Substitute(kJwksHsFileFormat, kKid1, "HS384", shared_secret));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(1, jwks->GetHSKeyNum());

  const JWTPublicKey* key1 = jwks->LookupHSKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(key1->get_key(), shared_secret);

  // Create a JWT token and sign it with HS384.
  auto token = jwt::create()
                   .set_issuer("auth0")
                   .set_type("JWS")
                   .set_algorithm("HS384")
                   .set_key_id(kKid1)
                   .set_payload_claim("username", picojson::value("kudu"))
                   .sign(jwt::algorithm::hs384(shared_secret));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtHS512) {
  // Cryptographic algorithm: HS512.
  // SharedSecret (Generated for MAC key (Base64 encoded)).
  string shared_secret = "ywc6DN7+iRw1E5HOqzvrsYodykSLFutT28KN3bJnLZcZpPCNjn0b6gbMfXPcxeY"
                         "VyuWWGDxh6gCDwPMejbuEEg==";
  TempTestDataFile jwks_file(
      Substitute(kJwksHsFileFormat, kKid1, "HS512", shared_secret));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  EXPECT_OK(status);
  ASSERT_EQ(1, jwks->GetHSKeyNum());

  const JWTPublicKey* key1 = jwks->LookupHSKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(key1->get_key(), shared_secret);

  // Create a JWT token and sign it with HS512.
  auto token = jwt::create()
                   .set_issuer("auth0")
                   .set_type("JWS")
                   .set_algorithm("HS512")
                   .set_key_id(kKid1)
                   .set_payload_claim("username", picojson::value("kudu"))
                   .sign(jwt::algorithm::hs512(shared_secret));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtRS256) {
  // Cryptographic algorithm: RS256.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS256",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(2, jwks->GetRSAPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupRSAPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kRsaPubKeyPem, key1->get_key());

  // Create a JWT token and sign it with RS256.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS256")
          .set_key_id(kKid1)
          .set_payload_claim("username", picojson::value("kudu"))
          .sign(jwt::algorithm::rs256(kRsaPubKeyPem, kRsaPrivKeyPem, "", ""));
  ASSERT_EQ(
      "eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzpjNDI0YjY3Yi1mZTI4LTQ1ZDctYjAxNS1mNzlkYTUwYjViMjEiLCJ0"
      "eXAiOiJKV1MifQ.eyJpc3MiOiJhdXRoMCIsInVzZXJuYW1lIjoia3VkdSJ9.OcAO1KFnYMyVyMXWqeWKlvZIDIYmeQYZ"
      "hMYcjOuGi5KKuBF5J7IlSl14EM6EhswQJ54pP8EPhMyHHNqncUOPt-QN9foS39aA5XpNPqOOWShQvZLQweEsogjfab66"
      "gWPO7baXGg8npqMBxpnvM5mjz4TIg6kwT4R_9p1NBGYmU5DQS6_jb7OfpMxY8bezKwL_iJB9yPgTlgZA5IJ0DPkIydcQ"
      "ejz3ycLy-75G8GWK78WgtOq2ejwpCsrPo3QlaqQH1reDPBit_2xme8ypwgGztc3Nss1ZF8g5U69WTdhP2Dy5k7iFXKua"
      "PHD5HBAFJiP1KVWMpuGX_POewU_ibt7v8g",
      token);

  // Verify the JWT token with jwt-cpp APIs directly.
  auto jwt_decoded_token = jwt::decode(token);
  auto verifier = jwt::verify()
                      .allow_algorithm(jwt::algorithm::rs256(kRsaPubKeyPem, "", "", ""))
                      .with_issuer("auth0");
  verifier.verify(jwt_decoded_token);

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtRS384) {
  // Cryptographic algorithm: RS384.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS384",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS384", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(2, jwks->GetRSAPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupRSAPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kRsaPubKeyPem, key1->get_key());

  // Create a JWT token and sign it with RS384.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS384")
          .set_key_id(kKid1)
          .set_payload_claim("username", picojson::value("kudu"))
          .sign(jwt::algorithm::rs384(kRsaPubKeyPem, kRsaPrivKeyPem, "", ""));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtRS512) {
  // Cryptographic algorithm: RS512.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS512",
      kRsa512PubKeyJwkN, kRsa512PubKeyJwkE, kKid2, "RS512",
      kRsa512InvalidPubKeyJwkN, kRsa512PubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(2, jwks->GetRSAPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupRSAPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kRsa512PubKeyPem, key1->get_key());

  // Create a JWT token and sign it with RS512.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS512")
          .set_key_id(kKid1)
          .set_payload_claim("username", picojson::value("kudu"))
          .sign(jwt::algorithm::rs512(kRsa512PubKeyPem, kRsa512PrivKeyPem, "", ""));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtPS256) {
  // Cryptographic algorithm: PS256.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "PS256",
      kRsa1024PubKeyJwkN, kRsa1024PubKeyJwkE, kKid2, "PS256",
      kRsaInvalidPubKeyJwkN, kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(2, jwks->GetRSAPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupRSAPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kRsa1024PubKeyPem, key1->get_key());

  // Create a JWT token and sign it with PS256.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("PS256")
          .set_key_id(kKid1)
          .set_payload_claim("username", picojson::value("kudu"))
          .sign(jwt::algorithm::ps256(kRsa1024PubKeyPem, kRsa1024PrivKeyPem, "", ""));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtPS384) {
  // Cryptographic algorithm: PS384.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "PS384",
      kRsa2048PubKeyJwkN, kRsa2048PubKeyJwkE, kKid2, "PS384",
      kRsaInvalidPubKeyJwkN, kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(2, jwks->GetRSAPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupRSAPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kRsa2048PubKeyPem, key1->get_key());

  // Create a JWT token and sign it with PS384.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("PS384")
          .set_key_id(kKid1)
          .set_payload_claim("username", picojson::value("kudu"))
          .sign(jwt::algorithm::ps384(kRsa2048PubKeyPem, kRsa2048PrivKeyPem, "", ""));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtPS512) {
  // Cryptographic algorithm: PS512.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "PS512",
      kRsa4096PubKeyJwkN, kRsa4096PubKeyJwkE, kKid2, "PS512",
      kRsaInvalidPubKeyJwkN, kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(2, jwks->GetRSAPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupRSAPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kRsa4096PubKeyPem, key1->get_key());

  // Create a JWT token and sign it with PS512.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("PS512")
          .set_key_id(kKid1)
          .set_payload_claim("username", picojson::value("kudu"))
          .sign(jwt::algorithm::ps512(kRsa4096PubKeyPem, kRsa4096PrivKeyPem, "", ""));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtES256) {
  // Cryptographic algorithm: ES256.
  TempTestDataFile jwks_file(Substitute(kJwksEcFileFormat, kKid1, "P-256",
      kEcdsa256PubKeyJwkX, kEcdsa256PubKeyJwkY));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(1, jwks->GetECPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupECPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kEcdsa256PubKeyPem, key1->get_key());

  // Create a JWT token and sign it with ES256.
  auto token = jwt::create()
                   .set_issuer("auth0")
                   .set_type("JWS")
                   .set_algorithm("ES256")
                   .set_key_id(kKid1)
                   .set_payload_claim("username", picojson::value("kudu"))
                   .sign(jwt::algorithm::es256(
                       kEcdsa256PubKeyPem, kEcdsa256PrivKeyPem, "", ""));

  // Verify the JWT token with jwt-cpp APIs directly.
  auto jwt_decoded_token = jwt::decode(token);
  auto verifier =
      jwt::verify()
          .allow_algorithm(jwt::algorithm::es256(kEcdsa256PubKeyPem, "", "", ""))
          .with_issuer("auth0");
  verifier.verify(jwt_decoded_token);

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtES384) {
  // Cryptographic algorithm: ES384.
  TempTestDataFile jwks_file(Substitute(kJwksEcFileFormat, kKid1, "P-384",
      kEcdsa384PubKeyJwkX, kEcdsa384PubKeyJwkY));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(1, jwks->GetECPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupECPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kEcdsa384PubKeyPem, key1->get_key());

  // Create a JWT token and sign it with ES384.
  auto token = jwt::create()
                   .set_issuer("auth0")
                   .set_type("JWS")
                   .set_algorithm("ES384")
                   .set_key_id(kKid1)
                   .set_payload_claim("username", picojson::value("kudu"))
                   .sign(jwt::algorithm::es384(
                       kEcdsa384PubKeyPem, kEcdsa384PrivKeyPem, "", ""));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtES512) {
  // Cryptographic algorithm: ES512.
  TempTestDataFile jwks_file(Substitute(kJwksEcFileFormat, kKid1, "P-521",
      kEcdsa521PubKeyJwkX, kEcdsa521PubKeyJwkY));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);
  JWKSSnapshotPtr jwks = jwt_helper.GetJWKS();
  ASSERT_EQ(1, jwks->GetECPublicKeyNum());

  const JWTPublicKey* key1 = jwks->LookupECPublicKey(kKid1);
  ASSERT_TRUE(key1 != nullptr);
  ASSERT_EQ(kEcdsa521PubKeyPem, key1->get_key());

  // Create a JWT token and sign it with ES512.
  auto token = jwt::create()
                   .set_issuer("auth0")
                   .set_type("JWS")
                   .set_algorithm("ES512")
                   .set_key_id(kKid1)
                   .set_payload_claim("username", picojson::value("kudu"))
                   .sign(jwt::algorithm::es512(
                       kEcdsa521PubKeyPem, kEcdsa521PrivKeyPem, "", ""));

  // Verify the JWT token with our wrapper class which use public key retrieved from JWKS,
  // and read username from the token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtNotVerifySignature) {
  // Create a JWT token and sign it with RS256.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS256")
          .set_payload_claim("username", picojson::value("kudu"))
          .sign(jwt::algorithm::rs256(kRsaPubKeyPem, kRsaPrivKeyPem, "", ""));

  // Do not verify signature.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  Status status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  string username;
  status = JWTHelper::GetCustomClaimUsername(decoded_token.get(), "username", username);
  EXPECT_OK(status);
  ASSERT_EQ("kudu", username);
}

TEST(JwtUtilTest, VerifyJwtFailMismatchingAlgorithms) {
  // JWT algorithm is not matching with algorithm in JWK.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS256",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);

  // Create a JWT token, but set mismatching algorithm.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS512")
          .set_key_id(kKid1)
          .sign(jwt::algorithm::rs256(kRsaPubKeyPem, kRsaPrivKeyPem, "", ""));
  // Failed to verify the token due to mismatching algorithms.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  ASSERT_TRUE(status.IsNotAuthorized()) << status.ToString();
  ASSERT_STR_CONTAINS(status.ToString(),
      "JWT algorithm 'rs512' is not matching with JWK algorithm 'rs256'");
}

TEST(JwtUtilTest, VerifyJwtFailKeyNotFound) {
  // The key cannot be found in JWKS.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS256",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);

  // Create a JWT token with a key ID which can not be found in JWKS.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS256")
          .set_key_id("unfound-key-id")
          .sign(jwt::algorithm::rs256(kRsaPubKeyPem, kRsaPrivKeyPem, "", ""));
  // Failed to verify the token since key is not found in JWKS.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  ASSERT_TRUE(status.IsNotAuthorized()) << status.ToString();
  ASSERT_STR_CONTAINS(status.ToString(), "Invalid JWK ID in the JWT token");
}

TEST(JwtUtilTest, VerifyJwtTokenWithoutKeyId) {
  // Verify JWT token without key ID.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS256",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);

  // Create a JWT token without key ID.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS256")
          .sign(jwt::algorithm::rs256(kRsaPubKeyPem, kRsaPrivKeyPem, "", ""));
  // Verify the token by trying each key in JWK set and there is one matched key.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  EXPECT_OK(status);
}

TEST(JwtUtilTest, VerifyJwtFailTokenWithoutKeyId) {
  // Verify JWT token without key ID.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS256",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);

  // Create a JWT token without key ID.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS512")
          .sign(jwt::algorithm::rs512(kRsa512PubKeyPem, kRsa512PrivKeyPem, "", ""));
  // Verify the token by trying each key in JWK set, but there is no matched key.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  ASSERT_FALSE(status.ok());
}

TEST(JwtUtilTest, VerifyJwtFailTokenWithoutSignature) {
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS256",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);

  // Create a JWT token without signature.
  auto token =
      jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::none{});
  // Failed to verify the unsigned token.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  ASSERT_TRUE(status.IsNotAuthorized()) << status.ToString();
  ASSERT_STR_CONTAINS(status.ToString(), "Unsecured JWT");
}

TEST(JwtUtilTest, VerifyJwtFailExpiredToken) {
  // Sign JWT token with RS256.
  TempTestDataFile jwks_file(Substitute(kJwksRsaFileFormat, kKid1, "RS256",
      kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
      kRsaPubKeyJwkE));
  JWTHelper jwt_helper;
  Status status = jwt_helper.Init(jwks_file.Filename());
  EXPECT_OK(status);

  // Create a JWT token and sign it with RS256.
  auto token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWS")
          .set_algorithm("RS256")
          .set_key_id(kKid1)
          .set_issued_at(std::chrono::system_clock::now())
          .set_expires_at(std::chrono::system_clock::now() - std::chrono::seconds{10})
          .set_payload_claim("username", picojson::value("kudu"))
          .sign(jwt::algorithm::rs256(kRsaPubKeyPem, kRsaPrivKeyPem, "", ""));

  // Verify the token, including expiring time.
  JWTHelper::UniqueJWTDecodedToken decoded_token;
  status = JWTHelper::Decode(token, decoded_token);
  EXPECT_OK(status);
  status = jwt_helper.Verify(decoded_token.get());
  ASSERT_TRUE(status.IsNotAuthorized()) << status.ToString();
  ASSERT_STR_CONTAINS(status.ToString(), "JWT verification failed: token expired");
}

namespace {

// Returns a simple JWKS to be used by tokens signed by 'rsa_pub_key_pem' and
// 'rsa_priv_key_pem'.
void SimpleJWKSHandler(const Webserver::WebRequest& /*req*/,
                       Webserver::PrerenderedWebResponse* resp) {
  resp->output <<
      Substitute(kJwksRsaFileFormat, kKid1, "RS256",
          kRsaPubKeyJwkN, kRsaPubKeyJwkE, kKid2, "RS256", kRsaInvalidPubKeyJwkN,
          kRsaPubKeyJwkE);
  resp->status_code = HttpStatusCode::Ok;
}

class JWKSMockServer {
 public:
  // Registers a path handler for a single JWKS to be used by tokens signed by
  // 'rsa_pub_key_pem' and 'rsa_priv_key_pem'.
  Status Start() {
    WebserverOptions opts;
    opts.port = 0;
    opts.bind_interface = "127.0.0.1";
    webserver_.reset(new Webserver(opts));
    webserver_->RegisterPrerenderedPathHandler("/jwks", "JWKS", SimpleJWKSHandler,
                                               /*is_styled*/false, /*is_on_nav_bar*/false);
    RETURN_NOT_OK(webserver_->Start());
    vector<Sockaddr> addrs;
    RETURN_NOT_OK(webserver_->GetBoundAddresses(&addrs));
    url_ = Substitute("http://$0/jwks", addrs[0].ToString());
    return Status::OK();
  }

  // Register a path handler for every account ID in 'account_id_to_resp' that
  // returns the correspodning HTTP response.
  Status StartWithAccounts(const unordered_map<string, string>& account_id_to_resp) {
    DCHECK(!webserver_);
    WebserverOptions opts;
    opts.port = 0;
    opts.bind_interface = "127.0.0.1";
    webserver_.reset(new Webserver(opts));
    for (const auto& ar : account_id_to_resp) {
      const auto& account_id = ar.first;
      const auto& jwks = ar.second;
      webserver_->RegisterPrerenderedPathHandler(Substitute("/jwks/$0", account_id), account_id,
          [account_id, jwks] (const Webserver::WebRequest& /*req*/,
                              Webserver::PrerenderedWebResponse* resp) {
            resp->output << jwks;
            resp->status_code = HttpStatusCode::Ok;
          },
          /*is_styled*/false, /*is_on_nav_bar*/false);
    }
    RETURN_NOT_OK(webserver_->Start());
    vector<Sockaddr> addrs;
    RETURN_NOT_OK(webserver_->GetBoundAddresses(&addrs));
    url_ = Substitute("http://$0/jwks", addrs[0].ToString());
    return Status::OK();
  }

  const string& url() const {
    return url_;
  }

  string url_for_account(const string& account_id) const {
    return Substitute("$0/$1", url_, account_id);
  }
 private:
  unique_ptr<Webserver> webserver_;
  string url_;
};

} // anonymous namespace

TEST(JwtUtilTest, VerifyJWKSUrl) {
  JWKSMockServer jwks_server;
  ASSERT_OK(jwks_server.Start());

  auto encoded_token =
      jwt::create()
          .set_issuer("auth0")
          .set_type("JWT")
          .set_algorithm("RS256")
          .set_key_id(kKid1)
          .set_subject("kudu")
          .sign(jwt::algorithm::rs256(kRsaPubKeyPem, kRsaPrivKeyPem, "", ""));
  ASSERT_EQ(
      "eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzpjNDI0YjY3Yi1mZTI4LTQ1ZDctYjAxNS1mNzlkYTUwYjViMjEiLCJ0"
      "eXAiOiJKV1QifQ.eyJpc3MiOiJhdXRoMCIsInN1YiI6Imt1ZHUifQ.VENjfXICRV1lr2M-jBElI_qaBZNFILjkXr1Amg"
      "poH8xlI41EFN8RVkihuJtFijUOEFxJ537LCEonDBHsouO9iQlrxh0AobIjB1QraqG1BoQLnKWF78E-rhPN2K1aueGed7"
      "A86lkIEB4s7VU9dSDtR3bwbP5RFaf3XRZ6TyVh0h5sdMo91YKpS6nLCvYh2OSIbsUJCSNu4BoCmDz97Wq1xLiDoRfAJh"
      "BZiHQeHO38ydRMWIeto78pV2s9sf1CdwVwycuJOfnKY_-M5-fl1hW_25kSTNt33L57a5BgbGZ1sabWP3AD__-HYD2muR"
      "klbfyYn_ghqjL7ihY2ECaZzZ0Utw",
      encoded_token);
  KeyBasedJwtVerifier jwt_verifier(jwks_server.url(),
                                   /*jwks_verify_server_certificate*/ false,
                                   /*jwks_ca_certificate*/ "");

  ASSERT_OK(jwt_verifier.Init());
  string subject;
  ASSERT_OK(jwt_verifier.VerifyToken(encoded_token, &subject));
  ASSERT_EQ("kudu", subject);
}

namespace {
const char kValidAccount[] = "new-phone";
const char kInvalidAccount[] = "who-is-this";
const char kMissingAccount[] = "no-one";
} // anonymous namespace

TEST(JwtUtilTest, VerifyOIDCDiscoveryEndpoint) {
  MiniOidcOptions opts;
  opts.account_ids = {
    { kValidAccount, /*is_valid*/true },
    { kInvalidAccount, /*is_valid*/false },
  };
  MiniOidc oidc(std::move(opts));
  ASSERT_OK(oidc.Start());

  const PerAccountKeyBasedJwtVerifier jwt_verifier(oidc.url(),
                                                   /*jwks_verify_server_certificate*/ false,
                                                   /*jwks_ca_certificate*/ "");

  // Create and verify a token on the happy path.
  const string kSubject = "kudu";
  auto valid_user_token =
      oidc.CreateJwt(kValidAccount, kSubject, /*is_valid*/true);
  string subject;
  ASSERT_OK(jwt_verifier.VerifyToken(valid_user_token, &subject));
  ASSERT_EQ(kSubject, subject);

  // Verify some expected failure scenarios.
  const unordered_map<string, string> invalid_jwts {
    { oidc.CreateJwt(kInvalidAccount, kSubject, false), "invalid issuer with invalid "
       "subject" },
    { oidc.CreateJwt(kInvalidAccount, kSubject, true), "invalid issuer with valid subject" },
    { oidc.CreateJwt(kValidAccount, kSubject, false), "valid issuer with invalid key id" },
    { oidc.CreateJwt(kMissingAccount, kSubject, true), "missing account" },
  };

  for (const auto& [jwt, msg] : invalid_jwts) {
    string invalid_subject;
    const Status s = jwt_verifier.VerifyToken(jwt, &invalid_subject);
    EXPECT_FALSE(s.ok()) << Substitute("failed case $0: $1", msg, s.ToString());
  }
}

TEST(JwtUtilTest, VerifyJWKSDiscoveryEndpointMultipleClients) {
  MiniOidcOptions opts;
  opts.account_ids = {
      { kValidAccount, /*is_valid*/true }
  };
  MiniOidc oidc(std::move(opts));
  ASSERT_OK(oidc.Start());
  PerAccountKeyBasedJwtVerifier jwt_verifier(oidc.url(),
                                             /*jwks_verify_server_certificate*/ false,
                                             /*jwks_ca_certificate*/ "");

  {
    const string kSubject = "kudu";
    auto valid_user_token =
        oidc.CreateJwt(kValidAccount, kSubject, /*is_valid*/true);
    string subject;
    ASSERT_OK(jwt_verifier.VerifyToken(valid_user_token, &subject));
    ASSERT_EQ(kSubject, subject);

    int constexpr n = 8;
    std::vector<std::thread> threads;
    threads.reserve(n);
    CountDownLatch latch(n);

    for (int i = 0; i < n; i++) {
      threads.emplace_back([&](){
        string subject;
        CHECK_OK(jwt_verifier.VerifyToken(valid_user_token, &subject));
        CHECK_EQ(kSubject, subject);
        latch.CountDown();
      });
    }

    latch.Wait();
    SCOPED_CLEANUP({
      for (auto& t : threads) {
        t.join();
      }
    });
  }
}

} // namespace kudu
