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

#include "src/privet/auth_manager.h"

#include <algorithm>

#include <base/bind.h>
#include <base/guid.h>
#include <base/rand_util.h>
#include <base/strings/string_number_conversions.h>

#include "src/access_black_list_manager.h"
#include "src/config.h"
#include "src/data_encoding.h"
#include "src/privet/constants.h"
#include "src/privet/openssl_utils.h"
#include "src/string_utils.h"

extern "C" {
#include "third_party/libuweave/src/macaroon.h"
#include "third_party/libuweave/src/macaroon_caveat_internal.h"
}

namespace weave {
namespace privet {

namespace {

const time_t kJ2000ToTimeT = 946684800;
const size_t kMaxMacaroonSize = 1024;
const size_t kMaxPendingClaims = 10;
const char kInvalidTokenError[] = "invalid_token";
const int kSessionIdTtlMinutes = 1;

uint32_t ToJ2000Time(const base::Time& time) {
  return std::max(time.ToTimeT(), kJ2000ToTimeT) - kJ2000ToTimeT;
}

base::Time FromJ2000Time(uint32_t time) {
  return base::Time::FromTimeT(time + kJ2000ToTimeT);
}

template <class T>
void AppendToArray(T value, std::vector<uint8_t>* array) {
  auto begin = reinterpret_cast<const uint8_t*>(&value);
  array->insert(array->end(), begin, begin + sizeof(value));
}

class Caveat {
 public:
  Caveat(UwMacaroonCaveatType type, size_t str_len)
      : buffer_(uw_macaroon_caveat_creation_get_buffsize_(type, str_len)) {
    CHECK(!buffer_.empty());
  }
  const UwMacaroonCaveat& GetCaveat() const { return caveat_; }

 protected:
  UwMacaroonCaveat caveat_{};
  std::vector<uint8_t> buffer_;

  DISALLOW_COPY_AND_ASSIGN(Caveat);
};

class ScopeCaveat : public Caveat {
 public:
  explicit ScopeCaveat(UwMacaroonCaveatScopeType scope)
      : Caveat(kUwMacaroonCaveatTypeScope, 0) {
    CHECK(uw_macaroon_caveat_create_scope_(scope, buffer_.data(),
                                           buffer_.size(), &caveat_));
  }

  DISALLOW_COPY_AND_ASSIGN(ScopeCaveat);
};

class TimestampCaveat : public Caveat {
 public:
  explicit TimestampCaveat(const base::Time& timestamp)
      : Caveat(kUwMacaroonCaveatTypeDelegationTimestamp, 0) {
    CHECK(uw_macaroon_caveat_create_delegation_timestamp_(
        ToJ2000Time(timestamp), buffer_.data(), buffer_.size(), &caveat_));
  }

  DISALLOW_COPY_AND_ASSIGN(TimestampCaveat);
};

class ExpirationCaveat : public Caveat {
 public:
  explicit ExpirationCaveat(const base::Time& timestamp)
      : Caveat(kUwMacaroonCaveatTypeExpirationAbsolute, 0) {
    CHECK(uw_macaroon_caveat_create_expiration_absolute_(
        ToJ2000Time(timestamp), buffer_.data(), buffer_.size(), &caveat_));
  }

  DISALLOW_COPY_AND_ASSIGN(ExpirationCaveat);
};

class UserIdCaveat : public Caveat {
 public:
  explicit UserIdCaveat(const std::vector<uint8_t>& id)
      : Caveat(kUwMacaroonCaveatTypeDelegateeUser, id.size()) {
    CHECK(uw_macaroon_caveat_create_delegatee_user_(
        id.data(), id.size(), buffer_.data(), buffer_.size(), &caveat_));
  }

  DISALLOW_COPY_AND_ASSIGN(UserIdCaveat);
};

class AppIdCaveat : public Caveat {
 public:
  explicit AppIdCaveat(const std::vector<uint8_t>& id)
      : Caveat(kUwMacaroonCaveatTypeDelegateeApp, id.size()) {
    CHECK(uw_macaroon_caveat_create_delegatee_app_(
        id.data(), id.size(), buffer_.data(), buffer_.size(), &caveat_));
  }

  DISALLOW_COPY_AND_ASSIGN(AppIdCaveat);
};

class ServiceCaveat : public Caveat {
 public:
  explicit ServiceCaveat(UwMacaroonCaveatCloudServiceId service_id)
      : Caveat(kUwMacaroonCaveatTypeDelegateeService, 0) {
    CHECK(uw_macaroon_caveat_create_delegatee_service_(
        service_id, buffer_.data(), buffer_.size(), &caveat_));
  }

