1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/signin/signin_profile_attributes_updater.h"
6 
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "build/build_config.h"
11 #include "chrome/browser/profiles/profile_attributes_entry.h"
12 #include "chrome/browser/profiles/profile_attributes_storage.h"
13 #include "chrome/browser/signin/signin_util.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/testing_browser_process.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "chrome/test/base/testing_profile_manager.h"
18 #include "components/signin/core/browser/signin_error_controller.h"
19 #include "components/signin/public/identity_manager/identity_test_environment.h"
20 #include "components/signin/public/identity_manager/identity_test_utils.h"
21 #include "components/sync_preferences/pref_service_syncable.h"
22 #include "content/public/test/browser_task_environment.h"
23 #include "google_apis/gaia/google_service_auth_error.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 
26 namespace {
27 const char kEmail[] = "example@email.com";
28 
29 #if !defined(OS_CHROMEOS)
CheckProfilePrefsReset(PrefService * pref_service,bool expected_using_default_name)30 void CheckProfilePrefsReset(PrefService* pref_service,
31                             bool expected_using_default_name) {
32   EXPECT_TRUE(pref_service->GetBoolean(prefs::kProfileUsingDefaultAvatar));
33   EXPECT_FALSE(pref_service->GetBoolean(prefs::kProfileUsingGAIAAvatar));
34   EXPECT_EQ(expected_using_default_name,
35             pref_service->GetBoolean(prefs::kProfileUsingDefaultName));
36 }
37 
CheckProfilePrefsSet(PrefService * pref_service,bool expected_is_using_default_name)38 void CheckProfilePrefsSet(PrefService* pref_service,
39                           bool expected_is_using_default_name) {
40   EXPECT_FALSE(pref_service->GetBoolean(prefs::kProfileUsingDefaultAvatar));
41   EXPECT_TRUE(pref_service->GetBoolean(prefs::kProfileUsingGAIAAvatar));
42   EXPECT_EQ(expected_is_using_default_name,
43             pref_service->GetBoolean(prefs::kProfileUsingDefaultName));
44 }
45 
46 // Set the prefs to nondefault values.
SetProfilePrefs(PrefService * pref_service)47 void SetProfilePrefs(PrefService* pref_service) {
48   pref_service->SetBoolean(prefs::kProfileUsingDefaultAvatar, false);
49   pref_service->SetBoolean(prefs::kProfileUsingGAIAAvatar, true);
50   pref_service->SetBoolean(prefs::kProfileUsingDefaultName, false);
51 
52   CheckProfilePrefsSet(pref_service, false);
53 }
54 #endif  // !defined(OS_CHROMEOS)
55 }  // namespace
56 
57 class SigninProfileAttributesUpdaterTest : public testing::Test {
58  public:
SigninProfileAttributesUpdaterTest()59   SigninProfileAttributesUpdaterTest()
60       : profile_manager_(TestingBrowserProcess::GetGlobal()),
61         signin_error_controller_(
62             SigninErrorController::AccountMode::PRIMARY_ACCOUNT,
63             identity_test_env_.identity_manager()) {}
64 
65   // Recreates |signin_profile_attributes_updater_|. Useful for tests that want
66   // to set up the updater with specific preconditions.
RecreateSigninProfileAttributesUpdater()67   void RecreateSigninProfileAttributesUpdater() {
68     signin_profile_attributes_updater_ =
69         std::make_unique<SigninProfileAttributesUpdater>(
70             identity_test_env_.identity_manager(), &signin_error_controller_,
71             profile_manager_.profile_attributes_storage(), profile_->GetPath(),
72             profile_->GetPrefs());
73   }
74 
SetUp()75   void SetUp() override {
76     testing::Test::SetUp();
77 
78     ASSERT_TRUE(profile_manager_.SetUp());
79     std::string name = "profile_name";
80     profile_ = profile_manager_.CreateTestingProfile(
81         name, /*prefs=*/nullptr, base::UTF8ToUTF16(name), 0, std::string(),
82         TestingProfile::TestingFactories());
83 
84     RecreateSigninProfileAttributesUpdater();
85   }
86 
87   content::BrowserTaskEnvironment task_environment_;
88   TestingProfileManager profile_manager_;
89   TestingProfile* profile_;
90   signin::IdentityTestEnvironment identity_test_env_;
91   SigninErrorController signin_error_controller_;
92   std::unique_ptr<SigninProfileAttributesUpdater>
93       signin_profile_attributes_updater_;
94 };
95 
96 #if !defined(OS_CHROMEOS)
97 // Tests that the browser state info is updated on signin and signout.
98 // ChromeOS does not support signout.
TEST_F(SigninProfileAttributesUpdaterTest,SigninSignout)99 TEST_F(SigninProfileAttributesUpdaterTest, SigninSignout) {
100   ProfileAttributesEntry* entry;
101   ASSERT_TRUE(profile_manager_.profile_attributes_storage()
102                   ->GetProfileAttributesWithPath(profile_->GetPath(), &entry));
103   ASSERT_EQ(entry->GetSigninState(), SigninState::kNotSignedIn);
104   EXPECT_FALSE(entry->IsSigninRequired());
105 
106   // Signin.
107   identity_test_env_.MakePrimaryAccountAvailable(kEmail);
108   EXPECT_TRUE(entry->IsAuthenticated());
109   EXPECT_EQ(signin::GetTestGaiaIdForEmail(kEmail), entry->GetGAIAId());
110   EXPECT_EQ(kEmail, base::UTF16ToUTF8(entry->GetUserName()));
111 
112   // Signout.
113   identity_test_env_.ClearPrimaryAccount();
114   EXPECT_EQ(entry->GetSigninState(), SigninState::kNotSignedIn);
115   EXPECT_FALSE(entry->IsSigninRequired());
116 }
117 #endif  // !defined(OS_CHROMEOS)
118 
119 // Tests that the browser state info is updated on auth error change.
TEST_F(SigninProfileAttributesUpdaterTest,AuthError)120 TEST_F(SigninProfileAttributesUpdaterTest, AuthError) {
121   ProfileAttributesEntry* entry;
122   ASSERT_TRUE(profile_manager_.profile_attributes_storage()
123                   ->GetProfileAttributesWithPath(profile_->GetPath(), &entry));
124 
125   CoreAccountId account_id =
126       identity_test_env_.MakePrimaryAccountAvailable(kEmail).account_id;
127 
128 #if defined(OS_CHROMEOS)
129   // ChromeOS only observes signin state at initial creation of the updater, so
130   // recreate the updater after having set the primary account.
131   RecreateSigninProfileAttributesUpdater();
132 #endif
133 
134   EXPECT_TRUE(entry->IsAuthenticated());
135   EXPECT_FALSE(entry->IsAuthError());
136 
137   // Set auth error.
138   identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
139       account_id,
140       GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
141   EXPECT_TRUE(entry->IsAuthError());
142 
143   // Remove auth error.
144   identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
145       account_id, GoogleServiceAuthError::AuthErrorNone());
146   EXPECT_FALSE(entry->IsAuthError());
147 }
148 
149 #if !defined(OS_CHROMEOS)
TEST_F(SigninProfileAttributesUpdaterTest,SigninSignoutResetsProfilePrefs)150 TEST_F(SigninProfileAttributesUpdaterTest, SigninSignoutResetsProfilePrefs) {
151   PrefService* pref_service = profile_->GetPrefs();
152   ProfileAttributesEntry* entry;
153   ASSERT_TRUE(profile_manager_.profile_attributes_storage()
154                   ->GetProfileAttributesWithPath(profile_->GetPath(), &entry));
155 
156   // Set profile prefs.
157   CheckProfilePrefsReset(pref_service, true);
158 #if !defined(OS_ANDROID)
159   SetProfilePrefs(pref_service);
160 
161   // Set UPA should reset profile prefs.
162   AccountInfo account_info =
163       identity_test_env_.MakeUnconsentedPrimaryAccountAvailable(
164           "email1@example.com");
165   EXPECT_FALSE(entry->IsAuthenticated());
166   CheckProfilePrefsReset(pref_service, false);
167   SetProfilePrefs(pref_service);
168   // Signout should reset profile prefs.
169   identity_test_env_.ClearPrimaryAccount();
170   CheckProfilePrefsReset(pref_service, false);
171 #endif  // !defined(OS_ANDROID)
172 
173   SetProfilePrefs(pref_service);
174   // Set primary account should reset profile prefs.
175   AccountInfo primary_account =
176       identity_test_env_.MakePrimaryAccountAvailable("primary@example.com");
177   CheckProfilePrefsReset(pref_service, false);
178   SetProfilePrefs(pref_service);
179   // Disabling sync should reset profile prefs.
180   identity_test_env_.ClearPrimaryAccount();
181   CheckProfilePrefsReset(pref_service, false);
182 }
183 
184 #if !defined(OS_ANDROID)
TEST_F(SigninProfileAttributesUpdaterTest,EnablingSyncWithUPAAccountShouldNotResetProfilePrefs)185 TEST_F(SigninProfileAttributesUpdaterTest,
186        EnablingSyncWithUPAAccountShouldNotResetProfilePrefs) {
187   PrefService* pref_service = profile_->GetPrefs();
188   ProfileAttributesEntry* entry;
189   ASSERT_TRUE(profile_manager_.profile_attributes_storage()
190                   ->GetProfileAttributesWithPath(profile_->GetPath(), &entry));
191   // Set UPA.
192   AccountInfo account_info =
193       identity_test_env_.MakeUnconsentedPrimaryAccountAvailable(
194           "email1@example.com");
195   EXPECT_FALSE(entry->IsAuthenticated());
196   SetProfilePrefs(pref_service);
197   // Set primary account to be the same as the UPA.
198   // Given it is the same account, profile prefs should keep the same state.
199   identity_test_env_.SetPrimaryAccount(account_info.email);
200   EXPECT_TRUE(entry->IsAuthenticated());
201   CheckProfilePrefsSet(pref_service, false);
202   identity_test_env_.ClearPrimaryAccount();
203   CheckProfilePrefsReset(pref_service, false);
204 }
205 
TEST_F(SigninProfileAttributesUpdaterTest,EnablingSyncWithDifferentAccountThanUPAResetsProfilePrefs)206 TEST_F(SigninProfileAttributesUpdaterTest,
207        EnablingSyncWithDifferentAccountThanUPAResetsProfilePrefs) {
208   PrefService* pref_service = profile_->GetPrefs();
209   ProfileAttributesEntry* entry;
210   ASSERT_TRUE(profile_manager_.profile_attributes_storage()
211                   ->GetProfileAttributesWithPath(profile_->GetPath(), &entry));
212   AccountInfo account_info =
213       identity_test_env_.MakeUnconsentedPrimaryAccountAvailable(
214           "email1@example.com");
215   EXPECT_FALSE(entry->IsAuthenticated());
216   SetProfilePrefs(pref_service);
217   // Set primary account to a different account than the UPA.
218   AccountInfo primary_account =
219       identity_test_env_.MakePrimaryAccountAvailable("primary@example.com");
220   EXPECT_TRUE(entry->IsAuthenticated());
221   CheckProfilePrefsReset(pref_service, false);
222 }
223 #endif  // !defined(OS_ANDROID)
224 
225 class SigninProfileAttributesUpdaterWithForceSigninTest
226     : public SigninProfileAttributesUpdaterTest {
SetUp()227   void SetUp() override {
228     signin_util::SetForceSigninForTesting(true);
229     SigninProfileAttributesUpdaterTest::SetUp();
230   }
231 
TearDown()232   void TearDown() override {
233     SigninProfileAttributesUpdaterTest::TearDown();
234     signin_util::ResetForceSigninForTesting();
235   }
236 };
237 
TEST_F(SigninProfileAttributesUpdaterWithForceSigninTest,IsSigninRequired)238 TEST_F(SigninProfileAttributesUpdaterWithForceSigninTest, IsSigninRequired) {
239   ProfileAttributesEntry* entry;
240   ASSERT_TRUE(profile_manager_.profile_attributes_storage()
241                   ->GetProfileAttributesWithPath(profile_->GetPath(), &entry));
242   EXPECT_FALSE(entry->IsAuthenticated());
243   EXPECT_TRUE(entry->IsSigninRequired());
244 
245   AccountInfo account_info =
246       identity_test_env_.MakePrimaryAccountAvailable(kEmail);
247 
248   EXPECT_TRUE(entry->IsAuthenticated());
249   EXPECT_EQ(signin::GetTestGaiaIdForEmail(kEmail), entry->GetGAIAId());
250   EXPECT_EQ(kEmail, base::UTF16ToUTF8(entry->GetUserName()));
251 
252   identity_test_env_.ClearPrimaryAccount();
253   EXPECT_EQ(entry->GetSigninState(), SigninState::kNotSignedIn);
254   EXPECT_TRUE(entry->IsSigninRequired());
255 }
256 #endif  // !defined(OS_CHROMEOS)
257