Chromium Code Reviews| 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..b24a6ac3116215a06a51221a22f3319b2218f1a6 100644 |
| --- a/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc |
| +++ b/chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc |
| @@ -35,6 +35,8 @@ const char kErrorTimeout[] = "Request timed out, reply rejected."; |
| } // namespace |
| +const int MAX_CLOSED_DIALOGS_PER_10_MINUTES = 2; |
| + |
| CertificateProviderInternalReportCertificatesFunction:: |
| ~CertificateProviderInternalReportCertificatesFunction() {} |
| @@ -148,6 +150,165 @@ bool CertificateProviderInternalReportCertificatesFunction:: |
| return true; |
| } |
| +chromeos::RequestPinErrorType GetErrorTypeForView( |
|
emaxx
2016/09/06 15:02:11
nit: Put this function into an anonymous namespace
igorcov
2016/09/09 15:53:42
Done.
|
| + api_cp::PinRequestErrorType error_type) { |
| + switch (error_type) { |
| + case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_INVALID_PIN: |
| + return chromeos::RequestPinErrorType::INVALID_PIN; |
| + case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_INVALID_PUK: |
| + return chromeos::RequestPinErrorType::INVALID_PUK; |
| + case |
| + api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_MAX_ATTEMPTS_EXCEEDED: |
| + return chromeos::RequestPinErrorType::MAX_ATTEMPTS_EXCEEDED; |
| + case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_UNKNOWN_ERROR: |
| + return chromeos::RequestPinErrorType::UNKNOWN_ERROR; |
| + case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_NONE: |
| + return chromeos::RequestPinErrorType::NONE; |
| + } |
| +} |
| + |
| +CertificateProviderStopPinRequestFunction:: |
|
emaxx
2016/09/06 15:02:11
nit: Please reorder the method definitions so that
igorcov
2016/09/09 15:53:43
Done.
|
| + ~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("No active dialog from extension.")); |
| + } |
| + |
| + std::unique_ptr<base::ListValue> create_results(new base::ListValue()); |
| + return RespondNow(ArgumentList(std::move(create_results))); |
| + } |
| + |
| + chromeos::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("No active dialog from extension.")); |
| + } |
| + |
| + 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()->OnPinDialogInput(extension_id(), true); |
| +} |
| + |
| +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 = { |
| + 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 |
| +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::RequestPinErrorType error_type = GetErrorTypeForView( |
| + params->details.error_type); |
| + |
| + chromeos::RequestPinCodeType code_type = |
| + (pin_request_type == api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN) ? |
| + chromeos::RequestPinCodeType::PIN : chromeos::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::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::RequestPinResponse::SUCCESS: |
| + return RespondLater(); |
| + case chromeos::RequestPinResponse::INVALID_ID: |
| + return RespondNow(Error("Invalid signRequestId")); |
| + case chromeos::RequestPinResponse::OTHER_FLOW_IN_PROGRESS: |
| + return RespondNow(Error("Other flow in progress")); |
| + case chromeos::RequestPinResponse::DIALOG_DISPLAYED_ALREADY: |
| + return RespondNow(Error("Previous request not finished")); |
| + } |
| +} |
| + |
| +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))); |
| + service->pin_dialog_manager()-> |
| + OnPinDialogInput(extension_id(), value.empty()); |
| +} |
| + |
| CertificateProviderInternalReportSignatureFunction:: |
| ~CertificateProviderInternalReportSignatureFunction() {} |