Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: chrome/browser/chromeos/login/signin/device_id_browsertest.cc

Issue 1141163002: Browser tests for the new way of handling device ID in Chrome OS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@device_id
Patch Set: Fixed flakiness. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
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"
24
25 namespace {
26
27 char kRefreshToken1[] = "refresh_token_1";
28 char kRefreshToken2[] = "refresh_token_2";
29 const base::FilePath::CharType kRefreshTokenToDeviceIdMapPath[] =
achuithb 2015/05/26 06:28:20 kRefreshTokenToDeviceIdMapFile or kRefreshTokenToD
dzhioev (left Google) 2015/05/26 21:18:15 Done.
30 FILE_PATH_LITERAL("refrest_token_to_device_id.json");
31
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";
36
37 } // namespace
38
39 namespace chromeos {
40
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);
47 }
48
49 void SetUpOnMainThread() override {
50 OobeBaseTest::SetUpOnMainThread();
51 LoadRefreshTokenToDeviceIdMap();
52 }
53
54 void TearDownOnMainThread() override {
55 SaveRefreshTokenToDeviceIdMap();
56 OobeBaseTest::TearDownOnMainThread();
57 }
58
59 std::string GetDeviceId(const std::string& user_id) {
60 return user_manager::UserManager::Get()->GetKnownUserDeviceId(user_id);
61 }
62
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();
68 }
69
70 std::string GetDeviceIdFromGAIA(const std::string& refresh_token) {
71 return fake_gaia_->GetDeviceIdByRefreshToken(refresh_token);
72 }
73
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 std::string device_id_in_signin_client =
achuithb 2015/05/26 06:28:20 nit: const
dzhioev (left Google) 2015/05/26 21:18:14 Done.
81 GetDeviceIdFromSigninClient(user_id);
82 std::string device_id_in_local_state = GetDeviceId(user_id);
achuithb 2015/05/26 06:28:20 nit: const
dzhioev (left Google) 2015/05/26 21:18:14 Done.
83
84 EXPECT_FALSE(device_id_in_signin_client.empty());
85 EXPECT_EQ(device_id_in_signin_client, device_id_in_local_state);
86
87 if (!refresh_token.empty()) {
88 std::string device_id_in_gaia = GetDeviceIdFromGAIA(refresh_token);
achuithb 2015/05/26 06:28:20 nit: const
dzhioev (left Google) 2015/05/26 21:18:14 Done.
89 EXPECT_EQ(device_id_in_signin_client, device_id_in_gaia);
90 }
91 }
92
93 void WaitForSessionStart() {
94 content::WindowedNotificationObserver(
95 chrome::NOTIFICATION_SESSION_STARTED,
96 content::NotificationService::AllSources()).Wait();
97 }
98
99 void SignInOnline(const std::string& user_id,
100 const std::string& password,
101 const std::string& refresh_token) {
102 WaitForGaiaPageLoad();
103
104 FakeGaia::MergeSessionParams params;
105 params.email = user_id;
106 params.refresh_token = refresh_token;
107 fake_gaia_->UpdateMergeSessionParams(params);
108
109 GetLoginDisplay()->ShowSigninScreenForCreds(user_id, password);
110 WaitForSessionStart();
111
112 CheckDeviceIDIsConsistent(user_id, refresh_token);
achuithb 2015/05/26 06:28:20 I feel you should pull this function out and expli
dzhioev (left Google) 2015/05/26 21:18:14 Done.
113 }
114
115 void SignInOffline(const std::string& user_id,
116 const std::string& password,
117 const std::string& refresh_token) {
118 WaitForSigninScreen();
119
120 JS().Execute(
121 base::StringPrintf("chrome.send('authenticateUser', ['%s', '%s'])",
122 user_id.c_str(), password.c_str()));
123 WaitForSessionStart();
124
125 CheckDeviceIDIsConsistent(user_id, refresh_token);
achuithb 2015/05/26 06:28:20 Same
dzhioev (left Google) 2015/05/26 21:18:15 Done.
126 }
127
128 void RemoveUser(const std::string& user_id) {
129 user_manager::UserManager::Get()->RemoveUser(user_id, this);
130 user_removal_loop_.Run();
131 }
132
133 private:
134 void OnBeforeUserRemoved(const std::string& username) override {}
achuithb 2015/05/26 06:28:19 // RemoveUserDelegate:
dzhioev (left Google) 2015/05/26 21:18:14 Done.
135
136 void OnUserRemoved(const std::string& username) override {
137 user_removal_loop_.Quit();
138 }
139
140 void LoadRefreshTokenToDeviceIdMap() {
141 base::FilePath path = base::CommandLine::ForCurrentProcess()
achuithb 2015/05/26 06:28:20 nit: const, also a slightly more descriptive name
dzhioev (left Google) 2015/05/26 21:18:14 Done.
142 ->GetSwitchValuePath(::switches::kUserDataDir)
143 .Append(kRefreshTokenToDeviceIdMapPath);
144 std::string file_contents;
145 if (!base::ReadFileToString(path, &file_contents))
146 return;
achuithb 2015/05/26 06:28:20 When is this a valid outcome?
dzhioev (left Google) 2015/05/26 21:18:15 When the file doesn't exist. This happens in the v
147 scoped_ptr<base::Value> value(base::JSONReader::Read(file_contents));
148 base::DictionaryValue* dictionary;
149 EXPECT_TRUE(value->GetAsDictionary(&dictionary));
150 FakeGaia::RefreshTokenToDeviceIdMap map;
151 for (base::DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd();
achuithb 2015/05/26 06:28:20 Why not auto here?
dzhioev (left Google) 2015/05/26 21:18:14 base::Dictionary doesn't have begin() method retur
152 it.Advance()) {
153 std::string device_id;
154 EXPECT_TRUE(it.value().GetAsString(&device_id));
155 map[it.key()] = device_id;
156 }
157 fake_gaia_->SetRefreshTokenToDeviceIdMap(map);
158 }
159
160 void SaveRefreshTokenToDeviceIdMap() const {
161 base::DictionaryValue dictionary;
162 for (const auto& kv : fake_gaia_->refresh_token_to_device_id_map())
163 dictionary.SetStringWithoutPathExpansion(kv.first, kv.second);
164 std::string json;
165 EXPECT_TRUE(base::JSONWriter::Write(dictionary, &json));
166 base::FilePath path = base::CommandLine::ForCurrentProcess()
achuithb 2015/05/26 06:28:20 nit: const, also more descriptive name.
dzhioev (left Google) 2015/05/26 21:18:14 Done.
167 ->GetSwitchValuePath(::switches::kUserDataDir)
168 .Append(kRefreshTokenToDeviceIdMapPath);
169 EXPECT_TRUE(base::WriteFile(path, json.c_str(), json.length()));
170 }
171
172 base::RunLoop user_removal_loop_;
173 };
174
175 // Add the first user and check that device ID is consistent.
176 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_PRE_PRE_NewUsers) {
177 SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken1);
178 }
179
180 // Authenticate the first user through GAIA and verify that device ID remains
181 // the same.
182 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_PRE_NewUsers) {
183 std::string device_id = GetDeviceId(kFakeUserEmail);
achuithb 2015/05/26 06:28:20 nit: const
dzhioev (left Google) 2015/05/26 21:18:15 Done.
184 EXPECT_FALSE(device_id.empty());
185 EXPECT_EQ(device_id, GetDeviceIdFromGAIA(kRefreshToken1));
186
187 SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken2);
188
189 CHECK_EQ(device_id, GetDeviceId(kFakeUserEmail));
190 }
191
192 // Authenticate the first user online and verify that device ID remains
193 // the same.
194 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_PRE_NewUsers) {
195 std::string device_id = GetDeviceId(kFakeUserEmail);
achuithb 2015/05/26 06:28:20 nit:const
dzhioev (left Google) 2015/05/26 21:18:14 Done.
196 EXPECT_FALSE(device_id.empty());
197
198 SignInOffline(kFakeUserEmail, kFakeUserPassword, kRefreshToken2);
199
200 // Verify that device ID remained the same after offline auth.
201 CHECK_EQ(device_id, GetDeviceId(kFakeUserEmail));
202 }
203
204 // Add the second user.
205 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_PRE_NewUsers) {
206 WaitForSigninScreen();
207 JS().Execute("chrome.send('showAddUser')");
208 SignInOnline(kSecondUserEmail, kSecondUserPassword, kSecondUserRefreshToken1);
209 }
210
211 // Remove the second user.
212 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_NewUsers) {
213 WaitForSigninScreen();
214 RemoveUser(kSecondUserEmail);
215 }
216
217 // Add the second user back. Verify that device ID has been changed.
218 IN_PROC_BROWSER_TEST_F(DeviceIDTest, NewUsers) {
219 EXPECT_TRUE(GetDeviceId(kSecondUserEmail).empty());
220 SignInOnline(kSecondUserEmail, kSecondUserPassword, kSecondUserRefreshToken2);
221 EXPECT_NE(GetDeviceIdFromGAIA(kSecondUserRefreshToken1),
222 GetDeviceId(kSecondUserEmail));
223 }
224
225 // Tests migration process from the old way of storing device ID (in
226 // preference), to the new one (in Local State).
227 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_Migration) {
achuithb 2015/05/26 06:28:20 This "test" isn't testing anything, is it? If it'
dzhioev (left Google) 2015/05/26 21:18:15 Yes, that is PRE test case where we set up the sta
228 SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken1);
229
230 // Simulate user that has device ID saved only in preferences (pre-M44).
231 PrefService* prefs =
232 ProfileHelper::Get()
233 ->GetProfileByUser(user_manager::UserManager::Get()->GetActiveUser())
234 ->GetPrefs();
235 prefs->SetString(prefs::kGoogleServicesSigninScopedDeviceId,
236 GetDeviceId(kFakeUserEmail));
237
238 // Can't use SetKnownUserDeviceId here, because it forbids changing a device
239 // ID.
240 user_manager::UserManager::Get()->SetKnownUserStringPref(
241 kFakeUserEmail, "device_id", std::string());
242 }
243
244 IN_PROC_BROWSER_TEST_F(DeviceIDTest, Migration) {
245 EXPECT_TRUE(GetDeviceId(kFakeUserEmail).empty());
246 SignInOffline(kFakeUserEmail, kFakeUserPassword, kRefreshToken1);
247 }
248
249 // Tests that device ID is generated for users that has device ID stored neither
250 // in preference, nor in Local State.
251 IN_PROC_BROWSER_TEST_F(DeviceIDTest, PRE_LegacyUsers) {
252 SignInOnline(kFakeUserEmail, kFakeUserPassword, kRefreshToken1);
253
254 PrefService* prefs =
255 ProfileHelper::Get()
256 ->GetProfileByUser(user_manager::UserManager::Get()->GetActiveUser())
257 ->GetPrefs();
258 EXPECT_TRUE(
259 prefs->GetString(prefs::kGoogleServicesSigninScopedDeviceId).empty());
260
261 // Can't use SetKnownUserDeviceId here, because it forbids changing a device
262 // ID.
263 user_manager::UserManager::Get()->SetKnownUserStringPref(
264 kFakeUserEmail, "device_id", std::string());
265 }
266
267 IN_PROC_BROWSER_TEST_F(DeviceIDTest, LegacyUsers) {
268 EXPECT_TRUE(GetDeviceId(kFakeUserEmail).empty());
269 // Last param |auth_code| is empty, because we don't pass a device ID to GAIA
270 // in this case.
271 SignInOffline(kFakeUserEmail, kFakeUserPassword, std::string());
272 }
273
274 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698