Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / managed / locally_managed_user_creation_screen.cc
1 // Copyright (c) 2013 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/chromeos/login/managed/locally_managed_user_creation_screen.h"
6
7 #include "ash/desktop_background/desktop_background_controller.h"
8 #include "ash/shell.h"
9 #include "base/command_line.h"
10 #include "base/rand_util.h"
11 #include "base/values.h"
12 #include "chrome/browser/chromeos/camera_detector.h"
13 #include "chrome/browser/chromeos/login/existing_user_controller.h"
14 #include "chrome/browser/chromeos/login/managed/managed_user_creation_controller.h"
15 #include "chrome/browser/chromeos/login/managed/managed_user_creation_controller_new.h"
16 #include "chrome/browser/chromeos/login/managed/managed_user_creation_controller_old.h"
17 #include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
18 #include "chrome/browser/chromeos/login/screens/error_screen.h"
19 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
20 #include "chrome/browser/chromeos/login/supervised_user_manager.h"
21 #include "chrome/browser/chromeos/login/user_image.h"
22 #include "chrome/browser/chromeos/login/user_image_manager.h"
23 #include "chrome/browser/chromeos/login/wizard_controller.h"
24 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
25 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chromeos/network/network_state.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "grit/generated_resources.h"
30 #include "third_party/skia/include/core/SkBitmap.h"
31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/gfx/image/image_skia.h"
33
34 namespace chromeos {
35
36 namespace {
37
38 // Key for (boolean) value that indicates that user already exists on device.
39 const char kUserExists[] = "exists";
40 // Key for  value that indicates why user can not be imported.
41 const char kUserConflict[] = "conflict";
42 // User is already imported.
43 const char kUserConflictImported[] = "imported";
44 // There is another supervised user with same name.
45 const char kUserConflictName[] = "name";
46
47 const char kUserNeedPassword[] = "needPassword";
48
49 const char kAvatarURLKey[] = "avatarurl";
50 const char kRandomAvatarKey[] = "randomAvatar";
51 const char kNameOfIntroScreen[] = "intro";
52 const char kNameOfNewUserParametersScreen[] = "username";
53
54 void ConfigureErrorScreen(ErrorScreen* screen,
55     const NetworkState* network,
56     const NetworkPortalDetector::CaptivePortalStatus status) {
57   switch (status) {
58     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN:
59     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE:
60       NOTREACHED();
61       break;
62     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE:
63       screen->SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE,
64                             std::string());
65       break;
66     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL:
67       screen->SetErrorState(ErrorScreen::ERROR_STATE_PORTAL,
68                             network ? network->name() : std::string());
69       screen->FixCaptivePortal();
70       break;
71     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED:
72       screen->SetErrorState(ErrorScreen::ERROR_STATE_PROXY,
73                             std::string());
74       break;
75     default:
76       NOTREACHED();
77       break;
78   }
79 }
80
81 } // namespace
82
83 LocallyManagedUserCreationScreen::LocallyManagedUserCreationScreen(
84     ScreenObserver* observer,
85     LocallyManagedUserCreationScreenHandler* actor)
86     : WizardScreen(observer),
87       weak_factory_(this),
88       actor_(actor),
89       on_error_screen_(false),
90       last_page_(kNameOfIntroScreen),
91       image_decoder_(NULL),
92       apply_photo_after_decoding_(false),
93       selected_image_(0) {
94   DCHECK(actor_);
95   if (actor_)
96     actor_->SetDelegate(this);
97 }
98
99 LocallyManagedUserCreationScreen::~LocallyManagedUserCreationScreen() {
100   CameraPresenceNotifier::GetInstance()->RemoveObserver(this);
101   if (actor_)
102     actor_->SetDelegate(NULL);
103   if (image_decoder_.get())
104     image_decoder_->set_delegate(NULL);
105   NetworkPortalDetector::Get()->RemoveObserver(this);
106 }
107
108 void LocallyManagedUserCreationScreen::PrepareToShow() {
109   if (actor_)
110     actor_->PrepareToShow();
111 }
112
113 void LocallyManagedUserCreationScreen::Show() {
114   CameraPresenceNotifier::GetInstance()->AddObserver(this);
115   if (actor_) {
116     actor_->Show();
117     // TODO(antrim) : temorary hack (until upcoming hackaton). Should be
118     // removed once we have screens reworked.
119     if (on_error_screen_)
120       actor_->ShowPage(last_page_);
121     else
122       actor_->ShowIntroPage();
123   }
124
125   if (!on_error_screen_)
126     NetworkPortalDetector::Get()->AddAndFireObserver(this);
127   on_error_screen_ = false;
128 }
129
130 void LocallyManagedUserCreationScreen::OnPageSelected(const std::string& page) {
131   last_page_ = page;
132 }
133
134 void LocallyManagedUserCreationScreen::OnPortalDetectionCompleted(
135     const NetworkState* network,
136     const NetworkPortalDetector::CaptivePortalState& state)  {
137   if (state.status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE) {
138     get_screen_observer()->HideErrorScreen(this);
139   } else {
140     on_error_screen_ = true;
141     ErrorScreen* screen = get_screen_observer()->GetErrorScreen();
142     ConfigureErrorScreen(screen, network, state.status);
143     screen->SetUIState(ErrorScreen::UI_STATE_LOCALLY_MANAGED);
144     get_screen_observer()->ShowErrorScreen();
145   }
146 }
147
148 void LocallyManagedUserCreationScreen::
149     ShowManagerInconsistentStateErrorScreen() {
150   if (!actor_)
151     return;
152   actor_->ShowErrorPage(
153       l10n_util::GetStringUTF16(
154           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE_TITLE),
155       l10n_util::GetStringUTF16(
156           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE),
157       l10n_util::GetStringUTF16(
158           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE_BUTTON));
159 }
160
161 void LocallyManagedUserCreationScreen::ShowInitialScreen() {
162   if (actor_)
163     actor_->ShowIntroPage();
164 }
165
166 void LocallyManagedUserCreationScreen::Hide() {
167   CameraPresenceNotifier::GetInstance()->RemoveObserver(this);
168   if (actor_)
169     actor_->Hide();
170   if (!on_error_screen_)
171     NetworkPortalDetector::Get()->RemoveObserver(this);
172 }
173
174 std::string LocallyManagedUserCreationScreen::GetName() const {
175   return WizardController::kLocallyManagedUserCreationScreenName;
176 }
177
178 void LocallyManagedUserCreationScreen::AbortFlow() {
179   controller_->CancelCreation();
180 }
181
182 void LocallyManagedUserCreationScreen::FinishFlow() {
183   controller_->FinishCreation();
184 }
185
186 void LocallyManagedUserCreationScreen::AuthenticateManager(
187     const std::string& manager_id,
188     const std::string& manager_password) {
189   // Make sure no two controllers exist at the same time.
190   controller_.reset();
191   SupervisedUserAuthentication* authentication =
192       UserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
193
194   if (authentication->GetStableSchema() ==
195       SupervisedUserAuthentication::SCHEMA_PLAIN) {
196     controller_.reset(new ManagedUserCreationControllerOld(this, manager_id));
197   } else {
198     controller_.reset(new ManagedUserCreationControllerNew(this, manager_id));
199   }
200
201   ExistingUserController::current_controller()->
202       Login(UserContext(manager_id,
203                         manager_password,
204                         std::string()  /* auth_code */));
205 }
206
207 void LocallyManagedUserCreationScreen::CreateManagedUser(
208     const base::string16& display_name,
209     const std::string& managed_user_password) {
210   DCHECK(controller_.get());
211   int image;
212   if (selected_image_ == User::kExternalImageIndex)
213     // TODO(dzhioev): crbug/249660
214     image = ManagedUserCreationController::kDummyAvatarIndex;
215   else
216     image = selected_image_;
217   controller_->StartCreation(display_name, managed_user_password, image);
218 }
219
220 void LocallyManagedUserCreationScreen::ImportManagedUser(
221     const std::string& user_id) {
222   DCHECK(controller_.get());
223   DCHECK(existing_users_.get());
224   VLOG(1) << "Importing user " << user_id;
225   base::DictionaryValue* user_info;
226   if (!existing_users_->GetDictionary(user_id, &user_info)) {
227     LOG(ERROR) << "Can not import non-existing user " << user_id;
228     return;
229   }
230   base::string16 display_name;
231   std::string master_key;
232   std::string avatar;
233   bool exists;
234   int avatar_index = ManagedUserCreationController::kDummyAvatarIndex;
235   user_info->GetString(ManagedUserSyncService::kName, &display_name);
236   user_info->GetString(ManagedUserSyncService::kMasterKey, &master_key);
237   user_info->GetString(ManagedUserSyncService::kChromeOsAvatar, &avatar);
238   user_info->GetBoolean(kUserExists, &exists);
239
240   // We should not get here with existing user selected, so just display error.
241   if (exists) {
242     actor_->ShowErrorPage(
243         l10n_util::GetStringUTF16(
244             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_TITLE),
245         l10n_util::GetStringUTF16(
246             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR),
247         l10n_util::GetStringUTF16(
248             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_BUTTON));
249     return;
250   }
251
252   ManagedUserSyncService::GetAvatarIndex(avatar, &avatar_index);
253
254   controller_->StartImport(display_name,
255                            std::string(),
256                            avatar_index,
257                            user_id,
258                            master_key);
259 }
260
261 // TODO(antrim): Code duplication with previous method will be removed once
262 // password sync is implemented.
263 void LocallyManagedUserCreationScreen::ImportManagedUserWithPassword(
264     const std::string& user_id,
265     const std::string& password) {
266   DCHECK(controller_.get());
267   DCHECK(existing_users_.get());
268   VLOG(1) << "Importing user " << user_id;
269   base::DictionaryValue* user_info;
270   if (!existing_users_->GetDictionary(user_id, &user_info)) {
271     LOG(ERROR) << "Can not import non-existing user " << user_id;
272     return;
273   }
274   base::string16 display_name;
275   std::string master_key;
276   std::string avatar;
277   bool exists;
278   int avatar_index = ManagedUserCreationController::kDummyAvatarIndex;
279   user_info->GetString(ManagedUserSyncService::kName, &display_name);
280   user_info->GetString(ManagedUserSyncService::kMasterKey, &master_key);
281   user_info->GetString(ManagedUserSyncService::kChromeOsAvatar, &avatar);
282   user_info->GetBoolean(kUserExists, &exists);
283
284   // We should not get here with existing user selected, so just display error.
285   if (exists) {
286     actor_->ShowErrorPage(
287         l10n_util::GetStringUTF16(
288             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_TITLE),
289         l10n_util::GetStringUTF16(
290             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR),
291         l10n_util::GetStringUTF16(
292             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_BUTTON));
293     return;
294   }
295
296   ManagedUserSyncService::GetAvatarIndex(avatar, &avatar_index);
297
298   controller_->StartImport(display_name,
299                            password,
300                            avatar_index,
301                            user_id,
302                            master_key);
303 }
304
305 void LocallyManagedUserCreationScreen::OnManagerLoginFailure() {
306   if (actor_)
307     actor_->ShowManagerPasswordError();
308 }
309
310 void LocallyManagedUserCreationScreen::OnManagerFullyAuthenticated(
311     Profile* manager_profile) {
312   DCHECK(controller_.get());
313   // For manager user, move desktop to locked container so that windows created
314   // during the user image picker step are below it.
315   ash::Shell::GetInstance()->
316       desktop_background_controller()->MoveDesktopToLockedContainer();
317
318   controller_->SetManagerProfile(manager_profile);
319   if (actor_)
320     actor_->ShowUsernamePage();
321
322   last_page_ = kNameOfNewUserParametersScreen;
323
324   CommandLine* command_line = CommandLine::ForCurrentProcess();
325   if (!command_line->HasSwitch(::switches::kAllowCreateExistingManagedUsers))
326     return;
327
328   ManagedUserSyncServiceFactory::GetForProfile(manager_profile)->
329       GetManagedUsersAsync(base::Bind(
330           &LocallyManagedUserCreationScreen::OnGetManagedUsers,
331           weak_factory_.GetWeakPtr()));
332 }
333
334 void LocallyManagedUserCreationScreen::OnManagerCryptohomeAuthenticated() {
335   if (actor_) {
336     actor_->ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16(
337             IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_AUTH_PROGRESS_MESSAGE));
338   }
339 }
340
341 void LocallyManagedUserCreationScreen::OnActorDestroyed(
342     LocallyManagedUserCreationScreenHandler* actor) {
343   if (actor_ == actor)
344     actor_ = NULL;
345 }
346
347 void LocallyManagedUserCreationScreen::OnCreationError(
348     ManagedUserCreationController::ErrorCode code) {
349   base::string16 title;
350   base::string16 message;
351   base::string16 button;
352   // TODO(antrim) : find out which errors do we really have.
353   // We might reuse some error messages from ordinary user flow.
354   switch (code) {
355     case ManagedUserCreationController::CRYPTOHOME_NO_MOUNT:
356     case ManagedUserCreationController::CRYPTOHOME_FAILED_MOUNT:
357     case ManagedUserCreationController::CRYPTOHOME_FAILED_TPM:
358       title = l10n_util::GetStringUTF16(
359           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR_TITLE);
360       message = l10n_util::GetStringUTF16(
361           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR);
362       button = l10n_util::GetStringUTF16(
363           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR_BUTTON);
364       break;
365     case ManagedUserCreationController::CLOUD_SERVER_ERROR:
366     case ManagedUserCreationController::TOKEN_WRITE_FAILED:
367       title = l10n_util::GetStringUTF16(
368           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_TITLE);
369       message = l10n_util::GetStringUTF16(
370           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR);
371       button = l10n_util::GetStringUTF16(
372           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_BUTTON);
373       break;
374     case ManagedUserCreationController::NO_ERROR:
375       NOTREACHED();
376   }
377   if (actor_)
378     actor_->ShowErrorPage(title, message, button);
379 }
380
381 void LocallyManagedUserCreationScreen::OnCreationTimeout() {
382   if (actor_) {
383     actor_->ShowStatusMessage(false /* error */, l10n_util::GetStringUTF16(
384         IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_CREATION_TIMEOUT_MESSAGE));
385   }
386 }
387
388 void LocallyManagedUserCreationScreen::OnLongCreationWarning() {
389   if (actor_) {
390     actor_->ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16(
391         IDS_PROFILES_CREATE_MANAGED_JUST_SIGNED_IN));
392   }
393 }
394
395 bool LocallyManagedUserCreationScreen::FindUserByDisplayName(
396     const base::string16& display_name,
397     std::string *out_id) const {
398   if (!existing_users_.get())
399     return false;
400   for (base::DictionaryValue::Iterator it(*existing_users_.get());
401        !it.IsAtEnd(); it.Advance()) {
402     const base::DictionaryValue* user_info =
403         static_cast<const base::DictionaryValue*>(&it.value());
404     base::string16 user_display_name;
405     if (user_info->GetString(ManagedUserSyncService::kName,
406                              &user_display_name)) {
407       if (display_name == user_display_name) {
408         if (out_id)
409           *out_id = it.key();
410         return true;
411       }
412     }
413   }
414   return false;
415 }
416
417 // TODO(antrim) : this is an explicit code duplications with UserImageScreen.
418 // It should be removed by issue 251179.
419
420 void LocallyManagedUserCreationScreen::ApplyPicture() {
421   std::string user_id = controller_->GetManagedUserId();
422   UserManager* user_manager = UserManager::Get();
423   UserImageManager* image_manager = user_manager->GetUserImageManager(user_id);
424   switch (selected_image_) {
425     case User::kExternalImageIndex:
426       // Photo decoding may not have been finished yet.
427       if (user_photo_.isNull()) {
428         apply_photo_after_decoding_ = true;
429         return;
430       }
431       image_manager->SaveUserImage(UserImage::CreateAndEncode(user_photo_));
432       break;
433     case User::kProfileImageIndex:
434       NOTREACHED() << "Supervised users have no profile pictures";
435       break;
436     default:
437       DCHECK(selected_image_ >= 0 && selected_image_ < kDefaultImagesCount);
438       image_manager->SaveUserDefaultImageIndex(selected_image_);
439       break;
440   }
441   // Proceed to tutorial.
442   actor_->ShowTutorialPage();
443 }
444
445 void LocallyManagedUserCreationScreen::OnCreationSuccess() {
446   ApplyPicture();
447 }
448
449 void LocallyManagedUserCreationScreen::OnCameraPresenceCheckDone(
450     bool is_camera_present) {
451   if (actor_)
452     actor_->SetCameraPresent(is_camera_present);
453 }
454
455 void LocallyManagedUserCreationScreen::OnGetManagedUsers(
456     const base::DictionaryValue* users) {
457   // Copy for passing to WebUI, contains only id, name and avatar URL.
458   scoped_ptr<base::ListValue> ui_users(new base::ListValue());
459   SupervisedUserManager* supervised_user_manager =
460       UserManager::Get()->GetSupervisedUserManager();
461
462   // Stored copy, contains all necessary information.
463   existing_users_.reset(new base::DictionaryValue());
464   for (base::DictionaryValue::Iterator it(*users); !it.IsAtEnd();
465        it.Advance()) {
466     // Copy that would be stored in this class.
467     base::DictionaryValue* local_copy =
468         static_cast<base::DictionaryValue*>(it.value().DeepCopy());
469     // Copy that would be passed to WebUI. It has some extra values for
470     // displaying, but does not contain sensitive data, such as master password.
471     base::DictionaryValue* ui_copy =
472         static_cast<base::DictionaryValue*>(new base::DictionaryValue());
473
474     int avatar_index = ManagedUserCreationController::kDummyAvatarIndex;
475     std::string chromeos_avatar;
476     if (local_copy->GetString(ManagedUserSyncService::kChromeOsAvatar,
477                               &chromeos_avatar) &&
478         !chromeos_avatar.empty() &&
479         ManagedUserSyncService::GetAvatarIndex(
480             chromeos_avatar, &avatar_index)) {
481       ui_copy->SetString(kAvatarURLKey, GetDefaultImageUrl(avatar_index));
482     } else {
483       int i = base::RandInt(kFirstDefaultImageIndex, kDefaultImagesCount - 1);
484       local_copy->SetString(
485           ManagedUserSyncService::kChromeOsAvatar,
486           ManagedUserSyncService::BuildAvatarString(i));
487       local_copy->SetBoolean(kRandomAvatarKey, true);
488       ui_copy->SetString(kAvatarURLKey, GetDefaultImageUrl(i));
489     }
490
491     local_copy->SetBoolean(kUserExists, false);
492     ui_copy->SetBoolean(kUserExists, false);
493
494     base::string16 display_name;
495     local_copy->GetString(ManagedUserSyncService::kName, &display_name);
496
497     if (supervised_user_manager->FindBySyncId(it.key())) {
498       local_copy->SetBoolean(kUserExists, true);
499       ui_copy->SetBoolean(kUserExists, true);
500       local_copy->SetString(kUserConflict, kUserConflictImported);
501       ui_copy->SetString(kUserConflict, kUserConflictImported);
502     } else if (supervised_user_manager->FindByDisplayName(display_name)) {
503       local_copy->SetBoolean(kUserExists, true);
504       ui_copy->SetBoolean(kUserExists, true);
505       local_copy->SetString(kUserConflict, kUserConflictName);
506       ui_copy->SetString(kUserConflict, kUserConflictName);
507     }
508     ui_copy->SetString(ManagedUserSyncService::kName, display_name);
509     // TODO(antrim): For now mark all users as having no password.
510     ui_copy->SetBoolean(kUserNeedPassword, true);
511     ui_copy->SetString("id", it.key());
512
513     existing_users_->Set(it.key(), local_copy);
514     ui_users->Append(ui_copy);
515   }
516   actor_->ShowExistingManagedUsers(ui_users.get());
517 }
518
519 void LocallyManagedUserCreationScreen::OnPhotoTaken(
520     const std::string& raw_data) {
521   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
522   user_photo_ = gfx::ImageSkia();
523   if (image_decoder_.get())
524     image_decoder_->set_delegate(NULL);
525   image_decoder_ = new ImageDecoder(this, raw_data,
526                                     ImageDecoder::DEFAULT_CODEC);
527   scoped_refptr<base::MessageLoopProxy> task_runner =
528       content::BrowserThread::GetMessageLoopProxyForThread(
529           content::BrowserThread::UI);
530   image_decoder_->Start(task_runner);
531 }
532
533 void LocallyManagedUserCreationScreen::OnImageDecoded(
534     const ImageDecoder* decoder,
535     const SkBitmap& decoded_image) {
536   DCHECK_EQ(image_decoder_.get(), decoder);
537   user_photo_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image);
538   if (apply_photo_after_decoding_)
539     ApplyPicture();
540 }
541
542 void LocallyManagedUserCreationScreen::OnDecodeImageFailed(
543     const ImageDecoder* decoder) {
544   NOTREACHED() << "Failed to decode PNG image from WebUI";
545 }
546
547 void LocallyManagedUserCreationScreen::OnImageSelected(
548     const std::string& image_type,
549     const std::string& image_url) {
550   if (image_url.empty())
551     return;
552   int user_image_index = User::kInvalidImageIndex;
553   if (image_type == "default" &&
554       IsDefaultImageUrl(image_url, &user_image_index)) {
555     selected_image_ = user_image_index;
556   } else if (image_type == "camera") {
557     selected_image_ = User::kExternalImageIndex;
558   } else {
559     NOTREACHED() << "Unexpected image type: " << image_type;
560   }
561 }
562
563 void LocallyManagedUserCreationScreen::OnImageAccepted() {
564 }
565
566 }  // namespace chromeos