OLD | NEW |
---|---|
(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 | |
OLD | NEW |