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..aa5d769d57d88e731c233edd78519cd0d95dd521 100644 |
--- a/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc |
+++ b/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc |
@@ -11,6 +11,7 @@ |
#include <vector> |
#include "base/logging.h" |
+#include "base/strings/utf_string_conversions.h" |
#include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h" |
#include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h" |
#include "chrome/common/extensions/api/certificate_provider.h" |
@@ -35,6 +36,8 @@ const char kErrorTimeout[] = "Request timed out, reply rejected."; |
} // namespace |
+const int MAX_CLOSED_DIALOGS_PER_10_MINUTES = 2; |
+ |
CertificateProviderInternalReportCertificatesFunction:: |
~CertificateProviderInternalReportCertificatesFunction() {} |
@@ -148,6 +151,113 @@ bool CertificateProviderInternalReportCertificatesFunction:: |
return true; |
} |
+CertificateProviderClosePinDialogFunction:: |
+ ~CertificateProviderClosePinDialogFunction() {} |
+ |
+ExtensionFunction::ResponseAction |
+CertificateProviderClosePinDialogFunction::Run() { |
+ chromeos::CertificateProviderService* const service = |
+ chromeos::CertificateProviderServiceFactory::GetForBrowserContext( |
+ browser_context()); |
+ DCHECK(service); |
+ bool dialog_closed = service->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("The extension doesn't own the active dialog")); |
+ } |
+ |
+ std::unique_ptr<base::ListValue> create_results(new base::ListValue()); |
+ |
+ return RespondNow(ArgumentList(std::move(create_results))); |
+} |
+ |
+CertificateProviderShowPinDialogFunction:: |
+ ~CertificateProviderShowPinDialogFunction() {} |
+ |
+bool CertificateProviderShowPinDialogFunction::ShouldSkipQuotaLimiting() const { |
+ chromeos::CertificateProviderService* const service = |
+ chromeos::CertificateProviderServiceFactory::GetForBrowserContext( |
+ browser_context()); |
+ DCHECK(service); |
+ |
+ return !service->LastPinDialogClosed(extension_id()); |
+} |
+ |
+void CertificateProviderShowPinDialogFunction::GetQuotaLimitHeuristics( |
+ extensions::QuotaLimitHeuristics* heuristics) const { |
+ QuotaLimitHeuristic::Config short_limit_config = { |
+ extensions::MAX_CLOSED_DIALOGS_PER_10_MINUTES, |
+ base::TimeDelta::FromMinutes(1)}; |
+ heuristics->push_back(new QuotaService::TimedLimit( |
+ short_limit_config, new QuotaLimitHeuristic::SingletonBucketMapper(), |
+ "MAX_SHOW_DIALOGS_PER_MINUTE")); |
+} |
+ |
+ExtensionFunction::ResponseAction |
+CertificateProviderShowPinDialogFunction::Run() { |
+ std::unique_ptr<api_cp::ShowPinDialog::Params> params( |
+ api_cp::ShowPinDialog::Params::Create(*args_)); |
+ EXTENSION_FUNCTION_VALIDATE(params.get()); |
+ |
+ api_cp::PinDialogType pin_dialog_type = |
+ (params->details && params->details->type) ? |
+ params->details->type : |
+ api_cp::PinDialogType::PIN_DIALOG_TYPE_PIN; |
+ |
+ base::string16 error_message; |
+ if (params->details && params->details->error_message) { |
+ std::basic_string<char>* err_msg = params->details->error_message.get(); |
+ error_message = base::ASCIIToUTF16(err_msg->c_str()); |
+ } |
+ |
+ bool accept_input = true; |
+ if (params->details && params->details->accept_input) { |
+ accept_input = *(params->details->accept_input.get()); |
+ } |
+ |
+ const std::string dialog_type = |
+ (pin_dialog_type == api_cp::PinDialogType::PIN_DIALOG_TYPE_PIN) ? |
+ "PIN: " : "PUK: "; |
+ |
+ chromeos::CertificateProviderService* const service = |
+ chromeos::CertificateProviderServiceFactory::GetForBrowserContext( |
+ browser_context()); |
+ DCHECK(service); |
+ |
+ bool success = service->ShowPinDialog( |
+ extension()->id(), |
+ extension()->name(), |
+ dialog_type, |
+ error_message, |
+ accept_input, |
+ base::Bind(&CertificateProviderShowPinDialogFunction::OnInputReceived, |
+ this)); |
+ if (!success) { |
+ return RespondNow(Error("Other flow in progress")); |
+ } |
+ |
+ return RespondLater(); |
+} |
+ |
+void CertificateProviderShowPinDialogFunction::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))); |
+ service->OnPinDialogInput(extension_id(), value.empty()); |
+} |
+ |
CertificateProviderInternalReportSignatureFunction:: |
~CertificateProviderInternalReportSignatureFunction() {} |