  DISALLOW_COPY_AND_ASSIGN(ServiceCaveat);
};

class SessionIdCaveat : public Caveat {
 public:
  explicit SessionIdCaveat(const std::string& id)
      : Caveat(kUwMacaroonCaveatTypeLanSessionID, id.size()) {
    CHECK(uw_macaroon_caveat_create_lan_session_id_(
        reinterpret_cast<const uint8_t*>(id.data()), id.size(), buffer_.data(),
        buffer_.size(), &caveat_));
  }

  DISALLOW_COPY_AND_ASSIGN(SessionIdCaveat);
};

class ClientAuthTokenCaveat : public Caveat {
 public:
  ClientAuthTokenCaveat()
      : Caveat(kUwMacaroonCaveatTypeClientAuthorizationTokenV1, 0) {
    CHECK(uw_macaroon_caveat_create_client_authorization_token_(
        nullptr, 0, buffer_.data(), buffer_.size(), &caveat_));
  }

  DISALLOW_COPY_AND_ASSIGN(ClientAuthTokenCaveat);
};

std::vector<uint8_t> CreateSecret() {
  std::vector<uint8_t> secret(kSha256OutputSize);
  base::RandBytes(secret.data(), secret.size());
  return secret;
}

bool IsClaimAllowed(RootClientTokenOwner curret, RootClientTokenOwner claimer) {
  return claimer > curret || claimer == RootClientTokenOwner::kCloud;
}

std::vector<uint8_t> CreateMacaroonToken(
    const std::vector<uint8_t>& secret,
    const base::Time& time,
    const std::vector<const UwMacaroonCaveat*>& caveats) {
  CHECK_EQ(kSha256OutputSize, secret.size());

  UwMacaroonContext context{};
  CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, nullptr, 0,
                                    &context));

  UwMacaroon macaroon{};
  CHECK(uw_macaroon_create_from_root_key_(&macaroon, secret.data(),
                                          secret.size(), &context,
                                          caveats.data(), caveats.size()));

  std::vector<uint8_t> serialized_token(kMaxMacaroonSize);
  size_t len = 0;
  CHECK(uw_macaroon_serialize_(&macaroon, serialized_token.data(),
                               serialized_token.size(), &len));
  serialized_token.resize(len);

  return serialized_token;
}

std::vector<uint8_t> ExtendMacaroonToken(
    const UwMacaroon& macaroon,
    const base::Time& time,
    const std::vector<const UwMacaroonCaveat*>& caveats) {
  UwMacaroonContext context{};
  CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, nullptr, 0,
                                    &context));

  UwMacaroon prev_macaroon = macaroon;
  std::vector<uint8_t> prev_buffer(kMaxMacaroonSize);
  std::vector<uint8_t> new_buffer(kMaxMacaroonSize);

  for (auto caveat : caveats) {
    UwMacaroon new_macaroon{};
    CHECK(uw_macaroon_extend_(&prev_macaroon, &new_macaroon, &context, caveat,
                              new_buffer.data(), new_buffer.size()));
    new_buffer.swap(prev_buffer);
    prev_macaroon = new_macaroon;
  }

  std::vector<uint8_t> serialized_token(kMaxMacaroonSize);
  size_t len = 0;
  CHECK(uw_macaroon_serialize_(&prev_macaroon, serialized_token.data(),
                               serialized_token.size(), &len));
  serialized_token.resize(len);

  return serialized_token;
}

bool LoadMacaroon(const std::vector<uint8_t>& token,
                  std::vector<uint8_t>* buffer,
                  UwMacaroon* macaroon,
                  ErrorPtr* error) {
  buffer->resize(kMaxMacaroonSize);
  if (!uw_macaroon_deserialize_(token.data(), token.size(), buffer->data(),
                                buffer->size(), macaroon)) {
    return Error::AddTo(error, FROM_HERE, kInvalidTokenError,
                        "Invalid token format");
  }
  return true;
}

bool VerifyMacaroon(const std::vector<uint8_t>& secret,
                    const UwMacaroon& macaroon,
                    const base::Time& time,
                    UwMacaroonValidationResult* result,
                    ErrorPtr* error) {
  CHECK_EQ(kSha256OutputSize, secret.size());
  UwMacaroonContext context = {};
  CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, nullptr, 0,
                                    &context));

  if (!uw_macaroon_validate_(&macaroon, secret.data(), secret.size(), &context,
                             result)) {
    return Error::AddTo(error, FROM_HERE, "invalid_token",
                        "Invalid token signature");
  }
  return true;
}

