File: test_payment.py

package info (click to toggle)
python-fido2 2.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,456 kB
  • sloc: python: 11,423; javascript: 181; sh: 21; makefile: 9
file content (97 lines) | stat: -rw-r--r-- 2,922 bytes parent folder | download
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
import pytest

from fido2.client import Fido2Client
from fido2.ctap2.extensions import (
    PaymentCredentialInstrument,
    PaymentCurrencyAmount,
    ThirdPartyPaymentExtension,
)
from fido2.payment import (
    CollectedClientAdditionalPaymentData,
    PaymentClientDataCollector,
)
from fido2.server import Fido2Server

from . import TEST_PIN, CliInteraction


@pytest.fixture(autouse=True, scope="module")
def preconditions(dev_manager):
    if "thirdPartyPayment" not in dev_manager.info.extensions:
        pytest.skip("thirdPartyPayment not supported by authenticator")


def test_payment_extension(device, printer):
    rp = {"id": "example.com", "name": "Example RP"}
    server = Fido2Server(rp)
    user = {"id": b"user_id", "name": "A. User"}

    # Prepare parameters for makeCredential
    create_options, state = server.register_begin(
        user,
        resident_key_requirement="required",
        user_verification="required",
        authenticator_attachment="cross-platform",
    )

    client = Fido2Client(
        device,
        client_data_collector=PaymentClientDataCollector("https://example.com"),
        user_interaction=CliInteraction(printer, TEST_PIN),
        extensions=[ThirdPartyPaymentExtension()],
    )

    # Create a credential
    result = client.make_credential(
        {
            **create_options["publicKey"],
            "extensions": {"payment": {"isPayment": True}},
        }
    )

    # Complete registration
    auth_data = server.register_complete(state, result)
    credentials = [auth_data.credential_data]

    print("Payment credential created!")

    # Prepare parameters for getAssertion
    request_options, state = server.authenticate_begin(
        credentials, user_verification="required"
    )

    # Prepare payment options
    payment = CollectedClientAdditionalPaymentData(
        rp_id="example.com",
        top_origin="https://top.example.com",
        payee_name="Mr. Payee",
        payee_origin="https://payee.example.com",
        total=PaymentCurrencyAmount(
            currency="USD",
            value="1.00",
        ),
        instrument=PaymentCredentialInstrument(
            display_name="My Payment",
            icon="https://example.com/icon.png",
        ),
    )

    # Authenticate the credential
    result = client.get_assertion(
        {
            **request_options["publicKey"],
            "extensions": {
                "payment": dict(payment, isPayment=True),
            },
        }
    )

    # Only one cred in allowCredentials, only one response.
    result = result.get_response(0)

    # Verify that the key includes the payment extension
    assert result.response.authenticator_data.extensions["thirdPartyPayment"] is True

    # Verify that the client has added the payment data
    assert result.response.client_data.type == "payment.get"
    assert result.response.client_data.payment == payment