// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Token manager integration tests using dev auth provider.

#include <fuchsia/auth/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/testing/test_with_environment.h>

#include <memory>
#include <string>

#include "gtest/gtest.h"
#include "lib/callback/capture.h"
#include "lib/fidl/cpp/binding.h"
#include "lib/fidl/cpp/synchronous_interface_ptr.h"
#include "src/lib/fxl/command_line.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/strings/string_view.h"

namespace e2e_dev {
namespace {

struct TestComponentParam {
  const std::string auth_provider_type;
  const char* auth_provider_url;
};

const std::string kEnvironment = "dev_token_mgr_test_env";
const std::string kTestUserId = "tq_auth_user_1";
const std::string kTestAppUrl = "/pkgfs/packages/test_auth_client/bin/app";
const std::string kDevIdp = "Dev";
const std::string kDevIotIDIdp = "DevIotID";
const bool kForce = true;

const std::string kTokenManagerFactoryUrl = "fuchsia-pkg://fuchsia.com/"
    "token_manager_factory#meta/token_manager_factory.cmx";
const TestComponentParam kTestComponentParams[] = {
    {kDevIdp,
     "fuchsia-pkg://fuchsia.com/dev_auth_provider#"
     "meta/dev_auth_provider.cmx"},
    {kDevIotIDIdp,
     "fuchsia-pkg://fuchsia.com/dev_auth_provider_iotid#"
     "meta/dev_auth_provider_iotid.cmx"}
};

fuchsia::auth::AppConfig MakeDevAppConfig(
    const std::string& auth_provider_type) {
  fuchsia::auth::AppConfig dev_app_config;
  dev_app_config.auth_provider_type = auth_provider_type;
  dev_app_config.client_id = "test_client_id";
  dev_app_config.client_secret = "test_client_secret";
  return dev_app_config;
}

using fuchsia::auth::AppConfig;
using fuchsia::auth::FirebaseTokenPtr;
using fuchsia::auth::Status;
using fuchsia::auth::TokenManagerFactory;
using fuchsia::auth::UserProfileInfoPtr;
using fuchsia::sys::LaunchInfo;
using sys::testing::EnclosingEnvironment;
using sys::testing::EnvironmentServices;

class DevTokenManagerAppTest
    : public sys::testing::TestWithEnvironment,
      public ::testing::WithParamInterface<TestComponentParam>,
      fuchsia::auth::AuthenticationContextProvider {
 public:
  DevTokenManagerAppTest()
      : auth_context_provider_binding_(this) {}

  ~DevTokenManagerAppTest() {}

 protected:
  // ::testing::Test:
  void SetUp() override {

    std::unique_ptr<EnvironmentServices> services = CreateServices();
    LaunchInfo launch_info;
    launch_info.url = kTokenManagerFactoryUrl;
    services->AddServiceWithLaunchInfo(std::move(launch_info), TokenManagerFactory::Name_);

    environment_ = CreateNewEnclosingEnvironment(kEnvironment, std::move(services));
    WaitForEnclosingEnvToStart(environment_.get());

    environment_->ConnectToService(token_mgr_factory_.NewRequest());
    ASSERT_TRUE(token_mgr_factory_.is_bound());

    std::string auth_provider_type = GetParam().auth_provider_type;
    dev_app_config_ = MakeDevAppConfig(auth_provider_type);

    fuchsia::auth::AuthProviderConfig dev_auth_provider_config;
    dev_auth_provider_config.auth_provider_type = auth_provider_type;
    dev_auth_provider_config.url = GetParam().auth_provider_url;
    std::vector<fuchsia::auth::AuthProviderConfig> auth_provider_configs;
    auth_provider_configs.push_back(std::move(dev_auth_provider_config));

    token_mgr_factory_->GetTokenManager(
        kTestUserId, kTestAppUrl, std::move(auth_provider_configs),
        auth_context_provider_binding_.NewBinding(), token_mgr_.NewRequest());
  }

  // ::testing::Test:
  void TearDown() override {
    // We attempt to clean up the tokens after each test. The Auth Provider
    // uses a different user_profile_id for each test and so any problems with
    // deletion should not impact test accuracy.
    if (token_mgr_.is_bound() && !user_profile_id_.is_null()) {
      bool call_complete = false;
      token_mgr_->DeleteAllTokens(dev_app_config_, user_profile_id_, kForce,
                [&] (Status status) {call_complete = true;});
      RunLoopUntil([&] {return call_complete;});
    }
  }

  // |AuthenticationContextProvider|
  void GetAuthenticationUIContext(
      fidl::InterfaceRequest<fuchsia::auth::AuthenticationUIContext> request)
      override {
    // Silently ignore this request. The TokenManager will pass the other end
    // of the channel into the dev auth provider, which will never attempt to
    // use it since it does not display UI.
  }

 private:
  std::unique_ptr<EnclosingEnvironment> environment_;

 protected:
  fidl::Binding<fuchsia::auth::AuthenticationContextProvider>
      auth_context_provider_binding_;

  fuchsia::auth::AppConfig dev_app_config_;
  fuchsia::auth::TokenManagerPtr token_mgr_;
  fuchsia::auth::TokenManagerFactoryPtr token_mgr_factory_;
  fidl::StringPtr user_profile_id_;

  void RegisterUser(fuchsia::auth::AppConfig app_config) {
    auto scopes = fidl::VectorPtr<std::string>::New(0);
    scopes.push_back("test_scope");

    bool call_complete = false;
    token_mgr_->Authorize(
        app_config, nullptr,   /* optional AuthenticationUiContext */
        std::move(scopes), "", /* new user, no existing user_profile_id */
        "",                    /* empty auth_code */
        [&](Status status, UserProfileInfoPtr user_info)  {
            EXPECT_EQ(Status::OK, status);
            EXPECT_NE(nullptr, user_info);
            user_profile_id_ = user_info->id;
            call_complete = true;
        });
    RunLoopUntil([&] {return call_complete;});
  }

  FXL_DISALLOW_COPY_AND_ASSIGN(DevTokenManagerAppTest);
};

TEST_P(DevTokenManagerAppTest, Authorize) {
  auto scopes = fidl::VectorPtr<std::string>::New(0);
  scopes.push_back("test_scope");
  bool call_complete = false;
  token_mgr_->Authorize(
      dev_app_config_, nullptr, /* optional AuthenticationUiContext */
      std::move(scopes), "",    /* new user, no existing user_profile_id */
      "",                       /* empty auth_code */
      [&](Status status, UserProfileInfoPtr user_info)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_NE(nullptr, user_info);
          EXPECT_FALSE(user_info->id.empty());
          EXPECT_FALSE(user_info->display_name.get().empty());
          EXPECT_FALSE(user_info->url.get().empty());
          EXPECT_FALSE(user_info->image_url.get().empty());
          call_complete = true;
      });

