blob: c9f69284621b6a321fe1e92a59c2524fdd45a223 [file] [log] [blame]
// Copyright 2019 The Chromium 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 "chrome/browser/ash/login/test/login_manager_mixin.h"
#include <memory>
#include <string>
#include <utility>
#include "ash/components/login/auth/auth_status_consumer.h"
#include "ash/components/login/auth/key.h"
#include "ash/components/login/auth/stub_authenticator_builder.h"
#include "ash/components/login/auth/user_context.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/strings/string_util.h"
#include "chrome/browser/ash/login/existing_user_controller.h"
#include "chrome/browser/ash/login/session/user_session_manager.h"
#include "chrome/browser/ash/login/session/user_session_manager_test_api.h"
#include "chrome/browser/ash/login/signin_specifics.h"
#include "chrome/browser/ash/login/startup_utils.h"
#include "chrome/browser/ash/login/test/cryptohome_mixin.h"
#include "chrome/browser/ash/login/test/local_state_mixin.h"
#include "chrome/browser/ash/login/test/oobe_screens_utils.h"
#include "chrome/browser/ash/login/test/profile_prepared_waiter.h"
#include "chrome/browser/ash/login/test/session_manager_state_waiter.h"
#include "chrome/browser/ash/login/ui/login_display_host.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/user_manager/known_user.h"
#include "google_apis/gaia/gaia_auth_util.h"
namespace ash {
namespace {
// Ensure LoginManagerMixin is only created once.
bool g_instance_created = false;
constexpr char kGmailDomain[] = "@gmail.com";
constexpr char kManagedDomain[] = "@example.com";
void AppendUsers(LoginManagerMixin::UserList* users,
const std::string& domain,
int n,
CryptohomeMixin* cryptohome_mixin) {
int num = users->size();
for (int i = 0; i < n; ++i, ++num) {
const std::string email = "test_user_" + base::NumberToString(num) + domain;
const std::string gaia_id = base::NumberToString(num) + "111111111";
const AccountId account_id = AccountId::FromUserEmailGaiaId(email, gaia_id);
users->push_back(LoginManagerMixin::TestUserInfo(account_id));
if (cryptohome_mixin != nullptr) {
cryptohome_mixin->MarkUserAsExisting(account_id);
}
}
}
} // namespace
// static
UserContext LoginManagerMixin::CreateDefaultUserContext(
const TestUserInfo& user_info) {
UserContext user_context(user_info.user_type, user_info.account_id);
user_context.SetKey(Key("password"));
return user_context;
}
void LoginManagerMixin::AppendRegularUsers(int n) {
AppendUsers(&initial_users_, kGmailDomain, n, cryptohome_mixin_);
}
void LoginManagerMixin::AppendManagedUsers(int n) {
AppendUsers(&initial_users_, kManagedDomain, n, cryptohome_mixin_);
}
LoginManagerMixin::LoginManagerMixin(InProcessBrowserTestMixinHost* host)
: LoginManagerMixin(host, UserList()) {}
LoginManagerMixin::LoginManagerMixin(InProcessBrowserTestMixinHost* host,
const UserList& initial_users)
: LoginManagerMixin(host, initial_users, nullptr) {}
LoginManagerMixin::LoginManagerMixin(InProcessBrowserTestMixinHost* host,
const UserList& initial_users,
FakeGaiaMixin* gaia_mixin)
: LoginManagerMixin(host, initial_users, gaia_mixin, nullptr) {}
LoginManagerMixin::LoginManagerMixin(InProcessBrowserTestMixinHost* host,
const UserList& initial_users,
FakeGaiaMixin* gaia_mixin,
CryptohomeMixin* cryptohome_mixin)
: InProcessBrowserTestMixin(host),
initial_users_(initial_users),
local_state_mixin_(host, this),
fake_gaia_mixin_(gaia_mixin),
cryptohome_mixin_(cryptohome_mixin) {
DCHECK(!g_instance_created);
g_instance_created = true;
if (cryptohome_mixin != nullptr) {
for (const auto& user : initial_users_) {
cryptohome_mixin_->MarkUserAsExisting(user.account_id);
}
}
}
LoginManagerMixin::~LoginManagerMixin() {
g_instance_created = false;
}
void LoginManagerMixin::SetDefaultLoginSwitches(
const std::vector<test::SessionFlagsManager::Switch>& switches) {
session_flags_manager_.SetDefaultLoginSwitches(switches);
}
bool LoginManagerMixin::SetUpUserDataDirectory() {
if (session_restore_enabled_)
session_flags_manager_.SetUpSessionRestore();
session_flags_manager_.AppendSwitchesToCommandLine(
base::CommandLine::ForCurrentProcess());
return true;
}
void LoginManagerMixin::SetUpLocalState() {
for (const auto& user : initial_users_) {
ListPrefUpdateDeprecated users_pref(g_browser_process->local_state(),
"LoggedInUsers");
base::Value email_value(user.account_id.GetUserEmail());
if (!base::Contains(users_pref->GetList(), email_value))
users_pref->Append(std::move(email_value));
DictionaryPrefUpdateDeprecated user_type_update(
g_browser_process->local_state(), "UserType");
user_type_update->SetKey(user.account_id.GetAccountIdKey(),
base::Value(static_cast<int>(user.user_type)));
DictionaryPrefUpdateDeprecated user_token_update(
g_browser_process->local_state(), "OAuthTokenStatus");
user_token_update->SetKey(user.account_id.GetUserEmail(),
base::Value(static_cast<int>(user.token_status)));
user_manager::known_user::UpdateId(user.account_id);
if (user.user_type == user_manager::USER_TYPE_CHILD) {
user_manager::known_user::SetProfileRequiresPolicy(
user.account_id,
user_manager::ProfileRequiresPolicy::kPolicyRequired);
}
if (base::EndsWith(kManagedDomain, gaia::ExtractDomainName(
user.account_id.GetUserEmail()))) {
user_manager::known_user::SetIsEnterpriseManaged(user.account_id, true);
}
}
StartupUtils::MarkOobeCompleted();
}
void LoginManagerMixin::SetUpOnMainThread() {
test::UserSessionManagerTestApi session_manager_test_api(
UserSessionManager::GetInstance());
session_manager_test_api.SetShouldLaunchBrowserInTests(
should_launch_browser_);
session_manager_test_api.SetShouldObtainTokenHandleInTests(
should_obtain_handles_);
}
void LoginManagerMixin::TearDownOnMainThread() {
session_flags_manager_.Finalize();
}
void LoginManagerMixin::AttemptLoginUsingAuthenticator(
const UserContext& user_context,
std::unique_ptr<StubAuthenticatorBuilder> authenticator_builder) {
test::UserSessionManagerTestApi(UserSessionManager::GetInstance())
.InjectAuthenticatorBuilder(std::move(authenticator_builder));
ExistingUserController::current_controller()->Login(user_context,
SigninSpecifics());
}
void LoginManagerMixin::WaitForActiveSession() {
SessionStateWaiter(session_manager::SessionState::ACTIVE).Wait();
}
bool LoginManagerMixin::LoginAndWaitForActiveSession(
const UserContext& user_context) {
AttemptLoginUsingAuthenticator(
user_context, std::make_unique<StubAuthenticatorBuilder>(user_context));
WaitForActiveSession();
user_manager::User* active_user =
user_manager::UserManager::Get()->GetActiveUser();
return active_user &&
active_user->GetAccountId() == user_context.GetAccountId();
}
void LoginManagerMixin::LoginWithDefaultContext(const TestUserInfo& user_info) {
UserContext user_context = CreateDefaultUserContext(user_info);
test::ProfilePreparedWaiter profile_prepared(user_info.account_id);
AttemptLoginUsingAuthenticator(
user_context, std::make_unique<StubAuthenticatorBuilder>(user_context));
profile_prepared.Wait();
}
void LoginManagerMixin::LoginAsNewRegularUser(
absl::optional<UserContext> user_context) {
ash::LoginDisplayHost::default_host()->StartWizard(GaiaView::kScreenId);
test::WaitForOobeJSReady();
ASSERT_FALSE(session_manager::SessionManager::Get()->IsSessionStarted());
if (!user_context.has_value()) {
user_context = CreateDefaultUserContext(TestUserInfo(
AccountId::FromUserEmailGaiaId(test::kTestEmail, test::kTestGaiaId)));
}
test::ProfilePreparedWaiter profile_prepared(user_context->GetAccountId());
AttemptLoginUsingAuthenticator(
*user_context, std::make_unique<StubAuthenticatorBuilder>(*user_context));
profile_prepared.Wait();
}
void LoginManagerMixin::LoginAsNewChildUser() {
ash::LoginDisplayHost::default_host()->StartWizard(GaiaView::kScreenId);
test::WaitForOobeJSReady();
ASSERT_FALSE(session_manager::SessionManager::Get()->IsSessionStarted());
TestUserInfo test_child_user_(
AccountId::FromUserEmailGaiaId(test::kTestEmail, test::kTestGaiaId),
user_manager::USER_TYPE_CHILD);
UserContext user_context = CreateDefaultUserContext(test_child_user_);
user_context.SetRefreshToken(FakeGaiaMixin::kFakeRefreshToken);
ASSERT_TRUE(fake_gaia_mixin_) << "Pass FakeGaiaMixin into constructor";
fake_gaia_mixin_->SetupFakeGaiaForChildUser(
test_child_user_.account_id.GetUserEmail(),
test_child_user_.account_id.GetGaiaId(), FakeGaiaMixin::kFakeRefreshToken,
false /*issue_any_scope_token*/);
test::ProfilePreparedWaiter profile_prepared(user_context.GetAccountId());
AttemptLoginUsingAuthenticator(
user_context, std::make_unique<StubAuthenticatorBuilder>(user_context));
profile_prepared.Wait();
}
} // namespace ash