blob: b886aa93fdaa827ee1f4c9f3718d57d514dee2ba [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 "services/network/trust_tokens/has_trust_tokens_answerer.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
#include "services/network/public/mojom/trust_tokens.mojom.h"
#include "services/network/trust_tokens/pending_trust_token_store.h"
#include "services/network/trust_tokens/trust_token_parameterization.h"
#include "services/network/trust_tokens/trust_token_store.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace network {
TEST(HasTrustTokensAnswerer, HandlesInsecureIssuerOrigin) {
PendingTrustTokenStore pending_store;
auto answerer = std::make_unique<HasTrustTokensAnswerer>(
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")),
&pending_store);
mojom::HasTrustTokensResultPtr result;
// Providing an insecure issuer origin should make the operation fail.
answerer->HasTrustTokens(
url::Origin::Create(GURL("http://issuer.com")),
base::BindLambdaForTesting(
[&](mojom::HasTrustTokensResultPtr obtained_result) {
result = std::move(obtained_result);
}));
ASSERT_TRUE(result);
EXPECT_EQ(result->status, mojom::TrustTokenOperationStatus::kInvalidArgument);
}
TEST(HasTrustTokensAnswerer, HandlesNonHttpNonHttpsIssuerOrigin) {
PendingTrustTokenStore pending_store;
auto answerer = std::make_unique<HasTrustTokensAnswerer>(
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com")),
&pending_store);
mojom::HasTrustTokensResultPtr result;
// Providing a secure but non-HTTP(S) issuer origin should make the operation
// fail.
answerer->HasTrustTokens(
url::Origin::Create(GURL("file:///hello.txt")),
base::BindLambdaForTesting(
[&](mojom::HasTrustTokensResultPtr obtained_result) {
result = std::move(obtained_result);
}));
ASSERT_TRUE(result);
EXPECT_EQ(result->status, mojom::TrustTokenOperationStatus::kInvalidArgument);
}
TEST(HasTrustTokensAnswerer, HandlesFailureToAssociateIssuer) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateForTesting();
const SuitableTrustTokenOrigin kToplevel =
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com"));
// This max-number-of-issuer limit is expected to be quite small (as of
// writing, 2).
for (int i = 0; i < kTrustTokenPerToplevelMaxNumberOfAssociatedIssuers; ++i) {
ASSERT_TRUE(store->SetAssociation(
*SuitableTrustTokenOrigin::Create(
GURL(base::StringPrintf("https://issuer%d.com", i))),
kToplevel));
}
PendingTrustTokenStore pending_store;
pending_store.OnStoreReady(std::move(store));
auto answerer =
std::make_unique<HasTrustTokensAnswerer>(kToplevel, &pending_store);
mojom::HasTrustTokensResultPtr result;
// Since there's no capacity to associate the issuer with the top-level
// origin, the operation should fail.
answerer->HasTrustTokens(
url::Origin::Create(GURL("https://issuer.com")),
base::BindLambdaForTesting(
[&](mojom::HasTrustTokensResultPtr obtained_result) {
result = std::move(obtained_result);
}));
ASSERT_TRUE(result);
EXPECT_EQ(result->status,
mojom::TrustTokenOperationStatus::kResourceExhausted);
}
TEST(HasTrustTokensAnswerer, SuccessWithNoTokens) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateForTesting();
TrustTokenStore* raw_store = store.get();
const SuitableTrustTokenOrigin kIssuer =
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com"));
const SuitableTrustTokenOrigin kToplevel =
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com"));
PendingTrustTokenStore pending_store;
pending_store.OnStoreReady(std::move(store));
auto answerer =
std::make_unique<HasTrustTokensAnswerer>(kToplevel, &pending_store);
mojom::HasTrustTokensResultPtr result;
// Since there's no capacity to associate the issuer with the top-level
// origin, the operation should fail.
answerer->HasTrustTokens(
kIssuer, base::BindLambdaForTesting(
[&](mojom::HasTrustTokensResultPtr obtained_result) {
result = std::move(obtained_result);
}));
ASSERT_TRUE(result);
EXPECT_EQ(result->status, mojom::TrustTokenOperationStatus::kOk);
EXPECT_FALSE(result->has_trust_tokens);
// The query should have associated the issuer with the top-level origin.
EXPECT_TRUE(raw_store->IsAssociated(kIssuer, kToplevel));
}
TEST(HasTrustTokensAnswerer, SuccessWithTokens) {
std::unique_ptr<TrustTokenStore> store = TrustTokenStore::CreateForTesting();
TrustTokenStore* raw_store = store.get();
const SuitableTrustTokenOrigin kIssuer =
*SuitableTrustTokenOrigin::Create(GURL("https://issuer.com"));
const SuitableTrustTokenOrigin kToplevel =
*SuitableTrustTokenOrigin::Create(GURL("https://toplevel.com"));
PendingTrustTokenStore pending_store;
pending_store.OnStoreReady(std::move(store));
auto answerer =
std::make_unique<HasTrustTokensAnswerer>(kToplevel, &pending_store);
// Populate the store, giving the issuer a key commitment for the key "issuing
// key" and a token issued with that key.
raw_store->AddTokens(kIssuer, std::vector<std::string>{"token"},
"issuing key");
mojom::HasTrustTokensResultPtr result;
// Since there's no capacity to associate the issuer with the top-level
// origin, the operation should fail.
answerer->HasTrustTokens(
kIssuer, base::BindLambdaForTesting(
[&](mojom::HasTrustTokensResultPtr obtained_result) {
result = std::move(obtained_result);
}));
ASSERT_TRUE(result);
EXPECT_EQ(result->status, mojom::TrustTokenOperationStatus::kOk);
EXPECT_TRUE(result->has_trust_tokens);
}
} // namespace network