summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/chromeos_strings.grdp6
-rw-r--r--chrome/browser/chromeos/login/base_login_display_host.cc4
-rw-r--r--chrome/browser/chromeos/login/base_login_display_host.h1
-rw-r--r--chrome/browser/chromeos/login/existing_user_controller.cc10
-rw-r--r--chrome/browser/chromeos/login/login_display_host.h6
-rw-r--r--chrome/browser/chromeos/login/login_status_consumer.h2
-rw-r--r--chrome/browser/chromeos/login/login_utils.cc2
-rw-r--r--chrome/browser/chromeos/login/managed/locally_managed_user_controller.cc44
-rw-r--r--chrome/browser/chromeos/login/managed/locally_managed_user_controller.h19
-rw-r--r--chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.cc38
-rw-r--r--chrome/browser/chromeos/login/managed/locally_managed_user_creation_flow.h5
-rw-r--r--chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.cc55
-rw-r--r--chrome/browser/chromeos/login/managed/locally_managed_user_creation_screen.h28
-rw-r--r--chrome/browser/chromeos/login/managed/managed_user_authenticator.cc50
-rw-r--r--chrome/browser/chromeos/login/managed/managed_user_authenticator.h16
-rw-r--r--chrome/browser/chromeos/login/mock_login_display_host.h1
-rw-r--r--chrome/browser/chromeos/login/mount_manager.cc19
-rw-r--r--chrome/browser/chromeos/login/mount_manager.h6
-rw-r--r--chrome/browser/chromeos/login/user_flow.cc11
-rw-r--r--chrome/browser/chromeos/login/user_flow.h12
-rw-r--r--chrome/browser/chromeos/login/wizard_controller.cc10
-rw-r--r--chrome/browser/resources/chromeos/login/login.html2
-rw-r--r--chrome/browser/resources/chromeos/login/login.js2
-rw-r--r--chrome/browser/resources/chromeos/login/managed_user_creation.css101
-rw-r--r--chrome/browser/resources/chromeos/login/managed_user_creation.html43
-rw-r--r--chrome/browser/resources/chromeos/login/managed_user_creation.js526
-rw-r--r--chrome/browser/resources/chromeos/login/oobe.html2
-rw-r--r--chrome/browser/resources/chromeos/login/oobe.js2
-rw-r--r--chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css95
-rw-r--r--chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.html48
-rw-r--r--chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.js544
-rw-r--r--chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.cc198
-rw-r--r--chrome/browser/ui/webui/chromeos/login/locally_managed_user_creation_screen_handler.h15
-rw-r--r--chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc165
-rw-r--r--chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h11
-rw-r--r--chromeos/cryptohome/async_method_caller.cc18
-rw-r--r--chromeos/cryptohome/async_method_caller.h7
-rw-r--r--chromeos/cryptohome/mock_async_method_caller.cc11
-rw-r--r--chromeos/cryptohome/mock_async_method_caller.h5
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);
};