blob: 0eb18fa140e85eddab4955f59abae9650cd9466c [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/device_bound_sessions/cookie_craving.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/unguessable_token.h"
#include "net/base/features.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_access_params.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_partition_key.h"
#include "net/device_bound_sessions/proto/storage.pb.h"
#include "net/test/test_with_task_environment.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net::device_bound_sessions {
// Default values for tests.
constexpr char kUrlString[] = "https://www.example.test/foo";
constexpr char kName[] = "name";
const base::Time kCreationTime = base::Time::Now();
constexpr net::NetworkTrafficAnnotationTag kDummyAnnotation =
net::DefineNetworkTrafficAnnotation("dbsc_registration", "");
class CookieCravingTest : public TestWithTaskEnvironment {
protected:
CookieCravingTest()
: context_(CreateTestURLRequestContextBuilder()->Build()) {}
std::unique_ptr<URLRequestContext> context_;
};
// Helper to Create() and unwrap a CookieCraving, expecting it to be valid.
CookieCraving CreateValidCookieCraving(
const GURL& url,
const std::string& name,
const std::string& attributes,
base::Time creation_time = kCreationTime) {
std::optional<CookieCraving> maybe_cc =
CookieCraving::Create(url, name, attributes, creation_time);
EXPECT_TRUE(maybe_cc);
EXPECT_TRUE(maybe_cc->IsValid());
return std::move(*maybe_cc);
}
// Helper to create and unwrap a CanonicalCookie.
CanonicalCookie CreateCanonicalCookie(
const GURL& url,
const std::string& cookie_line,
base::Time creation_time = kCreationTime) {
std::unique_ptr<CanonicalCookie> canonical_cookie =
CanonicalCookie::CreateForTesting(url, cookie_line, creation_time,
/*server_time=*/std::nullopt);
EXPECT_TRUE(canonical_cookie);
EXPECT_TRUE(canonical_cookie->IsCanonical());
return *canonical_cookie;
}
TEST_F(CookieCravingTest, CreateBasic) {
// Default cookie.
CookieCraving cc = CreateValidCookieCraving(GURL(kUrlString), kName, "");
EXPECT_EQ(cc.Name(), kName);
EXPECT_EQ(cc.Domain(), "www.example.test");
EXPECT_EQ(cc.Path(), "/");
EXPECT_EQ(cc.CreationDate(), kCreationTime);
EXPECT_FALSE(cc.SecureAttribute());
EXPECT_FALSE(cc.IsHttpOnly());
EXPECT_EQ(cc.SameSite(), CookieSameSite::UNSPECIFIED);
EXPECT_EQ(cc.PartitionKey(), std::nullopt);
EXPECT_EQ(cc.SourceScheme(), CookieSourceScheme::kSecure);
EXPECT_EQ(cc.SourcePort(), 443);
// Non-default attributes.
cc = CreateValidCookieCraving(
GURL(kUrlString), kName,
"Secure; HttpOnly; Path=/foo; Domain=example.test; SameSite=Lax");
EXPECT_EQ(cc.Name(), kName);
EXPECT_EQ(cc.Domain(), ".example.test");
EXPECT_EQ(cc.Path(), "/foo");
EXPECT_EQ(cc.CreationDate(), kCreationTime);
EXPECT_TRUE(cc.SecureAttribute());
EXPECT_TRUE(cc.IsHttpOnly());
EXPECT_EQ(cc.SameSite(), CookieSameSite::LAX_MODE);
EXPECT_EQ(cc.PartitionKey(), std::nullopt);
EXPECT_EQ(cc.SourceScheme(), CookieSourceScheme::kSecure);
EXPECT_EQ(cc.SourcePort(), 443);
// Normalize whitespace.
cc = CreateValidCookieCraving(
GURL(kUrlString), " name ",
" Secure;HttpOnly;Path = /foo; Domain= example.test; SameSite =Lax ");
EXPECT_EQ(cc.Name(), "name");
EXPECT_EQ(cc.Domain(), ".example.test");
EXPECT_EQ(cc.Path(), "/foo");
EXPECT_EQ(cc.CreationDate(), kCreationTime);
EXPECT_TRUE(cc.SecureAttribute());
EXPECT_TRUE(cc.IsHttpOnly());
EXPECT_EQ(cc.SameSite(), CookieSameSite::LAX_MODE);
EXPECT_EQ(cc.PartitionKey(), std::nullopt);
EXPECT_EQ(cc.SourceScheme(), CookieSourceScheme::kSecure);
EXPECT_EQ(cc.SourcePort(), 443);
}
TEST_F(CookieCravingTest, CreateWithPrefix) {
// Valid __Host- cookie.
CookieCraving cc = CreateValidCookieCraving(GURL(kUrlString), "__Host-blah",
"Secure; Path=/");
EXPECT_EQ(cc.Domain(), "www.example.test");
EXPECT_EQ(cc.Path(), "/");
EXPECT_TRUE(cc.SecureAttribute());
// Valid __Secure- cookie.
cc = CreateValidCookieCraving(GURL(kUrlString), "__Secure-blah",
"Secure; Path=/foo; Domain=example.test");
EXPECT_TRUE(cc.SecureAttribute());
// Valid __Http- cookie.
cc = CreateValidCookieCraving(GURL(kUrlString), "__http-blah",
"secure;Path=/;httpOnly");
// CreateValidCookieCraving already verifies `cc` is valid.
}
// Test various strange inputs that should still be valid.
TEST_F(CookieCravingTest, CreateStrange) {
const char* kStrangeNames[] = {
// Leading and trailing whitespace should get trimmed.
" name ",
// Internal whitespace is allowed.
"n a m e",
// Trim leading and trailing whitespace while preserving internal
// whitespace.
" n a m e ",
};
for (const char* name : kStrangeNames) {
SCOPED_TRACE(base::StringPrintf("name: %s", name));
CookieCraving cc = CreateValidCookieCraving(GURL(kUrlString), name, "");
EXPECT_EQ(cc.Name(), base::TrimWhitespaceASCII(name, base::TRIM_ALL));
}
const char* kStrangeAttributesLines[] = {
// Capitalization.
"SECURE; PATH=/; SAMESITE=LAX",
// Extra whitespace.
" Secure; Path=/; SameSite=Lax ",
// No whitespace.
"Secure;Path=/;SameSite=Lax",
// Domain attribute with leading dot.
"Domain=.example.test",
// Different path from the URL is allowed.
"Path=/different",
// Path not beginning with '/' is allowed. (It's just ignored.)
"Path=noslash",
// Attributes with extraneous values.
"Secure=true; HttpOnly=yes; SameSite=absolutely",
// Unknown attribute values.
"SameSite=SuperStrict",
};
for (const char* attributes : kStrangeAttributesLines) {
CreateValidCookieCraving(GURL(kUrlString), kName, attributes);
}
}
// Another strange/maybe unexpected case is that Create() does not check the
// secureness of the URL against the cookie's Secure attribute. (This is
// documented in the method comment.)
TEST_F(CookieCravingTest, CreateSecureFromInsecureUrl) {
CookieCraving cc =
CreateValidCookieCraving(GURL("http://insecure.test"), kName, "Secure");
EXPECT_TRUE(cc.SecureAttribute());
EXPECT_EQ(cc.SourceScheme(), CookieSourceScheme::kNonSecure);
}
// Test inputs that should result in a failure to parse the cookie line.
TEST_F(CookieCravingTest, CreateFailParse) {
const struct {
const char* name;
const char* attributes;
} kParseFailInputs[] = {
// Empty name is not permitted.
{"", ""},
// Invalid characters in name.
{"blah\nsomething", "Secure; Path=/"},
{"blah=something", "Secure; Path=/"},
{"blah;something", "Secure; Path=/"},
// Truncated lines are blocked.
{"name", "Secure;\n Path=/"},
};
for (const auto& input : kParseFailInputs) {
std::optional<CookieCraving> cc = CookieCraving::Create(
GURL(kUrlString), input.name, input.attributes, kCreationTime);
EXPECT_FALSE(cc);
}
}
// Test cases where the Create() params are not valid.
TEST_F(CookieCravingTest, CreateFailInvalidParams) {
// Invalid URL.
std::optional<CookieCraving> cc =
CookieCraving::Create(GURL(), kName, "", kCreationTime);
EXPECT_FALSE(cc);
// Null creation time.
cc = CookieCraving::Create(GURL(kUrlString), kName, "", base::Time());
EXPECT_FALSE(cc);
}
TEST_F(CookieCravingTest, CreateFailBadDomain) {
// URL does not match domain.
std::optional<CookieCraving> cc = CookieCraving::Create(
GURL(kUrlString), kName, "Domain=other.test", kCreationTime);
EXPECT_FALSE(cc);
// Public suffix is not allowed to be Domain attribute.
cc = CookieCraving::Create(GURL(kUrlString), kName, "Domain=test",
kCreationTime);
EXPECT_FALSE(cc);
// IP addresses cannot set suffixes as the Domain attribute.
cc = CookieCraving::Create(GURL("http://1.2.3.4"), kName, "Domain=2.3.4",
kCreationTime);
EXPECT_FALSE(cc);
// Forbidden attributes even if the attribute is in the name field too.
cc = CookieCraving::Create(GURL(kUrlString), "partitioned", "partitioned",
kCreationTime);
EXPECT_FALSE(cc);
}
TEST_F(CookieCravingTest, CreateFailInvalidPrefix) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{features::kPrefixCookieHttp, features::kPrefixCookieHostHttp}, {});
// __Host- with insecure URL.
std::optional<CookieCraving> cc =
CookieCraving::Create(GURL("http://insecure.test"), "__Host-blah",
"Secure; Path=/", kCreationTime);
EXPECT_FALSE(cc);
// __Host- with non-Secure cookie.
cc = CookieCraving::Create(GURL(kUrlString), "__Host-blah", "Path=/",
kCreationTime);
EXPECT_FALSE(cc);
// __Host- with Domain attribute value.
cc = CookieCraving::Create(GURL(kUrlString), "__Host-blah",
"Secure; Path=/; Domain=example.test",
kCreationTime);
EXPECT_FALSE(cc);
// __Host- with non-root path.
cc = CookieCraving::Create(GURL(kUrlString), "__Host-blah",
"Secure; Path=/foo", kCreationTime);
EXPECT_FALSE(cc);
// __Secure- with non-Secure cookie.
cc = CookieCraving::Create(GURL(kUrlString), "__Secure-blah", "",
kCreationTime);
EXPECT_FALSE(cc);
// Prefixes are checked case-insensitively, so these CookieCravings are also
// invalid for not satisfying the prefix requirements.
// Missing Secure.
cc = CookieCraving::Create(GURL(kUrlString), "__host-blah", "Path=/",
kCreationTime);
EXPECT_FALSE(cc);
// Specifies Domain.
cc = CookieCraving::Create(GURL(kUrlString), "__HOST-blah",
"Secure; Path=/; Domain=example.test",
kCreationTime);
EXPECT_FALSE(cc);
// Missing Secure.
cc = CookieCraving::Create(GURL(kUrlString), "__SeCuRe-blah", "",
kCreationTime);
EXPECT_FALSE(cc);
cc = CookieCraving::Create(GURL(kUrlString), "__http-blah", "Path=/",
kCreationTime);
EXPECT_FALSE(cc);
cc = CookieCraving::Create(GURL(kUrlString), "__http-blah", "secure;Path=/",
kCreationTime);
EXPECT_FALSE(cc);
cc = CookieCraving::Create(GURL(kUrlString), "__host-http-blah", "Path=/",
kCreationTime);
EXPECT_FALSE(cc);
cc = CookieCraving::Create(GURL(kUrlString), "__host-http-blah",
"secure;Path=/", kCreationTime);
EXPECT_FALSE(cc);
// TODO(crbug.com/435221694): This kind of cookie should actually be valid and
// move to CreateWithPrefix test. See other TODOs linked to this bug for plans
// for the fix.
cc = CookieCraving::Create(GURL(kUrlString), "__host-http-blah",
"secure;Path=/;httpOnly", kCreationTime);
EXPECT_FALSE(cc);
cc = CookieCraving::Create(GURL(kUrlString), "__host-http-blah",
"secure;Path=/cookies/;httpOnly", kCreationTime);
EXPECT_FALSE(cc);
cc = CookieCraving::Create(GURL(kUrlString), "__host-http-blah",
"secure;Path=/;httpOnly;Domain=example.test",
kCreationTime);
EXPECT_FALSE(cc);
}
// Valid cases were tested as part of the successful Create() tests above, so
// this only tests the invalid cases.
TEST_F(CookieCravingTest, IsNotValid) {
const struct {
const char* name;
const char* domain;
const char* path;
bool secure;
base::Time creation = kCreationTime;
} kTestCases[] = {
// Invalid name.
{" name", "www.example.test", "/", true},
{";", "www.example.test", "/", true},
{"=", "www.example.test", "/", true},
{"na\nme", "www.example.test", "/", true},
// Empty domain.
{"name", "", "/", true},
// Non-canonical domain.
{"name", "ExAmPlE.test", "/", true},
// Empty path.
{"name", "www.example.test", "", true},
// Path not beginning with slash.
{"name", "www.example.test", "noslash", true},
// Invalid __Host- prefix.
{"__Host-name", ".example.test", "/", true},
{"__Host-name", "www.example.test", "/", false},
{"__Host-name", "www.example.test", "/foo", false},
// Invalid __Secure- prefix.
{"__Secure-name", "www.example.test", "/", false},
// Invalid __Host- prefix (case insensitive).
{"__HOST-name", ".example.test", "/", true},
{"__HoSt-name", "www.example.test", "/", false},
{"__host-name", "www.example.test", "/foo", false},
// Invalid __Secure- prefix (case insensitive).
{"__secure-name", "www.example.test", "/", false},
// Null creation date.
{"name", "www.example.test", "/", true, base::Time()},
};
for (const auto& test_case : kTestCases) {
CookieCraving cc = CookieCraving::CreateUnsafeForTesting(
test_case.name, test_case.domain, test_case.path, test_case.creation,
test_case.secure,
/*httponly=*/false, CookieSameSite::LAX_MODE,
CookieSourceScheme::kSecure, 443);
SCOPED_TRACE(cc.DebugString());
EXPECT_FALSE(cc.IsValid());
}
}
TEST_F(CookieCravingTest, IsSatisfiedBy) {
// Default case with no attributes.
CanonicalCookie canonical_cookie =
CreateCanonicalCookie(GURL(kUrlString), "name=somevalue");
CookieCraving cookie_craving =
CreateValidCookieCraving(GURL(kUrlString), "name", "");
EXPECT_TRUE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// With attributes.
canonical_cookie =
CreateCanonicalCookie(GURL(kUrlString),
"name=somevalue; Domain=example.test; Path=/; "
"Secure; HttpOnly; SameSite=Lax");
cookie_craving = CreateValidCookieCraving(
GURL(kUrlString), "name",
"Domain=example.test; Path=/; Secure; HttpOnly; SameSite=Lax");
EXPECT_TRUE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// The URL may differ as long as the cookie attributes match.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Domain=example.test");
cookie_craving = CreateValidCookieCraving(
GURL("https://subdomain.example.test"), "name", "Domain=example.test");
EXPECT_TRUE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Creation time is not required to match.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Domain=example.test", kCreationTime);
cookie_craving =
CreateValidCookieCraving(GURL(kUrlString), "name", "Domain=example.test",
kCreationTime + base::Hours(1));
EXPECT_TRUE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Source scheme and port (and indeed source host) are not required to match.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Domain=example.test");
cookie_craving =
CreateValidCookieCraving(GURL("http://subdomain.example.test:8080"),
"name", "Domain=example.test");
EXPECT_TRUE(cookie_craving.IsSatisfiedBy(canonical_cookie));
}
TEST_F(CookieCravingTest, IsNotSatisfiedBy) {
// Name does not match.
CanonicalCookie canonical_cookie =
CreateCanonicalCookie(GURL(kUrlString), "realname=somevalue");
CookieCraving cookie_craving =
CreateValidCookieCraving(GURL(kUrlString), "fakename", "");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Domain does not match.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Domain=example.test");
cookie_craving = CreateValidCookieCraving(GURL(kUrlString), "name",
"Domain=www.example.test");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Host cookie vs domain cookie.
canonical_cookie = CreateCanonicalCookie(GURL(kUrlString), "name=somevalue");
cookie_craving = CreateValidCookieCraving(GURL(kUrlString), "name",
"Domain=www.example.test");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Domain cookie vs host cookie.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Domain=www.example.test");
cookie_craving = CreateValidCookieCraving(GURL(kUrlString), "name", "");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Path does not match.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Domain=example.test; Path=/");
cookie_craving = CreateValidCookieCraving(GURL(kUrlString), "name",
"Domain=example.test; Path=/foo");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Secure vs non-Secure.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Secure; Domain=example.test; Path=/");
cookie_craving = CreateValidCookieCraving(GURL(kUrlString), "name",
"Domain=example.test; Path=/foo");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Non-Secure vs Secure.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Domain=example.test; Path=/");
cookie_craving = CreateValidCookieCraving(
GURL(kUrlString), "name", "Secure; Domain=example.test; Path=/foo");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// HttpOnly vs non-HttpOnly.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString),
"name=somevalue; HttpOnly; Domain=example.test; Path=/");
cookie_craving = CreateValidCookieCraving(GURL(kUrlString), "name",
"Domain=example.test; Path=/foo");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// Non-HttpOnly vs HttpOnly.
canonical_cookie = CreateCanonicalCookie(
GURL(kUrlString), "name=somevalue; Domain=example.test; Path=/");
cookie_craving = CreateValidCookieCraving(
GURL(kUrlString), "name", "HttpOnly; Domain=example.test; Path=/foo");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// SameSite does not match.
canonical_cookie =
CreateCanonicalCookie(GURL(kUrlString), "name=somevalue; SameSite=Lax");
cookie_craving =
CreateValidCookieCraving(GURL(kUrlString), "name", "SameSite=Strict");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
// SameSite vs unspecified SameSite. (Note that the SameSite attribute value
// is compared, not the effective SameSite enforcement mode.)
canonical_cookie =
CreateCanonicalCookie(GURL(kUrlString), "name=somevalue; SameSite=Lax");
cookie_craving = CreateValidCookieCraving(GURL(kUrlString), "name", "");
EXPECT_FALSE(cookie_craving.IsSatisfiedBy(canonical_cookie));
}
TEST_F(CookieCravingTest, BasicCookieToFromProto) {
// Default cookie.
CookieCraving cc = CreateValidCookieCraving(GURL(kUrlString), kName, "");
proto::CookieCraving proto = cc.ToProto();
EXPECT_EQ(proto.name(), kName);
EXPECT_EQ(proto.domain(), "www.example.test");
EXPECT_EQ(proto.path(), "/");
EXPECT_EQ(proto.creation_time(),
kCreationTime.ToDeltaSinceWindowsEpoch().InMicroseconds());
EXPECT_FALSE(proto.secure());
EXPECT_FALSE(proto.httponly());
EXPECT_EQ(proto.same_site(),
proto::CookieSameSite::COOKIE_SAME_SITE_UNSPECIFIED);
EXPECT_EQ(proto.source_scheme(), proto::CookieSourceScheme::SECURE);
EXPECT_EQ(proto.source_port(), 443);
std::optional<CookieCraving> restored_cc =
CookieCraving::CreateFromProto(proto);
ASSERT_TRUE(restored_cc.has_value());
EXPECT_TRUE(restored_cc->IsEqualForTesting(cc));
// Non-default attributes.
cc = CreateValidCookieCraving(
GURL(kUrlString), kName,
"Secure; HttpOnly; Path=/foo; Domain=example.test; SameSite=Lax");
proto = cc.ToProto();
EXPECT_EQ(proto.name(), kName);
EXPECT_EQ(proto.domain(), ".example.test");
EXPECT_EQ(proto.path(), "/foo");
EXPECT_EQ(proto.creation_time(),
kCreationTime.ToDeltaSinceWindowsEpoch().InMicroseconds());
EXPECT_TRUE(proto.secure());
EXPECT_TRUE(proto.httponly());
EXPECT_EQ(proto.same_site(), proto::CookieSameSite::LAX_MODE);
EXPECT_EQ(proto.source_scheme(), proto::CookieSourceScheme::SECURE);
EXPECT_EQ(proto.source_port(), 443);
restored_cc = CookieCraving::CreateFromProto(proto);
ASSERT_TRUE(restored_cc.has_value());
EXPECT_TRUE(restored_cc->IsEqualForTesting(cc));
}
TEST_F(CookieCravingTest, FailCreateFromInvalidProto) {
// Empty proto.
proto::CookieCraving proto;
std::optional<CookieCraving> cc = CookieCraving::CreateFromProto(proto);
EXPECT_FALSE(cc.has_value());
cc = CreateValidCookieCraving(
GURL(kUrlString), kName,
"Secure; HttpOnly; Path=/foo; Domain=example.test; SameSite=Lax");
proto = cc->ToProto();
// Missing parameters.
{
proto::CookieCraving p(proto);
p.clear_name();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
{
proto::CookieCraving p(proto);
p.clear_domain();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
{
proto::CookieCraving p(proto);
p.clear_path();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
{
proto::CookieCraving p(proto);
p.clear_secure();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
{
proto::CookieCraving p(proto);
p.clear_httponly();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
{
proto::CookieCraving p(proto);
p.clear_source_port();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
{
proto::CookieCraving p(proto);
p.clear_creation_time();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
{
proto::CookieCraving p(proto);
p.clear_same_site();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
{
proto::CookieCraving p(proto);
p.clear_source_scheme();
std::optional<CookieCraving> c = CookieCraving::CreateFromProto(p);
EXPECT_FALSE(c.has_value());
}
}
TEST_F(CookieCravingTest, ShouldIncludeCantCreateCanonicalCookie) {
// Create a CookieCraving that is able to create a valid CanonicalCookie.
CookieCraving cc_valid = CookieCraving::CreateUnsafeForTesting(
/*name=*/"name", "www.example.test", "/foo", kCreationTime,
/*secure=*/true,
/*httponly=*/true, CookieSameSite::LAX_MODE,
/*source_scheme=*/CookieSourceScheme::kSecure, /*source_port=*/443);
// Create a CookieCraving that won't be able to create a CanonicalCookie
// (empty name).
CookieCraving cc_invalid = CookieCraving::CreateUnsafeForTesting(
/*name=*/"", "www.example.test", "/foo", kCreationTime, /*secure=*/true,
/*httponly=*/true, CookieSameSite::LAX_MODE,
/*source_scheme=*/CookieSourceScheme::kSecure, /*source_port=*/443);
CookieOptions options;
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
options.set_include_httponly();
CookieAccessParams params{CookieAccessSemantics::NONLEGACY,
CookieScopeSemantics::UNKNOWN, false};
net::TestDelegate delegate;
std::unique_ptr<URLRequest> request = context_->CreateRequest(
GURL(kUrlString), IDLE, &delegate, kDummyAnnotation);
// Confirm the valid craving is able to be included in the request.
EXPECT_TRUE(cc_valid.ShouldIncludeForRequest(
request.get(), FirstPartySetMetadata(), options, params));
// Confirm that if somehow there were an invalid craving created, it would
// just not be included in the request instead of causing a crash.
EXPECT_FALSE(cc_invalid.ShouldIncludeForRequest(
request.get(), FirstPartySetMetadata(), options, params));
}
} // namespace net::device_bound_sessions