Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1419)

Unified Diff: chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc

Issue 2094333002: Implementation for chrome.certificateProvider.requestPin/stopPinRequest (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed review comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc
diff --git a/chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc b/chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0aa9c09c2e1f1bfb15400b6febe87ef80d573783
--- /dev/null
+++ b/chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc
@@ -0,0 +1,176 @@
+// Copyright 2016 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.
+
+#include "chrome/browser/chromeos/certificate_provider/pin_dialog_manager.h"
+
+#include "ash/shell.h"
+#include "base/strings/string16.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "ui/views/window/dialog_client_view.h"
+
+namespace chromeos {
+
+// Define timeout for issued sign_request_id.
+const int SIGN_REQUEST_ID_TIMEOUT = 10; // 10 minutes
stevenjb 2016/09/12 21:16:39 nit: TIMEOUT_MINS instead of comment (makes it cle
+
+PinDialogManager::PinDialogManager() : weak_factory_(this) {}
+
+PinDialogManager::~PinDialogManager() {
+ // Close the active dialog if present to avoid leaking callbacks.
+ if (active_pin_dialog_) {
+ CloseDialog(active_dialog_extension_id_);
+ }
+}
+
+bool PinDialogManager::AddSignRequestId(const std::string& extension_id,
+ int sign_request_id) {
+ std::pair<std::string, int> key(extension_id, sign_request_id);
+ if (sign_request_times_.find(key) != sign_request_times_.end()) {
+ return false;
+ }
+ // Cache the ID with current timestamp.
+ base::Time current_time = base::Time::Now();
+ sign_request_times_[key] = current_time;
+
+ return true;
+}
+
+PinDialogManager::RequestPinResponse PinDialogManager::ShowPinDialog(
+ const std::string& extension_id,
+ const std::string& extension_name,
+ int sign_request_id,
+ RequestPinCodeType code_type,
+ RequestPinErrorType error_type,
+ int attempts_left,
+ const RequestPinView::RequestPinCallback& callback) {
+ bool accept_input = (attempts_left != 0);
+ // If active dialog exists already, we need to make sure it belongs to the
+ // same extension and the user submitted some input.
+ if (active_pin_dialog_ != nullptr) {
+ DCHECK(!active_dialog_extension_id_.empty());
+ if (extension_id != active_dialog_extension_id_) {
+ return RequestPinResponse::OTHER_FLOW_IN_PROGRESS;
+ }
+
+ // Extension requests a PIN without having received any input from its
+ // previous request. Reject the new request.
+ if (!active_pin_dialog_->IsLocked()) {
+ return RequestPinResponse::DIALOG_DISPLAYED_ALREADY;
+ }
+
+ // Set the new callback to be used by the view.
+ active_pin_dialog_->SetCallback(callback);
+ active_pin_dialog_->SetDialogParameters(code_type, error_type,
+ attempts_left, accept_input);
+ active_pin_dialog_->GetDialogClientView()->UpdateDialogButtons();
+ return RequestPinResponse::SUCCESS;
+ }
+
+ // Check the validity of sign_request_id
+ std::pair<std::string, int> key(extension_id, sign_request_id);
+ if (sign_request_times_.find(key) == sign_request_times_.end()) {
+ return RequestPinResponse::INVALID_ID;
+ }
+
+ base::Time current_time = base::Time::Now();
+ if ((current_time - sign_request_times_[key]).InMinutes() >
+ SIGN_REQUEST_ID_TIMEOUT) {
+ return RequestPinResponse::INVALID_ID;
+ }
+
+ active_dialog_extension_id_ = extension_id;
+ active_pin_dialog_ = new chromeos::RequestPinView(
+ extension_name, code_type, attempts_left, callback, this);
+
+ gfx::NativeWindow parent = nullptr;
+ if (chromeos::LoginDisplayHost::default_host()) {
+ parent = chromeos::LoginDisplayHost::default_host()->GetNativeWindow();
+ } else {
+ Browser* browser = chrome::FindTabbedBrowser(
+ ProfileManager::GetPrimaryUserProfile(), true);
+ if (browser) {
+ parent = browser->window()->GetNativeWindow();
+ }
+ }
stevenjb 2016/09/12 21:16:39 nit: Wrap the above in an anonymous namespaced hel
igorcov 2016/09/13 14:19:32 Done.
+ gfx::NativeWindow context =
+ parent ? nullptr : ash::Shell::GetPrimaryRootWindow();
+ active_window_ = views::DialogDelegate::CreateDialogWidget(active_pin_dialog_,
+ context, parent);
+ active_window_->Show();
+
+ return RequestPinResponse::SUCCESS;
+}
+
+void PinDialogManager::OnPinDialogInput() {
+ last_response_closed_[active_dialog_extension_id_] = false;
+}
+
+void PinDialogManager::OnPinDialogClosed() {
+ last_response_closed_[active_dialog_extension_id_] = true;
+ // |active_pin_dialog_| is managed by |active_window_|. This local copy of
+ // the pointer is reset here to allow a new dialog to be created when a new
+ // request comes.
+ active_pin_dialog_ = nullptr;
+}
+
+bool PinDialogManager::UpdatePinDialog(
+ const std::string& extension_id,
+ RequestPinErrorType error_type,
+ bool accept_input,
+ const RequestPinView::RequestPinCallback& callback) {
+ if (active_pin_dialog_ == nullptr) {
+ return false;
+ }
+
+ if (extension_id != active_dialog_extension_id_ ||
+ !active_pin_dialog_->IsLocked()) {
+ return false;
+ }
stevenjb 2016/09/12 21:16:39 nit: combine early exits
igorcov 2016/09/13 14:19:32 Done.
+
+ active_pin_dialog_->SetCallback(callback);
+ active_pin_dialog_->SetDialogParameters(RequestPinCodeType::UNCHANGED,
+ error_type, -1, accept_input);
+ active_pin_dialog_->GetDialogClientView()->UpdateDialogButtons();
+ return true;
+}
+
+bool PinDialogManager::LastPinDialogClosed(const std::string& extension_id) {
+ return last_response_closed_[extension_id];
+}
+
+bool PinDialogManager::CloseDialog(const std::string& extension_id) {
+ if (extension_id != active_dialog_extension_id_ ||
+ active_pin_dialog_ == nullptr) {
+ LOG(ERROR) << "StopPinRequest called by wrong extension";
stevenjb 2016/09/12 21:16:39 nit: "StopPinRequest called by unexpected extensio
igorcov 2016/09/13 14:19:32 Done.
+ return false;
+ }
+
+ // Close the window. |active_pin_dialog_| gets deleted inside Close().
+ active_window_->Close();
+ active_pin_dialog_ = nullptr;
+
+ return true;
+}
+
+void PinDialogManager::ExtensionUnloaded(const std::string& extension_id) {
+ if (active_pin_dialog_ && active_dialog_extension_id_ == extension_id) {
+ CloseDialog(extension_id);
+ }
+
+ last_response_closed_[extension_id] = false;
+
+ for (auto it = sign_request_times_.cbegin();
+ it != sign_request_times_.cend();) {
+ if (it->first.first == extension_id) {
+ sign_request_times_.erase(it++);
+ } else {
+ ++it;
+ }
+ }
+}
+
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698