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

Unified Diff: chrome/browser/extensions/api/certificate_provider/certificate_provider_api.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 and merged 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/extensions/api/certificate_provider/certificate_provider_api.cc
diff --git a/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc b/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc
index cdf49c4a99bb917151f68afafce097c98a7de2f5..3cad1c5d9eba479ea3ca46c99fd6eeeea5d7ad8f 100644
--- a/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc
+++ b/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc
@@ -19,10 +19,28 @@
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_private_key.h"
-namespace extensions {
+namespace api_cp = extensions::api::certificate_provider;
+namespace api_cpi = extensions::api::certificate_provider_internal;
+
+chromeos::RequestPinView::RequestPinErrorType GetErrorTypeForView(
emaxx 2016/09/19 14:01:44 nit: Move this function into an anonymous namespac
igorcov 2016/09/19 15:42:36 Done.
+ api_cp::PinRequestErrorType error_type) {
+ switch (error_type) {
+ case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_INVALID_PIN:
+ return chromeos::RequestPinView::RequestPinErrorType::INVALID_PIN;
+ case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_INVALID_PUK:
+ return chromeos::RequestPinView::RequestPinErrorType::INVALID_PUK;
+ case api_cp::PinRequestErrorType::
+ PIN_REQUEST_ERROR_TYPE_MAX_ATTEMPTS_EXCEEDED:
+ return chromeos::RequestPinView::RequestPinErrorType::
+ MAX_ATTEMPTS_EXCEEDED;
+ case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_UNKNOWN_ERROR:
+ return chromeos::RequestPinView::RequestPinErrorType::UNKNOWN_ERROR;
+ case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_NONE:
+ return chromeos::RequestPinView::RequestPinErrorType::NONE;
+ }
+}
-namespace api_cp = api::certificate_provider;
-namespace api_cpi = api::certificate_provider_internal;
+namespace extensions {
namespace {
@@ -33,8 +51,16 @@ const char kErrorUnknownKeyType[] = "Key type unknown.";
const char kErrorAborted[] = "Request was aborted.";
const char kErrorTimeout[] = "Request timed out, reply rejected.";
+// requestPin constants.
+const char kNoActiveDialog[] = "No active dialog from extension.";
+const char kInvalidId[] = "Invalid signRequestId";
+const char kOtherFlowInProgress[] = "Other flow in progress";
+const char kPreviousDialogActive[] = "Previous request not finished";
+
} // namespace
+const int api::certificate_provider::kMaxClosedDialogsPer10Mins = 2;
+
CertificateProviderInternalReportCertificatesFunction::
~CertificateProviderInternalReportCertificatesFunction() {}
@@ -148,6 +174,145 @@ bool CertificateProviderInternalReportCertificatesFunction::
return true;
}
+CertificateProviderStopPinRequestFunction::
+ ~CertificateProviderStopPinRequestFunction() {}
+
+ExtensionFunction::ResponseAction
+CertificateProviderStopPinRequestFunction::Run() {
+ std::unique_ptr<api_cp::RequestPin::Params> params(
+ api_cp::RequestPin::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ chromeos::CertificateProviderService* const service =
+ chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
+ browser_context());
+ DCHECK(service);
+ if (params->details.error_type ==
+ api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_NONE) {
+ bool dialog_closed =
+ service->pin_dialog_manager()->CloseDialog(extension_id());
+ if (!dialog_closed) {
+ // This might happen if the user closed the dialog while extension was
+ // processing the input.
+ LOG(ERROR) << "Wrong extension requesting to close the dialog";
+ return RespondNow(Error(kNoActiveDialog));
+ }
+
+ std::unique_ptr<base::ListValue> create_results(new base::ListValue());
+ return RespondNow(ArgumentList(std::move(create_results)));
+ }
+
+ chromeos::RequestPinView::RequestPinErrorType error_type =
+ GetErrorTypeForView(params->details.error_type);
+ bool success = service->pin_dialog_manager()->UpdatePinDialog(
+ extension()->id(), error_type,
+ false, // Don't accept any input.
+ base::Bind(&CertificateProviderStopPinRequestFunction::DialogClosed,
+ this));
+ if (!success) {
+ return RespondNow(Error(kNoActiveDialog));
+ }
+
+ return RespondLater();
+}
+
+void CertificateProviderStopPinRequestFunction::DialogClosed(
+ const base::string16& value) {
+ std::unique_ptr<base::ListValue> create_results(new base::ListValue());
+ chromeos::CertificateProviderService* const service =
+ chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
+ browser_context());
+ DCHECK(service);
+
+ Respond(ArgumentList(std::move(create_results)));
+ service->pin_dialog_manager()->OnPinDialogClosed();
+}
+
+CertificateProviderRequestPinFunction::
+ ~CertificateProviderRequestPinFunction() {}
+
+bool CertificateProviderRequestPinFunction::ShouldSkipQuotaLimiting() const {
+ chromeos::CertificateProviderService* const service =
+ chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
+ browser_context());
+ DCHECK(service);
+
+ return !service->pin_dialog_manager()->LastPinDialogClosed(extension_id());
+}
+
+void CertificateProviderRequestPinFunction::GetQuotaLimitHeuristics(
+ extensions::QuotaLimitHeuristics* heuristics) const {
+ QuotaLimitHeuristic::Config short_limit_config = {
+ api::certificate_provider::kMaxClosedDialogsPer10Mins,
+ base::TimeDelta::FromMinutes(1)};
+ heuristics->push_back(new QuotaService::TimedLimit(
+ short_limit_config, new QuotaLimitHeuristic::SingletonBucketMapper(),
+ "MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES"));
+}
+
+ExtensionFunction::ResponseAction CertificateProviderRequestPinFunction::Run() {
+ std::unique_ptr<api_cp::RequestPin::Params> params(
+ api_cp::RequestPin::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+
+ api_cp::PinRequestType pin_request_type =
+ (params->details.request_type)
+ ? params->details.request_type
+ : api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN;
+
+ chromeos::RequestPinView::RequestPinErrorType error_type =
+ GetErrorTypeForView(params->details.error_type);
+
+ chromeos::RequestPinView::RequestPinCodeType code_type =
+ (pin_request_type == api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN)
+ ? chromeos::RequestPinView::RequestPinCodeType::PIN
+ : chromeos::RequestPinView::RequestPinCodeType::PUK;
+
+ chromeos::CertificateProviderService* const service =
+ chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
+ browser_context());
+ DCHECK(service);
+
+ int attempts_left =
+ params->details.attempts_left ? *params->details.attempts_left.get() : -1;
+ chromeos::PinDialogManager::RequestPinResponse result =
+ service->pin_dialog_manager()->ShowPinDialog(
+ extension()->id(), extension()->name(),
+ params->details.sign_request_id, code_type, error_type, attempts_left,
+ base::Bind(&CertificateProviderRequestPinFunction::OnInputReceived,
+ this));
+ switch (result) {
+ case chromeos::PinDialogManager::RequestPinResponse::SUCCESS:
+ return RespondLater();
+ case chromeos::PinDialogManager::RequestPinResponse::INVALID_ID:
+ return RespondNow(Error(kInvalidId));
+ case chromeos::PinDialogManager::RequestPinResponse::OTHER_FLOW_IN_PROGRESS:
+ return RespondNow(Error(kOtherFlowInProgress));
+ case chromeos::PinDialogManager::RequestPinResponse::
+ DIALOG_DISPLAYED_ALREADY:
+ return RespondNow(Error(kPreviousDialogActive));
+ }
+}
+
+void CertificateProviderRequestPinFunction::OnInputReceived(
+ const base::string16& value) {
+ std::unique_ptr<base::ListValue> create_results(new base::ListValue());
+ chromeos::CertificateProviderService* const service =
+ chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
+ browser_context());
+ DCHECK(service);
+ if (!value.empty()) {
+ api::certificate_provider::PinResponseDetails details;
+ details.user_input.reset(new std::string(value.begin(), value.end()));
+ create_results->Append(details.ToValue());
+ }
+
+ Respond(ArgumentList(std::move(create_results)));
+ if (!value.empty()) {
+ service->pin_dialog_manager()->OnPinDialogInput();
+ }
+}
+
CertificateProviderInternalReportSignatureFunction::
~CertificateProviderInternalReportSignatureFunction() {}

Powered by Google App Engine
This is Rietveld 408576698