UwMacaroonCaveatScopeType ToMacaroonScope(AuthScope scope) {
  switch (scope) {
    case AuthScope::kViewer:
      return kUwMacaroonCaveatScopeTypeViewer;
    case AuthScope::kUser:
      return kUwMacaroonCaveatScopeTypeUser;
    case AuthScope::kManager:
      return kUwMacaroonCaveatScopeTypeManager;
    case AuthScope::kOwner:
      return kUwMacaroonCaveatScopeTypeOwner;
    default:
      NOTREACHED() << EnumToString(scope);
  }
  return kUwMacaroonCaveatScopeTypeViewer;
}

AuthScope FromMacaroonScope(uint32_t scope) {
  if (scope <= kUwMacaroonCaveatScopeTypeOwner)
    return AuthScope::kOwner;
  if (scope <= kUwMacaroonCaveatScopeTypeManager)
    return AuthScope::kManager;
  if (scope <= kUwMacaroonCaveatScopeTypeUser)
    return AuthScope::kUser;
  if (scope <= kUwMacaroonCaveatScopeTypeViewer)
    return AuthScope::kViewer;
  return AuthScope::kNone;
}

}  // namespace

AuthManager::AuthManager(Config* config,
                         AccessBlackListManager* black_list,
                         const std::vector<uint8_t>& certificate_fingerprint)
    : config_{config},
      black_list_{black_list},
      certificate_fingerprint_{certificate_fingerprint},
      access_secret_{CreateSecret()} {
  if (black_list_) {
    black_list_->AddEntryAddedCallback(base::Bind(
        &AuthManager::ResetAccessSecret, weak_ptr_factory_.GetWeakPtr()));
  }
  if (config_) {
    SetAuthSecret(config_->GetSettings().secret,
                  config_->GetSettings().root_client_token_owner);
  } else {
    SetAuthSecret({}, RootClientTokenOwner::kNone);
  }
}

AuthManager::AuthManager(const std::vector<uint8_t>& auth_secret,
                         const std::vector<uint8_t>& certificate_fingerprint,
                         const std::vector<uint8_t>& access_secret,
                         base::Clock* clock,
                         AccessBlackListManager* black_list)
    : AuthManager(nullptr, black_list, certificate_fingerprint) {
  access_secret_ = access_secret.size() == kSha256OutputSize ? access_secret
                                                             : CreateSecret();
  SetAuthSecret(auth_secret, RootClientTokenOwner::kNone);
  if (clock)
    clock_ = clock;
}

void AuthManager::SetAuthSecret(const std::vector<uint8_t>& secret,
                                RootClientTokenOwner owner) {
  auth_secret_ = secret;

  if (auth_secret_.size() != kSha256OutputSize) {
    auth_secret_ = CreateSecret();
    owner = RootClientTokenOwner::kNone;
  }

  if (!config_ || (config_->GetSettings().secret == auth_secret_ &&
                   config_->GetSettings().root_client_token_owner == owner)) {
    return;
  }

  Config::Transaction change{config_};
  change.set_secret(secret);
  change.set_root_client_token_owner(owner);
  change.Commit();
}

AuthManager::~AuthManager() {}

std::vector<uint8_t> AuthManager::CreateAccessToken(const UserInfo& user_info,
                                                    base::TimeDelta ttl) const {
  const base::Time now = Now();
  TimestampCaveat issued{now};
  ScopeCaveat scope{ToMacaroonScope(user_info.scope())};
  // Macaroons have no caveats for auth type. So we just append the type to the
  // user ID.
  std::vector<uint8_t> id_with_type{user_info.id().user};
  id_with_type.push_back(static_cast<uint8_t>(user_info.id().type));
  UserIdCaveat user{id_with_type};
  AppIdCaveat app{user_info.id().app};
  ExpirationCaveat expiration{now + ttl};
  return CreateMacaroonToken(
      access_secret_, now,
      {

          &issued.GetCaveat(), &scope.GetCaveat(), &user.GetCaveat(),
          &app.GetCaveat(), &expiration.GetCaveat(),
      });
}

bool AuthManager::ParseAccessToken(const std::vector<uint8_t>& token,
                                   UserInfo* user_info,
                                   ErrorPtr* error) const {
  std::vector<uint8_t> buffer;
  UwMacaroon macaroon{};

  UwMacaroonValidationResult result{};
  const base::Time now = Now();
  if (!LoadMacaroon(token, &buffer, &macaroon, error) ||
      macaroon.num_caveats != 5 ||
      !VerifyMacaroon(access_secret_, macaroon, now, &result, error)) {
    return Error::AddTo(error, FROM_HERE, errors::kInvalidAuthorization,
                        "Invalid token");
  }

  AuthScope auth_scope{FromMacaroonScope(result.granted_scope)};
  if (auth_scope == AuthScope::kNone) {
    return Error::AddTo(error, FROM_HERE, errors::kInvalidAuthorization,
                        "Invalid token data");
  }

  // If token is valid and token was not extended, it should has precisely this
  // values.
  CHECK_GE(FromJ2000Time(result.expiration_time), now);
  CHECK_EQ(2u, result.num_delegatees);
  CHECK_EQ(kUwMacaroonDelegateeTypeUser, result.delegatees[0].type);
  CHECK_EQ(kUwMacaroonDelegateeTypeApp, result.delegatees[1].type);
  CHECK_GT(result.delegatees[0].id_len, 1u);
  std::vector<uint8_t> user_id{
      result.delegatees[0].id,
      result.delegatees[0].id + result.delegatees[0].id_len};
  // Last byte is used for type. See |CreateAccessToken|.
  AuthType type = static_cast<AuthType>(user_id.back());
  user_id.pop_back();

  std::vector<uint8_t> app_id{
      result.delegatees[1].id,
      result.delegatees[1].id + result.delegatees[1].id_len};
  if (user_info)
    *user_info = UserInfo{auth_scope, UserAppId{type, user_id, app_id}};

  return true;
}

std::vector<uint8_t> AuthManager::ClaimRootClientAuthToken(
    RootClientTokenOwner owner,
    ErrorPtr* error) {
  CHECK(RootClientTokenOwner::kNone != owner);
  if (config_) {
    auto current = config_->GetSettings().root_client_token_owner;
    if (!IsClaimAllowed(current, owner)) {
      Error::AddToPrintf(error, FROM_HERE, errors::kAlreadyClaimed,
                         "Device already claimed by '%s'",
                         EnumToString(current).c_str());
      return {};
    }
  };

  pending_claims_.push_back(std::make_pair(
      std::unique_ptr<AuthManager>{new AuthManager{nullptr, nullptr, {}}},
      owner));
  if (pending_claims_.size() > kMaxPendingClaims)
    pending_claims_.pop_front();
  return pending_claims_.back().first->GetRootClientAuthToken(owner);
}

bool AuthManager::ConfirmClientAuthToken(const std::vector<uint8_t>& token,
                                         ErrorPtr* error) {
  // Cover case when caller sent confirm twice.
  if (pending_claims_.empty())
    return IsValidAuthToken(token, error);

  auto claim =
      std::find_if(pending_claims_.begin(), pending_claims_.end(),
                   [&token](const decltype(pending_claims_)::value_type& auth) {
                     return auth.first->IsValidAuthToken(token, nullptr);
                   });
  if (claim == pending_claims_.end()) {
    return Error::AddTo(error, FROM_HERE, errors::kNotFound, "Unknown claim");
  }

  SetAuthSecret(claim->first->GetAuthSecret(), claim->second);
  pending_claims_.clear();
  return true;
}

std::vector<uint8_t> AuthManager::GetRootClientAuthToken(
    RootClientTokenOwner owner) const {
  CHECK(RootClientTokenOwner::kNone != owner);
  ClientAuthTokenCaveat auth_token;
  const base::Time now = Now();
  TimestampCaveat issued{now};

  ServiceCaveat client{owner == RootClientTokenOwner::kCloud
                           ? kUwMacaroonCaveatCloudServiceIdGoogleWeave
                           : kUwMacaroonCaveatCloudServiceIdNotCloudRegistered};
  return CreateMacaroonToken(
      auth_secret_, now,
      {
          &auth_token.GetCaveat(), &issued.GetCaveat(), &client.GetCaveat(),
      });
}

base::Time AuthManager::Now() const {
  return clock_->Now();
}

bool AuthManager::IsValidAuthToken(const std::vector<uint8_t>& token,
                                   ErrorPtr* error) const {
  std::vector<uint8_t> buffer;
  UwMacaroon macaroon{};
  UwMacaroonValidationResult result{};
  if (!LoadMacaroon(token, &buffer, &macaroon, error) ||
      !VerifyMacaroon(auth_secret_, macaroon, Now(), &result, error)) {
    return Error::AddTo(error, FROM_HERE, errors::kInvalidAuthCode,
                        "Invalid token");
  }
  return true;
}

