blob: efe7ba3327786380235a367fbd113c97fe0deac3 [file] [log] [blame]
Ken Buchanan0786d2822020-08-26 18:59:281// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/payments/content/payment_credential.h"
6
Nick Burris3a404212021-02-24 23:21:277#include <utility>
Rouslan Solomakhin3732b2f2020-08-27 16:48:138
Rouslan Solomakhin9fc7b772021-02-23 19:57:129#include "base/compiler_specific.h"
Rouslan Solomakhin99e84d02021-02-24 18:00:2210#include "base/feature_list.h"
Sahel Sharifyf8b345732020-08-27 21:41:5011#include "base/memory/ref_counted_memory.h"
Rouslan Solomakhin3732b2f2020-08-27 16:48:1312#include "components/payments/content/payment_manifest_web_data_service.h"
Stephen McGruera3c39f52021-11-15 23:05:5913#include "components/payments/core/secure_payment_confirmation_credential.h"
Nick Burrisc36ef582021-03-05 19:44:4114#include "content/public/browser/navigation_handle.h"
Sahel Sharifyf8b345732020-08-27 21:41:5015#include "content/public/browser/web_contents.h"
Rouslan Solomakhin99e84d02021-02-24 18:00:2216#include "content/public/common/content_features.h"
Charlie Hue010cf22021-03-03 23:09:5117#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
Rouslan Solomakhin3732b2f2020-08-27 16:48:1318
Ken Buchanan0786d2822020-08-26 18:59:2819namespace payments {
20
Rouslan Solomakhin99e84d02021-02-24 18:00:2221// static
22bool PaymentCredential::IsFrameAllowedToUseSecurePaymentConfirmation(
23 content::RenderFrameHost* rfh) {
Sreeja Kamishettye49854f82021-06-02 00:52:0324 return rfh && rfh->IsActive() &&
Charlie Hu1b9da2c2021-03-04 18:51:3025 rfh->IsFeatureEnabled(
26 blink::mojom::PermissionsPolicyFeature::kPayment) &&
Rouslan Solomakhin99e84d02021-02-24 18:00:2227 base::FeatureList::IsEnabled(features::kSecurePaymentConfirmation);
28}
29
Ken Buchanan0786d2822020-08-26 18:59:2830PaymentCredential::PaymentCredential(
Ian Vollicka9f57fc2021-12-08 17:32:5631 content::RenderFrameHost& render_frame_host,
32 mojo::PendingReceiver<mojom::PaymentCredential> receiver,
33 scoped_refptr<PaymentManifestWebDataService> web_data_service)
danakjc70aec1f2022-07-07 15:48:1934 : DocumentService(render_frame_host, std::move(receiver)),
Ian Vollicka9f57fc2021-12-08 17:32:5635 web_data_service_(web_data_service) {}
Ken Buchanan0786d2822020-08-26 18:59:2836
Rouslan Solomakhin9244d6d2020-11-04 22:51:2437PaymentCredential::~PaymentCredential() {
Nick Burris787114bd2021-02-26 21:21:4038 Reset();
Rouslan Solomakhin9244d6d2020-11-04 22:51:2439}
Ken Buchanan0786d2822020-08-26 18:59:2840
Rouslan Solomakhin883df202021-08-27 01:12:5441void PaymentCredential::StorePaymentCredential(
Ken Buchanan0786d2822020-08-26 18:59:2842 const std::vector<uint8_t>& credential_id,
43 const std::string& rp_id,
Nick Burris9bd171af2021-12-09 21:27:5844 const std::vector<uint8_t>& user_id,
Rouslan Solomakhin883df202021-08-27 01:12:5445 StorePaymentCredentialCallback callback) {
46 if (state_ != State::kIdle || !IsCurrentStateValid() ||
Nick Burris9bd171af2021-12-09 21:27:5847 credential_id.empty() || rp_id.empty() || user_id.empty()) {
Nick Burris787114bd2021-02-26 21:21:4048 Reset();
Rouslan Solomakhin3732b2f2020-08-27 16:48:1349 std::move(callback).Run(
Stephen McGruera3c39f52021-11-15 23:05:5950 mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL);
Rouslan Solomakhin3732b2f2020-08-27 16:48:1351 return;
52 }
53
Rouslan Solomakhin60fa47482021-03-11 15:58:3954 RecordFirstSystemPromptResult(
55 SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted);
56
Nick Burrisc36ef582021-03-05 19:44:4157 storage_callback_ = std::move(callback);
Rouslan Solomakhin9fc7b772021-02-23 19:57:1258 state_ = State::kStoringCredential;
Nick Burrisc36ef582021-03-05 19:44:4159 data_service_request_handle_ =
Stephen McGruera3c39f52021-11-15 23:05:5960 web_data_service_->AddSecurePaymentConfirmationCredential(
61 std::make_unique<SecurePaymentConfirmationCredential>(credential_id,
Nick Burris9bd171af2021-12-09 21:27:5862 rp_id, user_id),
Nick Burrise431fc62021-02-18 17:49:3063 /*consumer=*/this);
Sahel Sharifyf8b345732020-08-27 21:41:5064}
65
Rouslan Solomakhinf1b29932021-02-22 19:40:0466void PaymentCredential::OnWebDataServiceRequestDone(
67 WebDataServiceBase::Handle h,
68 std::unique_ptr<WDTypedResult> result) {
Nick Burrisc36ef582021-03-05 19:44:4169 if (state_ != State::kStoringCredential || !IsCurrentStateValid() ||
70 data_service_request_handle_ != h) {
Nick Burris787114bd2021-02-26 21:21:4071 Reset();
Rouslan Solomakhinf1b29932021-02-22 19:40:0472 return;
73 }
74
Nick Burrisc36ef582021-03-05 19:44:4175 auto callback = std::move(storage_callback_);
Nick Burris787114bd2021-02-26 21:21:4076 Reset();
Rouslan Solomakhin60fa47482021-03-11 15:58:3977
Rouslan Solomakhinf1b29932021-02-22 19:40:0478 std::move(callback).Run(
79 static_cast<WDResult<bool>*>(result.get())->GetValue()
80 ? mojom::PaymentCredentialStorageStatus::SUCCESS
Stephen McGruera3c39f52021-11-15 23:05:5981 : mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL);
Rouslan Solomakhinf1b29932021-02-22 19:40:0482}
83
Rouslan Solomakhin9fc7b772021-02-23 19:57:1284bool PaymentCredential::IsCurrentStateValid() const {
danakjc70aec1f2022-07-07 15:48:1985 if (!IsFrameAllowedToUseSecurePaymentConfirmation(&render_frame_host()) ||
Ian Vollicka9f57fc2021-12-08 17:32:5686 !web_data_service_) {
Rouslan Solomakhin9fc7b772021-02-23 19:57:1287 return false;
88 }
89
90 switch (state_) {
91 case State::kIdle:
Rouslan Solomakhin883df202021-08-27 01:12:5492 return !storage_callback_ && !data_service_request_handle_;
Rouslan Solomakhin9fc7b772021-02-23 19:57:1293
94 case State::kStoringCredential:
Rouslan Solomakhin883df202021-08-27 01:12:5495 return storage_callback_ && data_service_request_handle_;
Rouslan Solomakhin60fa47482021-03-11 15:58:3996 }
97}
98
99void PaymentCredential::RecordFirstSystemPromptResult(
100 SecurePaymentConfirmationEnrollSystemPromptResult result) {
101 if (!is_system_prompt_result_recorded_) {
102 is_system_prompt_result_recorded_ = true;
103 RecordEnrollSystemPromptResult(result);
104 }
105}
106
Nick Burris787114bd2021-02-26 21:21:40107void PaymentCredential::Reset() {
Nick Burrisc36ef582021-03-05 19:44:41108 // Callbacks must either be run or disconnected before being destroyed, so
109 // run them if they are still connected.
Ian Vollicka9f57fc2021-12-08 17:32:56110 if (storage_callback_) {
111 std::move(storage_callback_)
112 .Run(mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL);
Rouslan Solomakhinf1b29932021-02-22 19:40:04113 }
Rouslan Solomakhin60fa47482021-03-11 15:58:39114
Nick Burrisc36ef582021-03-05 19:44:41115 if (web_data_service_ && data_service_request_handle_) {
116 web_data_service_->CancelRequest(data_service_request_handle_.value());
117 }
Rouslan Solomakhin60fa47482021-03-11 15:58:39118
Nick Burrisc36ef582021-03-05 19:44:41119 data_service_request_handle_.reset();
Rouslan Solomakhin60fa47482021-03-11 15:58:39120 is_system_prompt_result_recorded_ = false;
Rouslan Solomakhin9fc7b772021-02-23 19:57:12121 state_ = State::kIdle;
Ken Buchanan0786d2822020-08-26 18:59:28122}
123
124} // namespace payments