chromium/content/browser/network/trust_token_browsertest.cc

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/network/trust_token_browsertest.h"

#include <memory>
#include <string>
#include <string_view>

#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/public/test/url_loader_monitor.h"
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/trust_token_http_headers.h"
#include "services/network/public/cpp/trust_token_parameterization.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/test/trust_token_request_handler.h"
#include "services/network/test/trust_token_test_server_handler_registration.h"
#include "services/network/test/trust_token_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/url_canon_stdstring.h"

namespace content {

namespace {

TrustTokenRequestHandler;
SignedRequest;
AllOf;
DescribeMatcher;
Eq;
ExplainMatchResult;
Field;
HasSubstr;
IsFalse;
IsSubsetOf;
Not;
Optional;
StrEq;
Truly;

MATCHER_P(HasHeader, name, base::StringPrintf("Has header %s", name)) {}

MATCHER_P2(HasHeader,
           name,
           other_matcher,
           "has header " + std::string(name) + " that " +
               DescribeMatcher<std::string>(other_matcher)) {}

MATCHER(
    ReflectsSigningFailure,
    "The given signed request reflects a client-side signing failure, having "
    "an empty redemption record and no other related headers.") {}

}  // namespace

TrustTokenBrowsertest::TrustTokenBrowsertest() {}

void TrustTokenBrowsertest::SetUpOnMainThread() {}

void TrustTokenBrowsertest::ProvideRequestHandlerKeyCommitmentsToNetworkService(
    std::vector<std::string_view> hosts) {}

std::string TrustTokenBrowsertest::IssuanceOriginFromHost(
    const std::string& host) const {}

void TrustTokenBrowsertest::OnTrustTokensAccessed(
    RenderFrameHost* render_frame_host,
    const TrustTokenAccessDetails& details) {}

void TrustTokenBrowsertest::OnTrustTokensAccessed(
    NavigationHandle* navigation_handle,
    const TrustTokenAccessDetails& details) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, FetchEndToEnd) {}

// Fetch is called directly from top level (a.test), issuer origin (b.test)
// is different from top frame origin.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, FetchEndToEndThirdParty) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, XhrEndToEnd) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, IframeSendRedemptionRecord) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       IframeCanOnlySendRedemptionRecord) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, HasTrustTokenAfterIssuance) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       SigningWithNoRedemptionRecordDoesntCancelRequest) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, FetchEndToEndInIsolatedWorld) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, RecordsTimers) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, RecordsNetErrorCodes) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, RecordsFetchFailureReasons) {}

// Trust Tokens should require that their executing contexts be secure.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, OperationsRequireSecureContext) {}

// Issuance should fail if we don't have keys for the issuer at hand.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, IssuanceRequiresKeys) {}

// When the server rejects issuance, the client-side issuance operation should
// fail.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       CorrectlyReportsServerErrorDuringIssuance) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, CrossOriginIssuanceWorks) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, CrossSiteIssuanceWorks) {}

// Issuance should succeed only if the number of issuers associated with the
// requesting context's top frame origin is less than the limit on the number of
// such issuers.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       IssuanceRespectsAssociatedIssuersCap) {}

// When an issuance request is made in cors mode, a cross-origin redirect from
// issuer A to issuer B should result in a new issuance request to issuer B,
// obtaining issuer B tokens on success.
//
// Note: For more on the interaction between Trust Tokens and redirects, see the
// "Handling redirects" section in the design doc
// https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.5erfr3uo012t
IN_PROC_BROWSER_TEST_F(
    TrustTokenBrowsertest,
    CorsModeCrossOriginRedirectIssuanceUsesNewOriginAsIssuer) {}

// When an issuance request is made in no-cors mode, a cross-origin redirect
// from issuer A to issuer B should result in recycling the original issuance
// request, obtaining issuer A tokens on success.
//
// Note: For more on the interaction between Trust Tokens and redirects, see the
// "Handling redirects" section in the design doc
// https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.5erfr3uo012t
IN_PROC_BROWSER_TEST_F(
    TrustTokenBrowsertest,
    NoCorsModeCrossOriginRedirectIssuanceUsesOriginalOriginAsIssuer) {}

// Issuance from a context with a secure-but-non-HTTP/S top frame origin
// should fail.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       IssuanceRequiresSuitableTopFrameOrigin) {}

// Redemption from a secure-but-non-HTTP(S) top frame origin should fail.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       RedemptionRequiresSuitableTopFrameOrigin) {}

// hasPrivateToken from a context with a secure-but-non-HTTP/S top frame
// origin should fail.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       HasTrustTokenRequiresSuitableTopFrameOrigin) {}

