summaryrefslogtreecommitdiff
path: root/chromium/components/autofill/core/browser/payments/credit_card_cvc_authenticator.h
blob: 20fe78c46e81f2fcb73d06dab6f6b05b83853bba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_CVC_AUTHENTICATOR_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_CVC_AUTHENTICATOR_H_

#include <memory>

#include "base/strings/string16.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/data_model/credit_card.h"
#include "components/autofill/core/browser/payments/card_unmask_delegate.h"
#include "components/autofill/core/browser/payments/full_card_request.h"

namespace autofill {

// Authenticates credit card unmasking through CVC verification.
class CreditCardCVCAuthenticator
    : public payments::FullCardRequest::ResultDelegate,
      public payments::FullCardRequest::UIDelegate {
 public:
  struct CVCAuthenticationResponse {
    CVCAuthenticationResponse();
    ~CVCAuthenticationResponse();

    CVCAuthenticationResponse& with_did_succeed(bool b) {
      did_succeed = b;
      return *this;
    }
    // Data pointed to by |c| must outlive this object.
    CVCAuthenticationResponse& with_card(const CreditCard* c) {
      card = c;
      return *this;
    }
    CVCAuthenticationResponse& with_cvc(const base::string16 s) {
      cvc = base::string16(s);
      return *this;
    }
    CVCAuthenticationResponse& with_creation_options(
        base::Optional<base::Value> v) {
      creation_options = std::move(v);
      return *this;
    }
    CVCAuthenticationResponse& with_request_options(
        base::Optional<base::Value> v) {
      request_options = std::move(v);
      return *this;
    }
    CVCAuthenticationResponse& with_card_authorization_token(std::string s) {
      card_authorization_token = s;
      return *this;
    }
    bool did_succeed = false;
    const CreditCard* card = nullptr;
    base::string16 cvc = base::string16();
    base::Optional<base::Value> creation_options = base::nullopt;
    base::Optional<base::Value> request_options = base::nullopt;
    std::string card_authorization_token = std::string();
  };
  class Requester {
   public:
    virtual ~Requester() = default;
    virtual void OnCVCAuthenticationComplete(
        const CVCAuthenticationResponse& response) = 0;

#if defined(OS_ANDROID)
    // Returns whether or not the user, while on the CVC prompt, should be
    // offered to switch to FIDO authentication for card unmasking. This will
    // always be false for Desktop since FIDO authentication is offered as a
    // separate prompt after the CVC prompt. On Android, however, this is
    // offered through a checkbox on the CVC prompt. This feature does not yet
    // exist on iOS.
    virtual bool ShouldOfferFidoAuth() const = 0;

    // This returns true only on Android when the user previously opted-in for
    // FIDO authentication through the settings page and this is the first card
    // downstream since. In this case, the opt-in checkbox is not shown and the
    // opt-in request is sent.
    virtual bool UserOptedInToFidoFromSettingsPageOnMobile() const = 0;
#endif
  };
  explicit CreditCardCVCAuthenticator(AutofillClient* client);
  ~CreditCardCVCAuthenticator() override;

  // Authentication
  void Authenticate(const CreditCard* card,
                    base::WeakPtr<Requester> requester,
                    PersonalDataManager* personal_data_manager,
                    const base::TimeTicks& form_parsed_timestamp);

  // payments::FullCardRequest::ResultDelegate
  void OnFullCardRequestSucceeded(
      const payments::FullCardRequest& full_card_request,
      const CreditCard& card,
      const base::string16& cvc) override;
  void OnFullCardRequestFailed(
      payments::FullCardRequest::FailureType failure_type) override;

  // payments::FullCardRequest::UIDelegate
  void ShowUnmaskPrompt(const CreditCard& card,
                        AutofillClient::UnmaskCardReason reason,
                        base::WeakPtr<CardUnmaskDelegate> delegate) override;
  void OnUnmaskVerificationResult(
      AutofillClient::PaymentsRpcResult result) override;
#if defined(OS_ANDROID)
  bool ShouldOfferFidoAuth() const override;
  bool UserOptedInToFidoFromSettingsPageOnMobile() const override;
#endif

  payments::FullCardRequest* GetFullCardRequest();

  base::WeakPtr<payments::FullCardRequest::UIDelegate>
  GetAsFullCardRequestUIDelegate();

 private:
  friend class AutofillAssistantTest;
  friend class AutofillManagerTest;
  friend class AutofillMetricsTest;
  friend class CreditCardAccessManagerTest;
  friend class CreditCardCVCAuthenticatorTest;

  // The associated autofill client. Weak reference.
  AutofillClient* const client_;

  // Responsible for getting the full card details, including the PAN and the
  // CVC.
  std::unique_ptr<payments::FullCardRequest> full_card_request_;

  // Weak pointer to object that is requesting authentication.
  base::WeakPtr<Requester> requester_;

  base::WeakPtrFactory<CreditCardCVCAuthenticator> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(CreditCardCVCAuthenticator);
};

}  // namespace autofill

#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_CVC_AUTHENTICATOR_H_