  RunLoopUntil([&] {return call_complete;});
}

TEST_P(DevTokenManagerAppTest, GetAccessToken) {
  RegisterUser(dev_app_config_);
  auto scopes = fidl::VectorPtr<std::string>::New(0);
  bool call_complete = false;
  token_mgr_->GetAccessToken(
       dev_app_config_, user_profile_id_, std::move(scopes),
       [&](Status status, fidl::StringPtr access_token)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_NE(std::string::npos, access_token.get().find(":at_"));
          call_complete = true;
      });
  RunLoopUntil([&] {return call_complete;});
}

TEST_P(DevTokenManagerAppTest, GetIdToken) {
  RegisterUser(dev_app_config_);
  bool call_complete = false;
  token_mgr_->GetIdToken(
       dev_app_config_, user_profile_id_, "",
       [&](Status status, fidl::StringPtr id_token)  {
          if (dev_app_config_.auth_provider_type == kDevIotIDIdp) {
            // TODO(ukode): Not yet supported for IotID
            EXPECT_EQ(Status::INVALID_REQUEST, status);
          } else {
            EXPECT_EQ(Status::OK, status);
            EXPECT_NE(std::string::npos, id_token.get().find(":idt_"));
          }
          call_complete = true;
      });
  RunLoopUntil([&] {return call_complete;});
}

TEST_P(DevTokenManagerAppTest, GetFirebaseToken) {
  RegisterUser(dev_app_config_);
  bool call_complete = false;
  token_mgr_->GetFirebaseToken(
      dev_app_config_, user_profile_id_, "firebase_test_api_key", "",
      [&](Status status, FirebaseTokenPtr firebase_token)  {
        if (dev_app_config_.auth_provider_type == kDevIotIDIdp) {
          // TODO(ukode): Not yet supported for IotID
          EXPECT_EQ(Status::INVALID_REQUEST, status);
        } else {
          EXPECT_EQ(Status::OK, status);
          EXPECT_NE(std::string::npos, firebase_token->id_token.find(":fbt_"));
          EXPECT_NE(std::string::npos, firebase_token->email.get().find("@firebase.example.com"));
          EXPECT_NE(std::string::npos, firebase_token->local_id.get().find("local_id_"));
        }
        call_complete = true;
  });
  RunLoopUntil([&] {return call_complete;});
}