// A hasPrivateToken call initiated from a secure context should succeed
// even if the initiating frame's origin is opaque (e.g. from a sandboxed
// iframe).
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       HasTrustTokenFromSecureSubframeWithOpaqueOrigin) {}

// An operation initiated from a secure context should succeed even if the
// operation's associated request's initiator is opaque (e.g. from a sandboxed
// iframe with the right Permissions Policy).
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       OperationFromSecureSubframeWithOpaqueOrigin) {}

// If a server issues with a key not present in the client's collection of key
// commitments, the issuance operation should fail.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, IssuanceWithAbsentKeyFails) {}

// This regression test for crbug.com/1111735 ensures it's possible to execute
// redemption from a nested same-origin frame that hasn't committed a
// navigation.
//
// How it works: The main frame embeds a same-origin iframe that does not
// commit a navigation (here, specifically because of an HTTP 204 return). From
// this iframe, we execute a Trust Tokens redemption operation via the iframe
// interface (in other words, the Trust Tokens operation executes during the
// process of navigating to a grandchild frame).  The grandchild frame's load
// will result in a renderer kill without the fix for the bug applied.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       SignFromFrameLackingACommittedNavigation) {}

// Redemption should fail when there are no keys for the issuer.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, RedemptionRequiresKeys) {}

// Redemption should fail when there are no tokens to redeem.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, RedemptionRequiresTokens) {}

// When we have tokens for one issuer A, redemption against a different issuer B
// should still fail if we don't have any tokens for B.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       RedemptionWithoutTokensForDesiredIssuerFails) {}

// When the server rejects redemption, the client-side redemption operation
// should fail.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       CorrectlyReportsServerErrorDuringRedemption) {}

// After a successful issuance and redemption, a subsequent redemption against
// the same issuer should hit the redemption record cache.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       RedemptionHitsRedemptionRecordCache) {}

// Redemption with `refresh-policy: 'refresh'` from an issuer context should
// succeed, overwriting the existing redemption record.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       RefreshPolicyRefreshWorksInIssuerContext) {}

// Redemption with `refresh-policy: 'refresh'` from a non-issuer context should
// still work.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       RefreshPolicyRefreshRequiresIssuerContext) {}

// When a redemption request is made in cors mode, a cross-origin redirect from
// issuer A to issuer B should result in a new redemption request to issuer B,
// failing if there are no issuer B tokens.
//
// Note: For more on the interaction between Trust Tokens and redirects, see the
// "Handling redirects" section in the design doc
// https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.5erfr3uo012t
IN_PROC_BROWSER_TEST_F(
    TrustTokenBrowsertest,
    CorsModeCrossOriginRedirectRedemptionUsesNewOriginAsIssuer) {}

// When a redemption request is made in no-cors mode, a cross-origin redirect
// from issuer A to issuer B should result in recycling the original redemption
// request, obtaining an issuer A redemption record on success.
//
// Note: This isn't necessarily the behavior we'll end up wanting here; the test
// serves to document how redemption and redirects currently interact.  For more
// on the interaction between Trust Tokens and redirects, see the "Handling
// redirects" section in the design doc
// https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.5erfr3uo012t
IN_PROC_BROWSER_TEST_F(
    TrustTokenBrowsertest,
    NoCorsModeCrossOriginRedirectRedemptionUsesOriginalOriginAsIssuer) {}

// When a redemption request is made in no-cors mode, a cross-origin redirect
// from issuer A to issuer B should result in recycling the original redemption
// request and, in particular, sending the same token.
//
// Note: This isn't necessarily the behavior we'll end up wanting here; the test
// serves to document how redemption and redirects currently interact.
IN_PROC_BROWSER_TEST_F(
    TrustTokenBrowsertest,
    NoCorsModeCrossOriginRedirectRedemptionRecyclesSameRedemptionRequest) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       SigningRequiresRedemptionRecordInStorage) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, FetchEndToEndWithServiceWorker) {}

// Test redemption limit. Make three refreshing redemption calls back to back
// and test whether the third one fails. This test does not mock time. It
// assumes time (in network process) elapsed between the first and the last
// redemption call is less than the hard coded limit (currently 48 hours).
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, RedemptionLimit) {}

// Check whether depreciated fetch API where 'type' refers to operation
// type fails.
IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest, CheckDepreciatedTypeField) {}

IN_PROC_BROWSER_TEST_F(TrustTokenBrowsertest,
                       SendRedemptionRequestWithEmptyIssuers) {}

}  // namespace content