| // 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/session_inclusion_rules.h" |
| |
| #include <initializer_list> |
| |
| #include "base/strings/string_util.h" |
| #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| #include "net/device_bound_sessions/proto/storage.pb.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| #include "url/origin.h" |
| |
| namespace net::device_bound_sessions { |
| |
| namespace { |
| |
| using Result = SessionInclusionRules::InclusionResult; |
| |
| // These tests depend on the registry_controlled_domains code, so assert ahead |
| // of time that the eTLD+1 is what we expect, for clarity and to avoid confusing |
| // test failures. |
| #define ASSERT_DOMAIN_AND_REGISTRY(origin, expected_domain_and_registry) \ |
| { \ |
| ASSERT_EQ( \ |
| registry_controlled_domains::GetDomainAndRegistry( \ |
| origin, registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES), \ |
| expected_domain_and_registry) \ |
| << "Unexpected domain and registry."; \ |
| } |
| |
| struct EvaluateUrlTestCase { |
| const char* url; |
| Result expected_result; |
| }; |
| |
| void CheckEvaluateUrlTestCases( |
| const SessionInclusionRules& inclusion_rules, |
| std::initializer_list<EvaluateUrlTestCase> test_cases) { |
| for (const auto& test_case : test_cases) { |
| SCOPED_TRACE(test_case.url); |
| EXPECT_EQ(inclusion_rules.EvaluateRequestUrl(GURL(test_case.url)), |
| test_case.expected_result); |
| } |
| } |
| |
| struct AddUrlRuleTestCase { |
| Result rule_type; |
| const char* host_pattern; |
| const char* path_prefix; |
| bool expected_is_added; |
| }; |
| |
| void CheckAddUrlRuleTestCases( |
| SessionInclusionRules& inclusion_rules, |
| std::initializer_list<AddUrlRuleTestCase> test_cases) { |
| for (const auto& test_case : test_cases) { |
| SCOPED_TRACE(base::JoinString( |
| {test_case.host_pattern, test_case.path_prefix}, ", ")); |
| bool is_added = inclusion_rules.AddUrlRuleIfValid( |
| test_case.rule_type, test_case.host_pattern, test_case.path_prefix); |
| EXPECT_EQ(is_added, test_case.expected_is_added); |
| } |
| } |
| |
| TEST(SessionInclusionRulesTest, DefaultConstructorMatchesNothing) { |
| SessionInclusionRules inclusion_rules; |
| EXPECT_FALSE(inclusion_rules.may_include_site_for_testing()); |
| |
| EXPECT_EQ(Result::kExclude, |
| inclusion_rules.EvaluateRequestUrl(GURL("https://origin.test"))); |
| EXPECT_EQ(Result::kExclude, inclusion_rules.EvaluateRequestUrl(GURL())); |
| } |
| |
| TEST(SessionInclusionRulesTest, DefaultIncludeOriginMayNotIncludeSite) { |
| url::Origin subdomain_origin = |
| url::Origin::Create(GURL("https://some.site.test")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(subdomain_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{subdomain_origin}; |
| EXPECT_FALSE(inclusion_rules.may_include_site_for_testing()); |
| |
| CheckEvaluateUrlTestCases( |
| inclusion_rules, {// URL not valid. |
| {"", Result::kExclude}, |
| // Origins match. |
| {"https://some.site.test", Result::kInclude}, |
| // Path is allowed. |
| {"https://some.site.test/path", Result::kInclude}, |
| // Not same scheme. |
| {"http://some.site.test", Result::kExclude}, |
| // Not same host (same-site subdomain). |
| {"https://some.other.site.test", Result::kExclude}, |
| // Not same host (superdomain). |
| {"https://site.test", Result::kExclude}, |
| // Unrelated site. |
| {"https://unrelated.test", Result::kExclude}, |
| // Not same port. |
| {"https://some.site.test:8888", Result::kExclude}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, DefaultIncludeOriginThoughMayIncludeSite) { |
| url::Origin root_site_origin = url::Origin::Create(GURL("https://site.test")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(root_site_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{root_site_origin}; |
| EXPECT_TRUE(inclusion_rules.may_include_site_for_testing()); |
| |
| // All expectations are as above. Even though including the site is allowed, |
| // because the origin's host is its root eTLD+1, it is still limited to a |
| // default origin inclusion_rules because it did not set include_site. |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {// URL not valid. |
| {"", Result::kExclude}, |
| // Origins match. |
| {"https://site.test", Result::kInclude}, |
| // Path is allowed. |
| {"https://site.test/path", Result::kInclude}, |
| // Not same scheme. |
| {"http://site.test", Result::kExclude}, |
| // Not same host (same-site subdomain). |
| {"https://other.site.test", Result::kExclude}, |
| // Not same host (superdomain). |
| {"https://test", Result::kExclude}, |
| // Unrelated site. |
| {"https://unrelated.test", Result::kExclude}, |
| // Not same port. |
| {"https://site.test:8888", Result::kExclude}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, IncludeSiteAttemptedButNotAllowed) { |
| url::Origin subdomain_origin = |
| url::Origin::Create(GURL("https://some.site.test")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(subdomain_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{subdomain_origin}; |
| EXPECT_FALSE(inclusion_rules.may_include_site_for_testing()); |
| |
| // Only the origin is included. |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {{"https://some.site.test", Result::kInclude}, |
| {"https://other.site.test", Result::kExclude}}); |
| |
| // This shouldn't do anything. |
| inclusion_rules.SetIncludeSite(true); |
| EXPECT_FALSE(inclusion_rules.may_include_site_for_testing()); |
| |
| // Still only the origin is included. |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {{"https://some.site.test", Result::kInclude}, |
| {"https://other.site.test", Result::kExclude}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, IncludeSite) { |
| url::Origin root_site_origin = url::Origin::Create(GURL("https://site.test")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(root_site_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{root_site_origin}; |
| EXPECT_TRUE(inclusion_rules.may_include_site_for_testing()); |
| |
| inclusion_rules.SetIncludeSite(true); |
| |
| CheckEvaluateUrlTestCases( |
| inclusion_rules, {// URL not valid. |
| {"", Result::kExclude}, |
| // Origins match. |
| {"https://site.test", Result::kInclude}, |
| // Path is allowed. |
| {"https://site.test/path", Result::kInclude}, |
| // Not same scheme (site is schemeful). |
| {"http://site.test", Result::kExclude}, |
| // Same-site subdomain is allowed. |
| {"https://some.site.test", Result::kInclude}, |
| {"https://some.other.site.test", Result::kInclude}, |
| // Not same host (superdomain). |
| {"https://test", Result::kExclude}, |
| // Unrelated site. |
| {"https://unrelated.test", Result::kExclude}, |
| // Other port is allowed because whole site is included. |
| {"https://site.test:8888", Result::kInclude}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, AddUrlRuleToOriginOnly) { |
| url::Origin subdomain_origin = |
| url::Origin::Create(GURL("https://some.site.test")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(subdomain_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{subdomain_origin}; |
| EXPECT_FALSE(inclusion_rules.may_include_site_for_testing()); |
| |
| // Only the origin is allowed, since the setting origin is not the root |
| // eTLD+1. The only acceptable rules are limited to the origin/same host. |
| CheckAddUrlRuleTestCases( |
| inclusion_rules, |
| {// Host pattern equals origin's host. Path is valid. |
| {Result::kExclude, "some.site.test", "/static", true}, |
| // Add an opposite rule to check later. |
| {Result::kInclude, "some.site.test", "/static/included", true}, |
| // Path not valid. |
| {Result::kExclude, "some.site.test", "NotAPath", false}, |
| // Other host patterns not accepted. |
| {Result::kExclude, "*.site.test", "/", false}, |
| {Result::kExclude, "unrelated.test", "/", false}, |
| {Result::kExclude, "site.test", "/", false}, |
| {Result::kExclude, "other.site.test", "/", false}, |
| {Result::kExclude, "https://some.site.test", "/", false}, |
| {Result::kExclude, "some.site.test:443", "/", false}}); |
| |
| EXPECT_EQ(inclusion_rules.num_url_rules_for_testing(), 2u); |
| |
| CheckEvaluateUrlTestCases( |
| inclusion_rules, |
| {// Matches the rule. |
| {"https://some.site.test/static", Result::kExclude}, |
| // A path under the rule's path prefix is subject to the rule. |
| {"https://some.site.test/static/some/thing", Result::kExclude}, |
| // These do not match the rule, so are subject to the basic rules (the |
| // origin). |
| {"https://some.site.test/staticcccccccc", Result::kInclude}, |
| {"https://other.site.test/static", Result::kExclude}, |
| // The more recently added rule wins out. |
| {"https://some.site.test/static/included", Result::kInclude}}); |
| |
| // Note that what matters is when the rule was added, not how specific the URL |
| // path prefix is. Let's add another rule now to show that. |
| EXPECT_TRUE(inclusion_rules.AddUrlRuleIfValid(Result::kExclude, |
| "some.site.test", "/")); |
| EXPECT_EQ(Result::kExclude, inclusion_rules.EvaluateRequestUrl(GURL( |
| "https://some.site.test/static/included"))); |
| } |
| |
| TEST(SessionInclusionRulesTest, AddUrlRuleToOriginThatMayIncludeSite) { |
| url::Origin root_site_origin = url::Origin::Create(GURL("https://site.test")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(root_site_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{root_site_origin}; |
| EXPECT_TRUE(inclusion_rules.may_include_site_for_testing()); |
| |
| // Without any rules yet, the basic rules is just the origin, because |
| // include_site was not set. |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {{"https://site.test/static", Result::kInclude}, |
| {"https://other.site.test", Result::kExclude}}); |
| |
| // Since the origin's host is the root eTLD+1, it is allowed to set rules that |
| // affect URLs other than the setting origin (but still within the site). |
| CheckAddUrlRuleTestCases(inclusion_rules, |
| {{Result::kExclude, "excluded.site.test", "/", true}, |
| {Result::kInclude, "included.site.test", "/", true}, |
| {Result::kExclude, "site.test", "/static", true}, |
| // Rules outside of the site are not allowed. |
| {Result::kExclude, "unrelated.test", "/", false}}); |
| |
| EXPECT_EQ(inclusion_rules.num_url_rules_for_testing(), 3u); |
| |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {// Path is excluded by rule. |
| {"https://site.test/static", Result::kExclude}, |
| // Rule excludes URL explicitly. |
| {"https://excluded.site.test", Result::kExclude}, |
| // Rule includes URL explicitly. |
| {"https://included.site.test", Result::kInclude}, |
| // Rule does not apply to wrong scheme. |
| {"http://included.site.test", Result::kExclude}, |
| // No rules applies to these URLs, so the basic |
| // rules (origin) applies. |
| {"https://other.site.test", Result::kExclude}, |
| {"https://site.test/stuff", Result::kInclude}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, AddUrlRuleToRulesIncludingSite) { |
| url::Origin root_site_origin = url::Origin::Create(GURL("https://site.test")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(root_site_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{root_site_origin}; |
| EXPECT_TRUE(inclusion_rules.may_include_site_for_testing()); |
| |
| inclusion_rules.SetIncludeSite(true); |
| |
| // Without any rules yet, the basic rules is the site. |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {{"https://site.test/static", Result::kInclude}, |
| {"https://other.site.test", Result::kInclude}}); |
| |
| // Since the origin's host is the root eTLD+1, it is allowed to set rules that |
| // affect URLs other than the setting origin (but still within the site). |
| CheckAddUrlRuleTestCases(inclusion_rules, |
| {{Result::kExclude, "excluded.site.test", "/", true}, |
| {Result::kInclude, "included.site.test", "/", true}, |
| {Result::kExclude, "site.test", "/static", true}, |
| // Rules outside of the site are not allowed. |
| {Result::kExclude, "unrelated.test", "/", false}}); |
| |
| EXPECT_EQ(inclusion_rules.num_url_rules_for_testing(), 3u); |
| |
| CheckEvaluateUrlTestCases( |
| inclusion_rules, |
| {// Path is excluded by rule. |
| {"https://site.test/static", Result::kExclude}, |
| // Rule excludes URL explicitly. |
| {"https://excluded.site.test", Result::kExclude}, |
| // Rule includes URL explicitly. |
| {"https://included.site.test", Result::kInclude}, |
| // Rule does not apply to wrong scheme. |
| {"http://included.site.test", Result::kExclude}, |
| // No rule applies to these URLs, so the basic rules (site) applies. |
| {"https://other.site.test", Result::kInclude}, |
| {"https://site.test/stuff", Result::kInclude}}); |
| |
| // Note that the rules are independent of "include_site", so even if that is |
| // "revoked" the rules still work the same way. |
| inclusion_rules.SetIncludeSite(false); |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {// Path is excluded by rule. |
| {"https://site.test/static", Result::kExclude}, |
| // Rule excludes URL explicitly. |
| {"https://excluded.site.test", Result::kExclude}, |
| // Rule includes URL explicitly. |
| {"https://included.site.test", Result::kInclude}, |
| // No rules applies to these URLs, so the basic |
| // rules (which is now the origin) applies. |
| {"https://other.site.test", Result::kExclude}, |
| {"https://site.test/stuff", Result::kInclude}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, UrlRuleParsing) { |
| url::Origin root_site_origin = url::Origin::Create(GURL("https://site.test")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(root_site_origin, "site.test"); |
| |
| // Use the most permissive type of inclusion_rules, to hit the interesting |
| // edge cases. |
| SessionInclusionRules inclusion_rules{root_site_origin}; |
| EXPECT_TRUE(inclusion_rules.may_include_site_for_testing()); |
| |
| CheckAddUrlRuleTestCases( |
| inclusion_rules, |
| {// Empty host pattern not permitted. |
| {Result::kExclude, "", "/", false}, |
| // Host pattern that is only whitespace is not permitted. |
| {Result::kExclude, " ", "/", false}, |
| // Forbidden characters in host_pattern. |
| {Result::kExclude, "https://site.test", "/", false}, |
| {Result::kExclude, "site.test:8888", "/", false}, |
| {Result::kExclude, "site.test,other.test", "/", false}, |
| // Non-IPv6-allowable characters within the brackets. |
| {Result::kExclude, "[*.:abcd::3:4:ff]", "/", false}, |
| {Result::kExclude, "[1:ab+cd::3:4:ff]", "/", false}, |
| {Result::kExclude, "[[1:abcd::3:4:ff]]", "/", false}, |
| // Internal wildcard characters are forbidden in the host pattern. |
| {Result::kExclude, "sub.*.site.test", "/", false}, |
| // Multiple wildcard characters are forbidden in the host pattern. |
| {Result::kExclude, "*.sub.*.site.test", "/", false}, |
| // Wildcard must be followed by a dot. |
| {Result::kExclude, "*site.test", "/", false}, |
| // Wildcard must be followed by a non-eTLD. |
| {Result::kExclude, "*.com", "/", false}, |
| // Other sites are not allowed. |
| {Result::kExclude, "unrelated.site", "/", false}, |
| // Other hosts with no registrable domain are not allowed. |
| {Result::kExclude, "4.31.198.44", "/", false}, |
| {Result::kExclude, "[1:abcd::3:4:ff]", "/", false}, |
| {Result::kExclude, "co.uk", "/", false}, |
| {Result::kExclude, "com", "/", false}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, UrlRuleParsingTopLevelDomain) { |
| url::Origin tld_origin = url::Origin::Create(GURL("https://com")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(tld_origin, ""); |
| |
| SessionInclusionRules inclusion_rules{tld_origin}; |
| EXPECT_FALSE(inclusion_rules.may_include_site_for_testing()); |
| |
| CheckAddUrlRuleTestCases( |
| inclusion_rules, |
| {// Exact host is allowed. |
| {Result::kExclude, "com", "/", true}, |
| // Wildcards are not permitted. |
| {Result::kExclude, "*.com", "/", false}, |
| // Other hosts with no registrable domain are not allowed. |
| {Result::kExclude, "4.31.198.44", "/", false}, |
| {Result::kExclude, "[1:abcd::3:4:ff]", "/", false}, |
| {Result::kExclude, "co.uk", "/", false}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, UrlRuleParsingIPv4Address) { |
| url::Origin ip_origin = url::Origin::Create(GURL("https://4.31.198.44")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(ip_origin, ""); |
| |
| SessionInclusionRules inclusion_rules{ip_origin}; |
| EXPECT_FALSE(inclusion_rules.may_include_site_for_testing()); |
| |
| CheckAddUrlRuleTestCases( |
| inclusion_rules, |
| {// Exact host is allowed. |
| {Result::kExclude, "4.31.198.44", "/", true}, |
| // Wildcards are not permitted. |
| {Result::kExclude, "*.31.198.44", "/", false}, |
| {Result::kExclude, "*.4.31.198.44", "/", false}, |
| // Other hosts with no registrable domain are not allowed. |
| {Result::kExclude, "[1:abcd::3:4:ff]", "/", false}, |
| {Result::kExclude, "co.uk", "/", false}, |
| {Result::kExclude, "com", "/", false}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, UrlRuleParsingIPv6Address) { |
| url::Origin ipv6_origin = |
| url::Origin::Create(GURL("https://[1:abcd::3:4:ff]")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(ipv6_origin, ""); |
| |
| SessionInclusionRules inclusion_rules{ipv6_origin}; |
| EXPECT_FALSE(inclusion_rules.may_include_site_for_testing()); |
| |
| CheckAddUrlRuleTestCases( |
| inclusion_rules, |
| {// Exact host is allowed. |
| {Result::kExclude, "[1:abcd::3:4:ff]", "/", true}, |
| // Wildcards are not permitted. |
| {Result::kExclude, "*.[1:abcd::3:4:ff]", "/", false}, |
| // Brackets mismatched. |
| {Result::kExclude, "[1:abcd::3:4:ff", "/", false}, |
| {Result::kExclude, "1:abcd::3:4:ff]", "/", false}, |
| // Non-IPv6-allowable characters within the brackets. |
| {Result::kExclude, "[*.:abcd::3:4:ff]", "/", false}, |
| {Result::kExclude, "[1:ab+cd::3:4:ff]", "/", false}, |
| {Result::kExclude, "[[1:abcd::3:4:ff]]", "/", false}, |
| // Other hosts with no registrable domain are not allowed. |
| {Result::kExclude, "4.31.198.44", "/", false}, |
| {Result::kExclude, "co.uk", "/", false}, |
| {Result::kExclude, "com", "/", false}}); |
| } |
| |
| // This test is more to document the current behavior than anything else. We may |
| // discover a need for more comprehensive support for port numbers in the |
| // future, in which case: |
| // TODO(chlily): Support port numbers in URL rules. |
| TEST(SessionInclusionRulesTest, NonstandardPort) { |
| url::Origin nonstandard_port_origin = |
| url::Origin::Create(GURL("https://site.test:8888")); |
| |
| ASSERT_DOMAIN_AND_REGISTRY(nonstandard_port_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{nonstandard_port_origin}; |
| EXPECT_TRUE(inclusion_rules.may_include_site_for_testing()); |
| |
| // Without any URL rules, the default origin rule allows only the same origin. |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {{"https://site.test", Result::kExclude}, |
| {"https://site.test:8888", Result::kInclude}, |
| {"https://other.site.test", Result::kExclude}}); |
| |
| // If we include_site, then same-site URLs regardless of port number are |
| // included. |
| inclusion_rules.SetIncludeSite(true); |
| CheckEvaluateUrlTestCases(inclusion_rules, |
| {{"https://site.test", Result::kInclude}, |
| {"https://site.test:8888", Result::kInclude}, |
| {"https://site.test:1234", Result::kInclude}, |
| {"https://other.site.test", Result::kInclude}}); |
| |
| // However, adding URL rules to an inclusion_rules based on such an origin may |
| // lead to unintuitive outcomes. It is not possible to specify a rule that |
| // applies to the same origin as the setting origin if the setting origin has |
| // a nonstandard port. |
| CheckAddUrlRuleTestCases( |
| inclusion_rules, |
| {// The pattern is rejected due to the colon, despite being the |
| // same origin. |
| {Result::kExclude, "site.test:8888", "/", false}, |
| // A rule with the same host without port specified is accepted. |
| // This rule applies to any URL with the specified host. |
| {Result::kExclude, "site.test", "/", true}, |
| // Any explicitly specified port is rejected (due to the colon), |
| // even if it's the standard one. |
| {Result::kExclude, "site.test:443", "/", false}}); |
| |
| EXPECT_EQ(inclusion_rules.num_url_rules_for_testing(), 1u); |
| |
| CheckEvaluateUrlTestCases( |
| inclusion_rules, |
| {// This is same-origin but gets caught in the "site.test" rule because |
| // the rule didn't specify a port. |
| {"https://site.test:8888", Result::kExclude}, |
| // This is same-site but gets caught in the "site.test" rule because |
| // the rule didn't specify a port. |
| {"https://site.test:1234", Result::kExclude}, |
| // Same-site is included by basic rules. |
| {"https://other.site.test", Result::kInclude}, |
| // Also excluded explicitly by rule. |
| {"https://site.test", Result::kExclude}, |
| {"https://site.test:443", Result::kExclude}}); |
| } |
| |
| TEST(SessionInclusionRulesTest, ToFromProto) { |
| // Create a valid SessionInclusionRules object with default inclusion rule and |
| // a couple of additional URL rules. |
| url::Origin root_site_origin = url::Origin::Create(GURL("https://site.test")); |
| ASSERT_DOMAIN_AND_REGISTRY(root_site_origin, "site.test"); |
| |
| SessionInclusionRules inclusion_rules{root_site_origin}; |
| EXPECT_TRUE(inclusion_rules.may_include_site_for_testing()); |
| inclusion_rules.SetIncludeSite(true); |
| EXPECT_TRUE(inclusion_rules.AddUrlRuleIfValid(Result::kExclude, |
| "excluded.site.test", "/")); |
| EXPECT_TRUE(inclusion_rules.AddUrlRuleIfValid(Result::kInclude, |
| "included.site.test", "/")); |
| |
| // Create a corresponding proto object and validate. |
| proto::SessionInclusionRules proto = inclusion_rules.ToProto(); |
| EXPECT_EQ(root_site_origin.Serialize(), proto.origin()); |
| EXPECT_TRUE(proto.do_include_site()); |
| ASSERT_EQ(proto.url_rules().size(), 2); |
| { |
| const auto& rule = proto.url_rules(0); |
| EXPECT_EQ(rule.rule_type(), proto::RuleType::EXCLUDE); |
| EXPECT_EQ(rule.host_matcher_rule(), "excluded.site.test"); |
| EXPECT_EQ(rule.path_prefix(), "/"); |
| } |
| { |
| const auto& rule = proto.url_rules(1); |
| EXPECT_EQ(rule.rule_type(), proto::RuleType::INCLUDE); |
| EXPECT_EQ(rule.host_matcher_rule(), "included.site.test"); |
| EXPECT_EQ(rule.path_prefix(), "/"); |
| } |
| |
| // Create a SessionInclusionRules object from the proto and verify |
| // that it is the same as the original. |
| std::unique_ptr<SessionInclusionRules> restored_inclusion_rules = |
| SessionInclusionRules::CreateFromProto(proto); |
| ASSERT_TRUE(restored_inclusion_rules != nullptr); |
| EXPECT_EQ(*restored_inclusion_rules, inclusion_rules); |
| } |
| |
| TEST(SessionInclusionRulesTest, FailCreateFromInvalidProto) { |
| // Empty proto. |
| { |
| proto::SessionInclusionRules proto; |
| EXPECT_FALSE(SessionInclusionRules::CreateFromProto(proto)); |
| } |
| // Opaque origin. |
| { |
| proto::SessionInclusionRules proto; |
| proto.set_origin("about:blank"); |
| proto.set_do_include_site(false); |
| EXPECT_FALSE(SessionInclusionRules::CreateFromProto(proto)); |
| } |
| // Create a fully populated proto. |
| url::Origin root_site_origin = url::Origin::Create(GURL("https://site.test")); |
| SessionInclusionRules inclusion_rules{root_site_origin}; |
| inclusion_rules.SetIncludeSite(true); |
| inclusion_rules.AddUrlRuleIfValid(Result::kExclude, "excluded.site.test", |
| "/"); |
| inclusion_rules.AddUrlRuleIfValid(Result::kInclude, "included.site.test", |
| "/"); |
| proto::SessionInclusionRules proto = inclusion_rules.ToProto(); |
| |
| // Test for missing proto fields by clearing the fields one at a time. |
| { |
| proto::SessionInclusionRules p(proto); |
| p.clear_origin(); |
| EXPECT_FALSE(SessionInclusionRules::CreateFromProto(p)); |
| } |
| { |
| proto::SessionInclusionRules p(proto); |
| p.clear_do_include_site(); |
| EXPECT_FALSE(SessionInclusionRules::CreateFromProto(p)); |
| } |
| // URL rules with missing parameters. |
| { |
| proto::SessionInclusionRules p(proto); |
| p.mutable_url_rules(0)->clear_rule_type(); |
| EXPECT_FALSE(SessionInclusionRules::CreateFromProto(p)); |
| } |
| { |
| proto::SessionInclusionRules p(proto); |
| p.mutable_url_rules(0)->clear_host_matcher_rule(); |
| EXPECT_FALSE(SessionInclusionRules::CreateFromProto(p)); |
| } |
| { |
| proto::SessionInclusionRules p(proto); |
| p.mutable_url_rules(0)->clear_path_prefix(); |
| EXPECT_FALSE(SessionInclusionRules::CreateFromProto(p)); |
| } |
| } |
| |
| } // namespace |
| |
| } // namespace net::device_bound_sessions |