chromium/chromeos/ash/components/osauth/impl/auth_parts_impl.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/ash/components/osauth/impl/auth_parts_impl.h"

#include <memory>
#include <utility>
#include <vector>

#include "ash/constants/ash_features.h"
#include "base/check.h"
#include "base/check_is_test.h"
#include "base/check_op.h"
#include "base/logging.h"
#include "base/time/default_clock.h"
#include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
#include "chromeos/ash/components/osauth/impl/auth_hub_impl.h"
#include "chromeos/ash/components/osauth/impl/auth_session_storage_impl.h"
#include "chromeos/ash/components/osauth/impl/cryptohome_core_impl.h"
#include "chromeos/ash/components/osauth/impl/engines/cryptohome_password_engine.h"
#include "chromeos/ash/components/osauth/impl/engines/cryptohome_pin_engine.h"
#include "chromeos/ash/components/osauth/impl/engines/cryptohome_smart_card_engine.h"
#include "chromeos/ash/components/osauth/impl/engines/prefs_pin_engine.h"
#include "chromeos/ash/components/osauth/impl/login_screen_auth_policy_connector.h"
#include "chromeos/ash/components/osauth/public/auth_factor_engine_factory.h"
#include "chromeos/ash/components/osauth/public/auth_parts.h"
#include "components/prefs/pref_service.h"

namespace ash {

namespace {

AuthPartsImpl* g_instance = nullptr;

}

// static
std::unique_ptr<AuthPartsImpl> AuthPartsImpl::CreateTestInstance() {
  std::unique_ptr<AuthPartsImpl> result = std::make_unique<AuthPartsImpl>();
  return result;
}

// static
std::unique_ptr<AuthParts> AuthParts::Create(PrefService* local_state) {
  std::unique_ptr<AuthPartsImpl> result = std::make_unique<AuthPartsImpl>();
  result->CreateDefaultComponents(local_state);
  return result;
}

// static
AuthParts* AuthParts::Get() {
  CHECK(g_instance);
  return g_instance;
}

AuthPartsImpl::AuthPartsImpl() {
  CHECK(!g_instance);
  g_instance = this;
}

AuthPartsImpl::~AuthPartsImpl() {
  CHECK_EQ(g_instance, this);
  g_instance = nullptr;
}

void AuthPartsImpl::CreateDefaultComponents(PrefService* local_state) {
  session_storage_ = std::make_unique<AuthSessionStorageImpl>(
      UserDataAuthClient::Get(), base::DefaultClock::GetInstance());
  factors_cache_ = std::make_unique<AuthFactorPresenceCache>(local_state);
  auth_hub_ = std::make_unique<AuthHubImpl>(factors_cache_.get());
  cryptohome_core_ =
      std::make_unique<CryptohomeCoreImpl>(UserDataAuthClient::Get());
  RegisterEngineFactory(std::make_unique<CryptohomePasswordEngineFactory>());

  if (!features::IsUseAuthPanelInSessionEnabled()) {
    RegisterEngineFactory(
        std::make_unique<CryptohomePinEngineFactory>(local_state));
    RegisterEngineFactory(std::make_unique<CryptohomeSmartCardEngineFactory>());
    RegisterEngineFactory(
        std::make_unique<PrefsPinEngineFactory>(*local_state));
  }

  login_screen_policy_connector_ =
      std::make_unique<LoginScreenAuthPolicyConnector>(local_state);
  legacy_auth_surface_registry_ = std::make_unique<LegacyAuthSurfaceRegistry>();
  auth_surface_registry_ = std::make_unique<AuthSurfaceRegistry>();
}

AuthSessionStorage* AuthPartsImpl::GetAuthSessionStorage() {
  CHECK(session_storage_);
  return session_storage_.get();
}

AuthHub* AuthPartsImpl::GetAuthHub() {
  CHECK(auth_hub_);
  return auth_hub_.get();
}

void AuthPartsImpl::SetAuthHub(std::unique_ptr<AuthHub> auth_hub) {
  CHECK(!auth_hub_);
  auth_hub_ = std::move(auth_hub);
}

void AuthPartsImpl::SetAuthSessionStorage(
    std::unique_ptr<AuthSessionStorage> auth_session_storage) {
  CHECK(!session_storage_);
  session_storage_ = std::move(auth_session_storage);
}

CryptohomeCore* AuthPartsImpl::GetCryptohomeCore() {
  CHECK(cryptohome_core_);
  return cryptohome_core_.get();
}

void AuthPartsImpl::RegisterEngineFactory(
    std::unique_ptr<AuthFactorEngineFactory> factory) {
  engine_factories_.push_back(std::move(factory));
}

const std::vector<std::unique_ptr<AuthFactorEngineFactory>>&
AuthPartsImpl::GetEngineFactories() {
  return engine_factories_;
}

void AuthPartsImpl::RegisterEarlyLoginAuthPolicyConnector(
    std::unique_ptr<AuthPolicyConnector> connector) {
  CHECK(!early_login_policy_connector_);
  early_login_policy_connector_ = std::move(connector);
  early_login_policy_connector_->SetLoginScreenAuthPolicyConnector(
      login_screen_policy_connector_.get());
}

void AuthPartsImpl::ReleaseEarlyLoginAuthPolicyConnector() {
  early_login_policy_connector_.reset();
}

void AuthPartsImpl::SetProfilePrefsAuthPolicyConnector(
    AuthPolicyConnector* connector) {
  if (profile_prefs_policy_connector_) {
    CHECK_IS_TEST();
    LOG(WARNING) << "Overriding ProfilePrefsAuthPolicyConnector in test";
    profile_prefs_policy_connector_->OnShutdown();
  }

  profile_prefs_policy_connector_ = connector;
  profile_prefs_policy_connector_->SetLoginScreenAuthPolicyConnector(
      login_screen_policy_connector_.get());
}

AuthPolicyConnector* AuthPartsImpl::GetAuthPolicyConnector() {
  if (profile_prefs_policy_connector_) {
    return profile_prefs_policy_connector_;
  }
  if (early_login_policy_connector_) {
    return early_login_policy_connector_.get();
  }
  CHECK(login_screen_policy_connector_);
  return login_screen_policy_connector_.get();
}

void AuthPartsImpl::Shutdown() {
  if (auth_hub_) {
    auth_hub_->Shutdown();
  }
  if (profile_prefs_policy_connector_) {
    profile_prefs_policy_connector_->OnShutdown();
  }
}

LegacyAuthSurfaceRegistry* AuthPartsImpl::GetLegacyAuthSurfaceRegistry() {
  return legacy_auth_surface_registry_.get();
}

AuthSurfaceRegistry* AuthPartsImpl::GetAuthSurfaceRegistry() {
  return auth_surface_registry_.get();
}

}  // namespace ash