[go: nahoru, domu]

Fix incorrect error when cancelling pin request

Previously, the UI could not distinguish between a failed log in attempt
and the user cancelling the attempt. By saving that the user cancelled
the request, we suppress the error that would otherwise be displayed.

Fixed: 1045029
Change-Id: I758d2934db7da7206d13b6036c0723677ada33ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2017351
Commit-Queue: Fabian Sommer <fabiansommer@google.com>
Reviewed-by: Maksim Ivanov <emaxx@chromium.org>
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738164}
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc
index 8c8d0fe..b18c70d 100644
--- a/ash/login/login_screen_controller.cc
+++ b/ash/login/login_screen_controller.cc
@@ -207,6 +207,15 @@
   return client_->ValidateParentAccessCode(account_id, code, validation_time);
 }
 
+void LoginScreenController::OnSecurityTokenPinRequestCancelledByUser() {
+  security_token_pin_request_cancelled_ = true;
+  std::move(on_request_security_token_ui_closed_).Run();
+}
+
+bool LoginScreenController::GetSecurityTokenPinRequestCancelled() const {
+  return security_token_pin_request_cancelled_;
+}
+
 void LoginScreenController::HardlockPod(const AccountId& account_id) {
   if (!client_)
     return;
@@ -397,13 +406,24 @@
 
 void LoginScreenController::RequestSecurityTokenPin(
     SecurityTokenPinRequest request) {
-  if (!LockScreen::HasInstance()) {
-    // Corner case: the PIN request is made at inappropriate time, racing with
-    // the lock screen showing/hiding.
+  if (LockScreen::HasInstance() && !security_token_pin_request_cancelled_) {
+    // The caller must ensure that there is no unresolved pin request currently
+    // in progress.
+    on_request_security_token_ui_closed_ =
+        std::move(request.pin_ui_closed_callback);
+    // base::Unretained(this) could lead to errors if this controller is
+    // destroyed before the callback happens. This will be fixed by
+    // crbug.com/1001288 by using a UI owned by the controller.
+    request.pin_ui_closed_callback = base::BindOnce(
+        &LoginScreenController::OnSecurityTokenPinRequestCancelledByUser,
+        base::Unretained(this));
+    LockScreen::Get()->RequestSecurityTokenPin(std::move(request));
+  } else {
+    // The user closed the PIN UI on a previous request that was part of the
+    // same smart card login attempt, or the PIN request is made at an
+    // inappropriate time, racing with the lock screen showing/hiding.
     std::move(request.pin_ui_closed_callback).Run();
-    return;
   }
-  LockScreen::Get()->RequestSecurityTokenPin(std::move(request));
 }
 
 void LoginScreenController::ClearSecurityTokenPinRequest() {
@@ -477,6 +497,8 @@
     bool success) {
   authentication_stage_ = AuthenticationStage::kUserCallback;
   std::move(callback).Run(base::make_optional<bool>(success));
+  security_token_pin_request_cancelled_ = false;
+  on_request_security_token_ui_closed_.Reset();
   authentication_stage_ = AuthenticationStage::kIdle;
 }