Commit f4d1fe5f authored by Yicheng Li's avatar Yicheng Li Committed by Commit Bot

ash: Check PIN/fingerprint availability in in-session auth

In the in-session auth dialog, show PIN view only if PIN is set, and
show fingerprint view only if fingerprint is set.

      icon are not shown. Delete PIN, verify that PIN pad is not shown.

Bug: b:156258540
Test: On Nami, delete fingerprint, verify that fingerprint prompt and
Change-Id: I55604aeb9e66f04a2f49ffbb5e5160b6158a40d6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2351120
Commit-Queue: Yicheng Li <yichengli@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797721}
parent 9117519e
......@@ -99,7 +99,10 @@ class AuthDialogDebugView::FingerprintView : public views::View {
AnimatedRoundedImageView* icon_ = nullptr;
};
AuthDialogDebugView::AuthDialogDebugView() {
AuthDialogDebugView::AuthDialogDebugView(uint32_t auth_methods)
: auth_methods_(auth_methods) {
DCHECK(auth_methods_ & kAuthPassword);
SetLayoutManager(std::make_unique<views::FillLayout>());
container_ = AddChildView(std::make_unique<NonAccessibleView>());
container_->SetBackground(views::CreateSolidBackground(SK_ColorWHITE));
......@@ -120,8 +123,10 @@ AuthDialogDebugView::AuthDialogDebugView() {
AddPinView();
AddVerticalSpacing(kVerticalSpacingBetweenPasswordAndPINKeyboard);
fingerprint_view_ =
container_->AddChildView(std::make_unique<FingerprintView>());
if (auth_methods_ & kAuthFingerprint) {
fingerprint_view_ =
container_->AddChildView(std::make_unique<FingerprintView>());
}
AddActionButtonsView();
AddVerticalSpacing(kBottomVerticalSpacing);
......@@ -177,9 +182,11 @@ void AuthDialogDebugView::AddPasswordView() {
password_view_->SetFocusEnabledForChildViews(true);
password_view_->SetVisible(true);
// TODO(b/156258540): Set this text according to "has PIN or not".
password_view_->SetPlaceholderText(
l10n_util::GetStringUTF16(IDS_ASH_LOGIN_POD_PASSWORD_PIN_PLACEHOLDER));
(auth_methods_ & kAuthPin)
? l10n_util::GetStringUTF16(
IDS_ASH_LOGIN_POD_PASSWORD_PIN_PLACEHOLDER)
: l10n_util::GetStringUTF16(IDS_ASH_LOGIN_POD_PASSWORD_PLACEHOLDER));
}
void AuthDialogDebugView::AddPinView() {
......@@ -191,7 +198,7 @@ void AuthDialogDebugView::AddPinView() {
base::Unretained(password_view_)),
base::BindRepeating(&LoginPasswordView::SubmitPassword,
base::Unretained(password_view_))));
pin_view_->SetVisible(true);
pin_view_->SetVisible(auth_methods_ & kAuthPin);
}
void AuthDialogDebugView::InitPasswordView() {
......
......@@ -25,7 +25,15 @@ class LoginPinView;
// AuthDialogController.
class AuthDialogDebugView : public views::View, public views::ButtonListener {
public:
AuthDialogDebugView();
// Flags which describe the set of currently visible auth methods.
enum AuthMethods {
kAuthNone = 0, // No auth methods.
kAuthPassword = 1 << 0, // Display password.
kAuthPin = 1 << 1, // Display PIN keyboard.
kAuthFingerprint = 1 << 2, // Use fingerprint to unlock.
};
explicit AuthDialogDebugView(uint32_t auth_methods);
AuthDialogDebugView(const AuthDialogDebugView&) = delete;
AuthDialogDebugView& operator=(const AuthDialogDebugView&) = delete;
~AuthDialogDebugView() override;
......@@ -88,6 +96,9 @@ class AuthDialogDebugView : public views::View, public views::ButtonListener {
FingerprintView* fingerprint_view_ = nullptr;
// Flags of auth methods that should be visible.
uint32_t auth_methods_ = 0u;
// Show other authentication mechanisms if more than one.
views::LabelButton* more_options_button_ = nullptr;
......
......@@ -15,7 +15,9 @@
namespace ash {
namespace {
constexpr gfx::Size kDefaultSize(340, 224);
// The initial height does nothing except determining the vertical position of
// the dialog, since the dialog is centered with the initial height.
constexpr gfx::Size kDefaultSize(340, 490);
class AuthDialogWidgetDelegate : public views::WidgetDelegate {
public:
......@@ -54,11 +56,16 @@ std::unique_ptr<views::Widget> CreateAuthDialogWidget(aura::Window* parent) {
} // namespace
InSessionAuthDialog::InSessionAuthDialog() {
InSessionAuthDialog::InSessionAuthDialog(uint32_t auth_methods) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kShowAuthDialogDevOverlay)) {
widget_ = CreateAuthDialogWidget(nullptr);
widget_->SetContentsView(std::make_unique<AuthDialogDebugView>());
auto* contents_view = widget_->SetContentsView(
std::make_unique<AuthDialogDebugView>(auth_methods));
gfx::Rect bound = widget_->GetWindowBoundsInScreen();
// Calculate initial height based on which child views are shown.
bound.set_height(contents_view->GetPreferredSize().height());
widget_->SetBounds(bound);
widget_->Show();
}
......
......@@ -20,7 +20,7 @@ namespace ash {
// completed.
class InSessionAuthDialog {
public:
InSessionAuthDialog();
explicit InSessionAuthDialog(uint32_t auth_methods);
InSessionAuthDialog(const InSessionAuthDialog&) = delete;
InSessionAuthDialog& operator=(const InSessionAuthDialog&) = delete;
~InSessionAuthDialog();
......
......@@ -4,7 +4,10 @@
#include "ash/in_session_auth/in_session_auth_dialog_controller_impl.h"
#include "ash/in_session_auth/auth_dialog_debug_view.h"
#include "ash/public/cpp/in_session_auth_dialog_client.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/strings/string_util.h"
......@@ -23,7 +26,29 @@ void InSessionAuthDialogControllerImpl::SetClient(
}
void InSessionAuthDialogControllerImpl::ShowAuthenticationDialog() {
dialog_ = std::make_unique<InSessionAuthDialog>();
DCHECK(client_);
AccountId account_id =
Shell::Get()->session_controller()->GetActiveAccountId();
// Password should always be available.
uint32_t auth_methods = AuthDialogDebugView::kAuthPassword;
if (client_->IsFingerprintAuthAvailable(account_id))
auth_methods |= AuthDialogDebugView::kAuthFingerprint;
client_->CheckPinAuthAvailability(
account_id,
base::BindOnce(&InSessionAuthDialogControllerImpl::OnPinCanAuthenticate,
weak_factory_.GetWeakPtr(), auth_methods));
}
void InSessionAuthDialogControllerImpl::OnPinCanAuthenticate(
uint32_t auth_methods,
bool pin_auth_available) {
if (pin_auth_available)
auth_methods |= AuthDialogDebugView::kAuthPin;
dialog_ = std::make_unique<InSessionAuthDialog>(auth_methods);
}
void InSessionAuthDialogControllerImpl::DestroyAuthenticationDialog() {
......
......@@ -13,6 +13,8 @@
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
class AccountId;
namespace ash {
class InSessionAuthDialogClient;
......@@ -42,6 +44,9 @@ class InSessionAuthDialogControllerImpl : public InSessionAuthDialogController {
OnAuthenticateCallback callback) override;
private:
bool IsFingerprintAvailable(const AccountId& account_id);
void OnPinCanAuthenticate(uint32_t auth_methods, bool pin_auth_available);
// Callback to execute when auth on ChromeOS side completes.
void OnAuthenticateComplete(OnAuthenticateCallback callback, bool success);
......
......@@ -26,6 +26,17 @@ class MockInSessionAuthDialogClient : public InSessionAuthDialogClient {
bool authenticated_by_pin,
base::OnceCallback<void(bool)> callback),
(override));
MOCK_METHOD(bool,
IsFingerprintAuthAvailable,
(const AccountId& account_id),
(override));
MOCK_METHOD(void,
CheckPinAuthAvailability,
(const AccountId& account_id,
base::OnceCallback<void(bool)> callback),
(override));
};
} // namespace ash
......
......@@ -9,6 +9,7 @@
#include "ash/public/cpp/ash_public_export.h"
#include "base/callback_forward.h"
#include "components/account_id/account_id.h"
namespace ash {
......@@ -25,6 +26,14 @@ class ASH_PUBLIC_EXPORT InSessionAuthDialogClient {
bool authenticated_by_pin,
base::OnceCallback<void(bool)> callback) = 0;
// Check whether fingerprint auth is available for |account_id|.
virtual bool IsFingerprintAuthAvailable(const AccountId& account_id) = 0;
// Check whether PIN auth is available for |account_id|.
virtual void CheckPinAuthAvailability(
const AccountId& account_id,
base::OnceCallback<void(bool)> callback) = 0;
protected:
virtual ~InSessionAuthDialogClient() = default;
};
......
......@@ -10,8 +10,11 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.h"
#include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h"
#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h"
#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
......@@ -49,6 +52,22 @@ InSessionAuthDialogClient* InSessionAuthDialogClient::Get() {
return g_auth_dialog_client_instance;
}
bool InSessionAuthDialogClient::IsFingerprintAuthAvailable(
const AccountId& account_id) {
chromeos::quick_unlock::QuickUnlockStorage* quick_unlock_storage =
chromeos::quick_unlock::QuickUnlockFactory::GetForAccountId(account_id);
return quick_unlock_storage &&
quick_unlock_storage->fingerprint_storage()->IsFingerprintAvailable();
}
void InSessionAuthDialogClient::CheckPinAuthAvailability(
const AccountId& account_id,
base::OnceCallback<void(bool)> callback) {
// PinBackend may be using cryptohome backend or prefs backend.
chromeos::quick_unlock::PinBackend::GetInstance()->CanAuthenticate(
account_id, std::move(callback));
}
void InSessionAuthDialogClient::AuthenticateUserWithPasswordOrPin(
const std::string& password,
bool authenticated_by_pin,
......
......@@ -14,6 +14,8 @@
#include "chromeos/login/auth/extended_authenticator.h"
#include "chromeos/login/auth/user_context.h"
class AccountId;
// Handles method calls sent from Ash to ChromeOS.
class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient,
public chromeos::AuthStatusConsumer {
......@@ -34,6 +36,10 @@ class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient,
const std::string& password,
bool authenticated_by_pin,
AuthenticateCallback callback) override;
bool IsFingerprintAuthAvailable(const AccountId& account_id) override;
void CheckPinAuthAvailability(
const AccountId& account_id,
base::OnceCallback<void(bool)> callback) override;
// AuthStatusConsumer:
void OnAuthFailure(const chromeos::AuthFailure& error) override;
......
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