bool AuthManager::CreateAccessTokenFromAuth(
    const std::vector<uint8_t>& auth_token,
    base::TimeDelta ttl,
    std::vector<uint8_t>* access_token,
    AuthScope* access_token_scope,
    base::TimeDelta* access_token_ttl,
    ErrorPtr* error) const {
  std::vector<uint8_t> buffer;
  UwMacaroon macaroon{};
  UwMacaroonValidationResult result{};
  const base::Time now = Now();
  if (!LoadMacaroon(auth_token, &buffer, &macaroon, error) ||
      !VerifyMacaroon(auth_secret_, macaroon, now, &result, error)) {
    return Error::AddTo(error, FROM_HERE, errors::kInvalidAuthCode,
                        "Invalid token");
  }

  AuthScope auth_scope{FromMacaroonScope(result.granted_scope)};
  if (auth_scope == AuthScope::kNone) {
    return Error::AddTo(error, FROM_HERE, errors::kInvalidAuthCode,
                        "Invalid token data");
  }

  // TODO: Integrate black list checks.
  auto delegates_rbegin = std::reverse_iterator<const UwMacaroonDelegateeInfo*>(
      result.delegatees + result.num_delegatees);
  auto delegates_rend =
      std::reverse_iterator<const UwMacaroonDelegateeInfo*>(result.delegatees);
  auto last_user_id =
      std::find_if(delegates_rbegin, delegates_rend,
                   [](const UwMacaroonDelegateeInfo& delegatee) {
                     return delegatee.type == kUwMacaroonDelegateeTypeUser;
                   });
  auto last_app_id =
      std::find_if(delegates_rbegin, delegates_rend,
                   [](const UwMacaroonDelegateeInfo& delegatee) {
                     return delegatee.type == kUwMacaroonDelegateeTypeApp;
                   });

  if (last_user_id == delegates_rend || !last_user_id->id_len) {
    return Error::AddTo(error, FROM_HERE, errors::kInvalidAuthCode,
                        "User ID is missing");
  }

  const char* session_id = reinterpret_cast<const char*>(result.lan_session_id);
  if (!IsValidSessionId({session_id, session_id + result.lan_session_id_len})) {
    return Error::AddTo(error, FROM_HERE, errors::kInvalidAuthCode,
                        "Invalid session id");
  }

  CHECK_GE(FromJ2000Time(result.expiration_time), now);

  if (!access_token)
    return true;

  std::vector<uint8_t> user_id{last_user_id->id,
                               last_user_id->id + last_user_id->id_len};
  std::vector<uint8_t> app_id;
  if (last_app_id != delegates_rend)
    app_id.assign(last_app_id->id, last_app_id->id + last_app_id->id_len);

  UserInfo info{auth_scope, {AuthType::kLocal, user_id, app_id}};

  ttl = std::min(ttl, FromJ2000Time(result.expiration_time) - now);
  *access_token = CreateAccessToken(info, ttl);

  if (access_token_scope)
    *access_token_scope = info.scope();

  if (access_token_ttl)
    *access_token_ttl = ttl;
  return true;
}

std::string AuthManager::CreateSessionId() const {
  return std::to_string(ToJ2000Time(Now())) + ":" +
         std::to_string(++session_counter_);
}

bool AuthManager::IsValidSessionId(const std::string& session_id) const {
  base::Time ssid_time = FromJ2000Time(std::atoi(session_id.c_str()));
  return Now() - base::TimeDelta::FromMinutes(kSessionIdTtlMinutes) <=
             ssid_time &&
         ssid_time <= Now();
}

void AuthManager::ResetAccessSecret() {
  auto new_secret = CreateSecret();
  CHECK(new_secret != access_secret_);
  access_secret_.swap(new_secret);
}

std::vector<uint8_t> AuthManager::DelegateToUser(
    const std::vector<uint8_t>& token,
    base::TimeDelta ttl,
    const UserInfo& user_info) const {
  std::vector<uint8_t> buffer;
  UwMacaroon macaroon{};
  CHECK(LoadMacaroon(token, &buffer, &macaroon, nullptr));

  const base::Time now = Now();
  TimestampCaveat issued{now};
  ExpirationCaveat expiration{now + ttl};
  ScopeCaveat scope{ToMacaroonScope(user_info.scope())};
  UserIdCaveat user{user_info.id().user};
  AppIdCaveat app{user_info.id().app};
  SessionIdCaveat session{CreateSessionId()};

  std::vector<const UwMacaroonCaveat*> caveats{
      &issued.GetCaveat(), &expiration.GetCaveat(), &scope.GetCaveat(),
      &user.GetCaveat(),
  };

  if (!user_info.id().app.empty())
    caveats.push_back(&app.GetCaveat());

  caveats.push_back(&session.GetCaveat());

  return ExtendMacaroonToken(macaroon, now, caveats);
}

}  // namespace privet
}  // namespace weave
