diff options
39 files changed, 1222 insertions, 918 deletions
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 6d43240..93e9406 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp @@ -460,6 +460,12 @@ Press any key to continue exploring. <message name="IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_TOO_SHORT" desc="Error text shown in locally managed user creation dialog when typed password is too short."> Password is too short. </message> + <message name="IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_PASSWORD_ERROR" desc="Error text shown in locally managed user creation dialog when manager password is incorrect."> + Incorrect manager password. + </message> + <message name="IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE" desc="Error text shown in locally managed user creation dialog when account is in inconsistent state."> + Manager account is in inconsistent state. Please log in to manager account first and then try creating locally managed user again. + </message> <message name="IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_SUCCESS_TITLE" desc="Text shown when locally managed user was successfully created"> Setup is complete! Now learn what features are available to the manager of this account. </message> diff --git a/chrome/browser/chromeos/login/base_login_display_host.cc b/chrome/browser/chromeos/login/base_login_display_host.cc index 5af74fc..780a6ac 100644 --- a/chrome/browser/chromeos/login/base_login_display_host.cc +++ b/chrome/browser/chromeos/login/base_login_display_host.cc @@ -239,6 +239,10 @@ void BaseLoginDisplayHost::StartSignInScreen() { kPolicyServiceInitializationDelayMilliseconds); } +WizardController* BaseLoginDisplayHost::GetWizardController() { + return wizard_controller_.get(); +} + void BaseLoginDisplayHost::ResumeSignInScreen() { // We only get here after a previous call the StartSignInScreen. That sign-in // was successful but was interrupted by an auto-enrollment execution; once diff --git a/chrome/browser/chromeos/login/base_login_display_host.h b/chrome/browser/chromeos/login/base_login_display_host.h index a0a84e6..203eb1e 100644 --- a/chrome/browser/chromeos/login/base_login_display_host.h +++ b/chrome/browser/chromeos/login/base_login_display_host.h @@ -51,6 +51,7 @@ class BaseLoginDisplayHost : public LoginDisplayHost, virtual void StartSignInScreen() OVERRIDE; virtual void ResumeSignInScreen() OVERRIDE; virtual void CheckForAutoEnrollment() OVERRIDE; + virtual WizardController* GetWizardController() OVERRIDE; // Creates specific WizardController. virtual WizardController* CreateWizardController() = 0; diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index 930a766..e6bb177 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc @@ -697,6 +697,11 @@ void ExistingUserController::OnLoginFailure(const LoginFailure& failure) { guest_mode_url_ = GURL::EmptyGURL(); std::string error = failure.GetErrorString(); + if (UserManager::Get()->GetUserFlow(last_login_attempt_username_)-> + HandleLoginFailure(failure, host_)) { + return; + } + if (failure.reason() == LoginFailure::OWNER_REQUIRED) { ShowError(IDS_LOGIN_ERROR_OWNER_REQUIRED, error); content::BrowserThread::PostDelayedTask( @@ -853,6 +858,11 @@ void ExistingUserController::OnPasswordChangeDetected() { return; } + if (UserManager::Get()->GetUserFlow(last_login_attempt_username_)-> + HandlePasswordChangeDetected(host_)) { + return; + } + // True if user has already made an attempt to enter old password and failed. bool show_invalid_old_password_error = login_performer_->password_changed_callback_count() > 1; diff --git a/chrome/browser/chromeos/login/login_display_host.h b/chrome/browser/chromeos/login/login_display_host.h index 352ff8a..4a32fd4 100644 --- a/chrome/browser/chromeos/login/login_display_host.h +++ b/chrome/browser/chromeos/login/login_display_host.h @@ -18,6 +18,8 @@ class Widget; namespace chromeos { +class WizardController; + // An interface that defines OOBE/login screen host. // Host encapsulates implementation specific background window (views/WebUI), // OOBE/login controllers, views/WebUI UI implementation (such as LoginDisplay). @@ -70,6 +72,10 @@ class LoginDisplayHost { const std::string& first_screen_name, DictionaryValue* screen_parameters) = 0; + // Returns current WizardController, if it exists. + // Result should not be stored. + virtual WizardController* GetWizardController() = 0; + // Starts sign in screen. virtual void StartSignInScreen() = 0; diff --git a/chrome/browser/chromeos/login/login_status_consumer.h b/chrome/browser/chromeos/login/login_status_consumer.h index c82d1ac..8212ed3 100644 --- a/chrome/browser/chromeos/login/login_status_consumer.h +++ b/chrome/browser/chromeos/login/login_status_consumer.h @@ -67,7 +67,7 @@ class LoginFailure { case COULD_NOT_MOUNT_CRYPTOHOME: return "Could not mount cryptohome."; case COULD_NOT_UNMOUNT_CRYPTOHOME: - return "Could not mount cryptohome."; + return "Could not unmount cryptohome."; case COULD_NOT_MOUNT_TMPFS: return "Could not mount tmpfs."; case LOGIN_TIMED_OUT: diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc index cffb0b4..665e7ea 100644 --- a/chrome/browser/chromeos/login/login_utils.cc +++ b/chrome/browser/chromeos/login/login_utils.cc @@ -269,7 +269,7 @@ void LoginUtilsImpl::DoBrowserLaunch(Profile* profile, return; if (!UserManager::Get()->GetCurrentUserFlow()->ShouldLaunchBrowser()) { - UserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(); + UserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(login_host); return; } diff --git a/chrome/browser/chromeos/login/managed/locally_managed_user_controller.cc b/chrome/browser/chromeos/login/managed/locally_managed_user_controller.cc index 78fa801..f0dfb8c 100644 --- a/chrome/browser/chromeos/login/managed/locally_managed_user_controller.cc +++ b/chrome/browser/chromeos/login/managed/locally_managed_user_controller.cc @@ -4,12 +4,18 @@ #include "chrome/browser/chromeos/login/managed/locally_managed_user_controller.h" +#include "base/bind.h" +#include "base/file_util.h" +#include "base/files/file_path.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/values.h" +#include "chrome/browser/chromeos/login/mount_manager.h" #include "chrome/browser/chromeos/login/user.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager_client.h" +#include "content/public/browser/browser_thread.h" namespace chromeos { @@ -26,7 +32,8 @@ LocallyManagedUserController* LocallyManagedUserController::LocallyManagedUserController( LocallyManagedUserController::StatusConsumer* consumer) - : consumer_(consumer) { + : consumer_(consumer), + weak_factory_(this) { connector_.reset(new CloudConnector(this)); if (current_controller_) NOTREACHED() << "More than one controller exist."; @@ -37,14 +44,18 @@ LocallyManagedUserController::~LocallyManagedUserController() { current_controller_ = NULL; } -void LocallyManagedUserController::StartCreation(string16 display_name, +void LocallyManagedUserController::SetUpCreation(string16 display_name, std::string password) { - // Start transaction - UserManager::Get()->StartLocallyManagedUserCreationTransaction(display_name); creation_context_.reset( new LocallyManagedUserController::UserCreationContext()); creation_context_->display_name = display_name; creation_context_->password = password; +} + +void LocallyManagedUserController::StartCreation() { + DCHECK(creation_context_); + UserManager::Get()->StartLocallyManagedUserCreationTransaction( + creation_context_->display_name); connector_->GenerateNewUserId(); } @@ -79,7 +90,7 @@ void LocallyManagedUserController::NewUserIdGenerated(std::string& new_id) { authenticator_ = new ManagedUserAuthenticator(this); authenticator_->AuthenticateToCreate(user->email(), - creation_context_->user_id); + creation_context_->password); } void LocallyManagedUserController::OnCloudError( @@ -123,7 +134,9 @@ void LocallyManagedUserController::OnAuthenticationFailure( consumer_->OnCreationError(code, false); } -void LocallyManagedUserController::OnMountSuccess() { +void LocallyManagedUserController::OnMountSuccess( + const std::string& mount_hash) { + creation_context_->mount_hash = mount_hash; connector_->FetchDMToken(creation_context_->user_id); } @@ -136,8 +149,25 @@ void LocallyManagedUserController::DMTokenFetched(std::string& user_id, creation_context_->token_acquired = true; creation_context_->token = token; - // TODO(antrim) : store token to file here. + content::BrowserThread::GetBlockingPool()->PostTaskAndReply( + FROM_HERE, + base::Bind(&LocallyManagedUserController::StoreManagedUserFiles, + weak_factory_.GetWeakPtr(), + MountManager::GetHomeDir(creation_context_->mount_hash)), + base::Bind(&LocallyManagedUserController::OnManagedUserFilesStored, + weak_factory_.GetWeakPtr())); +} + +void LocallyManagedUserController::StoreManagedUserFiles( + const base::FilePath& base_path) { + base::FilePath token_file = base_path.Append("token"); + + file_util::WriteFile(token_file, + creation_context_->token.c_str(), + creation_context_->token.length()); +} +void LocallyManagedUserController::OnManagedUserFilesStored() { UserManager::Get()->CommitLocallyManagedUserCreationTransaction(); if (consumer_) consumer_->OnCreationSuccess(); diff --git a/chrome/browser/chromeos/login/managed/locally_managed_user_controller.h b/chrome/browser/chromeos/login/managed/locally_managed_user_controller.h index e4dbacd..761275c 100644 --- a/chrome/browser/chromeos/login/managed/locally_managed_user_controller.h +++ b/chrome/browser/chromeos/login/managed/locally_managed_user_controller.h @@ -7,7 +7,9 @@ #include <string> +#include "base/files/file_path.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "base/string16.h" #include "chrome/browser/chromeos/login/managed/cloud_connector.h" #include "chrome/browser/chromeos/login/managed/managed_user_authenticator.h" @@ -50,7 +52,8 @@ class LocallyManagedUserController return current_controller_; } - void StartCreation(string16 display_name, std::string password); + void SetUpCreation(string16 display_name, std::string password); + void StartCreation(); void RetryLastStep(); void FinishCreation(); @@ -64,6 +67,7 @@ class LocallyManagedUserController bool id_acquired; std::string user_id; std::string password; + std::string mount_hash; bool token_acquired; std::string token; }; @@ -77,9 +81,17 @@ class LocallyManagedUserController // ManagedUserAuthenticator::StatusConsumer overrides. virtual void OnAuthenticationFailure( ManagedUserAuthenticator::AuthState error) OVERRIDE; - virtual void OnMountSuccess() OVERRIDE; + virtual void OnMountSuccess(const std::string& mount_hash) OVERRIDE; virtual void OnCreationSuccess() OVERRIDE; + // Stores data files in locally managed user home directory. + // It is called on one of BlockingPool threads. + virtual void StoreManagedUserFiles(const base::FilePath& base_path); + + // Completion callback for StoreManagedUserFiles method. + // Called on the UI thread. + virtual void OnManagedUserFilesStored(); + // Pointer to the current instance of the controller to be used by // automation tests. static LocallyManagedUserController* current_controller_; @@ -93,6 +105,9 @@ class LocallyManagedUserController // Creation context. Not null while creating new LMU. scoped_ptr<UserCreationContext> creation_context_; + // Factory of callbacks. + base::WeakPtrFactory<LocallyManagedUserController> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(LocallyManagedUserController); }; diff --git a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.cc b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.cc index 42e6380..359119f 100644 --- a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.cc +++ b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.cc @@ -4,12 +4,25 @@ #include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.h" +#include "base/logging.h" #include "base/values.h" #include "chrome/browser/chromeos/login/base_login_display_host.h" +#include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h" #include "chrome/browser/chromeos/login/wizard_controller.h" namespace chromeos { +namespace { + +LocallyManagedUserCreationScreen* GetScreen(LoginDisplayHost* host) { + DCHECK(host); + DCHECK(host->GetWizardController()); + DCHECK(host->GetWizardController()->GetLocallyManagedUserCreationScreen()); + return host->GetWizardController()->GetLocallyManagedUserCreationScreen(); +} + +} // namespace + LocallyManagedUserCreationFlow::LocallyManagedUserCreationFlow( string16 name, std::string password) : name_(name), @@ -25,14 +38,25 @@ bool LocallyManagedUserCreationFlow::ShouldSkipPostLoginScreens() { return true; } -void LocallyManagedUserCreationFlow::LaunchExtraSteps() { - DictionaryValue* params = new DictionaryValue(); - params->SetString("user_display_name", name_); - params->SetString("password", password_); +bool LocallyManagedUserCreationFlow::HandleLoginFailure( + const LoginFailure& failure, + LoginDisplayHost* host) { + if (failure.reason() == LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME) + GetScreen(host)->OnManagerLoginFailure(); + else + GetScreen(host)->ShowManagerInconsistentStateErrorScreen(); + return true; +} + +bool LocallyManagedUserCreationFlow::HandlePasswordChangeDetected( + LoginDisplayHost* host) { + GetScreen(host)->ShowManagerInconsistentStateErrorScreen(); + return true; +} - BaseLoginDisplayHost::default_host()-> - StartWizard(WizardController::kLocallyManagedUserCreationScreenName, - params); +void LocallyManagedUserCreationFlow::LaunchExtraSteps( + LoginDisplayHost* host) { + GetScreen(host)->OnManagerSignIn(); } } // namespace chromeos diff --git a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.h b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.h index 7c9dd50..6968165 100644 --- a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.h +++ b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.h @@ -21,7 +21,10 @@ class LocallyManagedUserCreationFlow : public UserFlow { virtual bool ShouldLaunchBrowser() OVERRIDE; virtual bool ShouldSkipPostLoginScreens() OVERRIDE; - virtual void LaunchExtraSteps() OVERRIDE; + virtual bool HandleLoginFailure(const LoginFailure& failure, + LoginDisplayHost* host) OVERRIDE; + virtual bool HandlePasswordChangeDetected(LoginDisplayHost* host) OVERRIDE; + virtual void LaunchExtraSteps(LoginDisplayHost* host) OVERRIDE; private: // Display name for user being created. diff --git a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc index 0d2dce09..4c946463 100644 --- a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc +++ b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc @@ -4,6 +4,7 @@ #include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h" +#include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/managed/locally_managed_user_controller.h" #include "chrome/browser/chromeos/login/screen_observer.h" #include "chrome/browser/chromeos/login/wizard_controller.h" @@ -31,21 +32,29 @@ void LocallyManagedUserCreationScreen::PrepareToShow() { actor_->PrepareToShow(); } -void LocallyManagedUserCreationScreen::SetParameters(string16 name, - std::string password) { - name_ = name; - password_ = password; -} void LocallyManagedUserCreationScreen::Show() { - if (actor_) + if (actor_) { actor_->Show(); - // Make sure no two controllers exist at the same time. - controller_.reset(); - controller_.reset(new LocallyManagedUserController(this)); + actor_->ShowInitialScreen(); + } +} + +void LocallyManagedUserCreationScreen:: + ShowManagerInconsistentStateErrorScreen() { + if (!actor_) + return + actor_->ShowErrorMessage( + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_ERROR_TPM_ERROR), + false); +} - controller_->StartCreation(name_, password_); +void LocallyManagedUserCreationScreen::ShowInitialScreen() { + if (actor_) + actor_->ShowInitialScreen(); } + void LocallyManagedUserCreationScreen::Hide() { if (actor_) actor_->Hide(); @@ -67,6 +76,32 @@ void LocallyManagedUserCreationScreen::RetryLastStep() { controller_->RetryLastStep(); } +void LocallyManagedUserCreationScreen::RunFlow( + string16& display_name, + std::string& managed_user_password, + std::string& manager_id, + std::string& manager_password) { + + // Make sure no two controllers exist at the same time. + controller_.reset(); + controller_.reset(new LocallyManagedUserController(this)); + controller_->SetUpCreation(display_name, managed_user_password); + + ExistingUserController::current_controller()-> + Login(manager_id, manager_password); +} + +void LocallyManagedUserCreationScreen::OnManagerLoginFailure() { + if (actor_) + actor_->ShowManagerPasswordError(); +} + +void LocallyManagedUserCreationScreen::OnManagerSignIn() { + if (actor_) + actor_->ShowProgressScreen(); + controller_->StartCreation(); +} + void LocallyManagedUserCreationScreen::OnExit() {} void LocallyManagedUserCreationScreen::OnActorDestroyed( diff --git a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h index db1509f..c666661 100644 --- a/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h +++ b/chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h @@ -16,7 +16,6 @@ namespace chromeos { // Class that controls screen showing ui for locally managed user creation. - class LocallyManagedUserCreationScreen : public WizardScreen, public LocallyManagedUserCreationScreenHandler::Delegate, @@ -27,7 +26,24 @@ class LocallyManagedUserCreationScreen LocallyManagedUserCreationScreenHandler* actor); virtual ~LocallyManagedUserCreationScreen(); - virtual void SetParameters(string16 name, std::string password); + // Makes screen to show message about inconsistency in manager login flow + // (e.g. password change detected, invalid OAuth token, etc). + // Called when manager user is successfully authenticated, so ui elements + // should result in forced logout. + void ShowManagerInconsistentStateErrorScreen(); + + // Called when authentication fails for manager with provided password. + // Displays wrong password message on manager selection screen. + void OnManagerLoginFailure(); + + // Called when manager is successfully authenticated and account is in + // consistent state. + // Results in spinner indicating that creation is in process. + void OnManagerSignIn(); + + // Shows initial screen where managed user name/password are defined and + // manager is selected. + void ShowInitialScreen(); // WizardScreen implementation: virtual void PrepareToShow() OVERRIDE; @@ -39,6 +55,10 @@ class LocallyManagedUserCreationScreen virtual void OnExit() OVERRIDE; virtual void OnActorDestroyed(LocallyManagedUserCreationScreenHandler* actor) OVERRIDE; + virtual void RunFlow(string16& display_name, + std::string& managed_user_password, + std::string& manager_id, + std::string& manager_password) OVERRIDE; virtual void AbortFlow() OVERRIDE; virtual void RetryLastStep() OVERRIDE; virtual void FinishFlow() OVERRIDE; @@ -53,10 +73,6 @@ class LocallyManagedUserCreationScreen scoped_ptr<LocallyManagedUserController> controller_; - string16 name_; - - std::string password_; - DISALLOW_COPY_AND_ASSIGN(LocallyManagedUserCreationScreen); }; diff --git a/chrome/browser/chromeos/login/managed/managed_user_authenticator.cc b/chrome/browser/chromeos/login/managed/managed_user_authenticator.cc index f0ed26e..b989beb 100644 --- a/chrome/browser/chromeos/login/managed/managed_user_authenticator.cc +++ b/chrome/browser/chromeos/login/managed/managed_user_authenticator.cc @@ -40,6 +40,16 @@ void TriggerResolve(ManagedUserAuthenticator::AuthAttempt* attempt, resolver->Resolve(); } +// Records status and calls resolver->Resolve(). +void TriggerResolveResult(ManagedUserAuthenticator::AuthAttempt* attempt, + scoped_refptr<ManagedUserAuthenticator> resolver, + bool success, + const std::string& result) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + attempt->RecordHash(result); + resolver->Resolve(); +} + // Calls TriggerResolve while adding login time marker. void TriggerResolveWithLoginTimeMarker( const std::string& marker_name, @@ -67,6 +77,10 @@ void Mount(ManagedUserAuthenticator::AuthAttempt* attempt, "CryptohomeMount-LMU-End", attempt, resolver)); + + cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername( + attempt->username, + base::Bind(&TriggerResolveResult, attempt, resolver)); } // Returns hash of |password|, salted with the system salt. @@ -125,12 +139,13 @@ void ManagedUserAuthenticator::AuthenticateToCreate(const std::string& username, cryptohome::CREATE_IF_MISSING)); } -void ManagedUserAuthenticator::OnAuthenticationSuccess() { +void ManagedUserAuthenticator::OnAuthenticationSuccess( + const std::string& mount_hash) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); VLOG(1) << "Locally managed user authentication success"; - // TODO(antrim) : report mount path to mount manager. + if (consumer_) - consumer_->OnMountSuccess(); + consumer_->OnMountSuccess(mount_hash); } void ManagedUserAuthenticator::OnAuthenticationFailure( @@ -185,7 +200,9 @@ void ManagedUserAuthenticator::Resolve() { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&ManagedUserAuthenticator::OnAuthenticationSuccess, this)); + base::Bind(&ManagedUserAuthenticator::OnAuthenticationSuccess, + this, + current_state_->hash())); break; default: NOTREACHED(); @@ -202,6 +219,8 @@ ManagedUserAuthenticator::AuthState ManagedUserAuthenticator::ResolveState() { // This is an important invariant. if (!current_state_->cryptohome_complete()) return CONTINUE; + if (!current_state_->hash_obtained()) + return CONTINUE; AuthState state; @@ -210,7 +229,8 @@ ManagedUserAuthenticator::AuthState ManagedUserAuthenticator::ResolveState() { else state = ResolveCryptohomeFailureState(); - DCHECK(current_state_->cryptohome_complete()); // Ensure invariant holds. + DCHECK(current_state_->cryptohome_complete()); + DCHECK(current_state_->hash_obtained()); return state; } @@ -247,8 +267,11 @@ ManagedUserAuthenticator::AuthAttempt::AuthAttempt(const std::string& username, hashed_password(hashed), cryptohome_complete_(false), cryptohome_outcome_(false), + hash_obtained_(false), cryptohome_code_(cryptohome::MOUNT_ERROR_NONE) {} +ManagedUserAuthenticator::AuthAttempt::~AuthAttempt() {} + void ManagedUserAuthenticator::AuthAttempt::RecordCryptohomeStatus( bool cryptohome_outcome, cryptohome::MountError cryptohome_code) { @@ -258,6 +281,13 @@ void ManagedUserAuthenticator::AuthAttempt::RecordCryptohomeStatus( cryptohome_code_ = cryptohome_code; } +void ManagedUserAuthenticator::AuthAttempt::RecordHash( + const std::string& hash) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + hash_obtained_ = true; + hash_ = hash; +} + bool ManagedUserAuthenticator::AuthAttempt::cryptohome_complete() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); return cryptohome_complete_; @@ -274,4 +304,14 @@ cryptohome::MountError return cryptohome_code_; } +bool ManagedUserAuthenticator::AuthAttempt::hash_obtained() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + return hash_obtained_; +} + +std::string ManagedUserAuthenticator::AuthAttempt::hash() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + return hash_; +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/login/managed/managed_user_authenticator.h b/chrome/browser/chromeos/login/managed/managed_user_authenticator.h index c37a59f..583f38f 100644 --- a/chrome/browser/chromeos/login/managed/managed_user_authenticator.h +++ b/chrome/browser/chromeos/login/managed/managed_user_authenticator.h @@ -37,14 +37,23 @@ class ManagedUserAuthenticator AuthAttempt(const std::string& username, const std::string& password, const std::string& hashed_password); + ~AuthAttempt(); + // Copy |cryptohome_code| and |cryptohome_outcome| into this object, // so we can have a copy we're sure to own, and can make available // on the IO thread. Must be called from the IO thread. void RecordCryptohomeStatus(bool cryptohome_outcome, cryptohome::MountError cryptohome_code); + // Copy |hash| into this object so we can have a copy we're sure to own + // and can make available on the IO thread. + // Must be called from the IO thread. + void RecordHash(const std::string& hash); + bool cryptohome_complete(); bool cryptohome_outcome(); + bool hash_obtained(); + std::string hash(); cryptohome::MountError cryptohome_code(); const std::string username; @@ -54,6 +63,9 @@ class ManagedUserAuthenticator private: bool cryptohome_complete_; bool cryptohome_outcome_; + bool hash_obtained_; + std::string hash_; + cryptohome::MountError cryptohome_code_; DISALLOW_COPY_AND_ASSIGN(AuthAttempt); }; @@ -64,7 +76,7 @@ class ManagedUserAuthenticator // The current login attempt has ended in failure, with error. virtual void OnAuthenticationFailure(AuthState state) = 0; // The current login attempt has ended succesfully. - virtual void OnMountSuccess() = 0; + virtual void OnMountSuccess(const std::string& mount_hash) = 0; // The current cryptohome creation attempt has ended succesfully. virtual void OnCreationSuccess() = 0; }; @@ -86,7 +98,7 @@ class ManagedUserAuthenticator AuthState ResolveState(); AuthState ResolveCryptohomeFailureState(); AuthState ResolveCryptohomeSuccessState(); - void OnAuthenticationSuccess(); + void OnAuthenticationSuccess(const std::string& mount_hash); void OnAuthenticationFailure(AuthState state); scoped_ptr<AuthAttempt> current_state_; diff --git a/chrome/browser/chromeos/login/mock_login_display_host.h b/chrome/browser/chromeos/login/mock_login_display_host.h index 5bc740b..f2146b6 100644 --- a/chrome/browser/chromeos/login/mock_login_display_host.h +++ b/chrome/browser/chromeos/login/mock_login_display_host.h @@ -29,6 +29,7 @@ class MockLoginDisplayHost : public LoginDisplayHost { MOCK_METHOD0(ShowBackground, void(void)); MOCK_METHOD0(CheckForAutoEnrollment, void(void)); MOCK_METHOD2(StartWizard, void(const std::string&, DictionaryValue*)); + MOCK_METHOD0(GetWizardController, WizardController*(void)); MOCK_METHOD0(StartSignInScreen, void(void)); MOCK_METHOD0(ResumeSignInScreen, void(void)); MOCK_METHOD0(OnPreferencesChanged, void(void)); diff --git a/chrome/browser/chromeos/login/mount_manager.cc b/chrome/browser/chromeos/login/mount_manager.cc index 340783f..0bce980 100644 --- a/chrome/browser/chromeos/login/mount_manager.cc +++ b/chrome/browser/chromeos/login/mount_manager.cc @@ -7,10 +7,19 @@ namespace chromeos { +const char kBaseChromeosMountPath[] = "/home/user"; + MountManager* MountManager::Get() { - if (!instance_.get()) - instance_.reset(new MountManager()); - return instance_.get(); + if (!instance_) + instance_ = new MountManager(); + return instance_; +} + +// static +MountManager* MountManager::instance_ = NULL; + +base::FilePath MountManager::GetHomeDir(std::string& user_hash) { + return base::FilePath(kBaseChromeosMountPath).Append(user_hash); } MountManager::MountManager() {} @@ -18,10 +27,6 @@ MountManager::MountManager() {} MountManager::~MountManager() {} bool MountManager::IsMounted(const std::string& user_id) { -// if (UserManager::Get()->IsUserLoggedIn() && -// ) { -// return ProfileManager::GetDefaultProfile()-> -// } UserToPathMap::iterator i(additional_mounts_.find(user_id)); return i != additional_mounts_.end(); } diff --git a/chrome/browser/chromeos/login/mount_manager.h b/chrome/browser/chromeos/login/mount_manager.h index a7d03d24..b0f61dd 100644 --- a/chrome/browser/chromeos/login/mount_manager.h +++ b/chrome/browser/chromeos/login/mount_manager.h @@ -22,13 +22,15 @@ class MountManager { // should only be called from the main UI thread. static MountManager* Get(); + static base::FilePath GetHomeDir(std::string& user_hash); + virtual ~MountManager(); virtual bool IsMounted(const std::string& user_id); virtual base::FilePath GetPath(const std::string& user_id); virtual void SetPath(const std::string& user_id, - const base::FilePath& path); + const base::FilePath& path); virtual void DeletePath(const std::string& user_id); private: @@ -38,7 +40,7 @@ class MountManager { UserToPathMap additional_mounts_; - static scoped_ptr<MountManager> instance_; + static MountManager* instance_; DISALLOW_COPY_AND_ASSIGN(MountManager); }; diff --git a/chrome/browser/chromeos/login/user_flow.cc b/chrome/browser/chromeos/login/user_flow.cc index 5eeea2e..15019c0 100644 --- a/chrome/browser/chromeos/login/user_flow.cc +++ b/chrome/browser/chromeos/login/user_flow.cc @@ -18,7 +18,16 @@ bool DefaultUserFlow::ShouldSkipPostLoginScreens() { return false; } -void DefaultUserFlow::LaunchExtraSteps() { +bool DefaultUserFlow::HandleLoginFailure(const LoginFailure& failure, + LoginDisplayHost* host) { + return false; +} + +bool DefaultUserFlow::HandlePasswordChangeDetected(LoginDisplayHost* host) { + return false; +} + +void DefaultUserFlow::LaunchExtraSteps(LoginDisplayHost* host) { } } // namespace chromeos diff --git a/chrome/browser/chromeos/login/user_flow.h b/chrome/browser/chromeos/login/user_flow.h index 3586d5b..c8a93f3 100644 --- a/chrome/browser/chromeos/login/user_flow.h +++ b/chrome/browser/chromeos/login/user_flow.h @@ -6,9 +6,11 @@ #define CHROME_BROWSER_CHROMEOS_LOGIN_USER_FLOW_H_ #include "base/compiler_specific.h" +#include "chrome/browser/chromeos/login/login_status_consumer.h" namespace chromeos { +class LoginDisplayHost; // Defines possible variants of user flow upon logging in. // See UserManager::SetUserFlow for usage contract. class UserFlow { @@ -16,7 +18,10 @@ class UserFlow { virtual ~UserFlow() = 0; virtual bool ShouldLaunchBrowser() = 0; virtual bool ShouldSkipPostLoginScreens() = 0; - virtual void LaunchExtraSteps() = 0; + virtual bool HandleLoginFailure(const LoginFailure& failure, + LoginDisplayHost* host) = 0; + virtual bool HandlePasswordChangeDetected(LoginDisplayHost* host) = 0; + virtual void LaunchExtraSteps(LoginDisplayHost* host) = 0; }; // UserFlow implementation for regular login flow. @@ -26,7 +31,10 @@ class DefaultUserFlow : public UserFlow { virtual bool ShouldLaunchBrowser() OVERRIDE; virtual bool ShouldSkipPostLoginScreens() OVERRIDE; - virtual void LaunchExtraSteps() OVERRIDE; + virtual bool HandleLoginFailure(const LoginFailure& failure, + LoginDisplayHost* host) OVERRIDE; + virtual bool HandlePasswordChangeDetected(LoginDisplayHost* host) OVERRIDE; + virtual void LaunchExtraSteps(LoginDisplayHost* host) OVERRIDE; }; } // namespace chromeos diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 52ce9bd2..b198441 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc @@ -371,16 +371,6 @@ void WizardController::ShowLocallyManagedUserCreationScreen() { SetStatusAreaVisible(false); LocallyManagedUserCreationScreen* screen = GetLocallyManagedUserCreationScreen(); - - string16 name; - std::string password; - DCHECK(screen_parameters_.get()); - - if (screen_parameters_.get()) { - screen_parameters_->GetString("user_display_name", &name); - screen_parameters_->GetString("password", &password); - } - screen->SetParameters(name, password); SetCurrentScreen(screen); } diff --git a/chrome/browser/resources/chromeos/login/login.html b/chrome/browser/resources/chromeos/login/login.html index 1082818..5c00ea2 100644 --- a/chrome/browser/resources/chromeos/login/login.html +++ b/chrome/browser/resources/chromeos/login/login.html @@ -22,7 +22,6 @@ <link rel="stylesheet" href="screen_password_changed.css"> <link rel="stylesheet" href="screen_wrong_hwid.css"> <link rel="stylesheet" href="screen_locally_managed_user_creation.css"> -<link rel="stylesheet" href="managed_user_creation.css"> <link rel="stylesheet" href="oobe_screen_terms_of_service.css"> <link rel="stylesheet" href="user_pod_row.css"> <script src="chrome://resources/js/cr.js"></script> @@ -65,7 +64,6 @@ <include src="screen_error_message.html"> <include src="screen_tpm_error.html"> <include src="screen_password_changed.html"> - <include src="managed_user_creation.html"> <include src="screen_locally_managed_user_creation.html"> <include src="oobe_screen_reset.html"> <include src="oobe_screen_terms_of_service.html"> diff --git a/chrome/browser/resources/chromeos/login/login.js b/chrome/browser/resources/chromeos/login/login.js index 55fe07d..8afdf89 100644 --- a/chrome/browser/resources/chromeos/login/login.js +++ b/chrome/browser/resources/chromeos/login/login.js @@ -12,7 +12,6 @@ <include src="bubble.js"></include> <include src="display_manager.js"></include> <include src="header_bar.js"></include> -<include src="managed_user_creation.js"></include> <include src="network_dropdown.js"></include> <include src="oobe_screen_oauth_enrollment.js"></include> <include src="oobe_screen_user_image.js"></include> @@ -60,7 +59,6 @@ cr.define('cr.ui', function() { login.ErrorMessageScreen.register(); login.TPMErrorMessageScreen.register(); login.PasswordChangedScreen.register(); - login.ManagedUserCreationScreen.register(); login.LocallyManagedUserCreationScreen.register(); oobe.TermsOfServiceScreen.register(); diff --git a/chrome/browser/resources/chromeos/login/managed_user_creation.css b/chrome/browser/resources/chromeos/login/managed_user_creation.css deleted file mode 100644 index 7f4890f..0000000 --- a/chrome/browser/resources/chromeos/login/managed_user_creation.css +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (c) 2013 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * This is the stylesheet used by the network drop-down control. - */ - -#managed-user-creation-dialog { - height: 488px; - padding: 70px 17px 50px; - width: 704px; -} - -#managed-user-creation-contents { - color: #606060; - margin: 10px 33px; -} - -#managed-user-creation-name-block, -#managed-user-creation-password-block, -#managed-user-creation-password-title { - margin-top: 10px; -} - -#managed-user-creation-password { - padding: 4px 6px; -} -#managed-user-creation-password-confirm { - margin-top: 12px; - padding: 4px 6px; -} - -#managed-user-creation-password-error { - height: 16px; - margin-top: 10px; -} - -#managed-user-creation-name-error, -#managed-user-creation-password-error { - visibility: hidden; -} - -#managed-user-creation-name-error.error, -#managed-user-creation-password-error.error { - background: url('chrome://theme/IDR_WARNING') left top /24px no-repeat; - color: red; - padding-left: 28px; - visibility: visible; -} - -#managed-user-creation-managers-pane { - height: 140px; - margin-top: 6px; - overflow-y: auto; - width: 645px; -} - -.manager-pod { - margin-bottom: 4px; - opacity: 0.8; - padding-bottom: 5px; - padding-top: 5px; - width: 625px; -} - -#managed-user-creation-managers-pane .focused { - background-color: #f0f0f0; - opacity: 1; -} - -.manager-pod .managed-user-creation-manager-info-block { - min-height: 40px; -} - -.manager-pod .managed-user-creation-manager-image { - display: inline-block; - height: 30px; - width: 30px; -} - -.manager-pod .managed-user-creation-manager-info { - display: inline-block; - margin: 0 8px; - min-height: 30px; -} - -.manager-pod .managed-user-creation-manager-info-text { - display: inline-block; - min-height: 30px; - vertical-align: top; -} - -.manager-pod .managed-user-creation-manager-email { - color: #666; - font-size: small; -} - -.manager-pod .managed-user-creation-manager-name { - color: #000; - font-size: small; -} diff --git a/chrome/browser/resources/chromeos/login/managed_user_creation.html b/chrome/browser/resources/chromeos/login/managed_user_creation.html deleted file mode 100644 index 10e1ac3..0000000 --- a/chrome/browser/resources/chromeos/login/managed_user_creation.html +++ /dev/null @@ -1,43 +0,0 @@ -<div id="managed-user-creation-dialog" class="step hidden left"> - <div id="managed-user-creation-contents" class="step-contents"> - <div id="managed-user-creation-name-title" - i18n-content="createManagedUserNameTitle"></div> - <div id="managed-user-creation-name-block"> - <input id="managed-user-creation-name" type="text" /> - <span id="managed-user-creation-name-error" class="no-error"></span> - </div> - <div id="managed-user-creation-password-title" - i18n-content="createManagedUserPasswordTitle"></div> - <div id="managed-user-creation-password-block"> - <div> - <input id="managed-user-creation-password" type="password" - i18n-values="placeholder:createManagedUserPasswordHint"/> - </div> - <div> - <input id="managed-user-creation-password-confirm" type="password" - i18n-values="placeholder:createManagedUserPasswordConfirmHint"/> - </div> - </div> - <div id="managed-user-creation-password-error" class="no-error"></div> - <div id="managed-user-creation-managers-block" hidden> - <div id="managed-user-creation-managers-block-title" - i18n-content="createManagedUserSelectManagerTitle"></div> - <div id="managed-user-creation-managers-pane"></div> - </div> - </div> - <div id="managed-user-creation-dialog-controls" class="step-controls"></div> - <div id="managed-user-creation-cancel-button" class="close-button"></div> - <div id="managed-user-creation-manager-template" hidden class="manager-pod"> - <div class="managed-user-creation-manager-info-block"> - <img class="managed-user-creation-manager-image" alt=""> - <div class="managed-user-creation-manager-info-text"> - <div class="managed-user-creation-manager-name"></div> - <div class="managed-user-creation-manager-email"></div> - </div> - </div> - <div class="managed-user-creation-manager-password-block" hidden> - <input class="managed-user-creation-manager-password" type="password" - i18n-values="placeholder:createManagedUserManagerPasswordHint"/> - </div> - </div> -</div>
\ No newline at end of file diff --git a/chrome/browser/resources/chromeos/login/managed_user_creation.js b/chrome/browser/resources/chromeos/login/managed_user_creation.js deleted file mode 100644 index 157d0a3..0000000 --- a/chrome/browser/resources/chromeos/login/managed_user_creation.js +++ /dev/null @@ -1,526 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Create managed user implementation. - */ - -cr.define('login', function() { - var ManagerPod = cr.ui.define(function() { - var node = $('managed-user-creation-manager-template').cloneNode(true); - node.removeAttribute('id'); - node.removeAttribute('hidden'); - return node; - }); - - ManagerPod.userImageSalt_ = {}; - - /** - * UI element for displaying single account in list of possible managers for - * new locally managed user. - * @type {Object} - */ - ManagerPod.prototype = { - __proto__: HTMLDivElement.prototype, - - /** @override */ - decorate: function() { - // Mousedown has to be used instead of click to be able to prevent 'focus' - // event later. - this.addEventListener('mousedown', - this.handleMouseDown_.bind(this)); - }, - - /** - * Updates UI elements from user data. - */ - update: function() { - this.imageElement.src = 'chrome://userimage/' + this.user.username + - '?id=' + ManagerPod.userImageSalt_[this.user.username]; - - this.nameElement.textContent = this.user.displayName; - this.emailElement.textContent = this.user.emailAddress; - }, - - /** - * Brings focus to password field. - */ - focusInput: function() { - this.passwordElement.focus(); - }, - - /** - * Gets image element. - * @type {!HTMLImageElement} - */ - get imageElement() { - return this.querySelector('.managed-user-creation-manager-image'); - }, - - /** - * Gets name element. - * @type {!HTMLDivElement} - */ - get nameElement() { - return this.querySelector('.managed-user-creation-manager-name'); - }, - - /** - * Gets e-mail element. - * @type {!HTMLDivElement} - */ - get emailElement() { - return this.querySelector('.managed-user-creation-manager-email'); - }, - - /** - * Gets password element. - * @type {!HTMLDivElement} - */ - get passwordElement() { - return this.querySelector('.managed-user-creation-manager-password'); - }, - - /** - * Gets password enclosing block. - * @type {!HTMLDivElement} - */ - get passwordBlock() { - return this.querySelector( - '.managed-user-creation-manager-password-block'); - }, - - /** @override */ - handleMouseDown_: function(e) { - this.parentNode.selectPod(this); - // Prevent default so that we don't trigger 'focus' event. - e.preventDefault(); - }, - - - /** - * The user that this pod represents. - * @type {!Object} - */ - user_: undefined, - get user() { - return this.user_; - }, - set user(userDict) { - this.user_ = userDict; - this.update(); - }, - }; - - var ManagerPodList = cr.ui.define('managerList'); - - /** - * UI element for selecting manager account for new managed user. - * @type {Object} - */ - ManagerPodList.prototype = { - __proto__: HTMLDivElement.prototype, - - selectedPod_: null, - - /** @override */ - decorate: function() { - }, - - /** - * Returns all the pods in this pod list. - * @type {NodeList} - */ - get pods() { - return this.children; - }, - - addPod: function(manager) { - var managerPod = new ManagerPod({user: manager}); - this.appendChild(managerPod); - managerPod.update(); - }, - - clearPods: function() { - this.innerHTML = ''; - this.selectedPod_ = null; - }, - - selectPod: function(podToSelect) { - if (this.selectedPod_ == podToSelect) { - podToSelect.focusInput(); - return; - } - this.selectedPod_ = podToSelect; - for (var i = 0, pod; pod = this.pods[i]; ++i) { - if (pod != podToSelect) { - pod.classList.remove('focused'); - pod.passwordElement.value = ''; - pod.passwordBlock.hidden = true; - } - } - podToSelect.classList.add('focused'); - podToSelect.passwordBlock.hidden = false; - podToSelect.passwordElement.value = ''; - podToSelect.focusInput(); - }, - }; - - /** - * Creates a new managed user creation screen div. - * @constructor - * @extends {HTMLDivElement} - */ - var ManagedUserCreationScreen = cr.ui.define('div'); - - /** - * Registers with Oobe. - */ - ManagedUserCreationScreen.register = function() { - var screen = $('managed-user-creation-dialog'); - ManagedUserCreationScreen.decorate(screen); - Oobe.getInstance().registerScreen(screen); - }; - - ManagedUserCreationScreen.prototype = { - __proto__: HTMLDivElement.prototype, - - lastVerifiedName_: null, - lastIncorrectUserName_: null, - managerList_: null, - useManagerBasedCreationFlow_: false, - - /** @override */ - decorate: function() { - this.managerList_ = new ManagerPodList(); - $('managed-user-creation-managers-pane').appendChild(this.managerList_); - - var closeButton = $('managed-user-creation-cancel-button'); - var userNameField = $('managed-user-creation-name'); - var passwordField = $('managed-user-creation-password'); - var password2Field = $('managed-user-creation-password-confirm'); - - closeButton.addEventListener('click', this.cancel.bind(this)); - var creationScreen = this; - userNameField.addEventListener('keydown', function(e) { - if (e.keyIdentifier == 'Enter') { - if (userNameField.value.length > 0) - passwordField.focus(); - e.stopPropagation(); - return; - } - creationScreen.clearUserNameError_(); - }); - - userNameField.addEventListener('keyup', function(e) { - creationScreen.checkUserName_(); - }); - - passwordField.addEventListener('keydown', function(e) { - creationScreen.passwordErrorVisible = false; - if (e.keyIdentifier == 'Enter') { - if (passwordField.value.length > 0) { - password2Field.focus(); - creationScreen.updateContinueButton_(); - } - e.stopPropagation(); - } - }); - password2Field.addEventListener('keydown', function(e) { - creationScreen.passwordErrorVisible = false; - if (e.keyIdentifier == 'Enter') { - if (creationScreen.updateContinueButton_()) - creationScreen.validateAndContinue_(); - e.stopPropagation(); - } - }); - - password2Field.addEventListener('keyup', function(e) { - creationScreen.updateContinueButton_(); - }); - passwordField.addEventListener('keyup', function(e) { - creationScreen.updateContinueButton_(); - }); - }, - - /** - * Calls backend part to check if current user name is valid/not taken. - * Results in call to either managedUserNameOk or managedUserNameError. - * @private - */ - checkUserName_: function() { - var userName = $('managed-user-creation-name').value; - - // Avoid flickering - if (userName == this.lastIncorrectUserName_ || - userName == this.lastVerifiedName_) { - return; - } - if (userName.length > 0) { - chrome.send('checkLocallyManagedUserName', [userName]); - } else { - this.nameErrorVisible = false; - this.lastVerifiedName_ = null; - this.lastIncorrectUserName_ = null; - } - }, - - /** - * Called by backend part in case of successful name validation. - * @param {string} name - name that was validated. - */ - managedUserNameOk: function(name) { - this.lastVerifiedName_ = name; - this.lastIncorrectUserName_ = null; - if ($('managed-user-creation-name').value == name) - this.clearUserNameError_(); - this.updateContinueButton_(); - }, - - /** - * Called by backend part in case of name validation failure. - * @param {string} name - name that was validated. - * @param {string} errorText - reason why this name is invalid. - */ - managedUserNameError: function(name, errorText) { - this.lastIncorrectUserName_ = name; - this.lastVerifiedName_ = null; - - var userNameField = $('managed-user-creation-name'); - if (userNameField.value == this.lastIncorrectUserName_) { - this.nameErrorVisible = true; - $('managed-user-creation-name-error').textContent = errorText; - $('managed-user-creation-continue-button').disabled = true; - } - }, - - /** - * Clears user name error, if name is no more guaranteed to be invalid. - * @private - */ - clearUserNameError_: function() { - // Avoid flickering - if ($('managed-user-creation-name').value == this.lastIncorrectUserName_) - return; - this.nameErrorVisible = false; - }, - - /** - * Called by backend part in case of password validation failure. - * @param {string} errorText - reason why this password is invalid. - */ - showPasswordError: function(errorText) { - $('managed-user-creation-password-error').textContent = errorText; - this.passwordErrorVisible = true; - $('managed-user-creation-password').focus(); - $('managed-user-creation-continue-button').disabled = true; - }, - - /** - * True if user name error should be displayed. - * @type {boolean} - */ - set nameErrorVisible(value) { - $('managed-user-creation-name-error'). - classList[value ? 'add' : 'remove']('error'); - $('managed-user-creation-name'). - classList[value ? 'add' : 'remove']('duplicate-name'); - if (!value) - $('managed-user-creation-name-error').textContent = ''; - }, - - /** - * True if user name error should be displayed. - * @type {boolean} - */ - set passwordErrorVisible(value) { - $('managed-user-creation-password-error'). - classList[value ? 'add' : 'remove']('error'); - if (!value) - $('managed-user-creation-password-error').textContent = ''; - }, - - /** - * Updates state of Continue button after minimal checks. - * @return {boolean} true, if form seems to be valid. - * @private - */ - updateContinueButton_: function() { - var firstPassword = $('managed-user-creation-password').value; - var secondPassword = $('managed-user-creation-password-confirm').value; - var userName = $('managed-user-creation-name').value; - - var canProceed = - (firstPassword.length > 0) && - (firstPassword.length == secondPassword.length) && - this.lastVerifiedName_ && - (userName == this.lastVerifiedName_); - - $('managed-user-creation-continue-button').disabled = !canProceed; - return canProceed; - }, - - /** - * Does sanity check and calls backend with current user name/password pair - * to create a user. May result in showPasswordError. - * @private - */ - validateAndContinue_: function() { - var firstPassword = $('managed-user-creation-password').value; - var secondPassword = $('managed-user-creation-password-confirm').value; - var userName = $('managed-user-creation-name').value; - - if (firstPassword != secondPassword) { - this.showPasswordError( - loadTimeData.getString('createManagedUserPasswordMismatchError')); - return; - } - if (!this.useManagerBasedCreationFlow_) { - this.disabled = true; - chrome.send('tryCreateLocallyManagedUser', [userName, firstPassword]); - } else { - var selectedPod = this.managerList_.selectedPod_; - // TODO(antrim) : validation - if (null == selectedPod) - return; - - var custodianId = selectedPod.user.emailAddress; - var custodianPassword = selectedPod.passwordElement.value; - this.disabled = true; - chrome.send('runLocallyManagedUserCreationFlow', - [userName, firstPassword, custodianId, custodianPassword]); - } - }, - - /** - * Screen controls. - * @type {array} Array of Buttons. - */ - get buttons() { - var buttons = []; - - var continueButton = this.ownerDocument.createElement('button'); - continueButton.id = 'managed-user-creation-continue-button'; - continueButton.textContent = - loadTimeData.getString('createManagedUserContinueButton'); - buttons.push(continueButton); - - var creationScreen = this; - continueButton.addEventListener('click', function(e) { - creationScreen.validateAndContinue_(); - e.stopPropagation(); - }); - - return buttons; - }, - - /** - * Update state of login header so that necessary buttons are displayed. - */ - onBeforeShow: function(data) { - $('login-header-bar').signinUIState = - SIGNIN_UI_STATE.MANAGED_USER_CREATION_DIALOG; - }, - - /** - * Update state of login header so that necessary buttons are displayed. - */ - onBeforeHide: function() { - $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN; - }, - - /** - * Returns a control which should receive an initial focus. - */ - get defaultControl() { - return $('managed-user-creation-name'); - }, - - /** - * True if the the screen is disabled (handles no user interaction). - * @type {boolean} - */ - disabled_: false, - - get disabled() { - return this.disabled_; - }, - - set disabled(value) { - this.disabled_ = value; - var controls = this.querySelectorAll('button,input'); - for (var i = 0, control; control = controls[i]; ++i) { - control.disabled = value; - } - $('login-header-bar').disabled = value; - }, - - /** - * Called by backend part to propagate list of possible managers. - * @param {Array} userList - list of users that can be managers. - */ - loadManagers: function(userList) { - $('managed-user-creation-managers-block').hidden = false; - this.useManagerBasedCreationFlow_ = true; - this.managerList_.clearPods(); - for (var i = 0; i < userList.length; ++i) - this.managerList_.addPod(userList[i]); - if (userList.length > 0) - this.managerList_.selectPod(this.managerList_.pods[0]); - }, - - /** - * Called on user creation cancellation. - */ - cancel: function() { - if (!this.disabled) - Oobe.goBack(); - }, - }; - - /** - * Show Create managed user screen. - */ - ManagedUserCreationScreen.show = function() { - Oobe.getInstance().headerHidden = false; - var screen = $('managed-user-creation-dialog'); - - Oobe.showScreen({id: SCREEN_CREATE_MANAGED_USER_DIALOG}); - - // Clear all fields. - $('managed-user-creation-password').value = ''; - $('managed-user-creation-password-confirm').value = ''; - $('managed-user-creation-name').value = ''; - screen.lastVerifiedName_ = null; - screen.lastIncorrectUserName_ = null; - screen.passwordErrorVisible = false; - screen.nameErrorVisible = false; - - $('managed-user-creation-continue-button').disabled = true; - }; - - ManagedUserCreationScreen.managedUserNameOk = function(name) { - var screen = $('managed-user-creation-dialog'); - screen.managedUserNameOk(name); - }; - - ManagedUserCreationScreen.managedUserNameError = function(name, error) { - var screen = $('managed-user-creation-dialog'); - screen.managedUserNameError(name, error); - }; - - ManagedUserCreationScreen.showPasswordError = function(error) { - var screen = $('managed-user-creation-dialog'); - screen.showPasswordError(error); - }; - - ManagedUserCreationScreen.loadManagers = function(userList) { - var screen = $('managed-user-creation-dialog'); - screen.loadManagers(userList); - }; - - return { - ManagedUserCreationScreen: ManagedUserCreationScreen - }; -}); diff --git a/chrome/browser/resources/chromeos/login/oobe.html b/chrome/browser/resources/chromeos/login/oobe.html index 77a605d..0dc6703 100644 --- a/chrome/browser/resources/chromeos/login/oobe.html +++ b/chrome/browser/resources/chromeos/login/oobe.html @@ -21,7 +21,6 @@ <link rel="stylesheet" href="screen_error_message.css"> <link rel="stylesheet" href="screen_tpm_error.css"> <link rel="stylesheet" href="screen_locally_managed_user_creation.css"> -<link rel="stylesheet" href="managed_user_creation.css"> <link rel="stylesheet" href="screen_password_changed.css"> <link rel="stylesheet" href="oobe_screen_terms_of_service.css"> <link rel="stylesheet" href="screen_wrong_hwid.css"> @@ -64,7 +63,6 @@ <include src="oobe_screen_update.html"> <include src="oobe_screen_oauth_enrollment.html"> <include src="oobe_screen_user_image.html"> - <include src="managed_user_creation.html"> <include src="screen_locally_managed_user_creation.html"> <include src="screen_gaia_signin.html"> <include src="screen_account_picker.html"> diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js index 5da24af..5d86ae1 100644 --- a/chrome/browser/resources/chromeos/login/oobe.js +++ b/chrome/browser/resources/chromeos/login/oobe.js @@ -12,7 +12,6 @@ <include src="bubble.js"></include> <include src="display_manager.js"></include> <include src="header_bar.js"></include> -<include src="managed_user_creation.js"></include> <include src="screen_locally_managed_user_creation.js"></include> <include src="network_dropdown.js"></include> <include src="oobe_screen_eula.js"></include> @@ -99,7 +98,6 @@ cr.define('cr.ui', function() { login.ErrorMessageScreen.register(); login.TPMErrorMessageScreen.register(); login.PasswordChangedScreen.register(); - login.ManagedUserCreationScreen.register(); login.LocallyManagedUserCreationScreen.register(); oobe.TermsOfServiceScreen.register(); diff --git a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css index 5ea7c4b..c753812 100644 --- a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css +++ b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css @@ -11,7 +11,6 @@ width: 704px; } - #managed-user-creation-flow-success-title { font-size: x-large; } @@ -19,9 +18,10 @@ #managed-user-creation-flow-success-image { background-color: #d3d3d3; color: gray; - height: 300px; + height: 237px; + margin-left: 127px; margin-top: 25px; - width: 400px; + width: 417px; } #managed-user-creation-flow-success-image-text { @@ -34,3 +34,92 @@ #managed-user-creation-flow-success-email-instructions { margin-top: 12px; } + +#managed-user-creation-flow-name-block, +#managed-user-creation-flow-password-block, +#managed-user-creation-flow-password-title { + margin-top: 10px; +} + +#managed-user-creation-flow-password { + padding: 4px 6px; +} +#managed-user-creation-flow-password-confirm { + margin-top: 12px; + padding: 4px 6px; +} + +#managed-user-creation-flow-password-error { + height: 16px; + margin-top: 10px; +} + +#managed-user-creation-flow-name-error, +#managed-user-creation-flow-password-error { + visibility: hidden; +} + +#managed-user-creation-flow-name-error.error, +#managed-user-creation-flow-password-error.error { + background: url('chrome://theme/IDR_WARNING') left top /24px no-repeat; + color: red; + padding-left: 28px; + visibility: visible; +} + +#managed-user-creation-flow-managers-pane { + height: 140px; + margin-top: 6px; + overflow-y: auto; + width: 645px; +} + +.manager-pod { + margin-bottom: 4px; + opacity: 0.8; + padding-bottom: 5px; + padding-top: 5px; + width: 625px; +} + +#managed-user-creation-flow-managers-pane .focused { + background-color: #f0f0f0; + opacity: 1; +} + +.manager-pod .managed-user-creation-flow-manager-info-block { + min-height: 40px; +} + +.manager-pod .managed-user-creation-flow-manager-image { + display: inline-block; + height: 30px; + width: 30px; +} + +.manager-pod .managed-user-creation-flow-manager-info { + display: inline-block; + margin: 0 8px; + min-height: 30px; +} + +.manager-pod .managed-user-creation-flow-manager-info-text { + display: inline-block; + min-height: 30px; + vertical-align: top; +} + +.manager-pod .managed-user-creation-flow-manager-email { + color: #666; + font-size: small; +} + +.manager-pod .managed-user-creation-flow-manager-name { + color: #000; + font-size: small; +} +.manager-pod .managed-user-creation-flow-manager-wrong-password { + background: url('chrome://theme/IDR_WARNING') left top /24px no-repeat; + color: red; + padding-left: 28px; +}
\ No newline at end of file diff --git a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.html b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.html index d81e11b..c85e42c 100644 --- a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.html +++ b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.html @@ -1,6 +1,35 @@ <div class="step hidden" id="managed-user-creation-flow"> <div class="step-contents"> - <div id="managed-user-creation-flow-progress" class="step-loading"> + <div id="managed-user-creation-flow-initial" > + <div id="managed-user-creation-flow-name-title" + i18n-content="createManagedUserNameTitle"></div> + <div id="managed-user-creation-flow-name-block"> + <input id="managed-user-creation-flow-name" type="text" /> + <span id="managed-user-creation-flow-name-error" class="no-error"> + </span> + </div> + <div id="managed-user-creation-flow-password-title" + i18n-content="createManagedUserPasswordTitle"></div> + <div id="managed-user-creation-flow-password-block"> + <div> + <input id="managed-user-creation-flow-password" type="password" + i18n-values="placeholder:createManagedUserPasswordHint"/> + </div> + <div> + <input id="managed-user-creation-flow-password-confirm" + type="password" + i18n-values="placeholder:createManagedUserPasswordConfirmHint"/> + </div> + </div> + <div id="managed-user-creation-flow-password-error" class="no-error"> + </div> + <div id="managed-user-creation-flow-managers-block" hidden> + <div id="managed-user-creation-flow-managers-block-title" + i18n-content="createManagedUserSelectManagerTitle"></div> + <div id="managed-user-creation-flow-managers-pane"></div> + </div> + </div> + <div id="managed-user-creation-flow-progress" hidden> <div class="spinner"></div> </div> <div id="managed-user-creation-flow-error" hidden> @@ -24,4 +53,21 @@ </div> <div id="managed-user-creation-flow-controls" class="step-controls"> </div> + <div id="managed-user-creation-flow-manager-template" hidden + class="manager-pod"> + <div class="managed-user-creation-flow-manager-info-block"> + <img class="managed-user-creation-flow-manager-image"> + <div class="managed-user-creation-flow-manager-info-text"> + <div class="managed-user-creation-flow-manager-name"></div> + <div class="managed-user-creation-flow-manager-email"></div> + </div> + </div> + <div class="managed-user-creation-flow-manager-password-block" hidden> + <input class="managed-user-creation-flow-manager-password" type="password" + i18n-values="placeholder:createManagedUserManagerPasswordHint"/> + <span class="managed-user-creation-flow-manager-wrong-password" + i18n-content="createManagedUserWrongManagerPasswordText" + hidden/> + </div> + </div> </div>
\ No newline at end of file diff --git a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js index 40e55ab..5bb0d7b 100644 --- a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js +++ b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js @@ -7,6 +7,187 @@ */ cr.define('login', function() { + + var ManagerPod = cr.ui.define(function() { + var node = $('managed-user-creation-flow-manager-template').cloneNode(true); + node.removeAttribute('id'); + node.removeAttribute('hidden'); + return node; + }); + + ManagerPod.userImageSalt_ = {}; + + /** + * UI element for displaying single account in list of possible managers for + * new locally managed user. + * @type {Object} + */ + ManagerPod.prototype = { + __proto__: HTMLDivElement.prototype, + + /** @override */ + decorate: function() { + // Mousedown has to be used instead of click to be able to prevent 'focus' + // event later. + this.addEventListener('mousedown', + this.handleMouseDown_.bind(this)); + var screen = $('managed-user-creation-flow'); + var managerPod = this; + this.passwordElement.addEventListener('keydown', function(e) { + managerPod.passwordErrorElement.hidden = true; + }); + this.passwordElement.addEventListener('keyup', function(e) { + screen.updateContinueButton_(); + }); + }, + + /** + * Updates UI elements from user data. + */ + update: function() { + this.imageElement.src = 'chrome://userimage/' + this.user.username + + '?id=' + ManagerPod.userImageSalt_[this.user.username]; + + this.nameElement.textContent = this.user.displayName; + this.emailElement.textContent = this.user.emailAddress; + }, + + showPasswordError: function() { + this.passwordErrorElement.hidden = false; + }, + + /** + * Brings focus to password field. + */ + focusInput: function() { + this.passwordElement.focus(); + }, + + /** + * Gets image element. + * @type {!HTMLImageElement} + */ + get imageElement() { + return this.querySelector('.managed-user-creation-flow-manager-image'); + }, + + /** + * Gets name element. + * @type {!HTMLDivElement} + */ + get nameElement() { + return this.querySelector('.managed-user-creation-flow-manager-name'); + }, + + /** + * Gets e-mail element. + * @type {!HTMLDivElement} + */ + get emailElement() { + return this.querySelector('.managed-user-creation-flow-manager-email'); + }, + + /** + * Gets password element. + * @type {!HTMLDivElement} + */ + get passwordElement() { + return this.querySelector('.managed-user-creation-flow-manager-password'); + }, + + /** + * Gets password error element. + * @type {!HTMLDivElement} + */ + get passwordErrorElement() { + return this. + querySelector('.managed-user-creation-flow-manager-wrong-password'); + }, + + /** + * Gets password enclosing block. + * @type {!HTMLDivElement} + */ + get passwordBlock() { + return this.querySelector( + '.managed-user-creation-flow-manager-password-block'); + }, + + /** @override */ + handleMouseDown_: function(e) { + this.parentNode.selectPod(this); + // Prevent default so that we don't trigger 'focus' event. + e.preventDefault(); + }, + + /** + * The user that this pod represents. + * @type {!Object} + */ + user_: undefined, + get user() { + return this.user_; + }, + set user(userDict) { + this.user_ = userDict; + this.update(); + }, + }; + + var ManagerPodList = cr.ui.define('managerList'); + + /** + * UI element for selecting manager account for new managed user. + * @type {Object} + */ + ManagerPodList.prototype = { + __proto__: HTMLDivElement.prototype, + + selectedPod_: null, + + /** @override */ + decorate: function() { + }, + + /** + * Returns all the pods in this pod list. + * @type {NodeList} + */ + get pods() { + return this.children; + }, + + addPod: function(manager) { + var managerPod = new ManagerPod({user: manager}); + this.appendChild(managerPod); + managerPod.update(); + }, + + clearPods: function() { + this.innerHTML = ''; + this.selectedPod_ = null; + }, + + selectPod: function(podToSelect) { + if (this.selectedPod_ == podToSelect) { + podToSelect.focusInput(); + return; + } + this.selectedPod_ = podToSelect; + for (var i = 0, pod; pod = this.pods[i]; ++i) { + if (pod != podToSelect) { + pod.classList.remove('focused'); + pod.passwordElement.value = ''; + pod.passwordBlock.hidden = true; + } + } + podToSelect.classList.add('focused'); + podToSelect.passwordBlock.hidden = false; + podToSelect.passwordElement.value = ''; + podToSelect.focusInput(); + }, + }; + /** * Creates a new screen div. * @constructor @@ -26,10 +207,72 @@ cr.define('login', function() { LocallyManagedUserCreationScreen.prototype = { __proto__: HTMLDivElement.prototype, + lastVerifiedName_: null, + lastIncorrectUserName_: null, + managerList_: null, + useManagerBasedCreationFlow_: false, + /** @override */ decorate: function() { - //TODO(antrim) : add event listeners etc. - this.showFinishedMessage(); + this.managerList_ = new ManagerPodList(); + $('managed-user-creation-flow-managers-pane'). + appendChild(this.managerList_); + + var userNameField = $('managed-user-creation-flow-name'); + var passwordField = $('managed-user-creation-flow-password'); + var password2Field = $('managed-user-creation-flow-password-confirm'); + + var creationScreen = this; + + userNameField.addEventListener('keydown', function(e) { + if (e.keyIdentifier == 'Enter') { + if (userNameField.value.length > 0) + passwordField.focus(); + e.stopPropagation(); + return; + } + creationScreen.clearUserNameError_(); + }); + + userNameField.addEventListener('keyup', function(e) { + creationScreen.checkUserName_(); + }); + + passwordField.addEventListener('keydown', function(e) { + creationScreen.passwordErrorVisible = false; + if (e.keyIdentifier == 'Enter') { + if (passwordField.value.length > 0) { + password2Field.focus(); + creationScreen.updateContinueButton_(); + } + e.stopPropagation(); + } + }); + + password2Field.addEventListener('keydown', function(e) { + creationScreen.passwordErrorVisible = false; + if (e.keyIdentifier == 'Enter') { + if (creationScreen.useManagerBasedCreationFlow_) { + if (passwordField.value.length > 0) { + if (creationScreen.managerList_.selectedPod_) + creationScreen.managerList_.selectedPod_.focusInput(); + creationScreen.updateContinueButton_(); + } + } else { + if (creationScreen.updateContinueButton_()) + creationScreen.validateInputAndStartFlow_(); + } + e.stopPropagation(); + } + }); + + password2Field.addEventListener('keyup', function(e) { + creationScreen.updateContinueButton_(); + }); + + passwordField.addEventListener('keyup', function(e) { + creationScreen.updateContinueButton_(); + }); }, /** @@ -39,6 +282,14 @@ cr.define('login', function() { get buttons() { var buttons = []; + var proceedButton = this.ownerDocument.createElement('button'); + proceedButton.id = 'managed-user-creation-flow-proceed-button'; + + proceedButton.textContent = loadTimeData. + getString('managedUserCreationFlowProceedButtonTitle'); + proceedButton.hidden = true; + buttons.push(proceedButton); + var finishButton = this.ownerDocument.createElement('button'); finishButton.id = 'managed-user-creation-flow-finish-button'; @@ -68,6 +319,10 @@ cr.define('login', function() { creationFlowScreen.finishFlow_(); e.stopPropagation(); }); + proceedButton.addEventListener('click', function(e) { + creationFlowScreen.proceedFlow_(); + e.stopPropagation(); + }); retryButton.addEventListener('click', function(e) { creationFlowScreen.retryFlow_(); e.stopPropagation(); @@ -81,6 +336,175 @@ cr.define('login', function() { }, /** + * Does sanity check and calls backend with current user name/password pair + * to create a user. May result in showPasswordError. + * @private + */ + validateInputAndStartFlow_: function() { + var firstPassword = $('managed-user-creation-flow-password').value; + var secondPassword = + $('managed-user-creation-flow-password-confirm').value; + var userName = $('managed-user-creation-flow-name').value; + if (firstPassword != secondPassword) { + this.showPasswordError( + loadTimeData.getString('createManagedUserPasswordMismatchError')); + return; + } + if (!this.useManagerBasedCreationFlow_) { + this.disabled = true; + chrome.send('tryCreateLocallyManagedUser', [userName, firstPassword]); + } else { + var selectedPod = this.managerList_.selectedPod_; + if (null == selectedPod) + return; + + var managerId = selectedPod.user.emailAddress; + var managerPassword = selectedPod.passwordElement.value; + this.disabled = true; + // TODO(antrim) : we might use some minimal password validation + // (e.g. non-empty etc.) here. + chrome.send('runLocallyManagedUserCreationFlow', + [userName, firstPassword, managerId, managerPassword]); + } + }, + + /** + * Calls backend part to check if current user name is valid/not taken. + * Results in call to either managedUserNameOk or managedUserNameError. + * @private + */ + checkUserName_: function() { + var userName = $('managed-user-creation-flow-name').value; + + // Avoid flickering + if (userName == this.lastIncorrectUserName_ || + userName == this.lastVerifiedName_) { + return; + } + if (userName.length > 0) { + chrome.send('checkLocallyManagedUserName', [userName]); + } else { + this.nameErrorVisible = false; + this.lastVerifiedName_ = null; + this.lastIncorrectUserName_ = null; + } + }, + + /** + * Called by backend part in case of successful name validation. + * @param {string} name - name that was validated. + */ + managedUserNameOk: function(name) { + this.lastVerifiedName_ = name; + this.lastIncorrectUserName_ = null; + if ($('managed-user-creation-flow-name').value == name) + this.clearUserNameError_(); + this.updateContinueButton_(); + }, + + /** + * Called by backend part in case of name validation failure. + * @param {string} name - name that was validated. + * @param {string} errorText - reason why this name is invalid. + */ + managedUserNameError: function(name, errorText) { + this.lastIncorrectUserName_ = name; + this.lastVerifiedName_ = null; + + var userNameField = $('managed-user-creation-flow-name'); + if (userNameField.value == this.lastIncorrectUserName_) { + this.nameErrorVisible = true; + $('managed-user-creation-flow-name-error').textContent = errorText; + + this.setButtonDisabledStatus('proceed', true); + } + }, + + /** + * Clears user name error, if name is no more guaranteed to be invalid. + * @private + */ + clearUserNameError_: function() { + // Avoid flickering + if ($('managed-user-creation-flow-name').value == + this.lastIncorrectUserName_) { + return; + } + this.nameErrorVisible = false; + }, + + /** + * Called by backend part in case of password validation failure. + * @param {string} errorText - reason why this password is invalid. + */ + showPasswordError: function(errorText) { + $('managed-user-creation-flow-password-error').textContent = errorText; + this.passwordErrorVisible = true; + $('managed-user-creation-flow-password').focus(); + + this.setButtonDisabledStatus('proceed', true); + }, + + /** + * True if user name error should be displayed. + * @type {boolean} + */ + set nameErrorVisible(value) { + $('managed-user-creation-flow-name-error'). + classList[value ? 'add' : 'remove']('error'); + $('managed-user-creation-flow-name'). + classList[value ? 'add' : 'remove']('duplicate-name'); + if (!value) + $('managed-user-creation-flow-name-error').textContent = ''; + }, + + /** + * True if user name error should be displayed. + * @type {boolean} + */ + set passwordErrorVisible(value) { + $('managed-user-creation-flow-password-error'). + classList[value ? 'add' : 'remove']('error'); + if (!value) + $('managed-user-creation-flow-password-error').textContent = ''; + }, + + /** + * Updates state of Continue button after minimal checks. + * @return {boolean} true, if form seems to be valid. + * @private + */ + updateContinueButton_: function() { + var firstPassword = $('managed-user-creation-flow-password').value; + var secondPassword = + $('managed-user-creation-flow-password-confirm').value; + var userName = $('managed-user-creation-flow-name').value; + + var canProceed = + (firstPassword.length > 0) && + (firstPassword.length == secondPassword.length) && + this.lastVerifiedName_ && + (userName == this.lastVerifiedName_); + + if (this.useManagerBasedCreationFlow_) { + var selectedPod = this.managerList_.selectedPod_; + canProceed = canProceed && + null != selectedPod && + selectedPod.passwordElement.value.length > 0; + } + + this.setButtonDisabledStatus('proceed', !canProceed); + return canProceed; + }, + + showSelectedManagerPasswordError_: function() { + var selectedPod = this.managerList_.selectedPod_; + selectedPod.showPasswordError(); + selectedPod.passwordElement.value = ''; + selectedPod.focusInput(); + }, + + /** * Show final splash screen with success message. */ showFinishedMessage: function() { @@ -107,7 +531,7 @@ cr.define('login', function() { * @private */ setVisiblePage_: function(visiblePage) { - var screenNames = ['progress', 'error', 'success']; + var screenNames = ['initial', 'progress', 'error', 'success']; for (i in screenNames) { var screenName = screenNames[i]; var screen = $('managed-user-creation-flow-' + screenName); @@ -122,7 +546,7 @@ cr.define('login', function() { * @private */ setVisibleButtons_: function(buttonsList) { - var buttonNames = ['retry', 'finish', 'cancel']; + var buttonNames = ['proceed', 'retry', 'finish', 'cancel']; for (i in buttonNames) { var buttonName = buttonNames[i]; var button = $('managed-user-creation-flow-' + buttonName + '-button'); @@ -131,10 +555,19 @@ cr.define('login', function() { } }, + setButtonDisabledStatus: function(buttonName, status) { + var button = $('managed-user-creation-flow-' + buttonName + '-button'); + button.disabled = status; + }, + finishFlow_: function() { chrome.send('finishLocalManagedUserCreation'); }, + proceedFlow_: function() { + this.validateInputAndStartFlow_(); + }, + retryFlow_: function() { this.setVisiblePage_('progress'); chrome.send('retryLocalManagedUserCreation'); @@ -150,21 +583,124 @@ cr.define('login', function() { onBeforeShow: function(data) { $('login-header-bar').signinUIState = SIGNIN_UI_STATE.MANAGED_USER_CREATION_FLOW; + if (data['managers']) { + this.loadManagers(data['managers']); + } + }, + + /** + * Update state of login header so that necessary buttons are displayed. + */ + onBeforeHide: function() { + $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN; + }, + + /** + * Returns a control which should receive an initial focus. + */ + get defaultControl() { + return $('managed-user-creation-flow-name'); + }, + + /** + * True if the the screen is disabled (handles no user interaction). + * @type {boolean} + */ + disabled_: false, + + get disabled() { + return this.disabled_; }, + set disabled(value) { + this.disabled_ = value; + var controls = this.querySelectorAll('button,input'); + for (var i = 0, control; control = controls[i]; ++i) { + control.disabled = value; + } + $('login-header-bar').disabled = value; + }, + + /** + * Called by backend part to propagate list of possible managers. + * @param {Array} userList - list of users that can be managers. + */ + loadManagers: function(userList) { + $('managed-user-creation-flow-managers-block').hidden = false; + this.useManagerBasedCreationFlow_ = true; + this.managerList_.clearPods(); + for (var i = 0; i < userList.length; ++i) + this.managerList_.addPod(userList[i]); + if (userList.length > 0) + this.managerList_.selectPod(this.managerList_.pods[0]); + }, + }; + + LocallyManagedUserCreationScreen.showProgressScreen = function() { + var screen = $('managed-user-creation-flow'); + screen.disabled = false; + screen.setVisiblePage_('progress'); + screen.setVisibleButtons_(['cancel']); + }; + + LocallyManagedUserCreationScreen.showIntialScreen = function() { + var screen = $('managed-user-creation-flow'); + + $('managed-user-creation-flow-password').value = ''; + $('managed-user-creation-flow-password-confirm').value = ''; + $('managed-user-creation-flow-name').value = ''; + + screen.lastVerifiedName_ = null; + screen.lastIncorrectUserName_ = null; + screen.passwordErrorVisible = false; + screen.nameErrorVisible = false; + + screen.setButtonDisabledStatus('proceed', true); + + screen.setVisiblePage_('initial'); + screen.setVisibleButtons_(['proceed', 'cancel']); }; LocallyManagedUserCreationScreen.showFinishedMessage = function() { var screen = $('managed-user-creation-flow'); + screen.disabled = false; screen.showFinishedMessage(); }; + LocallyManagedUserCreationScreen.showManagerPasswordError = function() { + var screen = $('managed-user-creation-flow'); + screen.disabled = false; + screen.showSelectedManagerPasswordError_(); + }; + LocallyManagedUserCreationScreen.showErrorMessage = function(errorText, recoverable) { var screen = $('managed-user-creation-flow'); + screen.disabled = false; screen.showErrorMessage(errorText, recoverable); }; + LocallyManagedUserCreationScreen.managedUserNameOk = function(name) { + var screen = $('managed-user-creation-flow'); + screen.managedUserNameOk(name); + }; + + LocallyManagedUserCreationScreen.managedUserNameError = + function(name, error) { + var screen = $('managed-user-creation-flow'); + screen.managedUserNameError(name, error); + }; + + LocallyManagedUserCreationScreen.showPasswordError = function(error) { + var screen = $('managed-user-creation-flow'); + screen.showPasswordError(error); + }; + + LocallyManagedUserCreationScreen.loadManagers = function(userList) { + var screen = $('managed-user-creation-flow'); + screen.loadManagers(userList); + }; + return { LocallyManagedUserCreationScreen: LocallyManagedUserCreationScreen }; diff --git a/chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.cc index 71764de..d2fe2a9 100644 --- a/chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.cc @@ -6,8 +6,15 @@ #include <string> +#include "base/command_line.h" #include "base/values.h" +#include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.h" +#include "chrome/browser/chromeos/login/user_manager.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" +#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" +#include "chromeos/chromeos_switches.h" +#include "google_apis/gaia/gaia_auth_util.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" @@ -57,6 +64,34 @@ void LocallyManagedUserCreationScreenHandler::GetLocalizedStrings( "managedUserCreationFlowFinishButtonTitle", l10n_util::GetStringUTF16( IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_SUCCESS_BUTTON_TITLE)); + localized_strings->SetString("createManagedUserNameTitle", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_ACCOUNT_NAME_TITLE)); + localized_strings->SetString("createManagedUserPasswordTitle", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_TITLE)); + localized_strings->SetString("createManagedUserPasswordHint", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_HINT)); + localized_strings->SetString("createManagedUserPasswordConfirmHint", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_CONFIRM_HINT)); + localized_strings->SetString("managedUserCreationFlowProceedButtonTitle", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_CONTINUE_BUTTON_TEXT)); + localized_strings->SetString("createManagedUserPasswordMismatchError", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_MISMATCH_ERROR)); + + localized_strings->SetString("createManagedUserSelectManagerTitle", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_SELECT_MANAGER_TEXT)); + localized_strings->SetString("createManagedUserManagerPasswordHint", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_MANAGER_PASSWORD_HINT)); + localized_strings->SetString("createManagedUserWrongManagerPasswordText", + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_PASSWORD_ERROR)); } void LocallyManagedUserCreationScreenHandler::Initialize() {} @@ -77,16 +112,74 @@ void LocallyManagedUserCreationScreenHandler::RegisterMessages() { base::Bind(&LocallyManagedUserCreationScreenHandler:: HandleRetryLocalManagedUserCreation, base::Unretained(this))); + + web_ui()->RegisterMessageCallback("checkLocallyManagedUserName", + base::Bind(&LocallyManagedUserCreationScreenHandler:: + HandleCheckLocallyManagedUserName, + base::Unretained(this))); + web_ui()->RegisterMessageCallback("tryCreateLocallyManagedUser", + base::Bind(&LocallyManagedUserCreationScreenHandler:: + HandleTryCreateLocallyManagedUser, + base::Unretained(this))); + web_ui()->RegisterMessageCallback("runLocallyManagedUserCreationFlow", + base::Bind(&LocallyManagedUserCreationScreenHandler:: + HandleRunLocallyManagedUserCreationFlow, + base::Unretained(this))); } void LocallyManagedUserCreationScreenHandler::PrepareToShow() {} void LocallyManagedUserCreationScreenHandler::Show() { - ShowScreen(OobeUI::kScreenManagedUserCreationFlow, NULL); + const CommandLine* command_line = CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch( + chromeos::switches::kEnableLocallyManagedUserUIExperiments)) { + scoped_ptr<DictionaryValue> data(new base::DictionaryValue()); + scoped_ptr<ListValue> users_list(new base::ListValue()); + const UserList& users = UserManager::Get()->GetUsers(); + std::string owner; + chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner); + + for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { + if ((*it)->GetType() != User::USER_TYPE_REGULAR) + continue; + bool is_owner = ((*it)->email() == owner); + DictionaryValue* user_dict = new DictionaryValue(); + SigninScreenHandler::FillUserDictionary(*it, is_owner, user_dict); + users_list->Append(user_dict); + } + data->Set("managers", users_list.release()); + ShowScreen(OobeUI::kScreenManagedUserCreationFlow, data.get()); + } else { + ShowScreen(OobeUI::kScreenManagedUserCreationFlow, NULL); + } } void LocallyManagedUserCreationScreenHandler::Hide() {} +void LocallyManagedUserCreationScreenHandler::ShowInitialScreen() { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.showIntialScreen"); +} + + +void LocallyManagedUserCreationScreenHandler:: + ShowManagerInconsistentStateErrorScreen() { + ShowErrorMessage( + l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE), + false); +} + +void LocallyManagedUserCreationScreenHandler::ShowManagerPasswordError() { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.showManagerPasswordError"); +} + +void LocallyManagedUserCreationScreenHandler::ShowProgressScreen() { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.showProgressScreen"); +} + void LocallyManagedUserCreationScreenHandler::ShowSuccessMessage() { web_ui()->CallJavascriptFunction( "login.LocallyManagedUserCreationScreen.showFinishedMessage"); @@ -120,4 +213,107 @@ void LocallyManagedUserCreationScreenHandler:: delegate_->AbortFlow(); } +void LocallyManagedUserCreationScreenHandler::HandleCheckLocallyManagedUserName( + const base::ListValue* args) { + DCHECK(args && args->GetSize() == 1); + + string16 name; + if (!args->GetString(0, &name)) { + NOTREACHED(); + return; + } + if (NULL != UserManager::Get()-> + FindLocallyManagedUser(CollapseWhitespace(name, true))) { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.managedUserNameError", + base::StringValue(name), + base::StringValue(l10n_util::GetStringFUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_USERNAME_ALREADY_EXISTS, + name))); + } else { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.managedUserNameOk", + base::StringValue(name)); + } +} + +// TODO(antrim): Remove method once new managed-based flow is implemented. +void LocallyManagedUserCreationScreenHandler::HandleTryCreateLocallyManagedUser( + const base::ListValue* args) { + DCHECK(args && args->GetSize() == 2); + + string16 name; + std::string password; + if (!args->GetString(0, &name) || !args->GetString(1, &password)) { + NOTREACHED(); + return; + } + name = CollapseWhitespace(name, true); + if (NULL != UserManager::Get()->FindLocallyManagedUser(name)) { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.managedUserNameError", + base::StringValue(name), + base::StringValue(l10n_util::GetStringFUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_USERNAME_ALREADY_EXISTS, + name))); + return; + } + // TODO(antrim): Any other password checks here? + if (password.length() == 0) { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.showPasswordError", + base::StringValue(l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_TOO_SHORT))); + return; + } +} + +void LocallyManagedUserCreationScreenHandler:: + HandleRunLocallyManagedUserCreationFlow(const base::ListValue* args) { + if (!delegate_) + return; + DCHECK(args && args->GetSize() == 4); + + string16 new_user_name; + std::string new_user_password; + std::string custodian_username; + std::string custodian_password; + if (!args->GetString(0, &new_user_name) || + !args->GetString(1, &new_user_password) || + !args->GetString(2, &custodian_username) || + !args->GetString(3, &custodian_password)) { + NOTREACHED(); + return; + } + + new_user_name = CollapseWhitespace(new_user_name, true); + if (NULL != UserManager::Get()->FindLocallyManagedUser(new_user_name)) { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.managedUserNameError", + base::StringValue(new_user_name), + base::StringValue(l10n_util::GetStringFUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_USERNAME_ALREADY_EXISTS, + new_user_name))); + return; + } + + // TODO(antrim): Any other password checks here? + if (new_user_password.length() == 0) { + web_ui()->CallJavascriptFunction( + "login.LocallyManagedUserCreationScreen.showPasswordError", + base::StringValue(l10n_util::GetStringUTF16( + IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_TOO_SHORT))); + return; + } + + custodian_username = gaia::SanitizeEmail(custodian_username); + + UserFlow* flow = + new LocallyManagedUserCreationFlow(new_user_name, new_user_password); + UserManager::Get()->SetUserFlow(custodian_username, flow); + + delegate_->RunFlow(new_user_name, new_user_password, + custodian_username, custodian_password); +} + } // namespace chromeos diff --git a/chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h index b7b4ac3..456bb7f 100644 --- a/chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h @@ -31,6 +31,13 @@ class LocallyManagedUserCreationScreenHandler : public BaseScreenHandler { virtual void OnActorDestroyed( LocallyManagedUserCreationScreenHandler* actor) = 0; + // Starts managed user creation flow, with manager identified by + // |manager_id| and |manager_password|, and locally managed user that would + // have |display_name| and authenticated by the |managed_user_password|. + virtual void RunFlow(string16& display_name, + std::string& managed_user_password, + std::string& manager_id, + std::string& manager_password) = 0; virtual void AbortFlow() = 0; virtual void FinishFlow() = 0; virtual void RetryLastStep() = 0; @@ -44,6 +51,10 @@ class LocallyManagedUserCreationScreenHandler : public BaseScreenHandler { virtual void Hide(); virtual void SetDelegate(Delegate* delegate); + void ShowManagerInconsistentStateErrorScreen(); + void ShowManagerPasswordError(); + void ShowInitialScreen(); + void ShowProgressScreen(); virtual void ShowSuccessMessage(); virtual void ShowErrorMessage(string16 message, bool recoverable); @@ -61,6 +72,10 @@ class LocallyManagedUserCreationScreenHandler : public BaseScreenHandler { void HandleAbortLocalManagedUserCreation(const base::ListValue* args); void HandleRetryLocalManagedUserCreation(const base::ListValue* args); + void HandleCheckLocallyManagedUserName(const base::ListValue* args); + void HandleTryCreateLocallyManagedUser(const base::ListValue* args); + void HandleRunLocallyManagedUserCreationFlow(const base::ListValue* args); + Delegate* delegate_; DISALLOW_COPY_AND_ASSIGN(LocallyManagedUserCreationScreenHandler); diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 1400947..8ab51cd 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc @@ -28,10 +28,10 @@ #include "chrome/browser/chromeos/login/base_login_display_host.h" #include "chrome/browser/chromeos/login/error_screen_actor.h" #include "chrome/browser/chromeos/login/hwid_checker.h" -#include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.h" #include "chrome/browser/chromeos/login/screen_locker.h" #include "chrome/browser/chromeos/login/user.h" #include "chrome/browser/chromeos/login/webui_login_display.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/net/network_portal_detector.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/io_thread.h" @@ -452,32 +452,6 @@ void SigninScreenHandler::GetLocalizedStrings( l10n_util::GetStringUTF16( IDS_LOGIN_PUBLIC_ACCOUNT_ENTER_ACCESSIBLE_NAME)); - localized_strings->SetString("createManagedUserNameTitle", - l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_ACCOUNT_NAME_TITLE)); - localized_strings->SetString("createManagedUserPasswordTitle", - l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_TITLE)); - localized_strings->SetString("createManagedUserPasswordHint", - l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_HINT)); - localized_strings->SetString("createManagedUserPasswordConfirmHint", - l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_CONFIRM_HINT)); - localized_strings->SetString("createManagedUserContinueButton", - l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_CONTINUE_BUTTON_TEXT)); - localized_strings->SetString("createManagedUserPasswordMismatchError", - l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_MISMATCH_ERROR)); - - localized_strings->SetString("createManagedUserSelectManagerTitle", - l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_SELECT_MANAGER_TEXT)); - localized_strings->SetString("createManagedUserManagerPasswordHint", - l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_MANAGER_PASSWORD_HINT)); - if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled()) { localized_strings->SetString("demoLoginMessage", l10n_util::GetStringUTF16(IDS_KIOSK_MODE_LOGIN_MESSAGE)); @@ -885,15 +859,6 @@ void SigninScreenHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("updateOfflineLogin", base::Bind(&SigninScreenHandler::HandleUpdateOfflineLogin, base::Unretained(this))); - web_ui()->RegisterMessageCallback("checkLocallyManagedUserName", - base::Bind(&SigninScreenHandler::HandleCheckLocallyManagedUserName, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("tryCreateLocallyManagedUser", - base::Bind(&SigninScreenHandler::HandleTryCreateLocallyManagedUser, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("runLocallyManagedUserCreationFlow", - base::Bind(&SigninScreenHandler::HandleRunLocallyManagedUserCreationFlow, - base::Unretained(this))); } void SigninScreenHandler::HandleGetUsers(const base::ListValue* args) { @@ -1219,27 +1184,9 @@ void SigninScreenHandler::HandleLaunchIncognito(const base::ListValue* args) { void SigninScreenHandler::HandleShowLocallyManagedUserCreationScreen( const base::ListValue* args) { - const CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch( - chromeos::switches::kEnableLocallyManagedUserUIExperiments)) { - ListValue users_list; - const UserList& users = delegate_->GetUsers(); - std::string owner; - chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner); - - for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { - if ((*it)->GetType() != User::USER_TYPE_REGULAR) - continue; - bool is_owner = ((*it)->email() == owner); - DictionaryValue* user_dict = new DictionaryValue(); - FillUserDictionary(*it, is_owner, user_dict); - users_list.Append(user_dict); - } - web_ui()-> - CallJavascriptFunction("login.ManagedUserCreationScreen.loadManagers", - users_list); - } - UpdateUIState(UI_STATE_LOCALLY_MANAGED_USER_CREATION, NULL); + BaseLoginDisplayHost::default_host()-> + StartWizard(WizardController::kLocallyManagedUserCreationScreenName, + NULL); } void SigninScreenHandler::HandleLaunchPublicAccount( @@ -1662,110 +1609,6 @@ void SigninScreenHandler::HandleUpdateOfflineLogin( offline_login_active_ = offline_login_active; } -void SigninScreenHandler::HandleCheckLocallyManagedUserName( - const base::ListValue* args) { - DCHECK(args && args->GetSize() == 1); - - string16 name; - if (!args->GetString(0, &name)) { - NOTREACHED(); - return; - } - if (NULL != UserManager::Get()-> - FindLocallyManagedUser(CollapseWhitespace(name, true))) { - web_ui()->CallJavascriptFunction( - "login.ManagedUserCreationScreen.managedUserNameError", - base::StringValue(name), - base::StringValue(l10n_util::GetStringFUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_USERNAME_ALREADY_EXISTS, - name))); - } else { - web_ui()->CallJavascriptFunction( - "login.ManagedUserCreationScreen.managedUserNameOk", - base::StringValue(name)); - } -} - -void SigninScreenHandler::HandleTryCreateLocallyManagedUser( - const base::ListValue* args) { - DCHECK(args && args->GetSize() == 2); - - string16 name; - std::string password; - if (!args->GetString(0, &name) || !args->GetString(1, &password)) { - NOTREACHED(); - return; - } - name = CollapseWhitespace(name, true); - if (NULL != UserManager::Get()->FindLocallyManagedUser(name)) { - web_ui()->CallJavascriptFunction( - "login.ManagedUserCreationScreen.managedUserNameError", - base::StringValue(name), - base::StringValue(l10n_util::GetStringFUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_USERNAME_ALREADY_EXISTS, - name))); - return; - } - // TODO(antrim): Any other password checks here? - if (password.length() == 0) { - web_ui()->CallJavascriptFunction( - "login.ManagedUserCreationScreen.showPasswordError", - base::StringValue(l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_TOO_SHORT))); - return; - } - - if (delegate_) - delegate_->CreateLocallyManagedUser(name, password); -} - -void SigninScreenHandler::HandleRunLocallyManagedUserCreationFlow( - const base::ListValue* args) { - if (!delegate_) - return; - DCHECK(args && args->GetSize() == 4); - - string16 new_user_name; - std::string new_user_password; - std::string custodian_username; - std::string custodian_password; - if (!args->GetString(0, &new_user_name) || - !args->GetString(1, &new_user_password) || - !args->GetString(2, &custodian_username) || - !args->GetString(3, &custodian_password)) { - NOTREACHED(); - return; - } - - new_user_name = CollapseWhitespace(new_user_name, true); - if (NULL != UserManager::Get()->FindLocallyManagedUser(new_user_name)) { - web_ui()->CallJavascriptFunction( - "login.ManagedUserCreationScreen.managedUserNameError", - base::StringValue(new_user_name), - base::StringValue(l10n_util::GetStringFUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_USERNAME_ALREADY_EXISTS, - new_user_name))); - return; - } - - // TODO(antrim): Any other password checks here? - if (new_user_password.length() == 0) { - web_ui()->CallJavascriptFunction( - "login.ManagedUserCreationScreen.showPasswordError", - base::StringValue(l10n_util::GetStringUTF16( - IDS_CREATE_LOCALLY_MANAGED_USER_CREATE_PASSWORD_TOO_SHORT))); - return; - } - - custodian_username = gaia::SanitizeEmail(custodian_username); - - UserFlow* flow = - new LocallyManagedUserCreationFlow(new_user_name, new_user_password); - UserManager::Get()->SetUserFlow(custodian_username, flow); - - delegate_->Login(custodian_username, custodian_password); -} - void SigninScreenHandler::StartClearingDnsCache() { if (dns_clear_task_running_ || !g_browser_process->io_thread()) return; diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h index 1e138ff..d22b9f4 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h @@ -36,6 +36,7 @@ namespace chromeos { class CaptivePortalWindowProxy; class ErrorScreenActor; +class LocallyManagedUserCreationScreenHandler; class NativeWindowDelegate; class User; @@ -200,6 +201,7 @@ class SigninScreenHandler typedef base::hash_set<std::string> WebUIObservers; friend class ReportDnsCacheClearedOnUIThread; + friend class LocallyManagedUserCreationScreenHandler; // Updates current UI of the signin screen according to |ui_state| // argument. Optionally it can pass screen initialization data via @@ -314,14 +316,11 @@ class SigninScreenHandler void HandleShowLoadingTimeoutError(const base::ListValue* args); void HandleUpdateOfflineLogin(const base::ListValue* args); void HandleShowLocallyManagedUserCreationScreen(const base::ListValue* args); - void HandleCheckLocallyManagedUserName(const base::ListValue* args); - void HandleTryCreateLocallyManagedUser(const base::ListValue* args); - void HandleRunLocallyManagedUserCreationFlow(const base::ListValue* args); // Fills |user_dict| with information about |user|. - void FillUserDictionary(User* user, - bool is_owner, - DictionaryValue* user_dict); + static void FillUserDictionary(User* user, + bool is_owner, + DictionaryValue* user_dict); // Sends user list to account picker. void SendUserList(bool animated); diff --git a/chromeos/cryptohome/async_method_caller.cc b/chromeos/cryptohome/async_method_caller.cc index aa25658..4de4f76 100644 --- a/chromeos/cryptohome/async_method_caller.cc +++ b/chromeos/cryptohome/async_method_caller.cc @@ -131,6 +131,24 @@ class AsyncMethodCallerImpl : public AsyncMethodCaller { "Couldn't initiate async attestation finish cert request.")); } + virtual void AsyncGetSanitizedUsername( + const std::string& user, + const DataCallback& callback) OVERRIDE { + DBusThreadManager::Get()->GetCryptohomeClient()-> + GetSanitizedUsername(user, + base::Bind( + &AsyncMethodCallerImpl::GetSanitizedUsernameCallback, + weak_ptr_factory_.GetWeakPtr(), + callback)); + } + + virtual void GetSanitizedUsernameCallback( + const DataCallback& callback, + const chromeos::DBusMethodCallStatus call_status, + const std::string& result) { + callback.Run(true, result); + } + private: struct CallbackElement { CallbackElement() {} diff --git a/chromeos/cryptohome/async_method_caller.h b/chromeos/cryptohome/async_method_caller.h index c6956ff..78ff687 100644 --- a/chromeos/cryptohome/async_method_caller.h +++ b/chromeos/cryptohome/async_method_caller.h @@ -110,6 +110,13 @@ class CHROMEOS_EXPORT AsyncMethodCaller { const std::string& pca_response, const DataCallback& callback) = 0; + // Asks cryptohome to asynchronously retrieve a string associated with given + // |user| that would be used in mount path instead of |user|. + // On success the data is sent to |callback|. + virtual void AsyncGetSanitizedUsername( + const std::string& user, + const DataCallback& callback) = 0; + // Creates the global AsyncMethodCaller instance. static void Initialize(); diff --git a/chromeos/cryptohome/mock_async_method_caller.cc b/chromeos/cryptohome/mock_async_method_caller.cc index ce02bd3..e17da7f 100644 --- a/chromeos/cryptohome/mock_async_method_caller.cc +++ b/chromeos/cryptohome/mock_async_method_caller.cc @@ -13,6 +13,7 @@ namespace cryptohome { const char MockAsyncMethodCaller::kFakeAttestationEnrollRequest[] = "enrollreq"; const char MockAsyncMethodCaller::kFakeAttestationCertRequest[] = "certreq"; const char MockAsyncMethodCaller::kFakeAttestationCert[] = "cert"; +const char MockAsyncMethodCaller::kFakeSanitizedUsername[] = "01234567890ABC"; MockAsyncMethodCaller::MockAsyncMethodCaller() : success_(false), return_code_(cryptohome::MOUNT_ERROR_NONE) { @@ -53,6 +54,11 @@ void MockAsyncMethodCaller::SetUp(bool success, MountError return_code) { .WillByDefault( WithArgs<1>(Invoke(this, &MockAsyncMethodCaller::FakeFinishCertRequest))); + ON_CALL(*this, AsyncGetSanitizedUsername(_, _)) + .WillByDefault( + WithArgs<1>(Invoke(this, + &MockAsyncMethodCaller:: + FakeGetSanitizedUsername))); } void MockAsyncMethodCaller::DoCallback(Callback callback) { @@ -74,4 +80,9 @@ void MockAsyncMethodCaller::FakeFinishCertRequest( callback.Run(success_, kFakeAttestationCert); } +void MockAsyncMethodCaller::FakeGetSanitizedUsername( + const DataCallback& callback) { + callback.Run(success_, kFakeSanitizedUsername); +} + } // namespace cryptohome diff --git a/chromeos/cryptohome/mock_async_method_caller.h b/chromeos/cryptohome/mock_async_method_caller.h index 2e8d352..62df8e4 100644 --- a/chromeos/cryptohome/mock_async_method_caller.h +++ b/chromeos/cryptohome/mock_async_method_caller.h @@ -19,6 +19,7 @@ class MockAsyncMethodCaller : public AsyncMethodCaller { static const char kFakeAttestationEnrollRequest[]; static const char kFakeAttestationCertRequest[]; static const char kFakeAttestationCert[]; + static const char kFakeSanitizedUsername[]; MockAsyncMethodCaller(); virtual ~MockAsyncMethodCaller(); @@ -48,6 +49,9 @@ class MockAsyncMethodCaller : public AsyncMethodCaller { MOCK_METHOD2(AsyncTpmAttestationFinishCertRequest, void(const std::string& pca_response, const DataCallback& callback)); + MOCK_METHOD2(AsyncGetSanitizedUsername, + void(const std::string& user, + const DataCallback& callback)); private: bool success_; @@ -58,6 +62,7 @@ class MockAsyncMethodCaller : public AsyncMethodCaller { void FakeCreateEnrollRequest(const DataCallback& callback); void FakeCreateCertRequest(const DataCallback& callback); void FakeFinishCertRequest(const DataCallback& callback); + void FakeGetSanitizedUsername(const DataCallback& callback); DISALLOW_COPY_AND_ASSIGN(MockAsyncMethodCaller); }; |