TEST_P(DevTokenManagerAppTest, GetFirebaseTokenFromCache) {
  // TODO(ukode): Not yet supported for IotID
  if (dev_app_config_.auth_provider_type == kDevIotIDIdp) {
    return;
  }

  FirebaseTokenPtr firebase_token;
  FirebaseTokenPtr other_firebase_token;
  FirebaseTokenPtr cached_firebase_token;

  RegisterUser(dev_app_config_);

  bool last_call_complete = false;
  token_mgr_->GetFirebaseToken(
      dev_app_config_, user_profile_id_, "", "key1",
      [&](Status status, FirebaseTokenPtr token)  {
          EXPECT_EQ(Status::OK, status);
          firebase_token = std::move(token);
      });
  token_mgr_->GetFirebaseToken(
      dev_app_config_, user_profile_id_, "", "key2",
      [&](Status status, FirebaseTokenPtr token)  {
          EXPECT_EQ(Status::OK, status);
          other_firebase_token = std::move(token);
      });
  token_mgr_->GetFirebaseToken(
      dev_app_config_, user_profile_id_, "", "key1",
      [&](Status status, FirebaseTokenPtr token)  {
          EXPECT_EQ(Status::OK, status);
          cached_firebase_token = std::move(token);
          last_call_complete = true;
      });

  RunLoopUntil([&] {return last_call_complete;});
  EXPECT_NE(firebase_token->id_token, other_firebase_token->id_token);
  EXPECT_EQ(firebase_token->id_token, cached_firebase_token->id_token);
  EXPECT_EQ(firebase_token->email, cached_firebase_token->email);
  EXPECT_EQ(firebase_token->local_id, cached_firebase_token->local_id);
}

TEST_P(DevTokenManagerAppTest, EraseAllTokens) {
  // TODO(ukode): Not yet supported for IotID
  if (dev_app_config_.auth_provider_type == kDevIotIDIdp) {
    return;
  }

  RegisterUser(dev_app_config_);
  bool last_call_complete = false;

  token_mgr_->GetIdToken(
       dev_app_config_, user_profile_id_, "",
       [&](Status status, fidl::StringPtr id_token)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_NE(nullptr, id_token);
      });

  auto scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->GetAccessToken(
       dev_app_config_, user_profile_id_, std::move(scopes),
       [&](Status status, fidl::StringPtr access_token)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_NE(nullptr, access_token);
      });

  token_mgr_->GetFirebaseToken(
      dev_app_config_, user_profile_id_, "", "",
      [&](Status status, FirebaseTokenPtr firebase_token)  {
        EXPECT_EQ(Status::OK, status);
        EXPECT_NE(nullptr, firebase_token);
  });

  token_mgr_->DeleteAllTokens(
      dev_app_config_, user_profile_id_, kForce,
      [&](Status status)  {
        EXPECT_EQ(Status::OK, status);
      });

  token_mgr_->GetIdToken(
       dev_app_config_, user_profile_id_, "",
       [&](Status status, fidl::StringPtr id_token)  {
          EXPECT_EQ(Status::USER_NOT_FOUND, status);
      });

  scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->GetAccessToken(
       dev_app_config_, user_profile_id_, std::move(scopes),
       [&](Status status, fidl::StringPtr access_token)  {
          EXPECT_EQ(Status::USER_NOT_FOUND, status);
      });

  token_mgr_->GetFirebaseToken(
      dev_app_config_, user_profile_id_, "", "",
      [&](Status status, FirebaseTokenPtr firebase_token)  {
        EXPECT_EQ(Status::USER_NOT_FOUND, status);
        last_call_complete = true;
  });

  RunLoopUntil([&] {return last_call_complete;});
}

