Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / chromeos / login / enrollment_screen_handler.cc
1 // Copyright (c) 2012 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/chromeos/login/enrollment_screen_handler.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/compiler_specific.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/browsing_data/browsing_data_helper.h"
16 #include "chrome/browser/browsing_data/browsing_data_remover.h"
17 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/webui/chromeos/login/authenticated_user_email_retriever.h"
20 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
21 #include "components/policy/core/browser/cloud/message_util.h"
22 #include "content/public/browser/web_contents.h"
23 #include "google_apis/gaia/gaia_auth_fetcher.h"
24 #include "google_apis/gaia/gaia_auth_util.h"
25 #include "google_apis/gaia/gaia_constants.h"
26 #include "google_apis/gaia/gaia_urls.h"
27 #include "google_apis/gaia/google_service_auth_error.h"
28 #include "grit/chromium_strings.h"
29 #include "grit/generated_resources.h"
30 #include "net/url_request/url_request_context_getter.h"
31 #include "ui/base/l10n/l10n_util.h"
32
33 namespace chromeos {
34 namespace {
35
36 const char kJsScreenPath[] = "login.OAuthEnrollmentScreen";
37
38 // Start page of GAIA authentication extension.
39 const char kGaiaExtStartPage[] =
40     "chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/main.html";
41
42 // Enrollment step names.
43 const char kEnrollmentStepSignin[] = "signin";
44 const char kEnrollmentStepSuccess[] = "success";
45
46 // Enrollment mode strings.
47 const char kEnrollmentModeManual[] = "manual";
48 const char kEnrollmentModeForced[] = "forced";
49 const char kEnrollmentModeAuto[] = "auto";
50
51 std::string EnrollmentModeToString(EnrollmentScreenActor::EnrollmentMode mode) {
52   switch (mode) {
53     case EnrollmentScreenActor::ENROLLMENT_MODE_MANUAL:
54       return kEnrollmentModeManual;
55     case EnrollmentScreenActor::ENROLLMENT_MODE_FORCED:
56       return kEnrollmentModeForced;
57     case EnrollmentScreenActor::ENROLLMENT_MODE_AUTO:
58       return kEnrollmentModeAuto;
59   }
60
61   NOTREACHED() << "Bad enrollment mode " << mode;
62   return kEnrollmentModeManual;
63 }
64
65 // A helper class that takes care of asynchronously revoking a given token.
66 class TokenRevoker : public GaiaAuthConsumer {
67  public:
68   TokenRevoker()
69       : gaia_fetcher_(this,
70                       GaiaConstants::kChromeOSSource,
71                       g_browser_process->system_request_context()) {}
72   virtual ~TokenRevoker() {}
73
74   void Start(const std::string& token) {
75     gaia_fetcher_.StartRevokeOAuth2Token(token);
76   }
77
78   // GaiaAuthConsumer:
79   virtual void OnOAuth2RevokeTokenCompleted() OVERRIDE {
80     base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
81   }
82
83  private:
84   GaiaAuthFetcher gaia_fetcher_;
85
86   DISALLOW_COPY_AND_ASSIGN(TokenRevoker);
87 };
88
89 }  // namespace
90
91 // EnrollmentScreenHandler, public ------------------------------
92
93 EnrollmentScreenHandler::EnrollmentScreenHandler()
94     : BaseScreenHandler(kJsScreenPath),
95       controller_(NULL),
96       show_on_init_(false),
97       enrollment_mode_(ENROLLMENT_MODE_MANUAL),
98       browsing_data_remover_(NULL) {
99   set_async_assets_load_id(OobeUI::kScreenOobeEnrollment);
100 }
101
102 EnrollmentScreenHandler::~EnrollmentScreenHandler() {
103   if (browsing_data_remover_)
104     browsing_data_remover_->RemoveObserver(this);
105 }
106
107 // EnrollmentScreenHandler, WebUIMessageHandler implementation --
108
109 void EnrollmentScreenHandler::RegisterMessages() {
110   AddCallback("oauthEnrollRetrieveAuthenticatedUserEmail",
111               &EnrollmentScreenHandler::HandleRetrieveAuthenticatedUserEmail);
112   AddCallback("oauthEnrollClose",
113               &EnrollmentScreenHandler::HandleClose);
114   AddCallback("oauthEnrollCompleteLogin",
115               &EnrollmentScreenHandler::HandleCompleteLogin);
116   AddCallback("oauthEnrollRetry",
117               &EnrollmentScreenHandler::HandleRetry);
118 }
119
120 // EnrollmentScreenHandler
121 //      EnrollmentScreenActor implementation -----------------------------------
122
123 void EnrollmentScreenHandler::SetParameters(
124     Controller* controller,
125     EnrollmentMode enrollment_mode,
126     const std::string& management_domain) {
127   controller_ = controller;
128   enrollment_mode_ = enrollment_mode;
129   management_domain_ = management_domain;
130 }
131
132 void EnrollmentScreenHandler::PrepareToShow() {
133 }
134
135 void EnrollmentScreenHandler::Show() {
136   if (!page_is_ready())
137     show_on_init_ = true;
138   else
139     DoShow();
140 }
141
142 void EnrollmentScreenHandler::Hide() {
143 }
144
145 void EnrollmentScreenHandler::FetchOAuthToken() {
146   Profile* profile = Profile::FromWebUI(web_ui());
147   oauth_fetcher_.reset(
148       new policy::PolicyOAuth2TokenFetcher(
149           profile->GetRequestContext(),
150           g_browser_process->system_request_context(),
151           base::Bind(&EnrollmentScreenHandler::OnTokenFetched,
152                      base::Unretained(this))));
153   oauth_fetcher_->Start();
154 }
155
156 void EnrollmentScreenHandler::ResetAuth(const base::Closure& callback) {
157   auth_reset_callbacks_.push_back(callback);
158   if (browsing_data_remover_)
159     return;
160
161   if (oauth_fetcher_) {
162     if (!oauth_fetcher_->oauth2_access_token().empty())
163       (new TokenRevoker())->Start(oauth_fetcher_->oauth2_access_token());
164
165     if (!oauth_fetcher_->oauth2_refresh_token().empty())
166       (new TokenRevoker())->Start(oauth_fetcher_->oauth2_refresh_token());
167   }
168
169   Profile* profile = Profile::FromBrowserContext(
170       web_ui()->GetWebContents()->GetBrowserContext());
171   browsing_data_remover_ =
172       BrowsingDataRemover::CreateForUnboundedRange(profile);
173   browsing_data_remover_->AddObserver(this);
174   browsing_data_remover_->Remove(BrowsingDataRemover::REMOVE_SITE_DATA,
175                                  BrowsingDataHelper::UNPROTECTED_WEB);
176 }
177
178 void EnrollmentScreenHandler::ShowSigninScreen() {
179   ShowStep(kEnrollmentStepSignin);
180 }
181
182 void EnrollmentScreenHandler::ShowEnrollmentSpinnerScreen() {
183   ShowWorking(IDS_ENTERPRISE_ENROLLMENT_WORKING);
184 }
185
186 void EnrollmentScreenHandler::ShowLoginSpinnerScreen() {
187   ShowWorking(IDS_ENTERPRISE_ENROLLMENT_RESUMING_LOGIN);
188 }
189
190 void EnrollmentScreenHandler::ShowAuthError(
191     const GoogleServiceAuthError& error) {
192   switch (error.state()) {
193     case GoogleServiceAuthError::NONE:
194     case GoogleServiceAuthError::CAPTCHA_REQUIRED:
195     case GoogleServiceAuthError::TWO_FACTOR:
196     case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
197     case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
198     case GoogleServiceAuthError::REQUEST_CANCELED:
199     case GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE:
200     case GoogleServiceAuthError::SERVICE_ERROR:
201       ShowError(IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR, false);
202       return;
203     case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
204     case GoogleServiceAuthError::ACCOUNT_DELETED:
205     case GoogleServiceAuthError::ACCOUNT_DISABLED:
206       ShowError(IDS_ENTERPRISE_ENROLLMENT_AUTH_ACCOUNT_ERROR, true);
207       return;
208     case GoogleServiceAuthError::CONNECTION_FAILED:
209     case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
210       ShowError(IDS_ENTERPRISE_ENROLLMENT_AUTH_NETWORK_ERROR, true);
211       return;
212     case GoogleServiceAuthError::NUM_STATES:
213       break;
214   }
215   NOTREACHED();
216 }
217
218 void EnrollmentScreenHandler::ShowUIError(UIError error) {
219   switch (error) {
220     case UI_ERROR_DOMAIN_MISMATCH:
221       ShowError(IDS_ENTERPRISE_ENROLLMENT_STATUS_LOCK_WRONG_USER, true);
222       return;
223     case UI_ERROR_AUTO_ENROLLMENT_BAD_MODE:
224       ShowError(IDS_ENTERPRISE_AUTO_ENROLLMENT_BAD_MODE, true);
225       return;
226     case UI_ERROR_FATAL:
227       ShowError(IDS_ENTERPRISE_ENROLLMENT_FATAL_ENROLLMENT_ERROR, true);
228       return;
229   }
230   NOTREACHED();
231 }
232
233 void EnrollmentScreenHandler::ShowEnrollmentStatus(
234     policy::EnrollmentStatus status) {
235   switch (status.status()) {
236     case policy::EnrollmentStatus::STATUS_SUCCESS:
237       ShowStep(kEnrollmentStepSuccess);
238       return;
239     case policy::EnrollmentStatus::STATUS_NO_STATE_KEYS:
240       ShowError(IDS_ENTERPRISE_ENROLLMENT_STATUS_NO_STATE_KEYS, false);
241       return;
242     case policy::EnrollmentStatus::STATUS_REGISTRATION_FAILED:
243       // Some special cases for generating a nicer message that's more helpful.
244       switch (status.client_status()) {
245         case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
246           ShowError(IDS_ENTERPRISE_ENROLLMENT_ACCOUNT_ERROR, true);
247           break;
248         case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
249           ShowError(IDS_ENTERPRISE_ENROLLMENT_MISSING_LICENSES_ERROR, true);
250           break;
251         case policy::DM_STATUS_SERVICE_DEPROVISIONED:
252           ShowError(IDS_ENTERPRISE_ENROLLMENT_DEPROVISIONED_ERROR, true);
253           break;
254         case policy::DM_STATUS_SERVICE_DOMAIN_MISMATCH:
255           ShowError(IDS_ENTERPRISE_ENROLLMENT_DOMAIN_MISMATCH_ERROR, true);
256           break;
257         default:
258           ShowErrorMessage(
259               l10n_util::GetStringFUTF8(
260                   IDS_ENTERPRISE_ENROLLMENT_STATUS_REGISTRATION_FAILED,
261                   policy::FormatDeviceManagementStatus(status.client_status())),
262               true);
263       }
264       return;
265     case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED:
266       ShowError(IDS_ENTERPRISE_ENROLLMENT_ROBOT_AUTH_FETCH_FAILED, true);
267       return;
268     case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED:
269       ShowError(IDS_ENTERPRISE_ENROLLMENT_ROBOT_REFRESH_FETCH_FAILED, true);
270       return;
271     case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED:
272       ShowError(IDS_ENTERPRISE_ENROLLMENT_ROBOT_REFRESH_STORE_FAILED, true);
273       return;
274     case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE:
275       ShowError(IDS_ENTERPRISE_ENROLLMENT_STATUS_REGISTRATION_BAD_MODE, false);
276       return;
277     case policy::EnrollmentStatus::STATUS_POLICY_FETCH_FAILED:
278       ShowErrorMessage(
279           l10n_util::GetStringFUTF8(
280               IDS_ENTERPRISE_ENROLLMENT_STATUS_POLICY_FETCH_FAILED,
281               policy::FormatDeviceManagementStatus(status.client_status())),
282           true);
283       return;
284     case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED:
285       ShowErrorMessage(
286           l10n_util::GetStringFUTF8(
287               IDS_ENTERPRISE_ENROLLMENT_STATUS_VALIDATION_FAILED,
288               policy::FormatValidationStatus(status.validation_status())),
289           true);
290       return;
291     case policy::EnrollmentStatus::STATUS_LOCK_ERROR:
292       ShowError(IDS_ENTERPRISE_ENROLLMENT_STATUS_LOCK_ERROR, false);
293       return;
294     case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT:
295       ShowError(IDS_ENTERPRISE_ENROLLMENT_STATUS_LOCK_TIMEOUT, false);
296       return;
297     case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER:
298       ShowError(IDS_ENTERPRISE_ENROLLMENT_STATUS_LOCK_WRONG_USER, true);
299       return;
300     case policy::EnrollmentStatus::STATUS_STORE_ERROR:
301       ShowErrorMessage(
302           l10n_util::GetStringFUTF8(
303               IDS_ENTERPRISE_ENROLLMENT_STATUS_STORE_ERROR,
304               policy::FormatStoreStatus(status.store_status(),
305                                         status.validation_status())),
306           true);
307       return;
308   }
309   NOTREACHED();
310 }
311
312 // EnrollmentScreenHandler BaseScreenHandler implementation -----
313
314 void EnrollmentScreenHandler::Initialize() {
315   if (show_on_init_) {
316     Show();
317     show_on_init_ = false;
318   }
319 }
320
321 void EnrollmentScreenHandler::DeclareLocalizedValues(
322     LocalizedValuesBuilder* builder) {
323   builder->Add("oauthEnrollScreenTitle",
324                IDS_ENTERPRISE_ENROLLMENT_SCREEN_TITLE);
325   builder->Add("oauthEnrollDescription", IDS_ENTERPRISE_ENROLLMENT_DESCRIPTION);
326   builder->Add("oauthEnrollReEnrollmentText",
327                IDS_ENTERPRISE_ENROLLMENT_RE_ENROLLMENT_TEXT);
328   builder->Add("oauthEnrollRetry", IDS_ENTERPRISE_ENROLLMENT_RETRY);
329   builder->Add("oauthEnrollCancel", IDS_ENTERPRISE_ENROLLMENT_CANCEL);
330   builder->Add("oauthEnrollDone", IDS_ENTERPRISE_ENROLLMENT_DONE);
331   builder->Add("oauthEnrollSuccess", IDS_ENTERPRISE_ENROLLMENT_SUCCESS);
332   builder->Add("oauthEnrollExplain", IDS_ENTERPRISE_ENROLLMENT_EXPLAIN);
333   builder->Add("oauthEnrollExplainLink",
334                IDS_ENTERPRISE_ENROLLMENT_EXPLAIN_LINK);
335   builder->Add("oauthEnrollExplainButton",
336                IDS_ENTERPRISE_ENROLLMENT_EXPLAIN_BUTTON);
337   builder->Add("oauthEnrollCancelAutoEnrollmentReally",
338                IDS_ENTERPRISE_ENROLLMENT_CANCEL_AUTO_REALLY);
339   builder->Add("oauthEnrollCancelAutoEnrollmentConfirm",
340                IDS_ENTERPRISE_ENROLLMENT_CANCEL_AUTO_CONFIRM);
341   builder->Add("oauthEnrollCancelAutoEnrollmentGoBack",
342                IDS_ENTERPRISE_ENROLLMENT_CANCEL_AUTO_GO_BACK);
343 }
344
345 void EnrollmentScreenHandler::OnBrowsingDataRemoverDone() {
346   browsing_data_remover_->RemoveObserver(this);
347   browsing_data_remover_ = NULL;
348
349   std::vector<base::Closure> callbacks_to_run;
350   callbacks_to_run.swap(auth_reset_callbacks_);
351   for (std::vector<base::Closure>::iterator callback(callbacks_to_run.begin());
352        callback != callbacks_to_run.end(); ++callback) {
353     callback->Run();
354   }
355 }
356
357 // EnrollmentScreenHandler, private -----------------------------
358
359 void EnrollmentScreenHandler::HandleRetrieveAuthenticatedUserEmail(
360     double attempt_token) {
361   email_retriever_.reset(new AuthenticatedUserEmailRetriever(
362       base::Bind(&EnrollmentScreenHandler::CallJS<double, std::string>,
363                  base::Unretained(this),
364                  "setAuthenticatedUserEmail",
365                  attempt_token),
366       Profile::FromWebUI(web_ui())->GetRequestContext()));
367 }
368
369 void EnrollmentScreenHandler::HandleClose(const std::string& reason) {
370   if (!controller_) {
371     NOTREACHED();
372     return;
373   }
374
375   if (reason == "cancel" || reason == "autocancel")
376     controller_->OnCancel();
377   else if (reason == "done")
378     controller_->OnConfirmationClosed();
379   else
380     NOTREACHED();
381 }
382
383 void EnrollmentScreenHandler::HandleCompleteLogin(const std::string& user) {
384   if (!controller_) {
385     NOTREACHED();
386     return;
387   }
388   controller_->OnLoginDone(gaia::SanitizeEmail(user));
389 }
390
391 void EnrollmentScreenHandler::HandleRetry() {
392   if (!controller_) {
393     NOTREACHED();
394     return;
395   }
396   controller_->OnRetry();
397 }
398
399 void EnrollmentScreenHandler::ShowStep(const char* step) {
400   CallJS("showStep", std::string(step));
401 }
402
403 void EnrollmentScreenHandler::ShowError(int message_id, bool retry) {
404   ShowErrorMessage(l10n_util::GetStringUTF8(message_id), retry);
405 }
406
407 void EnrollmentScreenHandler::ShowErrorMessage(const std::string& message,
408                                                bool retry) {
409   CallJS("showError", message, retry);
410 }
411
412 void EnrollmentScreenHandler::ShowWorking(int message_id) {
413   CallJS("showWorking", l10n_util::GetStringUTF16(message_id));
414 }
415
416 void EnrollmentScreenHandler::OnTokenFetched(
417     const std::string& token,
418     const GoogleServiceAuthError& error) {
419   if (!controller_)
420     return;
421
422   if (error.state() != GoogleServiceAuthError::NONE)
423     controller_->OnAuthError(error);
424   else
425     controller_->OnOAuthTokenAvailable(token);
426 }
427
428 void EnrollmentScreenHandler::DoShow() {
429   base::DictionaryValue screen_data;
430   screen_data.SetString("signin_url", kGaiaExtStartPage);
431   screen_data.SetString("gaiaUrl", GaiaUrls::GetInstance()->gaia_url().spec());
432   screen_data.SetString("enrollment_mode",
433                         EnrollmentModeToString(enrollment_mode_));
434   screen_data.SetString("management_domain", management_domain_);
435
436   ShowScreen(OobeUI::kScreenOobeEnrollment, &screen_data);
437 }
438
439 }  // namespace chromeos