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() {} |