TEST_P(DevTokenManagerAppTest, GetIdTokenFromCache) {
  // TODO(ukode): Not yet supported for IotID
  if (dev_app_config_.auth_provider_type == kDevIotIDIdp) {
    return;
  }

  fidl::StringPtr id_token;
  fidl::StringPtr second_user_id_token;

  RegisterUser(dev_app_config_);

  bool last_call_complete = false;
  token_mgr_->GetIdToken(
       dev_app_config_, user_profile_id_, "",
       [&](Status status, fidl::StringPtr token)  {
          EXPECT_EQ(Status::OK, status);
          id_token = std::move(token);
      });

  token_mgr_->GetIdToken(
       dev_app_config_, user_profile_id_, "",
       [&](Status status, fidl::StringPtr token)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_EQ(id_token.get(), token.get());
      });

  // Verify ID tokens are different for different user to prevent a
  // degenerate test.
  fidl::StringPtr original_user_profile_id = user_profile_id_;
  RegisterUser(dev_app_config_);
  EXPECT_NE(user_profile_id_, original_user_profile_id);
  token_mgr_->GetIdToken(
       dev_app_config_, user_profile_id_, "",
       [&](Status status, fidl::StringPtr token)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_NE(id_token.get(), token.get());
          last_call_complete = true;
      });

  RunLoopUntil([&] {return last_call_complete;});
}

TEST_P(DevTokenManagerAppTest, GetAccessTokenFromCache) {
  fidl::StringPtr access_token;

  RegisterUser(dev_app_config_);

  bool last_call_complete = false;
  auto scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->GetAccessToken(
       dev_app_config_, user_profile_id_, std::move(scopes),
       [&](Status status, fidl::StringPtr token)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_NE(std::string::npos, token.get().find(":at_"));
          access_token = std::move(token);
      });

  scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->GetAccessToken(
       dev_app_config_, user_profile_id_, std::move(scopes),
       [&](Status status, fidl::StringPtr token)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_EQ(access_token.get(), token.get());
          last_call_complete = true;
      });

  RunLoopUntil([&] {return last_call_complete;});
}

// Tests user re-authorization flow that generates fresh long lived credentials
// and verifies that short lived credentials are based on the most recent long
// lived credentials.
TEST_P(DevTokenManagerAppTest, Reauthorize) {
  fidl::StringPtr user_profile_id;
  std::string credential;
  bool authorize_complete = false;
  bool last_call_complete = false;

  auto scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->Authorize(
        dev_app_config_, nullptr, std::move(scopes), "", "",
        [&](Status status, UserProfileInfoPtr user_info)  {
            EXPECT_EQ(Status::OK, status);
            user_profile_id = user_info->id;
            authorize_complete = true;
        });
  RunLoopUntil([&] {return authorize_complete;});

  scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->GetAccessToken(
       dev_app_config_, user_profile_id, std::move(scopes),
       [&](Status status, fidl::StringPtr access_token)  {
          EXPECT_EQ(Status::OK, status);
          // Extract part of the fake access token reflecting the refresh token
          credential = access_token->substr(0, access_token->find(":"));
      });

  token_mgr_->DeleteAllTokens(
      dev_app_config_, user_profile_id, kForce,
      [&](Status status)  {
        EXPECT_EQ(Status::OK, status);
      });

  // Verify that the credential and cache should now be cleared
  scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->GetAccessToken(
       dev_app_config_, user_profile_id, std::move(scopes),
       [&](Status status, fidl::StringPtr access_token)  {
          EXPECT_EQ(Status::USER_NOT_FOUND, status);
          EXPECT_EQ(nullptr, access_token);
      });

  // Re-authorize the same |user_profile_id|
  scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->Authorize(
        dev_app_config_, nullptr, std::move(scopes), user_profile_id, "",
        [&](Status status, UserProfileInfoPtr user_info)  {
            EXPECT_EQ(Status::OK, status);
            EXPECT_EQ(user_info->id, user_profile_id);
        });

  // Verify that new access token is not based on the original credential
  scopes = fidl::VectorPtr<std::string>::New(0);
  token_mgr_->GetAccessToken(
       dev_app_config_, user_profile_id, std::move(scopes),
       [&](Status status, fidl::StringPtr access_token)  {
          EXPECT_EQ(Status::OK, status);
          EXPECT_NE(nullptr, access_token);
          EXPECT_EQ(std::string::npos, access_token.get().find(credential));
          last_call_complete = true;
      });

  RunLoopUntil([&] {return last_call_complete;});
}

INSTANTIATE_TEST_SUITE_P(Cpp, DevTokenManagerAppTest,
                         ::testing::ValuesIn(kTestComponentParams));
}  // namespace
}  // namespace e2e_dev
