blob: d8bfdfa63eac231a0687142e509a7ccf262706ac [file] [log] [blame]
// Copyright 2020 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.
#include "third_party/blink/renderer/core/html/trust_token_attribute_parsing.h"
#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "services/network/trust_tokens/test/trust_token_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/json/json_parser.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
namespace internal {
namespace {
network::mojom::blink::TrustTokenParamsPtr NetworkParamsToBlinkParams(
network::mojom::TrustTokenParamsPtr params) {
auto ret = network::mojom::blink::TrustTokenParams::New();
ret->type = params->type;
ret->refresh_policy = params->refresh_policy;
ret->sign_request_data = params->sign_request_data;
ret->include_timestamp_header = params->include_timestamp_header;
for (const url::Origin& issuer : params->issuers) {
ret->issuers.push_back(SecurityOrigin::CreateFromUrlOrigin(issuer));
}
for (const std::string& header : params->additional_signed_headers) {
ret->additional_signed_headers.push_back(String::FromUTF8(header));
}
if (params->possibly_unsafe_additional_signing_data) {
ret->possibly_unsafe_additional_signing_data =
String::FromUTF8(*params->possibly_unsafe_additional_signing_data);
}
return ret;
}
} // namespace
using TrustTokenAttributeParsingSuccess =
::testing::TestWithParam<network::TrustTokenTestParameters>;
INSTANTIATE_TEST_SUITE_P(
WithIssuanceParams,
TrustTokenAttributeParsingSuccess,
::testing::ValuesIn(network::kIssuanceTrustTokenTestParameters));
INSTANTIATE_TEST_SUITE_P(
WithRedemptionParams,
TrustTokenAttributeParsingSuccess,
::testing::ValuesIn(network::kRedemptionTrustTokenTestParameters));
INSTANTIATE_TEST_SUITE_P(
WithSigningParams,
TrustTokenAttributeParsingSuccess,
::testing::ValuesIn(network::kSigningTrustTokenTestParameters));
// Test roundtrip serializations-then-deserializations for a collection of test
// cases covering all possible values of all enum attributes, and all
// possibilities (e.g. optional members present vs. not present) for all other
// attributes.
TEST_P(TrustTokenAttributeParsingSuccess, Roundtrip) {
network::mojom::TrustTokenParams network_expectation;
std::string input;
network::TrustTokenParametersAndSerialization
expected_params_and_serialization =
network::SerializeTrustTokenParametersAndConstructExpectation(
GetParam());
network::mojom::blink::TrustTokenParamsPtr expectation =
NetworkParamsToBlinkParams(
std::move(expected_params_and_serialization.params));
std::unique_ptr<JSONValue> json_value = ParseJSON(
String::FromUTF8(expected_params_and_serialization.serialized_params));
ASSERT_TRUE(json_value);
auto result = TrustTokenParamsFromJson(std::move(json_value));
ASSERT_TRUE(result);
// We can't use mojo's generated Equals method here because it doesn't play
// well with the "issuers" field's members' type of
// scoped_refptr<blink::SecurityOrigin>: in particular, the method does an
// address-to-address comparison of the pointers.
EXPECT_EQ(result->type, expectation->type);
EXPECT_EQ(result->refresh_policy, expectation->refresh_policy);
EXPECT_EQ(result->sign_request_data, expectation->sign_request_data);
EXPECT_EQ(result->include_timestamp_header,
expectation->include_timestamp_header);
EXPECT_EQ(result->issuers.size(), expectation->issuers.size());
for (size_t i = 0; i < result->issuers.size(); ++i) {
EXPECT_EQ(!!result->issuers.at(i), !!expectation->issuers.at(i));
if (result->issuers.at(i)) {
EXPECT_EQ(result->issuers.at(i)->ToString(),
expectation->issuers.at(i)->ToString());
}
}
EXPECT_EQ(result->additional_signed_headers,
expectation->additional_signed_headers);
EXPECT_EQ(result->possibly_unsafe_additional_signing_data,
expectation->possibly_unsafe_additional_signing_data);
}
TEST(TrustTokenAttributeParsing, NotADictionary) {
auto json = ParseJSON(R"(
3
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, MissingType) {
auto json = ParseJSON(R"(
{ }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, TypeUnsafeType) {
auto json = ParseJSON(R"(
{ "type": 3 }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, InvalidType) {
auto json = ParseJSON(R"(
{ "type": "not a valid type" }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, TypeUnsafeRefreshPolicy) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"refreshPolicy": 3 }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, InvalidRefreshPolicy) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"refreshPolicy": "not a valid refresh policy" }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, TypeUnsafeSignRequestData) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"signRequestData": 3 }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, InvalidSignRequestData) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"signRequestData": "not a member of the signRequestData enum" }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, TypeUnsafeIncludeTimestampHeader) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"includeTimestampHeader": 3 }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, NonListIssuers) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"issuers": 3 }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, EmptyIssuers) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"issuers": [] }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, WrongListTypeIssuers) {
JSONParseError err;
auto json = ParseJSON(R"(
{ "type": "token-request",
"issuers": [1995] }
)",
&err);
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
// Test that the parser requires each member of |issuers| be a valid origin.
TEST(TrustTokenAttributeParsing, NonUrlIssuer) {
JSONParseError err;
auto json = ParseJSON(R"(
{ "type": "token-request",
"issuers": ["https://ok.test", "not a URL"] }
)",
&err);
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
// Test that the parser requires that each member of |issuers| be a potentially
// trustworthy origin.
TEST(TrustTokenAttributeParsing, InsecureIssuer) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"issuers": ["https://trustworthy.example",
"http://not-potentially-trustworthy.example"] }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
// Test that the parser requires that each member of |issuers| be a HTTP or
// HTTPS origin.
TEST(TrustTokenAttributeParsing, NonHttpNonHttpsIssuer) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"issuers": ["https://ok.test", "file:///"] }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSignedHeaders) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"additionalSignedHeaders": 3}
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
// Test that the parser requires that all members of the additionalSignedHeaders
// be strings.
TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSignedHeader) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"additionalSignedHeaders": ["plausible header", 17] }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
// Test that the parser requires that additionalSigningData be a string.
TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSigningData) {
auto json = ParseJSON(R"(
{ "type": "token-request",
"additionalSigningData": 15 }
)");
ASSERT_TRUE(json);
ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
}
} // namespace internal
} // namespace blink