Ken Buchanan | 0786d282 | 2020-08-26 18:59:28 | [diff] [blame] | 1 | // 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 Burris | 3a40421 | 2021-02-24 23:21:27 | [diff] [blame] | 7 | #include <utility> |
Rouslan Solomakhin | 3732b2f | 2020-08-27 16:48:13 | [diff] [blame] | 8 | |
Rouslan Solomakhin | 9fc7b77 | 2021-02-23 19:57:12 | [diff] [blame] | 9 | #include "base/compiler_specific.h" |
Rouslan Solomakhin | 99e84d0 | 2021-02-24 18:00:22 | [diff] [blame] | 10 | #include "base/feature_list.h" |
Sahel Sharify | f8b34573 | 2020-08-27 21:41:50 | [diff] [blame] | 11 | #include "base/memory/ref_counted_memory.h" |
Rouslan Solomakhin | 3732b2f | 2020-08-27 16:48:13 | [diff] [blame] | 12 | #include "components/payments/content/payment_manifest_web_data_service.h" |
Stephen McGruer | a3c39f5 | 2021-11-15 23:05:59 | [diff] [blame] | 13 | #include "components/payments/core/secure_payment_confirmation_credential.h" |
Nick Burris | c36ef58 | 2021-03-05 19:44:41 | [diff] [blame] | 14 | #include "content/public/browser/navigation_handle.h" |
Sahel Sharify | f8b34573 | 2020-08-27 21:41:50 | [diff] [blame] | 15 | #include "content/public/browser/web_contents.h" |
Rouslan Solomakhin | 99e84d0 | 2021-02-24 18:00:22 | [diff] [blame] | 16 | #include "content/public/common/content_features.h" |
Charlie Hu | e010cf2 | 2021-03-03 23:09:51 | [diff] [blame] | 17 | #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h" |
Rouslan Solomakhin | 3732b2f | 2020-08-27 16:48:13 | [diff] [blame] | 18 | |
Ken Buchanan | 0786d282 | 2020-08-26 18:59:28 | [diff] [blame] | 19 | namespace payments { |
| 20 | |
Rouslan Solomakhin | 99e84d0 | 2021-02-24 18:00:22 | [diff] [blame] | 21 | // static |
| 22 | bool PaymentCredential::IsFrameAllowedToUseSecurePaymentConfirmation( |
| 23 | content::RenderFrameHost* rfh) { |
Sreeja Kamishetty | e49854f8 | 2021-06-02 00:52:03 | [diff] [blame] | 24 | return rfh && rfh->IsActive() && |
Charlie Hu | 1b9da2c | 2021-03-04 18:51:30 | [diff] [blame] | 25 | rfh->IsFeatureEnabled( |
| 26 | blink::mojom::PermissionsPolicyFeature::kPayment) && |
Rouslan Solomakhin | 99e84d0 | 2021-02-24 18:00:22 | [diff] [blame] | 27 | base::FeatureList::IsEnabled(features::kSecurePaymentConfirmation); |
| 28 | } |
| 29 | |
Ken Buchanan | 0786d282 | 2020-08-26 18:59:28 | [diff] [blame] | 30 | PaymentCredential::PaymentCredential( |
Ian Vollick | a9f57fc | 2021-12-08 17:32:56 | [diff] [blame] | 31 | content::RenderFrameHost& render_frame_host, |
| 32 | mojo::PendingReceiver<mojom::PaymentCredential> receiver, |
| 33 | scoped_refptr<PaymentManifestWebDataService> web_data_service) |
danakj | c70aec1f | 2022-07-07 15:48:19 | [diff] [blame^] | 34 | : DocumentService(render_frame_host, std::move(receiver)), |
Ian Vollick | a9f57fc | 2021-12-08 17:32:56 | [diff] [blame] | 35 | web_data_service_(web_data_service) {} |
Ken Buchanan | 0786d282 | 2020-08-26 18:59:28 | [diff] [blame] | 36 | |
Rouslan Solomakhin | 9244d6d | 2020-11-04 22:51:24 | [diff] [blame] | 37 | PaymentCredential::~PaymentCredential() { |
Nick Burris | 787114bd | 2021-02-26 21:21:40 | [diff] [blame] | 38 | Reset(); |
Rouslan Solomakhin | 9244d6d | 2020-11-04 22:51:24 | [diff] [blame] | 39 | } |
Ken Buchanan | 0786d282 | 2020-08-26 18:59:28 | [diff] [blame] | 40 | |
Rouslan Solomakhin | 883df20 | 2021-08-27 01:12:54 | [diff] [blame] | 41 | void PaymentCredential::StorePaymentCredential( |
Ken Buchanan | 0786d282 | 2020-08-26 18:59:28 | [diff] [blame] | 42 | const std::vector<uint8_t>& credential_id, |
| 43 | const std::string& rp_id, |
Nick Burris | 9bd171af | 2021-12-09 21:27:58 | [diff] [blame] | 44 | const std::vector<uint8_t>& user_id, |
Rouslan Solomakhin | 883df20 | 2021-08-27 01:12:54 | [diff] [blame] | 45 | StorePaymentCredentialCallback callback) { |
| 46 | if (state_ != State::kIdle || !IsCurrentStateValid() || |
Nick Burris | 9bd171af | 2021-12-09 21:27:58 | [diff] [blame] | 47 | credential_id.empty() || rp_id.empty() || user_id.empty()) { |
Nick Burris | 787114bd | 2021-02-26 21:21:40 | [diff] [blame] | 48 | Reset(); |
Rouslan Solomakhin | 3732b2f | 2020-08-27 16:48:13 | [diff] [blame] | 49 | std::move(callback).Run( |
Stephen McGruer | a3c39f5 | 2021-11-15 23:05:59 | [diff] [blame] | 50 | mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL); |
Rouslan Solomakhin | 3732b2f | 2020-08-27 16:48:13 | [diff] [blame] | 51 | return; |
| 52 | } |
| 53 | |
Rouslan Solomakhin | 60fa4748 | 2021-03-11 15:58:39 | [diff] [blame] | 54 | RecordFirstSystemPromptResult( |
| 55 | SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted); |
| 56 | |
Nick Burris | c36ef58 | 2021-03-05 19:44:41 | [diff] [blame] | 57 | storage_callback_ = std::move(callback); |
Rouslan Solomakhin | 9fc7b77 | 2021-02-23 19:57:12 | [diff] [blame] | 58 | state_ = State::kStoringCredential; |
Nick Burris | c36ef58 | 2021-03-05 19:44:41 | [diff] [blame] | 59 | data_service_request_handle_ = |
Stephen McGruer | a3c39f5 | 2021-11-15 23:05:59 | [diff] [blame] | 60 | web_data_service_->AddSecurePaymentConfirmationCredential( |
| 61 | std::make_unique<SecurePaymentConfirmationCredential>(credential_id, |
Nick Burris | 9bd171af | 2021-12-09 21:27:58 | [diff] [blame] | 62 | rp_id, user_id), |
Nick Burris | e431fc6 | 2021-02-18 17:49:30 | [diff] [blame] | 63 | /*consumer=*/this); |
Sahel Sharify | f8b34573 | 2020-08-27 21:41:50 | [diff] [blame] | 64 | } |
| 65 | |
Rouslan Solomakhin | f1b2993 | 2021-02-22 19:40:04 | [diff] [blame] | 66 | void PaymentCredential::OnWebDataServiceRequestDone( |
| 67 | WebDataServiceBase::Handle h, |
| 68 | std::unique_ptr<WDTypedResult> result) { |
Nick Burris | c36ef58 | 2021-03-05 19:44:41 | [diff] [blame] | 69 | if (state_ != State::kStoringCredential || !IsCurrentStateValid() || |
| 70 | data_service_request_handle_ != h) { |
Nick Burris | 787114bd | 2021-02-26 21:21:40 | [diff] [blame] | 71 | Reset(); |
Rouslan Solomakhin | f1b2993 | 2021-02-22 19:40:04 | [diff] [blame] | 72 | return; |
| 73 | } |
| 74 | |
Nick Burris | c36ef58 | 2021-03-05 19:44:41 | [diff] [blame] | 75 | auto callback = std::move(storage_callback_); |
Nick Burris | 787114bd | 2021-02-26 21:21:40 | [diff] [blame] | 76 | Reset(); |
Rouslan Solomakhin | 60fa4748 | 2021-03-11 15:58:39 | [diff] [blame] | 77 | |
Rouslan Solomakhin | f1b2993 | 2021-02-22 19:40:04 | [diff] [blame] | 78 | std::move(callback).Run( |
| 79 | static_cast<WDResult<bool>*>(result.get())->GetValue() |
| 80 | ? mojom::PaymentCredentialStorageStatus::SUCCESS |
Stephen McGruer | a3c39f5 | 2021-11-15 23:05:59 | [diff] [blame] | 81 | : mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL); |
Rouslan Solomakhin | f1b2993 | 2021-02-22 19:40:04 | [diff] [blame] | 82 | } |
| 83 | |
Rouslan Solomakhin | 9fc7b77 | 2021-02-23 19:57:12 | [diff] [blame] | 84 | bool PaymentCredential::IsCurrentStateValid() const { |
danakj | c70aec1f | 2022-07-07 15:48:19 | [diff] [blame^] | 85 | if (!IsFrameAllowedToUseSecurePaymentConfirmation(&render_frame_host()) || |
Ian Vollick | a9f57fc | 2021-12-08 17:32:56 | [diff] [blame] | 86 | !web_data_service_) { |
Rouslan Solomakhin | 9fc7b77 | 2021-02-23 19:57:12 | [diff] [blame] | 87 | return false; |
| 88 | } |
| 89 | |
| 90 | switch (state_) { |
| 91 | case State::kIdle: |
Rouslan Solomakhin | 883df20 | 2021-08-27 01:12:54 | [diff] [blame] | 92 | return !storage_callback_ && !data_service_request_handle_; |
Rouslan Solomakhin | 9fc7b77 | 2021-02-23 19:57:12 | [diff] [blame] | 93 | |
| 94 | case State::kStoringCredential: |
Rouslan Solomakhin | 883df20 | 2021-08-27 01:12:54 | [diff] [blame] | 95 | return storage_callback_ && data_service_request_handle_; |
Rouslan Solomakhin | 60fa4748 | 2021-03-11 15:58:39 | [diff] [blame] | 96 | } |
| 97 | } |
| 98 | |
| 99 | void 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 Burris | 787114bd | 2021-02-26 21:21:40 | [diff] [blame] | 107 | void PaymentCredential::Reset() { |
Nick Burris | c36ef58 | 2021-03-05 19:44:41 | [diff] [blame] | 108 | // Callbacks must either be run or disconnected before being destroyed, so |
| 109 | // run them if they are still connected. |
Ian Vollick | a9f57fc | 2021-12-08 17:32:56 | [diff] [blame] | 110 | if (storage_callback_) { |
| 111 | std::move(storage_callback_) |
| 112 | .Run(mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL); |
Rouslan Solomakhin | f1b2993 | 2021-02-22 19:40:04 | [diff] [blame] | 113 | } |
Rouslan Solomakhin | 60fa4748 | 2021-03-11 15:58:39 | [diff] [blame] | 114 | |
Nick Burris | c36ef58 | 2021-03-05 19:44:41 | [diff] [blame] | 115 | if (web_data_service_ && data_service_request_handle_) { |
| 116 | web_data_service_->CancelRequest(data_service_request_handle_.value()); |
| 117 | } |
Rouslan Solomakhin | 60fa4748 | 2021-03-11 15:58:39 | [diff] [blame] | 118 | |
Nick Burris | c36ef58 | 2021-03-05 19:44:41 | [diff] [blame] | 119 | data_service_request_handle_.reset(); |
Rouslan Solomakhin | 60fa4748 | 2021-03-11 15:58:39 | [diff] [blame] | 120 | is_system_prompt_result_recorded_ = false; |
Rouslan Solomakhin | 9fc7b77 | 2021-02-23 19:57:12 | [diff] [blame] | 121 | state_ = State::kIdle; |
Ken Buchanan | 0786d282 | 2020-08-26 18:59:28 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | } // namespace payments |