| // Copyright 2021 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 "components/user_manager/known_user.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/test/task_environment.h" |
| #include "base/util/values/values_util.h" |
| #include "base/values.h" |
| #include "components/account_id/account_id.h" |
| #include "components/prefs/scoped_user_pref_update.h" |
| #include "components/prefs/testing_pref_service.h" |
| #include "components/user_manager/fake_user_manager.h" |
| #include "components/user_manager/scoped_user_manager.h" |
| #include "components/user_manager/user_manager_base.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| namespace user_manager { |
| namespace { |
| absl::optional<std::string> GetStringPrefValue(KnownUser* known_user, |
| const AccountId& account_id, |
| const char* pref_name) { |
| std::string value; |
| if (!known_user->GetStringPref(account_id, pref_name, &value)) { |
| return {}; |
| } |
| return value; |
| } |
| } // namespace |
| |
| // Base class for tests of known_user. |
| // Sets up global objects necessary for known_user to be able to access |
| // local_state. |
| class KnownUserTest : public testing::Test { |
| public: |
| KnownUserTest() { |
| auto fake_user_manager = std::make_unique<FakeUserManager>(); |
| fake_user_manager_ = fake_user_manager.get(); |
| scoped_user_manager_ = |
| std::make_unique<ScopedUserManager>(std::move(fake_user_manager)); |
| |
| UserManagerBase::RegisterPrefs(local_state_.registry()); |
| } |
| ~KnownUserTest() override = default; |
| |
| KnownUserTest(const KnownUserTest& other) = delete; |
| KnownUserTest& operator=(const KnownUserTest& other) = delete; |
| |
| protected: |
| const AccountId kDefaultAccountId = |
| AccountId::FromUserEmailGaiaId("default_account@gmail.com", |
| "fake-gaia-id"); |
| const AccountId kDefaultAccountId2 = |
| AccountId::FromUserEmailGaiaId("default_account_2@gmail.com", |
| "fake-gaia-id-2"); |
| |
| FakeUserManager* fake_user_manager() { return fake_user_manager_; } |
| |
| PrefService* local_state() { return &local_state_; } |
| |
| private: |
| base::test::TaskEnvironment task_environment_{ |
| base::test::TaskEnvironment::MainThreadType::UI}; |
| |
| // Owned by |scoped_user_manager_|. |
| FakeUserManager* fake_user_manager_ = nullptr; |
| std::unique_ptr<ScopedUserManager> scoped_user_manager_; |
| TestingPrefServiceSimple local_state_; |
| }; |
| |
| TEST_F(KnownUserTest, FindPrefsNonExisting) { |
| KnownUser known_user(local_state()); |
| const base::DictionaryValue* value = nullptr; |
| bool read_success = known_user.FindPrefs(kDefaultAccountId, &value); |
| EXPECT_FALSE(read_success); |
| EXPECT_FALSE(value); |
| } |
| |
| TEST_F(KnownUserTest, FindPrefsExisting) { |
| KnownUser known_user(local_state()); |
| const std::string kCustomPrefName = "custom_pref"; |
| known_user.SetStringPref(kDefaultAccountId, kCustomPrefName, "value"); |
| |
| const base::DictionaryValue* value = nullptr; |
| bool read_success = known_user.FindPrefs(kDefaultAccountId, &value); |
| EXPECT_TRUE(read_success); |
| ASSERT_TRUE(value); |
| |
| const std::string* pref_value = value->FindStringKey(kCustomPrefName); |
| ASSERT_TRUE(pref_value); |
| EXPECT_EQ(*pref_value, "value"); |
| } |
| |
| TEST_F(KnownUserTest, FindPrefsIgnoresEphemeralGaiaUsers) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdEphemeralGaia = |
| AccountId::FromUserEmailGaiaId("account2@gmail.com", "gaia_id_2"); |
| const AccountId kAccountIdEphemeralAd = |
| AccountId::AdFromUserEmailObjGuid("account4@gmail.com", "guid_4"); |
| fake_user_manager()->SetUserNonCryptohomeDataEphemeral( |
| kAccountIdEphemeralGaia, |
| /*is_ephemeral=*/true); |
| fake_user_manager()->SetUserNonCryptohomeDataEphemeral(kAccountIdEphemeralAd, |
| /*is_ephemeral=*/true); |
| const std::string kCustomPrefName = "custom_pref"; |
| known_user.SetStringPref(kAccountIdEphemeralGaia, kCustomPrefName, "value"); |
| known_user.SetStringPref(kAccountIdEphemeralAd, kCustomPrefName, "value"); |
| |
| { |
| const base::DictionaryValue* value = nullptr; |
| bool read_success = known_user.FindPrefs(kAccountIdEphemeralGaia, &value); |
| EXPECT_FALSE(read_success); |
| EXPECT_FALSE(value); |
| } |
| |
| { |
| const base::DictionaryValue* value = nullptr; |
| bool read_success = known_user.FindPrefs(kAccountIdEphemeralAd, &value); |
| EXPECT_TRUE(read_success); |
| EXPECT_TRUE(value); |
| } |
| } |
| |
| TEST_F(KnownUserTest, FindPrefsMatchForUnknownAccountType) { |
| KnownUser known_user(local_state()); |
| // All account ids have the same e-mail |
| const AccountId kAccountIdUnknown = |
| AccountId::FromUserEmail("account1@gmail.com"); |
| const AccountId kAccountIdGaia = |
| AccountId::FromUserEmailGaiaId("account1@gmail.com", "gaia_id_2"); |
| const AccountId kAccountIdAd = |
| AccountId::AdFromUserEmailObjGuid("account1@gmail.com", "guid"); |
| |
| known_user.SetStringPref(kAccountIdUnknown, "some_pref", "some_value"); |
| |
| // Looking it up by AccountId always succeeds, no matter which AccountType is |
| // used for the lookup. |
| const base::DictionaryValue* value = nullptr; |
| EXPECT_TRUE(known_user.FindPrefs(kAccountIdUnknown, &value)); |
| EXPECT_TRUE(known_user.FindPrefs(kAccountIdGaia, &value)); |
| EXPECT_TRUE(known_user.FindPrefs(kAccountIdAd, &value)); |
| } |
| |
| TEST_F(KnownUserTest, FindPrefsMatchForGaiaAccountWithEmail) { |
| KnownUser known_user(local_state()); |
| const char* kEmailA = "a@gmail.com"; |
| const char* kEmailB = "b@gmail.com"; |
| const char* kGaiaIdA = "a"; |
| const char* kGaiaIdB = "b"; |
| |
| known_user.SaveKnownUser(AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdA)); |
| |
| const base::DictionaryValue* value = nullptr; |
| |
| // Finding by itself should work |
| EXPECT_TRUE(known_user.FindPrefs( |
| AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdA), &value)); |
| // Finding by gaia id should also work even if the e-mail doesn't match. |
| EXPECT_TRUE(known_user.FindPrefs( |
| AccountId::FromUserEmailGaiaId(kEmailB, kGaiaIdA), &value)); |
| // Finding by e-mail should also work even if the gaia id doesn't match. |
| // TODO(https://crbug.com/1190902): This should likely be EXPECT_FALSE going |
| // forward. |
| EXPECT_TRUE(known_user.FindPrefs( |
| AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdB), &value)); |
| // Finding by just gaia id without any e-mail doesn't work (because the |
| // resulting AccountId is not considered valid). |
| EXPECT_FALSE(known_user.FindPrefs(AccountId::FromGaiaId(kGaiaIdA), &value)); |
| |
| // An unrelated gaia AccountId with the same Account Type doesn't find |
| // anything. |
| EXPECT_FALSE(known_user.FindPrefs( |
| AccountId::FromUserEmailGaiaId(kEmailB, kGaiaIdB), &value)); |
| |
| // Looking up an AccountId stored as gaia by an unknown-type AccountId with |
| // the same e-mail address succeeds. |
| EXPECT_TRUE(known_user.FindPrefs(AccountId::FromUserEmail(kEmailA), &value)); |
| |
| // Looking up an AccountId stored as gaia by an AccountId with type Ad fails. |
| EXPECT_FALSE(known_user.FindPrefs( |
| AccountId::AdFromUserEmailObjGuid(kEmailA, "guid"), &value)); |
| } |
| |
| TEST_F(KnownUserTest, FindPrefsMatchForAdAccountWithEmail) { |
| KnownUser known_user(local_state()); |
| const std::string kEmailA = "a@gmail.com"; |
| const std::string kEmailB = "b@gmail.com"; |
| |
| known_user.SaveKnownUser(AccountId::AdFromUserEmailObjGuid(kEmailA, "a")); |
| |
| const base::DictionaryValue* value = nullptr; |
| |
| // Finding by itself should work |
| EXPECT_TRUE(known_user.FindPrefs( |
| AccountId::AdFromUserEmailObjGuid(kEmailA, "a"), &value)); |
| // Finding by guid should also work even if the e-mail doesn't match. |
| EXPECT_TRUE(known_user.FindPrefs( |
| AccountId::AdFromUserEmailObjGuid(kEmailB, "a"), &value)); |
| // Finding by e-mail should also work even if the guid doesn't match. |
| EXPECT_TRUE(known_user.FindPrefs( |
| AccountId::AdFromUserEmailObjGuid(kEmailA, "b"), &value)); |
| // Finding by just AD guid without any e-mail doesn't work (because the |
| // resulting AccountId is not considered valid). |
| EXPECT_FALSE(known_user.FindPrefs(AccountId::AdFromObjGuid("a"), &value)); |
| |
| // An unrelated AD AccountId with the same Account Type doesn't find |
| // anything. |
| EXPECT_FALSE(known_user.FindPrefs( |
| AccountId::AdFromUserEmailObjGuid(kEmailB, "b"), &value)); |
| |
| // Looking up an AccountId stored as AD by an unknown-type AccountId with |
| // the same e-mail address succeeds. |
| EXPECT_TRUE(known_user.FindPrefs(AccountId::FromUserEmail(kEmailA), &value)); |
| |
| // Looking up an AccountId stored as AD by an AccountId with type gaia fails. |
| EXPECT_FALSE(known_user.FindPrefs( |
| AccountId::FromUserEmailGaiaId(kEmailA, "gaia_id"), &value)); |
| } |
| |
| TEST_F(KnownUserTest, UpdatePrefsWithoutClear) { |
| KnownUser known_user(local_state()); |
| constexpr char kPrefName1[] = "pref1"; |
| constexpr char kPrefName2[] = "pref2"; |
| |
| { |
| base::DictionaryValue update; |
| update.SetKey(kPrefName1, base::Value("pref1_value1")); |
| known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/false); |
| } |
| |
| { |
| base::DictionaryValue update; |
| update.SetKey(kPrefName1, base::Value("pref1_value2")); |
| known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/false); |
| } |
| |
| { |
| base::DictionaryValue update; |
| update.SetKey(kPrefName2, base::Value("pref2_value1")); |
| known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/false); |
| } |
| |
| EXPECT_EQ(absl::make_optional(std::string("pref1_value2")), |
| GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName1)); |
| EXPECT_EQ(absl::make_optional(std::string("pref2_value1")), |
| GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName2)); |
| } |
| |
| TEST_F(KnownUserTest, UpdatePrefsWithClear) { |
| KnownUser known_user(local_state()); |
| constexpr char kPrefName1[] = "pref1"; |
| constexpr char kPrefName2[] = "pref2"; |
| |
| { |
| base::DictionaryValue update; |
| update.SetKey(kPrefName1, base::Value("pref1_value1")); |
| known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/false); |
| } |
| |
| { |
| base::DictionaryValue update; |
| update.SetKey(kPrefName2, base::Value("pref2_value1")); |
| known_user.UpdatePrefs(kDefaultAccountId, update, /*clear=*/true); |
| } |
| |
| EXPECT_EQ(absl::nullopt, |
| GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName1)); |
| EXPECT_EQ(absl::make_optional(std::string("pref2_value1")), |
| GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName2)); |
| } |
| |
| TEST_F(KnownUserTest, GetKnownAccountIdsNoAccounts) { |
| KnownUser known_user(local_state()); |
| EXPECT_THAT(known_user.GetKnownAccountIds(), testing::IsEmpty()); |
| } |
| |
| TEST_F(KnownUserTest, GetKnownAccountIdsWithAccounts) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdGaia = |
| AccountId::FromUserEmailGaiaId("account2@gmail.com", "gaia_id"); |
| const AccountId kAccountIdAd = |
| AccountId::AdFromUserEmailObjGuid("account3@gmail.com", "obj_guid"); |
| |
| known_user.SaveKnownUser(kAccountIdGaia); |
| known_user.SaveKnownUser(kAccountIdAd); |
| |
| EXPECT_THAT(known_user.GetKnownAccountIds(), |
| testing::UnorderedElementsAre(kAccountIdGaia, kAccountIdAd)); |
| } |
| |
| TEST_F(KnownUserTest, SaveKnownUserIgnoresUnknownType) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdUnknown = |
| AccountId::FromUserEmail("account2@gmail.com"); |
| |
| known_user.SaveKnownUser(kAccountIdUnknown); |
| |
| EXPECT_THAT(known_user.GetKnownAccountIds(), testing::IsEmpty()); |
| } |
| |
| TEST_F(KnownUserTest, SaveKnownUserIgnoresEphemeralGaiaUsers) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdNonEphemeralGaia = |
| AccountId::FromUserEmailGaiaId("account1@gmail.com", "gaia_id_1"); |
| const AccountId kAccountIdEphemeralGaia = |
| AccountId::FromUserEmailGaiaId("account2@gmail.com", "gaia_id_2"); |
| const AccountId kAccountIdNonEphemeralAd = |
| AccountId::AdFromUserEmailObjGuid("account3@gmail.com", "guid_3"); |
| const AccountId kAccountIdEphemeralAd = |
| AccountId::AdFromUserEmailObjGuid("account4@gmail.com", "guid_4"); |
| |
| fake_user_manager()->SetUserNonCryptohomeDataEphemeral( |
| kAccountIdEphemeralGaia, |
| /*is_ephemeral=*/true); |
| fake_user_manager()->SetUserNonCryptohomeDataEphemeral(kAccountIdEphemeralAd, |
| /*is_ephemeral=*/true); |
| |
| known_user.SaveKnownUser(kAccountIdNonEphemeralGaia); |
| known_user.SaveKnownUser(kAccountIdEphemeralGaia); |
| known_user.SaveKnownUser(kAccountIdNonEphemeralAd); |
| known_user.SaveKnownUser(kAccountIdEphemeralAd); |
| |
| EXPECT_THAT(known_user.GetKnownAccountIds(), |
| testing::UnorderedElementsAre(kAccountIdNonEphemeralGaia, |
| kAccountIdNonEphemeralAd, |
| kAccountIdEphemeralAd)); |
| } |
| |
| TEST_F(KnownUserTest, UpdateIdForGaiaAccount) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdUnknown = |
| AccountId::FromUserEmail("account1@gmail.com"); |
| known_user.SetStringPref(kAccountIdUnknown, "some_pref", "some_value"); |
| EXPECT_THAT(known_user.GetKnownAccountIds(), |
| testing::UnorderedElementsAre(kAccountIdUnknown)); |
| |
| const AccountId kAccountIdGaia = |
| AccountId::FromUserEmailGaiaId("account1@gmail.com", "gaia_id"); |
| known_user.UpdateId(kAccountIdGaia); |
| EXPECT_THAT(known_user.GetKnownAccountIds(), |
| testing::UnorderedElementsAre(kAccountIdGaia)); |
| } |
| |
| TEST_F(KnownUserTest, UpdateIdForAdAccount) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdUnknown = |
| AccountId::FromUserEmail("account1@gmail.com"); |
| known_user.SetStringPref(kAccountIdUnknown, "some_pref", "some_value"); |
| EXPECT_THAT(known_user.GetKnownAccountIds(), |
| testing::UnorderedElementsAre(kAccountIdUnknown)); |
| |
| const AccountId kAccountIdAd = |
| AccountId::AdFromUserEmailObjGuid("account1@gmail.com", "guid"); |
| known_user.UpdateId(kAccountIdAd); |
| EXPECT_THAT(known_user.GetKnownAccountIds(), |
| testing::UnorderedElementsAre(kAccountIdAd)); |
| } |
| |
| TEST_F(KnownUserTest, FindGaiaIdForGaiaAccount) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdGaia = |
| AccountId::FromUserEmailGaiaId("account1@gmail.com", "gaia_id"); |
| known_user.SaveKnownUser(kAccountIdGaia); |
| |
| std::string gaia_id; |
| EXPECT_TRUE(known_user.FindGaiaID(kAccountIdGaia, &gaia_id)); |
| EXPECT_EQ(gaia_id, "gaia_id"); |
| } |
| |
| TEST_F(KnownUserTest, FindGaiaIdForAdAccount) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdAd = |
| AccountId::AdFromUserEmailObjGuid("account1@gmail.com", "guid"); |
| known_user.SaveKnownUser(kAccountIdAd); |
| |
| std::string gaia_id; |
| EXPECT_FALSE(known_user.FindGaiaID(kAccountIdAd, &gaia_id)); |
| } |
| |
| // TODO(https://crbug.com/1148457): Add tests for GetAccountId. |
| |
| TEST_F(KnownUserTest, RemovePrefOnCustomPref) { |
| KnownUser known_user(local_state()); |
| const std::string kCustomPrefName = "custom_pref"; |
| |
| known_user.SetStringPref(kDefaultAccountId, kCustomPrefName, "value"); |
| { |
| std::string read_value; |
| EXPECT_TRUE(known_user.GetStringPref(kDefaultAccountId, kCustomPrefName, |
| &read_value)); |
| } |
| |
| known_user.RemovePref(kDefaultAccountId, kCustomPrefName); |
| { |
| std::string read_value; |
| EXPECT_FALSE(known_user.GetStringPref(kDefaultAccountId, kCustomPrefName, |
| &read_value)); |
| } |
| } |
| |
| // Test failing on linux-chromeos-chrome (crbug.com/1198519) |
| TEST_F(KnownUserTest, DISABLED_RemovePrefOnReservedPref) { |
| KnownUser known_user(local_state()); |
| const std::string kReservedPrefName = "device_id"; |
| |
| known_user.SetStringPref(kDefaultAccountId, kReservedPrefName, "value"); |
| ASSERT_DEATH(known_user.RemovePref(kDefaultAccountId, kReservedPrefName), |
| ".*Check failed.*"); |
| } |
| |
| TEST_F(KnownUserTest, GaiaIdMigrationStatus) { |
| KnownUser known_user(local_state()); |
| const std::string kSubsystem1 = "subsystem1"; |
| const std::string kSubsystem2 = "subsystem2"; |
| |
| EXPECT_FALSE( |
| known_user.GetGaiaIdMigrationStatus(kDefaultAccountId, kSubsystem1)); |
| EXPECT_FALSE( |
| known_user.GetGaiaIdMigrationStatus(kDefaultAccountId, kSubsystem2)); |
| |
| known_user.SetGaiaIdMigrationStatusDone(kDefaultAccountId, kSubsystem1); |
| |
| EXPECT_TRUE( |
| known_user.GetGaiaIdMigrationStatus(kDefaultAccountId, kSubsystem1)); |
| EXPECT_FALSE( |
| known_user.GetGaiaIdMigrationStatus(kDefaultAccountId, kSubsystem2)); |
| } |
| |
| TEST_F(KnownUserTest, DeviceId) { |
| KnownUser known_user(local_state()); |
| EXPECT_EQ(known_user.GetDeviceId(kDefaultAccountId), std::string()); |
| |
| known_user.SetDeviceId(kDefaultAccountId, "test"); |
| |
| EXPECT_EQ(known_user.GetDeviceId(kDefaultAccountId), "test"); |
| } |
| |
| TEST_F(KnownUserTest, GAPSCookie) { |
| KnownUser known_user(local_state()); |
| EXPECT_EQ(known_user.GetGAPSCookie(kDefaultAccountId), std::string()); |
| |
| known_user.SetGAPSCookie(kDefaultAccountId, "test"); |
| |
| EXPECT_EQ(known_user.GetGAPSCookie(kDefaultAccountId), "test"); |
| } |
| |
| TEST_F(KnownUserTest, UsingSAML) { |
| KnownUser known_user(local_state()); |
| EXPECT_FALSE(known_user.IsUsingSAML(kDefaultAccountId)); |
| |
| known_user.UpdateUsingSAML(kDefaultAccountId, /*using_saml=*/true); |
| EXPECT_TRUE(known_user.IsUsingSAML(kDefaultAccountId)); |
| } |
| |
| TEST_F(KnownUserTest, UsingSAMLPrincipalsAPI) { |
| KnownUser known_user(local_state()); |
| EXPECT_FALSE(known_user.GetIsUsingSAMLPrincipalsAPI(kDefaultAccountId)); |
| |
| known_user.UpdateIsUsingSAMLPrincipalsAPI(kDefaultAccountId, |
| /*using_saml=*/true); |
| EXPECT_TRUE(known_user.GetIsUsingSAMLPrincipalsAPI(kDefaultAccountId)); |
| } |
| |
| TEST_F(KnownUserTest, ProfileRequiresPolicy) { |
| KnownUser known_user(local_state()); |
| EXPECT_EQ(known_user.GetProfileRequiresPolicy(kDefaultAccountId), |
| ProfileRequiresPolicy::kUnknown); |
| |
| known_user.SetProfileRequiresPolicy(kDefaultAccountId, |
| ProfileRequiresPolicy::kPolicyRequired); |
| EXPECT_EQ(known_user.GetProfileRequiresPolicy(kDefaultAccountId), |
| ProfileRequiresPolicy::kPolicyRequired); |
| |
| known_user.SetProfileRequiresPolicy(kDefaultAccountId, |
| ProfileRequiresPolicy::kNoPolicyRequired); |
| EXPECT_EQ(known_user.GetProfileRequiresPolicy(kDefaultAccountId), |
| ProfileRequiresPolicy::kNoPolicyRequired); |
| |
| known_user.ClearProfileRequiresPolicy(kDefaultAccountId); |
| EXPECT_EQ(known_user.GetProfileRequiresPolicy(kDefaultAccountId), |
| ProfileRequiresPolicy::kUnknown); |
| } |
| |
| TEST_F(KnownUserTest, ReauthReason) { |
| KnownUser known_user(local_state()); |
| { |
| int auth_reason; |
| EXPECT_FALSE(known_user.FindReauthReason(kDefaultAccountId, &auth_reason)); |
| } |
| |
| known_user.UpdateReauthReason(kDefaultAccountId, 3); |
| { |
| int auth_reason; |
| EXPECT_TRUE(known_user.FindReauthReason(kDefaultAccountId, &auth_reason)); |
| EXPECT_EQ(auth_reason, 3); |
| } |
| } |
| |
| TEST_F(KnownUserTest, ChallengeResponseKeys) { |
| KnownUser known_user(local_state()); |
| EXPECT_TRUE(known_user.GetChallengeResponseKeys(kDefaultAccountId).is_none()); |
| |
| base::Value challenge_response_keys(base::Value::Type::LIST); |
| challenge_response_keys.Append(base::Value("key1")); |
| known_user.SetChallengeResponseKeys(kDefaultAccountId, |
| challenge_response_keys.Clone()); |
| |
| EXPECT_EQ(known_user.GetChallengeResponseKeys(kDefaultAccountId), |
| challenge_response_keys); |
| } |
| |
| TEST_F(KnownUserTest, LastOnlineSignin) { |
| KnownUser known_user(local_state()); |
| EXPECT_TRUE(known_user.GetLastOnlineSignin(kDefaultAccountId).is_null()); |
| |
| base::Time last_online_signin = base::Time::Now(); |
| known_user.SetLastOnlineSignin(kDefaultAccountId, last_online_signin); |
| |
| EXPECT_EQ(known_user.GetLastOnlineSignin(kDefaultAccountId), |
| last_online_signin); |
| } |
| |
| TEST_F(KnownUserTest, OfflineSigninLimit) { |
| KnownUser known_user(local_state()); |
| EXPECT_FALSE(known_user.GetOfflineSigninLimit(kDefaultAccountId).has_value()); |
| |
| base::TimeDelta offline_signin_limit = base::TimeDelta::FromMinutes(80); |
| known_user.SetOfflineSigninLimit(kDefaultAccountId, offline_signin_limit); |
| |
| EXPECT_EQ(known_user.GetOfflineSigninLimit(kDefaultAccountId).value(), |
| offline_signin_limit); |
| } |
| |
| TEST_F(KnownUserTest, IsEnterpriseManaged) { |
| KnownUser known_user(local_state()); |
| EXPECT_FALSE(known_user.GetIsEnterpriseManaged(kDefaultAccountId)); |
| |
| known_user.SetIsEnterpriseManaged(kDefaultAccountId, true); |
| |
| EXPECT_TRUE(known_user.GetIsEnterpriseManaged(kDefaultAccountId)); |
| } |
| |
| TEST_F(KnownUserTest, AccountManager) { |
| KnownUser known_user(local_state()); |
| { |
| std::string account_manager; |
| EXPECT_FALSE( |
| known_user.GetAccountManager(kDefaultAccountId, &account_manager)); |
| } |
| |
| known_user.SetAccountManager(kDefaultAccountId, "test"); |
| |
| { |
| std::string account_manager; |
| EXPECT_TRUE( |
| known_user.GetAccountManager(kDefaultAccountId, &account_manager)); |
| } |
| } |
| |
| TEST_F(KnownUserTest, UserLastLoginInputMethod) { |
| KnownUser known_user(local_state()); |
| { |
| std::string user_last_input_method; |
| EXPECT_FALSE(known_user.GetUserLastInputMethod(kDefaultAccountId, |
| &user_last_input_method)); |
| } |
| |
| known_user.SetUserLastLoginInputMethod(kDefaultAccountId, "test"); |
| |
| { |
| std::string user_last_input_method; |
| EXPECT_TRUE(known_user.GetUserLastInputMethod(kDefaultAccountId, |
| &user_last_input_method)); |
| } |
| } |
| |
| TEST_F(KnownUserTest, UserPinLength) { |
| KnownUser known_user(local_state()); |
| EXPECT_EQ(known_user.GetUserPinLength(kDefaultAccountId), 0); |
| |
| known_user.SetUserPinLength(kDefaultAccountId, 8); |
| |
| EXPECT_EQ(known_user.GetUserPinLength(kDefaultAccountId), 8); |
| } |
| |
| TEST_F(KnownUserTest, PinAutosubmitBackfillNeeded) { |
| KnownUser known_user(local_state()); |
| // If the pref is not set, returns true. |
| EXPECT_TRUE(known_user.PinAutosubmitIsBackfillNeeded(kDefaultAccountId)); |
| |
| known_user.PinAutosubmitSetBackfillNotNeeded(kDefaultAccountId); |
| |
| EXPECT_FALSE(known_user.PinAutosubmitIsBackfillNeeded(kDefaultAccountId)); |
| |
| known_user.PinAutosubmitSetBackfillNeededForTests(kDefaultAccountId); |
| |
| EXPECT_TRUE(known_user.PinAutosubmitIsBackfillNeeded(kDefaultAccountId)); |
| } |
| |
| TEST_F(KnownUserTest, PasswordSyncToken) { |
| KnownUser known_user(local_state()); |
| EXPECT_EQ(known_user.GetPasswordSyncToken(kDefaultAccountId), std::string()); |
| |
| known_user.SetPasswordSyncToken(kDefaultAccountId, "test"); |
| |
| EXPECT_EQ(known_user.GetPasswordSyncToken(kDefaultAccountId), "test"); |
| } |
| |
| TEST_F(KnownUserTest, CleanEphemeralUsersRemovesEphemeralAdOnly) { |
| KnownUser known_user(local_state()); |
| const AccountId kAccountIdNonEphemeralGaia = |
| AccountId::FromUserEmailGaiaId("account1@gmail.com", "gaia_id_1"); |
| const AccountId kAccountIdEphemeralGaia = |
| AccountId::FromUserEmailGaiaId("account2@gmail.com", "gaia_id_2"); |
| const AccountId kAccountIdNonEphemeralAd = |
| AccountId::AdFromUserEmailObjGuid("account3@gmail.com", "guid_3"); |
| const AccountId kAccountIdEphemeralAd = |
| AccountId::AdFromUserEmailObjGuid("account4@gmail.com", "guid_4"); |
| |
| known_user.SaveKnownUser(kAccountIdNonEphemeralGaia); |
| known_user.SaveKnownUser(kAccountIdEphemeralGaia); |
| known_user.SaveKnownUser(kAccountIdNonEphemeralAd); |
| known_user.SaveKnownUser(kAccountIdEphemeralAd); |
| known_user.SetIsEphemeralUser(kAccountIdEphemeralGaia, |
| /*is_ephemeral=*/true); |
| known_user.SetIsEphemeralUser(kAccountIdEphemeralAd, /*is_ephemeral=*/true); |
| |
| EXPECT_THAT(known_user.GetKnownAccountIds(), |
| testing::UnorderedElementsAre( |
| kAccountIdNonEphemeralGaia, kAccountIdEphemeralGaia, |
| kAccountIdNonEphemeralAd, kAccountIdEphemeralAd)); |
| |
| known_user.CleanEphemeralUsers(); |
| |
| EXPECT_THAT(known_user.GetKnownAccountIds(), |
| testing::UnorderedElementsAre(kAccountIdNonEphemeralGaia, |
| kAccountIdEphemeralGaia, |
| kAccountIdNonEphemeralAd)); |
| } |
| |
| TEST_F(KnownUserTest, CleanObsoletePrefs) { |
| KnownUser known_user(local_state()); |
| const std::string kObsoletePrefName = "minimal_migration_attempted"; |
| const std::string kCustomPrefName = "custom_pref"; |
| |
| // Set an obsolete pref. |
| known_user.SetBooleanPref(kDefaultAccountId, kObsoletePrefName, true); |
| // Set a custom pref. |
| known_user.SetBooleanPref(kDefaultAccountId, kCustomPrefName, true); |
| // Set a reserved, non-obsolete pref. |
| known_user.SetIsEnterpriseManaged(kDefaultAccountId, true); |
| |
| known_user.CleanObsoletePrefs(); |
| |
| // Verify that only the obsolete pref has been removed. |
| EXPECT_FALSE(known_user.GetBooleanPref(kDefaultAccountId, kObsoletePrefName, |
| /*out_value=*/nullptr)); |
| |
| bool custom_pref_value = false; |
| EXPECT_TRUE(known_user.GetBooleanPref(kDefaultAccountId, kCustomPrefName, |
| &custom_pref_value)); |
| EXPECT_TRUE(custom_pref_value); |
| |
| EXPECT_TRUE(known_user.GetIsEnterpriseManaged(kDefaultAccountId)); |
| } |
| |
| TEST_F(KnownUserTest, MigrateOfflineSigninLimit) { |
| KnownUser known_user(local_state()); |
| const std::string kDeprecatedPrefName = "offline_signin_limit"; |
| const std::string kNewPrefName = "offline_signin_limit2"; |
| |
| // Set a deprecated pref. base::TimeDelta() meant that value is not set. |
| known_user.SetPref(kDefaultAccountId, kDeprecatedPrefName, |
| util::TimeDeltaToValue(base::TimeDelta())); |
| |
| // Imitate that user is forced to online signin. |
| const char kUserForceOnlineSignin[] = "UserForceOnlineSignin"; |
| { |
| DictionaryPrefUpdate force_online_update(local_state(), |
| kUserForceOnlineSignin); |
| force_online_update->SetKey(kDefaultAccountId.GetUserEmail(), |
| base::Value(true)); |
| } |
| |
| const base::TimeDelta kLegitValue = base::TimeDelta::FromDays(14); |
| known_user.SetPref(kDefaultAccountId2, kDeprecatedPrefName, |
| util::TimeDeltaToValue(kLegitValue)); |
| |
| known_user.CleanObsoletePrefs(); |
| |
| const base::Value* out_value = nullptr; |
| // Verify that the deprecated pref has been removed. |
| EXPECT_FALSE( |
| known_user.GetPref(kDefaultAccountId, kDeprecatedPrefName, &out_value)); |
| EXPECT_FALSE( |
| known_user.GetPref(kDefaultAccountId2, kDeprecatedPrefName, &out_value)); |
| |
| EXPECT_FALSE(known_user.GetPref(kDefaultAccountId, kNewPrefName, &out_value)); |
| |
| EXPECT_TRUE(known_user.GetPref(kDefaultAccountId2, kNewPrefName, &out_value)); |
| EXPECT_EQ(kLegitValue, util::ValueToTimeDelta(*out_value)); |
| |
| // Verify that user is not forced to online signin anymore. |
| const base::DictionaryValue* prefs_force_online = |
| local_state()->GetDictionary(kUserForceOnlineSignin); |
| EXPECT_FALSE(prefs_force_online->FindBoolKey(kDefaultAccountId.GetUserEmail()) |
| .value()); |
| } |
| |
| // |
| // ============================================================================= |
| // Type-parametrized unittests for Set{String,Boolean,Integer,}Pref and |
| // Get{String,Boolean,Integer,}Pref. |
| // For every type (string, boolean, integer, raw base::Value) a PrefTypeInfo |
| // struct is declared which is then referenced in the generic test code. |
| |
| // Test type holder for known_user string prefs. |
| struct PrefTypeInfoString { |
| using PrefType = std::string; |
| using PrefTypeForReading = std::string; |
| |
| static constexpr auto SetFunc = &KnownUser::SetStringPref; |
| static constexpr auto GetFunc = &KnownUser::GetStringPref; |
| |
| static PrefType CreatePrefValue() { return std::string("test"); } |
| static bool CheckPrefValue(PrefTypeForReading read_value) { |
| return read_value == "test"; |
| } |
| static bool CheckPrefValueAsBaseValue(const base::Value& read_value) { |
| return read_value.is_string() && read_value.GetString() == "test"; |
| } |
| }; |
| |
| // Test type holder for known_user integer prefs. |
| struct PrefTypeInfoInteger { |
| using PrefType = int; |
| using PrefTypeForReading = int; |
| |
| static constexpr auto SetFunc = &KnownUser::SetIntegerPref; |
| static constexpr auto GetFunc = &KnownUser::GetIntegerPref; |
| |
| static PrefType CreatePrefValue() { return 7; } |
| static bool CheckPrefValue(PrefTypeForReading read_value) { |
| return read_value == 7; |
| } |
| static bool CheckPrefValueAsBaseValue(const base::Value& read_value) { |
| return read_value.is_int() && read_value.GetInt() == 7; |
| } |
| }; |
| |
| // Test type holder for known_user boolean prefs. |
| struct PrefTypeInfoBoolean { |
| using PrefType = bool; |
| using PrefTypeForReading = bool; |
| |
| static constexpr auto SetFunc = &KnownUser::SetBooleanPref; |
| static constexpr auto GetFunc = &KnownUser::GetBooleanPref; |
| |
| static PrefType CreatePrefValue() { return true; } |
| static bool CheckPrefValue(PrefTypeForReading read_value) { |
| return read_value == true; |
| } |
| static bool CheckPrefValueAsBaseValue(const base::Value& read_value) { |
| return read_value.is_bool() && read_value.GetBool() == true; |
| } |
| }; |
| |
| // Test type holder for known_user base::Value prefs. |
| struct PrefTypeInfoValue { |
| using PrefType = base::Value; |
| using PrefTypeForReading = const base::Value*; |
| |
| static constexpr auto SetFunc = &KnownUser::SetPref; |
| static constexpr auto GetFunc = &KnownUser::GetPref; |
| |
| static PrefType CreatePrefValue() { return base::Value("test"); } |
| static bool CheckPrefValue(PrefTypeForReading read_value) { |
| return *read_value == CreatePrefValue(); |
| } |
| static bool CheckPrefValueAsBaseValue(const base::Value& read_value) { |
| return read_value == CreatePrefValue(); |
| } |
| }; |
| |
| template <typename PrefTypeInfo> |
| class KnownUserWithPrefTypeTest : public KnownUserTest { |
| public: |
| KnownUserWithPrefTypeTest() = default; |
| ~KnownUserWithPrefTypeTest() = default; |
| }; |
| |
| TYPED_TEST_SUITE_P(KnownUserWithPrefTypeTest); |
| |
| TYPED_TEST_P(KnownUserWithPrefTypeTest, ReadOnNonExistingUser) { |
| KnownUser known_user(KnownUserTest::local_state()); |
| |
| constexpr char kPrefName[] = "some_pref"; |
| const AccountId kNonExistingUser = |
| AccountId::FromUserEmail("account1@gmail.com"); |
| |
| typename TypeParam::PrefTypeForReading read_result; |
| bool read_success = (known_user.*TypeParam::GetFunc)(kNonExistingUser, |
| kPrefName, &read_result); |
| EXPECT_FALSE(read_success); |
| } |
| |
| TYPED_TEST_P(KnownUserWithPrefTypeTest, ReadMissingPrefOnExistingUser) { |
| KnownUser known_user(KnownUserTest::local_state()); |
| |
| constexpr char kPrefName[] = "some_pref"; |
| const AccountId kUser = AccountId::FromUserEmail("account1@gmail.com"); |
| known_user.SaveKnownUser(kUser); |
| |
| typename TypeParam::PrefTypeForReading read_result; |
| bool read_success = |
| (known_user.*TypeParam::GetFunc)(kUser, kPrefName, &read_result); |
| EXPECT_FALSE(read_success); |
| } |
| |
| TYPED_TEST_P(KnownUserWithPrefTypeTest, ReadExistingPref) { |
| KnownUser known_user(KnownUserTest::local_state()); |
| |
| constexpr char kPrefName[] = "some_pref"; |
| const AccountId kUser = AccountId::FromUserEmail("account1@gmail.com"); |
| |
| // Set* implicitly creates the known_user user entry. |
| (known_user.*TypeParam::SetFunc)(kUser, kPrefName, |
| TypeParam::CreatePrefValue()); |
| |
| typename TypeParam::PrefTypeForReading read_result; |
| bool read_success = |
| (known_user.*TypeParam::GetFunc)(kUser, kPrefName, &read_result); |
| EXPECT_TRUE(read_success); |
| TypeParam::CheckPrefValue(read_result); |
| } |
| |
| TYPED_TEST_P(KnownUserWithPrefTypeTest, ReadExistingPrefAsValue) { |
| KnownUser known_user(KnownUserTest::local_state()); |
| |
| constexpr char kPrefName[] = "some_pref"; |
| const AccountId kUser = AccountId::FromUserEmail("account1@gmail.com"); |
| |
| // Set* implicitly creates the known_user user entry. |
| (known_user.*TypeParam::SetFunc)(kUser, kPrefName, |
| TypeParam::CreatePrefValue()); |
| |
| const base::Value* read_result; |
| bool read_success = known_user.GetPref(kUser, kPrefName, &read_result); |
| EXPECT_TRUE(read_success); |
| ASSERT_TRUE(read_result); |
| TypeParam::CheckPrefValueAsBaseValue(*read_result); |
| } |
| |
| REGISTER_TYPED_TEST_SUITE_P(KnownUserWithPrefTypeTest, |
| // All test functions must be listed: |
| ReadOnNonExistingUser, |
| ReadMissingPrefOnExistingUser, |
| ReadExistingPref, |
| ReadExistingPrefAsValue); |
| |
| // This must be an alias because the preprocessor does not understand <> so if |
| // it was directly embedded in the INSTANTIATE_TYPED_TEST_SUITE_P macro the |
| // prepocessor would be confused on the comma. |
| using AllTypeInfos = testing::Types<PrefTypeInfoString, |
| PrefTypeInfoInteger, |
| PrefTypeInfoBoolean, |
| PrefTypeInfoValue>; |
| |
| INSTANTIATE_TYPED_TEST_SUITE_P(AllTypes, |
| KnownUserWithPrefTypeTest, |
| AllTypeInfos); |
| |
| } // namespace user_manager |