Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / chromeos / login / signin / device_id_browsertest.cc
blob62f5f893e6b338962bb85f622515d926e0d8aa69
1 // Copyright 2015 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.
5 #include "base/command_line.h"
6 #include "base/files/file_path.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/run_loop.h"
12 #include "base/strings/stringprintf.h"
13 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
14 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
15 #include "chrome/browser/chromeos/login/ui/oobe_display.h"
16 #include "chrome/browser/chromeos/profiles/profile_helper.h"
17 #include "chrome/browser/signin/chrome_signin_client_factory.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chromeos/chromeos_switches.h"
21 #include "components/signin/core/common/signin_pref_names.h"
22 #include "components/user_manager/remove_user_delegate.h"
23 #include "components/user_manager/user_manager.h"
25 namespace {
27 char kRefreshToken1[] = "refresh_token_1";
28 char kRefreshToken2[] = "refresh_token_2";
29 const base::FilePath::CharType kRefreshTokenToDeviceIdMapFile[] =
30 FILE_PATH_LITERAL("refrest_token_to_device_id.json");
32 char kSecondUserEmail[] = "second_user@gmail.com";
33 char kSecondUserPassword[] = "password";
34 char kSecondUserRefreshToken1[] = "refresh_token_second_user_1";
35 char kSecondUserRefreshToken2[] = "refresh_token_second_user_2";
37 } // namespace
39 namespace chromeos {
41 class DeviceIDTest : public OobeBaseTest,
42 public user_manager::RemoveUserDelegate {
43 public:
44 void SetUpCommandLine(base::CommandLine* command_line) override {
45 OobeBaseTest::SetUpCommandLine(command_line);
46 command_line->AppendSwitch(switches::kOobeSkipPostLogin);
49 void SetUpOnMainThread() override {
50 OobeBaseTest::SetUpOnMainThread();
51 LoadRefreshTokenToDeviceIdMap();
54 void TearDownOnMainThread() override {
55 SaveRefreshTokenToDeviceIdMap();
56 OobeBaseTest::TearDownOnMainThread();
59 std::string GetDeviceId(const std::string& user_id) {
60 return user_manager::UserManager::Get()->GetKnownUserDeviceId(user_id);
63 std::string GetDeviceIdFromSigninClient(const std::string& user_id) {
64 return ChromeSigninClientFactory::GetForProfile(
65 ProfileHelper::Get()->GetProfileByUser(
66 user_manager::UserManager::Get()->FindUser(user_id)))
67 ->GetSigninScopedDeviceId();
70 std::string GetDeviceIdFromGAIA(const std::string& refresh_token) {
71 return fake_gaia_->GetDeviceIdByRefreshToken(refresh_token);
74 // Checks that user's device ID retrieved from UserManager and SigninClient
75 // are the same.
76 // If |refresh_token| is not empty, checks that device ID associated with the
77 // |refresh_token| in GAIA is the same as ID saved on device.
78 void CheckDeviceIDIsConsistent(const std::string& user_id,
79 const std::string& refresh_token) {
80 const std::string device_id_in_signin_client =
81 GetDeviceIdFromSigninClient(user_id);
82 const std::string device_id_in_local_state = GetDeviceId(user_id);
84 EXPECT_FALSE(device_id_in_signin_client.empty());
85 EXPECT_EQ(device_id_in_signin_client, device_id_in_local_state);
87 if (!refresh_token.empty()) {
88 const std::string device_id_in_gaia = GetDeviceIdFromGAIA(refresh_token);
89 EXPECT_EQ(device_id_in_signin_client, device_id_in_gaia);
93 void WaitForSessionStart() {
94 content::WindowedNotificationObserver(
95 chrome::NOTIFICATION_SESSION_STARTED,
96 content::NotificationService::AllSources()).Wait();
99 void SignInOnline(const std::string& user_id,
100 const std::string& password,
101 const std::string& refresh_token) {
102 WaitForGaiaPageLoad();
104 FakeGaia::MergeSessionParams params;
105 params.email = user_id;
106 params.refresh_token = refresh_token;
107 fake_gaia_->UpdateMergeSessionParams(params);
109 GetLoginDisplay()->ShowSigninScreenForCreds(user_id, password);
110 WaitForSessionStart();
113 void SignInOffline(const std::string& user_id, const std::string& password) {
114 WaitForSigninScreen();
116 JS().ExecuteAsync(
117 base::StringPrintf("chrome.send('authenticateUser', ['%s', '%s'])",
118 user_id.c_str(), password.c_str()));
119 WaitForSessionStart();
122 void RemoveUser(const std::string& user_id) {
123 user_manager::UserManager::Get()->RemoveUser(user_id, this);
124 user_removal_loop_.Run();
127 private:
128 // user_manager::RemoveUserDelegate:
129 void OnBeforeUserRemoved(const std::string& username) override {}
131 void OnUserRemoved(const std::string& username) override {
132 user_removal_loop_.Quit();
135 base::FilePath GetRefreshTokenToDeviceIdMapFilePath() const {
136 return base::CommandLine::ForCurrentProcess()
137 ->GetSwitchValuePath(::switches::kUserDataDir)
138 .Append(kRefreshTokenToDeviceIdMapFile);
141 void LoadRefreshTokenToDeviceIdMap() {
142 std::string file_contents;
143 if (!base::ReadFileToString(GetRefreshTokenToDeviceIdMapFilePath(),
144 &file_contents))
145 return;
146 scoped_ptr<base::Value> value(base::JSONReader::Read(file_contents));
147 base::DictionaryValue* dictionary;
148 EXPECT_TRUE(value->GetAsDictionary(&dictionary));
149 FakeGaia::RefreshTokenToDeviceIdMap map;
150 for (base::DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd();
151 it.Advance()) {
152 std::string device_id;
153 EXPECT_TRUE(it.value().GetAsString(&device_id));
154 map[it.key()] = device_id;
156 fake_gaia_->SetRefreshTokenToDeviceIdMap(map);
159 void SaveRefreshTokenToDeviceIdMap() {
160 base::DictionaryValue dictionary;
161 for (const auto& kv : fake_gaia_->refresh_token_to_device_id_map())
162 dictionary.SetStringWithoutPathExpansion(kv.first, kv.second);
163 std::string json;
164 EXPECT_TRUE(base::JSONWriter::Write(dictionary, &json));
165 EXPECT_TRUE(base::WriteFile(GetRefreshTokenToDeviceIdMapFilePath(),
166 json.c_str(), json.length()));
169 base::RunLoop user_removal_loop_;
172 // Add the first user and check that device ID is consistent.
173 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_PRE_PRE_NewUsers) {
174 SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken1);
175 CheckDeviceIDIsConsistent(kFakeUserEmail, kRefreshToken1);
178 // Authenticate the first user through GAIA and verify that device ID remains
179 // the same.
180 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_PRE_NewUsers) {
181 const std::string device_id = GetDeviceId(kFakeUserEmail);
182 EXPECT_FALSE(device_id.empty());
183 EXPECT_EQ(device_id, GetDeviceIdFromGAIA(kRefreshToken1));
185 SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken2);
186 CheckDeviceIDIsConsistent(kFakeUserEmail, kRefreshToken2);
188 CHECK_EQ(device_id, GetDeviceId(kFakeUserEmail));
191 // Authenticate the first user offline and verify that device ID remains
192 // the same.
193 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_NewUsers) {
194 const std::string device_id = GetDeviceId(kFakeUserEmail);
195 EXPECT_FALSE(device_id.empty());
197 SignInOffline(kFakeUserEmail, kFakeUserPassword);
198 CheckDeviceIDIsConsistent(kFakeUserEmail, kRefreshToken2);
200 // Verify that device ID remained the same after offline auth.
201 CHECK_EQ(device_id, GetDeviceId(kFakeUserEmail));
204 // Add the second user.
205 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_NewUsers) {
206 WaitForSigninScreen();
207 JS().ExecuteAsync("chrome.send('showAddUser')");
208 SignInOnline(kSecondUserEmail, kSecondUserPassword, kSecondUserRefreshToken1);
209 CheckDeviceIDIsConsistent(kSecondUserEmail, kSecondUserRefreshToken1);
212 // Remove the second user.
213 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_NewUsers) {
214 WaitForSigninScreen();
215 RemoveUser(kSecondUserEmail);
218 // Add the second user back. Verify that device ID has been changed.
219 IN_PROC_BROWSER_TEST_F(DeviceIDTest, NewUsers) {
220 EXPECT_TRUE(GetDeviceId(kSecondUserEmail).empty());
221 SignInOnline(kSecondUserEmail, kSecondUserPassword, kSecondUserRefreshToken2);
222 CheckDeviceIDIsConsistent(kSecondUserEmail, kSecondUserRefreshToken2);
223 EXPECT_NE(GetDeviceIdFromGAIA(kSecondUserRefreshToken1),
224 GetDeviceId(kSecondUserEmail));
227 // Set up a user that has a device ID stored in preference only.
228 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_Migration) {
229 SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken1);
231 // Simulate user that has device ID saved only in preferences (pre-M44).
232 PrefService* prefs =
233 ProfileHelper::Get()
234 ->GetProfileByUser(user_manager::UserManager::Get()->GetActiveUser())
235 ->GetPrefs();
236 prefs->SetString(prefs::kGoogleServicesSigninScopedDeviceId,
237 GetDeviceId(kFakeUserEmail));
239 // Can't use SetKnownUserDeviceId here, because it forbids changing a device
240 // ID.
241 user_manager::UserManager::Get()->SetKnownUserStringPref(
242 kFakeUserEmail, "device_id", std::string());
245 // Tests that after the first sign in the device ID has been moved to the Local
246 // state.
247 IN_PROC_BROWSER_TEST_F(DeviceIDTest, Migration) {
248 EXPECT_TRUE(GetDeviceId(kFakeUserEmail).empty());
249 SignInOffline(kFakeUserEmail, kFakeUserPassword);
250 CheckDeviceIDIsConsistent(kFakeUserEmail, kRefreshToken1);
253 // Set up a user that doesn't have a device ID.
254 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_LegacyUsers) {
255 SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken1);
257 PrefService* prefs =
258 ProfileHelper::Get()
259 ->GetProfileByUser(user_manager::UserManager::Get()->GetActiveUser())
260 ->GetPrefs();
261 EXPECT_TRUE(
262 prefs->GetString(prefs::kGoogleServicesSigninScopedDeviceId).empty());
264 // Can't use SetKnownUserDeviceId here, because it forbids changing a device
265 // ID.
266 user_manager::UserManager::Get()->SetKnownUserStringPref(
267 kFakeUserEmail, "device_id", std::string());
270 // Tests that device ID has been generated after the first sign in.
271 IN_PROC_BROWSER_TEST_F(DeviceIDTest, LegacyUsers) {
272 EXPECT_TRUE(GetDeviceId(kFakeUserEmail).empty());
273 SignInOffline(kFakeUserEmail, kFakeUserPassword);
274 // Last param |auth_code| is empty, because we don't pass a device ID to GAIA
275 // in this case.
276 CheckDeviceIDIsConsistent(kFakeUserEmail, std::string());
279 } // namespace chromeos