• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/ui/webui/options/sync_setup_handler.h"
6 
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/values.h"
10 #include "chrome/browser/google/google_util.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/sync/profile_sync_service.h"
13 #include "chrome/browser/sync/sync_setup_flow.h"
14 #include "grit/chromium_strings.h"
15 #include "grit/generated_resources.h"
16 #include "grit/locale_settings.h"
17 #include "ui/base/l10n/l10n_util.h"
18 
19 using l10n_util::GetStringFUTF16;
20 using l10n_util::GetStringUTF16;
21 
22 namespace {
23 
24 // TODO(jhawkins): Move these to url_constants.h.
25 const char* kInvalidPasswordHelpUrl =
26     "http://www.google.com/support/accounts/bin/answer.py?ctx=ch&answer=27444";
27 const char* kCanNotAccessAccountUrl =
28     "http://www.google.com/support/accounts/bin/answer.py?answer=48598";
29 #if defined(OS_CHROMEOS)
30 const char* kEncryptionHelpUrl =
31     "http://www.google.com/support/chromeos/bin/answer.py?answer=1181035";
32 #else
33 const char* kEncryptionHelpUrl =
34     "http://www.google.com/support/chrome/bin/answer.py?answer=1181035";
35 #endif
36 const char* kCreateNewAccountUrl =
37     "https://www.google.com/accounts/NewAccount?service=chromiumsync";
38 
GetAuthData(const std::string & json,std::string * username,std::string * password,std::string * captcha,std::string * access_code)39 bool GetAuthData(const std::string& json,
40                  std::string* username,
41                  std::string* password,
42                  std::string* captcha,
43                  std::string* access_code) {
44   scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
45   if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
46     return false;
47 
48   DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get());
49   if (!result->GetString("user", username) ||
50       !result->GetString("pass", password) ||
51       !result->GetString("captcha", captcha) ||
52       !result->GetString("access_code", access_code)) {
53       return false;
54   }
55   return true;
56 }
57 
GetConfiguration(const std::string & json,SyncConfiguration * config)58 bool GetConfiguration(const std::string& json, SyncConfiguration* config) {
59   scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
60   if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
61     return false;
62 
63   DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get());
64   if (!result->GetBoolean("keepEverythingSynced", &config->sync_everything))
65     return false;
66 
67   // These values need to be kept in sync with where they are written in
68   // choose_datatypes.html.
69   bool sync_bookmarks;
70   if (!result->GetBoolean("syncBookmarks", &sync_bookmarks))
71     return false;
72   if (sync_bookmarks)
73     config->data_types.insert(syncable::BOOKMARKS);
74 
75   bool sync_preferences;
76   if (!result->GetBoolean("syncPreferences", &sync_preferences))
77     return false;
78   if (sync_preferences)
79     config->data_types.insert(syncable::PREFERENCES);
80 
81   bool sync_themes;
82   if (!result->GetBoolean("syncThemes", &sync_themes))
83     return false;
84   if (sync_themes)
85     config->data_types.insert(syncable::THEMES);
86 
87   bool sync_passwords;
88   if (!result->GetBoolean("syncPasswords", &sync_passwords))
89     return false;
90   if (sync_passwords)
91     config->data_types.insert(syncable::PASSWORDS);
92 
93   bool sync_autofill;
94   if (!result->GetBoolean("syncAutofill", &sync_autofill))
95     return false;
96   if (sync_autofill)
97     config->data_types.insert(syncable::AUTOFILL);
98 
99   bool sync_extensions;
100   if (!result->GetBoolean("syncExtensions", &sync_extensions))
101     return false;
102   if (sync_extensions)
103     config->data_types.insert(syncable::EXTENSIONS);
104 
105   bool sync_typed_urls;
106   if (!result->GetBoolean("syncTypedUrls", &sync_typed_urls))
107     return false;
108   if (sync_typed_urls)
109     config->data_types.insert(syncable::TYPED_URLS);
110 
111   bool sync_sessions;
112   if (!result->GetBoolean("syncSessions", &sync_sessions))
113     return false;
114   if (sync_sessions)
115     config->data_types.insert(syncable::SESSIONS);
116 
117   bool sync_apps;
118   if (!result->GetBoolean("syncApps", &sync_apps))
119     return false;
120   if (sync_apps)
121     config->data_types.insert(syncable::APPS);
122 
123   // Encryption settings.
124   if (!result->GetBoolean("usePassphrase", &config->use_secondary_passphrase))
125     return false;
126   if (config->use_secondary_passphrase &&
127       !result->GetString("passphrase", &config->secondary_passphrase))
128     return false;
129 
130   return true;
131 }
132 
GetPassphrase(const std::string & json,std::string * passphrase)133 bool GetPassphrase(const std::string& json, std::string* passphrase) {
134   scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
135   if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
136     return false;
137 
138   DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get());
139   return result->GetString("passphrase", passphrase);
140 }
141 
GetFirstPassphrase(const std::string & json,std::string * option,std::string * passphrase)142 bool GetFirstPassphrase(const std::string& json,
143                         std::string* option,
144                         std::string* passphrase) {
145   scoped_ptr<Value> parsed_value(base::JSONReader::Read(json, false));
146   if (!parsed_value.get() || !parsed_value->IsType(Value::TYPE_DICTIONARY))
147     return false;
148 
149   DictionaryValue* result = static_cast<DictionaryValue*>(parsed_value.get());
150   return result->GetString("option", option) &&
151          result->GetString("passphrase", passphrase);
152 }
153 
154 }  // namespace
155 
SyncSetupHandler()156 SyncSetupHandler::SyncSetupHandler() : flow_(NULL) {
157 }
158 
~SyncSetupHandler()159 SyncSetupHandler::~SyncSetupHandler() {
160 }
161 
GetLocalizedValues(DictionaryValue * localized_strings)162 void SyncSetupHandler::GetLocalizedValues(DictionaryValue* localized_strings) {
163   DCHECK(localized_strings);
164 
165   localized_strings->SetString(
166       "invalidpasswordhelpurl",
167       google_util::StringAppendGoogleLocaleParam(kInvalidPasswordHelpUrl));
168   localized_strings->SetString(
169       "cannotaccessaccounturl",
170       google_util::StringAppendGoogleLocaleParam(kCanNotAccessAccountUrl));
171   localized_strings->SetString(
172       "createnewaccounturl",
173       google_util::StringAppendGoogleLocaleParam(kCreateNewAccountUrl));
174   localized_strings->SetString(
175       "introduction",
176       GetStringFUTF16(IDS_SYNC_LOGIN_INTRODUCTION,
177                       GetStringUTF16(IDS_PRODUCT_NAME)));
178   localized_strings->SetString(
179       "choosedatatypesinstructions",
180       GetStringFUTF16(IDS_SYNC_CHOOSE_DATATYPES_INSTRUCTIONS,
181                       GetStringUTF16(IDS_PRODUCT_NAME)));
182   localized_strings->SetString(
183       "encryptionInstructions",
184       GetStringFUTF16(IDS_SYNC_ENCRYPTION_INSTRUCTIONS,
185                       GetStringUTF16(IDS_PRODUCT_NAME)));
186   localized_strings->SetString(
187       "encryptionhelpurl",
188       google_util::StringAppendGoogleLocaleParam(kEncryptionHelpUrl));
189   localized_strings->SetString(
190       "passphraseEncryptionMessage",
191       GetStringFUTF16(IDS_SYNC_PASSPHRASE_ENCRYPTION_MESSAGE,
192                       GetStringUTF16(IDS_PRODUCT_NAME)));
193 
194   static OptionsStringResource resources[] = {
195     { "syncSetupOverlayTitle", IDS_SYNC_SETUP_TITLE },
196     { "syncSetupConfigureTitle", IDS_SYNC_SETUP_CONFIGURE_TITLE },
197     { "signinprefix", IDS_SYNC_LOGIN_SIGNIN_PREFIX },
198     { "signinsuffix", IDS_SYNC_LOGIN_SIGNIN_SUFFIX },
199     { "cannotbeblank", IDS_SYNC_CANNOT_BE_BLANK },
200     { "emaillabel", IDS_SYNC_LOGIN_EMAIL },
201     { "passwordlabel", IDS_SYNC_LOGIN_PASSWORD },
202     { "invalidcredentials", IDS_SYNC_INVALID_USER_CREDENTIALS },
203     { "signin", IDS_SYNC_SIGNIN },
204     { "couldnotconnect", IDS_SYNC_LOGIN_COULD_NOT_CONNECT },
205     { "cannotaccessaccount", IDS_SYNC_CANNOT_ACCESS_ACCOUNT },
206     { "createaccount", IDS_SYNC_CREATE_ACCOUNT },
207     { "cancel", IDS_CANCEL },
208     { "settingup", IDS_SYNC_LOGIN_SETTING_UP },
209     { "settingupsync", IDS_SYNC_LOGIN_SETTING_UP_SYNC },
210     { "errorsigningin", IDS_SYNC_ERROR_SIGNING_IN },
211     { "captchainstructions", IDS_SYNC_GAIA_CAPTCHA_INSTRUCTIONS },
212     { "invalidaccesscode", IDS_SYNC_INVALID_ACCESS_CODE_LABEL },
213     { "enteraccesscode", IDS_SYNC_ENTER_ACCESS_CODE_LABEL },
214     { "getaccesscodehelp", IDS_SYNC_ACCESS_CODE_HELP_LABEL },
215     { "getaccesscodeurl", IDS_SYNC_GET_ACCESS_CODE_URL },
216     { "dataTypes", IDS_SYNC_DATA_TYPES_TAB_NAME },
217     { "encryption", IDS_SYNC_ENCRYPTION_TAB_NAME },
218     { "choosedatatypesheader", IDS_SYNC_CHOOSE_DATATYPES_HEADER },
219     { "keepeverythingsynced", IDS_SYNC_EVERYTHING },
220     { "choosedatatypes", IDS_SYNC_CHOOSE_DATATYPES },
221     { "bookmarks", IDS_SYNC_DATATYPE_BOOKMARKS },
222     { "preferences", IDS_SYNC_DATATYPE_PREFERENCES },
223     { "autofill", IDS_SYNC_DATATYPE_AUTOFILL },
224     { "themes", IDS_SYNC_DATATYPE_THEMES },
225     { "passwords", IDS_SYNC_DATATYPE_PASSWORDS },
226     { "extensions", IDS_SYNC_DATATYPE_EXTENSIONS },
227     { "typedurls", IDS_SYNC_DATATYPE_TYPED_URLS },
228     { "apps", IDS_SYNC_DATATYPE_APPS },
229     { "foreignsessions", IDS_SYNC_DATATYPE_SESSIONS },
230     { "synczerodatatypeserror", IDS_SYNC_ZERO_DATA_TYPES_ERROR },
231     { "abortederror", IDS_SYNC_SETUP_ABORTED_BY_PENDING_CLEAR },
232     { "encryptAllLabel", IDS_SYNC_ENCRYPT_ALL_LABEL },
233     { "googleOption", IDS_SYNC_PASSPHRASE_OPT_GOOGLE },
234     { "explicitOption", IDS_SYNC_PASSPHRASE_OPT_EXPLICIT },
235     { "sectionGoogleMessage", IDS_SYNC_PASSPHRASE_MSG_GOOGLE },
236     { "sectionExplicitMessage", IDS_SYNC_PASSPHRASE_MSG_EXPLICIT },
237     { "passphraseLabel", IDS_SYNC_PASSPHRASE_LABEL },
238     { "confirmLabel", IDS_SYNC_CONFIRM_PASSPHRASE_LABEL },
239     { "emptyErrorMessage", IDS_SYNC_EMPTY_PASSPHRASE_ERROR },
240     { "mismatchErrorMessage", IDS_SYNC_PASSPHRASE_MISMATCH_ERROR },
241     { "passphraseWarning", IDS_SYNC_PASSPHRASE_WARNING },
242     { "cleardata", IDS_SYNC_CLEAR_DATA_FOR_PASSPHRASE },
243     { "cleardatalink", IDS_SYNC_CLEAR_DATA_LINK },
244     { "settingup", IDS_SYNC_LOGIN_SETTING_UP },
245     { "success", IDS_SYNC_SUCCESS },
246     { "firsttimesummary", IDS_SYNC_SETUP_FIRST_TIME_ALL_DONE },
247     { "okay", IDS_SYNC_SETUP_OK_BUTTON_LABEL },
248     { "enterPassphraseTitle", IDS_SYNC_ENTER_PASSPHRASE_TITLE },
249     { "firstPassphraseTitle", IDS_SYNC_FIRST_PASSPHRASE_TITLE },
250     { "customizeLinkLabel", IDS_SYNC_CUSTOMIZE_LINK_LABEL },
251     { "confirmSyncPreferences", IDS_SYNC_CONFIRM_SYNC_PREFERENCES },
252     { "syncEverything", IDS_SYNC_SYNC_EVERYTHING },
253     { "useDefaultSettings", IDS_SYNC_USE_DEFAULT_SETTINGS },
254     { "passphraseSectionTitle", IDS_SYNC_PASSPHRASE_SECTION_TITLE },
255     { "privacyDashboardLink", IDS_SYNC_PRIVACY_DASHBOARD_LINK_LABEL },
256     { "enterPassphraseTitle", IDS_SYNC_ENTER_PASSPHRASE_TITLE },
257     { "enterPassphraseBody", IDS_SYNC_ENTER_PASSPHRASE_BODY },
258     { "enterOtherPassphraseBody", IDS_SYNC_ENTER_OTHER_PASSPHRASE_BODY },
259     { "passphraseLabel", IDS_SYNC_PASSPHRASE_LABEL },
260     { "incorrectPassphrase", IDS_SYNC_INCORRECT_PASSPHRASE },
261     { "passphraseRecover", IDS_SYNC_PASSPHRASE_RECOVER },
262     { "passphraseWarning", IDS_SYNC_PASSPHRASE_WARNING },
263     { "cleardatalink", IDS_SYNC_CLEAR_DATA_LINK },
264     { "cancelWarningHeader", IDS_SYNC_PASSPHRASE_CANCEL_WARNING_HEADER },
265     { "cancelWarning", IDS_SYNC_PASSPHRASE_CANCEL_WARNING },
266     { "yes", IDS_SYNC_PASSPHRASE_CANCEL_YES },
267     { "no", IDS_SYNC_PASSPHRASE_CANCEL_NO },
268     { "sectionExplicitMessagePrefix", IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_PREFIX },
269     { "sectionExplicitMessagePostfix",
270         IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_POSTFIX },
271   };
272 
273   RegisterStrings(localized_strings, resources, arraysize(resources));
274 }
275 
Initialize()276 void SyncSetupHandler::Initialize() {
277 }
278 
RegisterMessages()279 void SyncSetupHandler::RegisterMessages() {
280   web_ui_->RegisterMessageCallback("didShowPage",
281       NewCallback(this, &SyncSetupHandler::OnDidShowPage));
282   web_ui_->RegisterMessageCallback("didClosePage",
283       NewCallback(this, &SyncSetupHandler::OnDidClosePage));
284   web_ui_->RegisterMessageCallback("SubmitAuth",
285       NewCallback(this, &SyncSetupHandler::HandleSubmitAuth));
286   web_ui_->RegisterMessageCallback("Configure",
287       NewCallback(this, &SyncSetupHandler::HandleConfigure));
288   web_ui_->RegisterMessageCallback("Passphrase",
289       NewCallback(this, &SyncSetupHandler::HandlePassphraseEntry));
290   web_ui_->RegisterMessageCallback("PassphraseCancel",
291       NewCallback(this, &SyncSetupHandler::HandlePassphraseCancel));
292   web_ui_->RegisterMessageCallback("FirstPassphrase",
293       NewCallback(this, &SyncSetupHandler::HandleFirstPassphrase));
294   web_ui_->RegisterMessageCallback("GoToDashboard",
295       NewCallback(this, &SyncSetupHandler::HandleGoToDashboard));
296 }
297 
298 // Called by SyncSetupFlow::Advance.
ShowGaiaLogin(const DictionaryValue & args)299 void SyncSetupHandler::ShowGaiaLogin(const DictionaryValue& args) {
300   StringValue page("login");
301   web_ui_->CallJavascriptFunction(
302       "SyncSetupOverlay.showSyncSetupPage", page, args);
303 }
304 
ShowGaiaSuccessAndClose()305 void SyncSetupHandler::ShowGaiaSuccessAndClose() {
306   web_ui_->CallJavascriptFunction("SyncSetupOverlay.showSuccessAndClose");
307 }
308 
ShowGaiaSuccessAndSettingUp()309 void SyncSetupHandler::ShowGaiaSuccessAndSettingUp() {
310   web_ui_->CallJavascriptFunction("SyncSetupOverlay.showSuccessAndSettingUp");
311 }
312 
313 // Called by SyncSetupFlow::Advance.
ShowConfigure(const DictionaryValue & args)314 void SyncSetupHandler::ShowConfigure(const DictionaryValue& args) {
315   StringValue page("configure");
316   web_ui_->CallJavascriptFunction(
317       "SyncSetupOverlay.showSyncSetupPage", page, args);
318 }
319 
ShowPassphraseEntry(const DictionaryValue & args)320 void SyncSetupHandler::ShowPassphraseEntry(const DictionaryValue& args) {
321   StringValue page("passphrase");
322   web_ui_->CallJavascriptFunction(
323       "SyncSetupOverlay.showSyncSetupPage", page, args);
324 }
325 
ShowFirstPassphrase(const DictionaryValue & args)326 void SyncSetupHandler::ShowFirstPassphrase(const DictionaryValue& args) {
327   // TODO(jhawkins): Remove this logic in SyncSetupFlow. It will never be
328   // reached.
329   NOTREACHED();
330 }
331 
ShowSettingUp()332 void SyncSetupHandler::ShowSettingUp() {
333   StringValue page("settingUp");
334   web_ui_->CallJavascriptFunction(
335       "SyncSetupOverlay.showSyncSetupPage", page);
336 }
337 
ShowSetupDone(const std::wstring & user)338 void SyncSetupHandler::ShowSetupDone(const std::wstring& user) {
339   StringValue page("done");
340   web_ui_->CallJavascriptFunction(
341       "SyncSetupOverlay.showSyncSetupPage", page);
342 }
343 
ShowFirstTimeDone(const std::wstring & user)344 void SyncSetupHandler::ShowFirstTimeDone(const std::wstring& user) {
345   // TODO(jhawkins): Remove this from Sync since it's not called anymore.
346   NOTREACHED();
347 }
348 
OnDidShowPage(const ListValue * args)349 void SyncSetupHandler::OnDidShowPage(const ListValue* args) {
350   DCHECK(web_ui_);
351 
352   ProfileSyncService* sync_service =
353       web_ui_->GetProfile()->GetProfileSyncService();
354   if (!sync_service)
355     return;
356 
357   flow_ = sync_service->get_wizard().AttachSyncSetupHandler(this);
358 }
359 
OnDidClosePage(const ListValue * args)360 void SyncSetupHandler::OnDidClosePage(const ListValue* args) {
361   if (flow_) {
362     flow_->OnDialogClosed(std::string());
363     flow_ = NULL;
364   }
365 }
366 
HandleSubmitAuth(const ListValue * args)367 void SyncSetupHandler::HandleSubmitAuth(const ListValue* args) {
368   std::string json;
369   if (!args->GetString(0, &json)) {
370     NOTREACHED() << "Could not read JSON argument";
371     return;
372   }
373 
374   if (json.empty())
375     return;
376 
377   std::string username, password, captcha, access_code;
378   if (!GetAuthData(json, &username, &password, &captcha, &access_code)) {
379     // The page sent us something that we didn't understand.
380     // This probably indicates a programming error.
381     NOTREACHED();
382     return;
383   }
384 
385   if (flow_)
386     flow_->OnUserSubmittedAuth(username, password, captcha, access_code);
387 }
388 
HandleConfigure(const ListValue * args)389 void SyncSetupHandler::HandleConfigure(const ListValue* args) {
390   std::string json;
391   if (!args->GetString(0, &json)) {
392     NOTREACHED() << "Could not read JSON argument";
393     return;
394   }
395   if (json.empty()) {
396     NOTREACHED();
397     return;
398   }
399 
400   SyncConfiguration configuration;
401   if (!GetConfiguration(json, &configuration)) {
402     // The page sent us something that we didn't understand.
403     // This probably indicates a programming error.
404     NOTREACHED();
405     return;
406   }
407 
408   DCHECK(flow_);
409   flow_->OnUserConfigured(configuration);
410 }
411 
HandlePassphraseEntry(const ListValue * args)412 void SyncSetupHandler::HandlePassphraseEntry(const ListValue* args) {
413   std::string json;
414   if (!args->GetString(0, &json)) {
415     NOTREACHED() << "Could not read JSON argument";
416     return;
417   }
418 
419   if (json.empty())
420     return;
421 
422   std::string passphrase;
423   if (!GetPassphrase(json, &passphrase)) {
424     // Couldn't understand what the page sent.  Indicates a programming error.
425     NOTREACHED();
426     return;
427   }
428 
429   DCHECK(flow_);
430   flow_->OnPassphraseEntry(passphrase);
431 }
432 
HandlePassphraseCancel(const ListValue * args)433 void SyncSetupHandler::HandlePassphraseCancel(const ListValue* args) {
434   DCHECK(flow_);
435   flow_->OnPassphraseCancel();
436 }
437 
HandleFirstPassphrase(const ListValue * args)438 void SyncSetupHandler::HandleFirstPassphrase(const ListValue* args) {
439   std::string json;
440   if (!args->GetString(0, &json)) {
441     NOTREACHED() << "Could not read JSON argument";
442     return;
443   }
444   if (json.empty())
445     return;
446 
447   std::string option;
448   std::string passphrase;
449   if (!GetFirstPassphrase(json, &option, &passphrase)) {
450     // Page sent result which couldn't be parsed.  Programming error.
451     NOTREACHED();
452     return;
453   }
454 
455   DCHECK(flow_);
456   flow_->OnFirstPassphraseEntry(option, passphrase);
457 }
458 
HandleGoToDashboard(const ListValue * args)459 void SyncSetupHandler::HandleGoToDashboard(const ListValue* args) {
460   DCHECK(flow_);
461   flow_->OnGoToDashboard();
462 }
463