Commit 77f04217 authored by Jacob Dufault's avatar Jacob Dufault Committed by Commit Bot

cros: Show gaia auth on login if user mistypes password 4 times in a row.

Bug: 784495
Change-Id: Iced3219a6e837e5abe4ed122d32086b9bc3f961c
Reviewed-on: https://chromium-review.googlesource.com/1012575Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Jacob Dufault <jdufault@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565132}
parent f47f082d
...@@ -242,11 +242,16 @@ LockContentsView::UserState::UserState(UserState&&) = default; ...@@ -242,11 +242,16 @@ LockContentsView::UserState::UserState(UserState&&) = default;
LockContentsView::UserState::~UserState() = default; LockContentsView::UserState::~UserState() = default;
// static
const int LockContentsView::kLoginAttemptsBeforeGaiaDialog = 4;
LockContentsView::LockContentsView( LockContentsView::LockContentsView(
mojom::TrayActionState initial_note_action_state, mojom::TrayActionState initial_note_action_state,
LockScreen::ScreenType screen_type,
LoginDataDispatcher* data_dispatcher, LoginDataDispatcher* data_dispatcher,
std::unique_ptr<LoginDetachableBaseModel> detachable_base_model) std::unique_ptr<LoginDetachableBaseModel> detachable_base_model)
: NonAccessibleView(kLockContentsViewName), : NonAccessibleView(kLockContentsViewName),
screen_type_(screen_type),
data_dispatcher_(data_dispatcher), data_dispatcher_(data_dispatcher),
detachable_base_model_(std::move(detachable_base_model)), detachable_base_model_(std::move(detachable_base_model)),
display_observer_(this), display_observer_(this),
...@@ -703,7 +708,7 @@ void LockContentsView::OnFingerprintUnlockStateChanged( ...@@ -703,7 +708,7 @@ void LockContentsView::OnFingerprintUnlockStateChanged(
void LockContentsView::SetAvatarForUser(const AccountId& account_id, void LockContentsView::SetAvatarForUser(const AccountId& account_id,
const mojom::UserAvatarPtr& avatar) { const mojom::UserAvatarPtr& avatar) {
auto replace = [&](const ash::mojom::LoginUserInfoPtr& user) { auto replace = [&](const mojom::LoginUserInfoPtr& user) {
auto changed = user->Clone(); auto changed = user->Clone();
changed->basic_user_info->avatar = avatar->Clone(); changed->basic_user_info->avatar = avatar->Clone();
return changed; return changed;
...@@ -958,8 +963,8 @@ void LockContentsView::OnAuthenticate(bool auth_success) { ...@@ -958,8 +963,8 @@ void LockContentsView::OnAuthenticate(bool auth_success) {
*CurrentBigUserView()->GetCurrentUser()->basic_user_info); *CurrentBigUserView()->GetCurrentUser()->basic_user_info);
} }
} else { } else {
ShowAuthErrorMessage();
++unlock_attempt_; ++unlock_attempt_;
ShowAuthErrorMessage();
} }
} }
...@@ -1092,9 +1097,17 @@ void LockContentsView::ShowAuthErrorMessage() { ...@@ -1092,9 +1097,17 @@ void LockContentsView::ShowAuthErrorMessage() {
if (!big_view->auth_user()) if (!big_view->auth_user())
return; return;
// Show gaia signin if this is login and the user has failed too many times.
if (screen_type_ == LockScreen::ScreenType::kLogin &&
unlock_attempt_ >= kLoginAttemptsBeforeGaiaDialog) {
Shell::Get()->login_screen_controller()->ShowGaiaSignin(
big_view->auth_user()->current_user()->basic_user_info->account_id);
return;
}
base::string16 error_text = l10n_util::GetStringUTF16( base::string16 error_text = l10n_util::GetStringUTF16(
unlock_attempt_ ? IDS_ASH_LOGIN_ERROR_AUTHENTICATING_2ND_TIME unlock_attempt_ > 1 ? IDS_ASH_LOGIN_ERROR_AUTHENTICATING_2ND_TIME
: IDS_ASH_LOGIN_ERROR_AUTHENTICATING); : IDS_ASH_LOGIN_ERROR_AUTHENTICATING);
ImeController* ime_controller = Shell::Get()->ime_controller(); ImeController* ime_controller = Shell::Get()->ime_controller();
if (ime_controller->IsCapsLockEnabled()) { if (ime_controller->IsCapsLockEnabled()) {
error_text += base::ASCIIToUTF16(" ") + error_text += base::ASCIIToUTF16(" ") +
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/login/login_screen_controller.h" #include "ash/login/login_screen_controller.h"
#include "ash/login/login_screen_controller_observer.h" #include "ash/login/login_screen_controller_observer.h"
#include "ash/login/ui/lock_screen.h"
#include "ash/login/ui/login_data_dispatcher.h" #include "ash/login/ui/login_data_dispatcher.h"
#include "ash/login/ui/login_display_style.h" #include "ash/login/ui/login_display_style.h"
#include "ash/login/ui/non_accessible_view.h" #include "ash/login/ui/non_accessible_view.h"
...@@ -100,8 +101,15 @@ class ASH_EXPORT LockContentsView ...@@ -100,8 +101,15 @@ class ASH_EXPORT LockContentsView
kExclusivePublicAccountExpandedView, kExclusivePublicAccountExpandedView,
}; };
// Number of login attempts before a login dialog is shown. For example, if
// this value is 4 then the user can submit their password 4 times, and on the
// 4th bad attempt the login dialog is shown. This only applies to the login
// screen.
static const int kLoginAttemptsBeforeGaiaDialog;
LockContentsView( LockContentsView(
mojom::TrayActionState initial_note_action_state, mojom::TrayActionState initial_note_action_state,
LockScreen::ScreenType screen_type,
LoginDataDispatcher* data_dispatcher, LoginDataDispatcher* data_dispatcher,
std::unique_ptr<LoginDetachableBaseModel> detachable_base_model); std::unique_ptr<LoginDetachableBaseModel> detachable_base_model);
~LockContentsView() override; ~LockContentsView() override;
...@@ -329,6 +337,8 @@ class ASH_EXPORT LockContentsView ...@@ -329,6 +337,8 @@ class ASH_EXPORT LockContentsView
// All the subsequent calls of |OnLockScreenNoteStateChanged| will be ignored. // All the subsequent calls of |OnLockScreenNoteStateChanged| will be ignored.
void DisableLockScreenNote(); void DisableLockScreenNote();
const LockScreen::ScreenType screen_type_;
std::vector<UserState> users_; std::vector<UserState> users_;
LoginDataDispatcher* const data_dispatcher_; // Unowned. LoginDataDispatcher* const data_dispatcher_; // Unowned.
......
This diff is collapsed.
...@@ -457,6 +457,7 @@ class LockDebugView::DebugLoginDetachableBaseModel ...@@ -457,6 +457,7 @@ class LockDebugView::DebugLoginDetachableBaseModel
}; };
LockDebugView::LockDebugView(mojom::TrayActionState initial_note_action_state, LockDebugView::LockDebugView(mojom::TrayActionState initial_note_action_state,
LockScreen::ScreenType screen_type,
LoginDataDispatcher* data_dispatcher) LoginDataDispatcher* data_dispatcher)
: debug_data_dispatcher_(std::make_unique<DebugDataDispatcherTransformer>( : debug_data_dispatcher_(std::make_unique<DebugDataDispatcherTransformer>(
initial_note_action_state, initial_note_action_state,
...@@ -468,7 +469,7 @@ LockDebugView::LockDebugView(mojom::TrayActionState initial_note_action_state, ...@@ -468,7 +469,7 @@ LockDebugView::LockDebugView(mojom::TrayActionState initial_note_action_state,
std::make_unique<DebugLoginDetachableBaseModel>(data_dispatcher); std::make_unique<DebugLoginDetachableBaseModel>(data_dispatcher);
debug_detachable_base_model_ = debug_detachable_base_model.get(); debug_detachable_base_model_ = debug_detachable_base_model.get();
lock_ = new LockContentsView(initial_note_action_state, lock_ = new LockContentsView(initial_note_action_state, screen_type,
debug_data_dispatcher_->debug_dispatcher(), debug_data_dispatcher_->debug_dispatcher(),
std::move(debug_detachable_base_model)); std::move(debug_detachable_base_model));
AddChildView(lock_); AddChildView(lock_);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/detachable_base/detachable_base_pairing_status.h" #include "ash/detachable_base/detachable_base_pairing_status.h"
#include "ash/login/login_screen_controller.h" #include "ash/login/login_screen_controller.h"
#include "ash/login/ui/lock_screen.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
#include "ui/views/view.h" #include "ui/views/view.h"
...@@ -31,6 +32,7 @@ enum class TrayActionState; ...@@ -31,6 +32,7 @@ enum class TrayActionState;
class LockDebugView : public views::View, public views::ButtonListener { class LockDebugView : public views::View, public views::ButtonListener {
public: public:
LockDebugView(mojom::TrayActionState initial_note_action_state, LockDebugView(mojom::TrayActionState initial_note_action_state,
LockScreen::ScreenType screen_type,
LoginDataDispatcher* data_dispatcher); LoginDataDispatcher* data_dispatcher);
~LockDebugView() override; ~LockDebugView() override;
......
...@@ -77,16 +77,16 @@ void LockScreen::Show(ScreenType type) { ...@@ -77,16 +77,16 @@ void LockScreen::Show(ScreenType type) {
Shell::Get()->tray_action()->GetLockScreenNoteState(); Shell::Get()->tray_action()->GetLockScreenNoteState();
if (base::CommandLine::ForCurrentProcess()->HasSwitch( if (base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kShowLoginDevOverlay)) { chromeos::switches::kShowLoginDevOverlay)) {
auto* debug_view = auto* debug_view = new LockDebugView(initial_note_action_state, type,
new LockDebugView(initial_note_action_state, data_dispatcher.get()); data_dispatcher.get());
instance_->contents_view_ = debug_view->lock(); instance_->contents_view_ = debug_view->lock();
instance_->window_->SetContentsView(debug_view); instance_->window_->SetContentsView(debug_view);
} else { } else {
auto detachable_base_model = LoginDetachableBaseModel::Create( auto detachable_base_model = LoginDetachableBaseModel::Create(
Shell::Get()->detachable_base_handler(), data_dispatcher.get()); Shell::Get()->detachable_base_handler(), data_dispatcher.get());
instance_->contents_view_ = instance_->contents_view_ = new LockContentsView(
new LockContentsView(initial_note_action_state, data_dispatcher.get(), initial_note_action_state, type, data_dispatcher.get(),
std::move(detachable_base_model)); std::move(detachable_base_model));
instance_->window_->SetContentsView(instance_->contents_view_); instance_->window_->SetContentsView(instance_->contents_view_);
} }
......
...@@ -58,6 +58,8 @@ class ASH_EXPORT LockScreen : public TrayActionObserver, ...@@ -58,6 +58,8 @@ class ASH_EXPORT LockScreen : public TrayActionObserver,
// Destroys an existing lock screen instance. // Destroys an existing lock screen instance.
void Destroy(); void Destroy();
ScreenType screen_type() const { return type_; }
// Enables/disables background blur. Used for debugging purpose. // Enables/disables background blur. Used for debugging purpose.
void ToggleBlurForDebug(); void ToggleBlurForDebug();
......
...@@ -108,7 +108,8 @@ testing::AssertionResult VerifyNotFocused(views::View* view) { ...@@ -108,7 +108,8 @@ testing::AssertionResult VerifyNotFocused(views::View* view) {
TEST_F(LockScreenSanityTest, PasswordIsInitiallyFocused) { TEST_F(LockScreenSanityTest, PasswordIsInitiallyFocused) {
// Build lock screen. // Build lock screen.
auto* contents = new LockContentsView( auto* contents = new LockContentsView(
mojom::TrayActionState::kNotAvailable, data_dispatcher(), mojom::TrayActionState::kNotAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
// The lock screen requires at least one user. // The lock screen requires at least one user.
...@@ -126,7 +127,8 @@ TEST_F(LockScreenSanityTest, PasswordIsInitiallyFocused) { ...@@ -126,7 +127,8 @@ TEST_F(LockScreenSanityTest, PasswordIsInitiallyFocused) {
TEST_F(LockScreenSanityTest, PasswordSubmitCallsLoginScreenClient) { TEST_F(LockScreenSanityTest, PasswordSubmitCallsLoginScreenClient) {
// Build lock screen. // Build lock screen.
auto* contents = new LockContentsView( auto* contents = new LockContentsView(
mojom::TrayActionState::kNotAvailable, data_dispatcher(), mojom::TrayActionState::kNotAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
// The lock screen requires at least one user. // The lock screen requires at least one user.
...@@ -153,7 +155,8 @@ TEST_F(LockScreenSanityTest, ...@@ -153,7 +155,8 @@ TEST_F(LockScreenSanityTest,
std::unique_ptr<MockLoginScreenClient> client = BindMockLoginScreenClient(); std::unique_ptr<MockLoginScreenClient> client = BindMockLoginScreenClient();
auto* contents = new LockContentsView( auto* contents = new LockContentsView(
mojom::TrayActionState::kAvailable, data_dispatcher(), mojom::TrayActionState::kAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
SetUserCount(1); SetUserCount(1);
std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(contents); std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(contents);
...@@ -207,7 +210,8 @@ TEST_F(LockScreenSanityTest, TabGoesFromLockToShelfAndBackToLock) { ...@@ -207,7 +210,8 @@ TEST_F(LockScreenSanityTest, TabGoesFromLockToShelfAndBackToLock) {
// Create lock screen. // Create lock screen.
auto* lock = new LockContentsView( auto* lock = new LockContentsView(
mojom::TrayActionState::kNotAvailable, data_dispatcher(), mojom::TrayActionState::kNotAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
SetUserCount(1); SetUserCount(1);
std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(lock); std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(lock);
...@@ -239,7 +243,8 @@ TEST_F(LockScreenSanityTest, ShiftTabGoesFromLockToStatusAreaAndBackToLock) { ...@@ -239,7 +243,8 @@ TEST_F(LockScreenSanityTest, ShiftTabGoesFromLockToStatusAreaAndBackToLock) {
session_manager::SessionState::LOCKED); session_manager::SessionState::LOCKED);
auto* lock = new LockContentsView( auto* lock = new LockContentsView(
mojom::TrayActionState::kNotAvailable, data_dispatcher(), mojom::TrayActionState::kNotAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
SetUserCount(1); SetUserCount(1);
std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(lock); std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(lock);
...@@ -269,7 +274,8 @@ TEST_F(LockScreenSanityTest, TabWithLockScreenAppActive) { ...@@ -269,7 +274,8 @@ TEST_F(LockScreenSanityTest, TabWithLockScreenAppActive) {
session_manager::SessionState::LOCKED); session_manager::SessionState::LOCKED);
auto* lock = new LockContentsView( auto* lock = new LockContentsView(
mojom::TrayActionState::kNotAvailable, data_dispatcher(), mojom::TrayActionState::kNotAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
SetUserCount(1); SetUserCount(1);
std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(lock); std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(lock);
...@@ -340,7 +346,8 @@ TEST_F(LockScreenSanityTest, FocusLockScreenWhenLockScreenAppExit) { ...@@ -340,7 +346,8 @@ TEST_F(LockScreenSanityTest, FocusLockScreenWhenLockScreenAppExit) {
GetSessionControllerClient()->SetSessionState( GetSessionControllerClient()->SetSessionState(
session_manager::SessionState::LOCKED); session_manager::SessionState::LOCKED);
auto* lock = new LockContentsView( auto* lock = new LockContentsView(
mojom::TrayActionState::kNotAvailable, data_dispatcher(), mojom::TrayActionState::kNotAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
SetUserCount(1); SetUserCount(1);
std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(lock); std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(lock);
...@@ -379,7 +386,8 @@ TEST_F(LockScreenSanityTest, RemoveUser) { ...@@ -379,7 +386,8 @@ TEST_F(LockScreenSanityTest, RemoveUser) {
ash::Shell::Get()->login_screen_controller(); ash::Shell::Get()->login_screen_controller();
auto* contents = new LockContentsView( auto* contents = new LockContentsView(
mojom::TrayActionState::kAvailable, data_dispatcher(), mojom::TrayActionState::kAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
// Add two users, the first of which can be removed. // Add two users, the first of which can be removed.
......
...@@ -112,7 +112,8 @@ TEST_F(LoginMetricsRecorderTest, UnlockAttempts) { ...@@ -112,7 +112,8 @@ TEST_F(LoginMetricsRecorderTest, UnlockAttempts) {
std::unique_ptr<MockLoginScreenClient> client = BindMockLoginScreenClient(); std::unique_ptr<MockLoginScreenClient> client = BindMockLoginScreenClient();
client->set_authenticate_user_callback_result(false); client->set_authenticate_user_callback_result(false);
auto* contents = new LockContentsView( auto* contents = new LockContentsView(
mojom::TrayActionState::kNotAvailable, data_dispatcher(), mojom::TrayActionState::kNotAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
LockContentsView::TestApi test_api(contents); LockContentsView::TestApi test_api(contents);
SetUserCount(1); SetUserCount(1);
...@@ -195,7 +196,8 @@ TEST_F(LoginMetricsRecorderTest, NoteActionButtonClick) { ...@@ -195,7 +196,8 @@ TEST_F(LoginMetricsRecorderTest, NoteActionButtonClick) {
session_manager::SessionState::LOCKED); session_manager::SessionState::LOCKED);
auto* contents = new LockContentsView( auto* contents = new LockContentsView(
mojom::TrayActionState::kAvailable, data_dispatcher(), mojom::TrayActionState::kAvailable, LockScreen::ScreenType::kLock,
data_dispatcher(),
std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher())); std::make_unique<FakeLoginDetachableBaseModel>(data_dispatcher()));
SetUserCount(1); SetUserCount(1);
std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(contents); std::unique_ptr<views::Widget> widget = CreateWidgetWithContent(contents);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment