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 "third_party/blink/renderer/core/html/trust_token_attribute_parsing.h"
6
7 #include "services/network/public/mojom/trust_tokens.mojom-blink.h"
8 #include "services/network/trust_tokens/test/trust_token_test_util.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/blink/renderer/platform/json/json_parser.h"
11 #include "third_party/blink/renderer/platform/json/json_values.h"
12 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
13 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
14
15 namespace blink {
16 namespace internal {
17 namespace {
18
NetworkParamsToBlinkParams(network::mojom::TrustTokenParamsPtr params)19 network::mojom::blink::TrustTokenParamsPtr NetworkParamsToBlinkParams(
20 network::mojom::TrustTokenParamsPtr params) {
21 auto ret = network::mojom::blink::TrustTokenParams::New();
22 ret->type = params->type;
23 ret->refresh_policy = params->refresh_policy;
24 ret->sign_request_data = params->sign_request_data;
25 ret->include_timestamp_header = params->include_timestamp_header;
26 if (params->issuer)
27 ret->issuer = SecurityOrigin::CreateFromUrlOrigin(*params->issuer);
28 for (const std::string& header : params->additional_signed_headers) {
29 ret->additional_signed_headers.push_back(String::FromUTF8(header));
30 }
31 return ret;
32 }
33
34 } // namespace
35
36 using TrustTokenAttributeParsingSuccess =
37 ::testing::TestWithParam<network::TrustTokenTestParameters>;
38
39 INSTANTIATE_TEST_SUITE_P(
40 WithIssuanceParams,
41 TrustTokenAttributeParsingSuccess,
42 ::testing::ValuesIn(network::kIssuanceTrustTokenTestParameters));
43 INSTANTIATE_TEST_SUITE_P(
44 WithRedemptionParams,
45 TrustTokenAttributeParsingSuccess,
46 ::testing::ValuesIn(network::kRedemptionTrustTokenTestParameters));
47 INSTANTIATE_TEST_SUITE_P(
48 WithSigningParams,
49 TrustTokenAttributeParsingSuccess,
50 ::testing::ValuesIn(network::kSigningTrustTokenTestParameters));
51
52 // Test roundtrip serializations-then-deserializations for a collection of test
53 // cases covering all possible values of all enum attributes, and all
54 // possibilities (e.g. optional members present vs. not present) for all other
55 // attributes.
TEST_P(TrustTokenAttributeParsingSuccess,Roundtrip)56 TEST_P(TrustTokenAttributeParsingSuccess, Roundtrip) {
57 network::mojom::TrustTokenParams network_expectation;
58 std::string input;
59
60 network::TrustTokenParametersAndSerialization
61 expected_params_and_serialization =
62 network::SerializeTrustTokenParametersAndConstructExpectation(
63 GetParam());
64
65 network::mojom::blink::TrustTokenParamsPtr expectation =
66 NetworkParamsToBlinkParams(
67 std::move(expected_params_and_serialization.params));
68
69 std::unique_ptr<JSONValue> json_value = ParseJSON(
70 String::FromUTF8(expected_params_and_serialization.serialized_params));
71 ASSERT_TRUE(json_value);
72 auto result = TrustTokenParamsFromJson(std::move(json_value));
73 ASSERT_TRUE(result);
74
75 // We can't use mojo's generated Equals method here because it doesn't play
76 // well with the "issuer" field's type of
77 // scoped_refptr<blink::SecurityOrigin>: in particular, the method does an
78 // address-to-address comparison of the pointers.
79 EXPECT_EQ(result->type, expectation->type);
80 EXPECT_EQ(result->refresh_policy, expectation->refresh_policy);
81 EXPECT_EQ(result->sign_request_data, expectation->sign_request_data);
82 EXPECT_EQ(result->include_timestamp_header,
83 expectation->include_timestamp_header);
84
85 EXPECT_EQ(!!result->issuer, !!expectation->issuer);
86 if (result->issuer)
87 EXPECT_EQ(result->issuer->ToString(), expectation->issuer->ToString());
88
89 EXPECT_EQ(result->additional_signed_headers,
90 expectation->additional_signed_headers);
91 }
92
TEST(TrustTokenAttributeParsing,NotADictionary)93 TEST(TrustTokenAttributeParsing, NotADictionary) {
94 auto json = ParseJSON(R"(
95 3
96 )");
97 ASSERT_TRUE(json);
98 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
99 }
100
TEST(TrustTokenAttributeParsing,MissingType)101 TEST(TrustTokenAttributeParsing, MissingType) {
102 auto json = ParseJSON(R"(
103 { }
104 )");
105 ASSERT_TRUE(json);
106 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
107 }
108
TEST(TrustTokenAttributeParsing,TypeUnsafeType)109 TEST(TrustTokenAttributeParsing, TypeUnsafeType) {
110 auto json = ParseJSON(R"(
111 { "type": 3 }
112 )");
113 ASSERT_TRUE(json);
114 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
115 }
116
TEST(TrustTokenAttributeParsing,InvalidType)117 TEST(TrustTokenAttributeParsing, InvalidType) {
118 auto json = ParseJSON(R"(
119 { "type": "not a valid type" }
120 )");
121 ASSERT_TRUE(json);
122 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
123 }
124
TEST(TrustTokenAttributeParsing,TypeUnsafeRefreshPolicy)125 TEST(TrustTokenAttributeParsing, TypeUnsafeRefreshPolicy) {
126 auto json = ParseJSON(R"(
127 { "type": "token-request",
128 "refreshPolicy": 3 }
129 )");
130 ASSERT_TRUE(json);
131 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
132 }
133
TEST(TrustTokenAttributeParsing,InvalidRefreshPolicy)134 TEST(TrustTokenAttributeParsing, InvalidRefreshPolicy) {
135 auto json = ParseJSON(R"(
136 { "type": "token-request",
137 "refreshPolicy": "not a valid refresh policy" }
138 )");
139 ASSERT_TRUE(json);
140 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
141 }
142
TEST(TrustTokenAttributeParsing,TypeUnsafeSignRequestData)143 TEST(TrustTokenAttributeParsing, TypeUnsafeSignRequestData) {
144 auto json = ParseJSON(R"(
145 { "type": "token-request",
146 "signRequestData": 3 }
147 )");
148 ASSERT_TRUE(json);
149 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
150 }
151
TEST(TrustTokenAttributeParsing,InvalidSignRequestData)152 TEST(TrustTokenAttributeParsing, InvalidSignRequestData) {
153 auto json = ParseJSON(R"(
154 { "type": "token-request",
155 "signRequestData": "not a member of the signRequestData enum" }
156 )");
157 ASSERT_TRUE(json);
158 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
159 }
160
TEST(TrustTokenAttributeParsing,TypeUnsafeIncludeTimestampHeader)161 TEST(TrustTokenAttributeParsing, TypeUnsafeIncludeTimestampHeader) {
162 auto json = ParseJSON(R"(
163 { "type": "token-request",
164 "includeTimestampHeader": 3 }
165 )");
166 ASSERT_TRUE(json);
167 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
168 }
169
TEST(TrustTokenAttributeParsing,TypeUnsafeIssuer)170 TEST(TrustTokenAttributeParsing, TypeUnsafeIssuer) {
171 auto json = ParseJSON(R"(
172 { "type": "token-request",
173 "issuer": 3 }
174 )");
175 ASSERT_TRUE(json);
176 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
177 }
178
179 // Test that the parser requires that |issuer| be a valid origin.
TEST(TrustTokenAttributeParsing,NonUrlIssuer)180 TEST(TrustTokenAttributeParsing, NonUrlIssuer) {
181 JSONParseError err;
182 auto json = ParseJSON(R"(
183 { "type": "token-request",
184 "issuer": "not a URL" }
185 )",
186 &err);
187 ASSERT_TRUE(json);
188 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
189 }
190
191 // Test that the parser requires that |issuer| be a potentially trustworthy
192 // origin.
TEST(TrustTokenAttributeParsing,InsecureIssuer)193 TEST(TrustTokenAttributeParsing, InsecureIssuer) {
194 auto json = ParseJSON(R"(
195 { "type": "token-request",
196 "issuer": "http://not-potentially-trustworthy.example" }
197 )");
198 ASSERT_TRUE(json);
199 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
200 }
201
202 // Test that the parser requires that |issuer| be a HTTP or HTTPS origin.
203 TEST(TrustTokenAttributeParsing, NonHttpNonHttpsIssuer) {
204 auto json = ParseJSON(R"(
205 { "type": "token-request",
206 "issuer": "file:///" }
207 )");
208 ASSERT_TRUE(json);
209 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
210 }
211
212 TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSignedHeaders) {
213 auto json = ParseJSON(R"(
214 { "type": "token-request",
215 "additionalSignedHeaders": 3}
216 )");
217 ASSERT_TRUE(json);
218 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
219 }
220
221 // Test that the parser requires that all members of the additionalSignedHeaders
222 // be strings.
223 TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSignedHeader) {
224 auto json = ParseJSON(R"(
225 { "type": "token-request",
226 "additionalSignedHeaders": ["plausible header", 17] }
227 )");
228 ASSERT_TRUE(json);
229 ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
230 }
231
232 } // namespace internal
233 } // namespace blink
234