| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/user_manager/fake_user_manager.h" |
| |
| #include <utility> |
| |
| #include "base/containers/contains.h" |
| #include "base/functional/callback.h" |
| #include "base/ranges/algorithm.h" |
| #include "base/system/sys_info.h" |
| #include "base/task/single_thread_task_runner.h" |
| #include "chromeos/ash/components/settings/cros_settings.h" |
| #include "components/user_manager/fake_user_manager_delegate.h" |
| #include "components/user_manager/user_names.h" |
| #include "components/user_manager/user_type.h" |
| |
| namespace { |
| |
| class FakeTaskRunner : public base::SingleThreadTaskRunner { |
| public: |
| // base::SingleThreadTaskRunner: |
| bool PostDelayedTask(const base::Location& from_here, |
| base::OnceClosure task, |
| base::TimeDelta delay) override { |
| std::move(task).Run(); |
| return true; |
| } |
| bool PostNonNestableDelayedTask(const base::Location& from_here, |
| base::OnceClosure task, |
| base::TimeDelta delay) override { |
| return PostDelayedTask(from_here, std::move(task), delay); |
| } |
| bool RunsTasksInCurrentSequence() const override { return true; } |
| |
| protected: |
| ~FakeTaskRunner() override {} |
| }; |
| |
| } // namespace |
| |
| namespace user_manager { |
| |
| FakeUserManager::FakeUserManager(PrefService* local_state) |
| : UserManagerBase(std::make_unique<FakeUserManagerDelegate>(), |
| new FakeTaskRunner(), |
| local_state, |
| ash::CrosSettings::IsInitialized() |
| ? ash::CrosSettings::Get() |
| : nullptr) {} |
| |
| FakeUserManager::~FakeUserManager() = default; |
| |
| std::string FakeUserManager::GetFakeUsernameHash(const AccountId& account_id) { |
| // Consistent with the |
| // kUserDataDirNameSuffix in fake_userdataauth_client.cc and |
| // UserDataAuthClient::GetStubSanitizedUsername. |
| // TODO(crbug.com/1347837): After resolving the dependent code, |
| // consolidate the all implementation to cryptohome utilities, |
| // and remove this. |
| DCHECK(account_id.is_valid()); |
| return account_id.GetUserEmail() + "-hash"; |
| } |
| |
| const User* FakeUserManager::AddUser(const AccountId& account_id) { |
| return AddUserWithAffiliation(account_id, false); |
| } |
| |
| const User* FakeUserManager::AddChildUser(const AccountId& account_id) { |
| User* user = User::CreateRegularUser(account_id, UserType::kChild); |
| user_storage_.emplace_back(user); |
| users_.push_back(user); |
| return user; |
| } |
| |
| const User* FakeUserManager::AddGuestUser(const AccountId& account_id) { |
| User* user = User::CreateGuestUser(account_id); |
| user_storage_.emplace_back(user); |
| users_.push_back(user); |
| return user; |
| } |
| |
| const User* FakeUserManager::AddKioskAppUser(const AccountId& account_id) { |
| User* user = User::CreateKioskAppUser(account_id); |
| user->set_username_hash(GetFakeUsernameHash(account_id)); |
| user_storage_.emplace_back(user); |
| users_.push_back(user); |
| return user; |
| } |
| |
| const User* FakeUserManager::AddUserWithAffiliation(const AccountId& account_id, |
| bool is_affiliated) { |
| User* user = User::CreateRegularUser(account_id, UserType::kRegular); |
| user->SetAffiliated(is_affiliated); |
| user->set_username_hash(GetFakeUsernameHash(account_id)); |
| user_storage_.emplace_back(user); |
| users_.push_back(user); |
| return user; |
| } |
| |
| const user_manager::User* FakeUserManager::AddPublicAccountUser( |
| const AccountId& account_id) { |
| User* user = User::CreatePublicAccountUserForTesting(account_id); |
| user_storage_.emplace_back(user); |
| users_.push_back(user); |
| return user; |
| } |
| |
| const UserList& FakeUserManager::GetUsers() const { |
| return users_; |
| } |
| |
| UserList FakeUserManager::GetUsersAllowedForMultiProfile() const { |
| UserList result; |
| for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) { |
| if ((*it)->GetType() == UserType::kRegular && !(*it)->is_logged_in()) { |
| result.push_back(*it); |
| } |
| } |
| return result; |
| } |
| |
| void FakeUserManager::UpdateUserAccountData( |
| const AccountId& account_id, |
| const UserAccountData& account_data) { |
| for (User* user : users_) { |
| if (user->GetAccountId() == account_id) { |
| user->set_display_name(account_data.display_name()); |
| user->set_given_name(account_data.given_name()); |
| return; |
| } |
| } |
| } |
| |
| void FakeUserManager::LogoutAllUsers() { |
| primary_user_ = nullptr; |
| active_user_ = nullptr; |
| |
| logged_in_users_.clear(); |
| lru_logged_in_users_.clear(); |
| } |
| |
| void FakeUserManager::SetUserNonCryptohomeDataEphemeral( |
| const AccountId& account_id, |
| bool is_ephemeral) { |
| if (is_ephemeral) { |
| accounts_with_ephemeral_non_cryptohome_data_.insert(account_id); |
| } else { |
| accounts_with_ephemeral_non_cryptohome_data_.erase(account_id); |
| } |
| } |
| |
| void FakeUserManager::SetUserCryptohomeDataEphemeral( |
| const AccountId& account_id, |
| bool is_ephemeral) { |
| accounts_with_ephemeral_cryptohome_data_.insert({account_id, is_ephemeral}); |
| } |
| |
| void FakeUserManager::UserLoggedIn(const AccountId& account_id, |
| const std::string& username_hash, |
| bool browser_restart, |
| bool is_child) { |
| // Please keep the implementation in sync with |
| // FakeChromeUserManager::UserLoggedIn. We're in process to merge. |
| for (user_manager::User* user : users_) { |
| if (user->GetAccountId() == account_id) { |
| user->set_is_logged_in(true); |
| user->set_username_hash(username_hash); |
| logged_in_users_.push_back(user); |
| if (!primary_user_) { |
| primary_user_ = user; |
| } |
| if (active_user_) { |
| NotifyUserAddedToSession(user); |
| } else { |
| active_user_ = user; |
| } |
| break; |
| } |
| } |
| |
| if (!active_user_ && IsEphemeralAccountId(account_id)) { |
| RegularUserLoggedInAsEphemeral(account_id, UserType::kRegular); |
| } |
| |
| NotifyOnLogin(); |
| } |
| |
| User* FakeUserManager::GetActiveUserInternal() const { |
| if (active_user_ != nullptr) |
| return active_user_; |
| |
| if (!users_.empty()) { |
| if (active_account_id_.is_valid()) { |
| for (UserList::const_iterator it = users_.begin(); it != users_.end(); |
| ++it) { |
| if ((*it)->GetAccountId() == active_account_id_) |
| return *it; |
| } |
| } |
| return users_[0]; |
| } |
| return nullptr; |
| } |
| |
| const User* FakeUserManager::GetActiveUser() const { |
| return GetActiveUserInternal(); |
| } |
| |
| User* FakeUserManager::GetActiveUser() { |
| return GetActiveUserInternal(); |
| } |
| |
| void FakeUserManager::SwitchActiveUser(const AccountId& account_id) { |
| for (UserList::const_iterator it = logged_in_users_.begin(); |
| it != logged_in_users_.end(); ++it) { |
| if ((*it)->GetAccountId() == account_id) { |
| active_user_ = (*it).get(); |
| break; |
| } |
| } |
| } |
| |
| void FakeUserManager::SaveUserDisplayName(const AccountId& account_id, |
| const std::u16string& display_name) { |
| for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) { |
| if ((*it)->GetAccountId() == account_id) { |
| (*it)->set_display_name(display_name); |
| return; |
| } |
| } |
| } |
| |
| const UserList& FakeUserManager::GetLRULoggedInUsers() const { |
| return users_; |
| } |
| |
| UserList FakeUserManager::GetUnlockUsers() const { |
| return users_; |
| } |
| |
| const AccountId& FakeUserManager::GetOwnerAccountId() const { |
| return owner_account_id_; |
| } |
| |
| bool FakeUserManager::IsKnownUser(const AccountId& account_id) const { |
| return true; |
| } |
| |
| const User* FakeUserManager::FindUser(const AccountId& account_id) const { |
| if (active_user_ != nullptr && active_user_->GetAccountId() == account_id) |
| return active_user_; |
| |
| for (const User* user : users_) { |
| if (user->GetAccountId() == account_id) { |
| return user; |
| } |
| } |
| |
| return nullptr; |
| } |
| |
| User* FakeUserManager::FindUserAndModify(const AccountId& account_id) { |
| return const_cast<User*>(FindUser(account_id)); |
| } |
| |
| std::optional<std::string> FakeUserManager::GetOwnerEmail() { |
| return GetLocalState() ? UserManagerBase::GetOwnerEmail() : std::nullopt; |
| } |
| |
| bool FakeUserManager::IsCurrentUserNonCryptohomeDataEphemeral() const { |
| return false; |
| } |
| |
| bool FakeUserManager::IsUserLoggedIn() const { |
| return logged_in_users_.size() > 0; |
| } |
| |
| bool FakeUserManager::IsLoggedInAsUserWithGaiaAccount() const { |
| return true; |
| } |
| |
| bool FakeUserManager::IsLoggedInAsManagedGuestSession() const { |
| const User* active_user = GetActiveUser(); |
| return active_user && active_user->GetType() == UserType::kPublicAccount; |
| } |
| |
| bool FakeUserManager::IsLoggedInAsGuest() const { |
| const User* active_user = GetActiveUser(); |
| return active_user && active_user->GetType() == UserType::kGuest; |
| } |
| |
| bool FakeUserManager::IsLoggedInAsKioskApp() const { |
| const User* active_user = GetActiveUser(); |
| return active_user ? active_user->GetType() == UserType::kKioskApp : false; |
| } |
| |
| bool FakeUserManager::IsLoggedInAsWebKioskApp() const { |
| const User* active_user = GetActiveUser(); |
| return active_user ? active_user->GetType() == UserType::kWebKioskApp : false; |
| } |
| |
| bool FakeUserManager::IsLoggedInAsAnyKioskApp() const { |
| const User* active_user = GetActiveUser(); |
| return active_user && active_user->IsKioskType(); |
| } |
| |
| bool FakeUserManager::IsLoggedInAsStub() const { |
| return false; |
| } |
| |
| bool FakeUserManager::IsUserNonCryptohomeDataEphemeral( |
| const AccountId& account_id) const { |
| return base::Contains(accounts_with_ephemeral_non_cryptohome_data_, |
| account_id); |
| } |
| |
| bool FakeUserManager::IsUserCryptohomeDataEphemeral( |
| const AccountId& account_id) const { |
| auto is_ephemeral_overriden = |
| base::Contains(accounts_with_ephemeral_cryptohome_data_, account_id); |
| |
| if (!is_ephemeral_overriden) { |
| // Otherwise fall back to default behavior. |
| return UserManagerBase::IsUserCryptohomeDataEphemeral(account_id); |
| } |
| |
| return accounts_with_ephemeral_cryptohome_data_.at(account_id); |
| } |
| |
| bool FakeUserManager::IsGuestSessionAllowed() const { |
| return true; |
| } |
| |
| bool FakeUserManager::IsGaiaUserAllowed(const User& user) const { |
| return true; |
| } |
| |
| bool FakeUserManager::IsUserAllowed(const User& user) const { |
| return true; |
| } |
| |
| bool FakeUserManager::IsDeviceLocalAccountMarkedForRemoval( |
| const AccountId& account_id) const { |
| return false; |
| } |
| |
| bool FakeUserManager::IsDeprecatedSupervisedAccountId( |
| const AccountId& account_id) const { |
| return false; |
| } |
| |
| } // namespace user_manager |