Commit 1067390e authored by Clemens Arbesser's avatar Clemens Arbesser Committed by Commit Bot

[Autofill Assistant] Extracted url utils to namespace for reuse.

This also refactors some of the calling methods to use GURL in favor of
plain strings. Unfortunately, the browse_domains_allowlist is currently
specified in an incompatible format without the http spec, so those are
still plain strings.

Bug: b/171776026
Change-Id: I4774209f71eef1b2ec6e5e8580d173e06bcd9ec2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2517447
Auto-Submit: Clemens Arbesser <arbesser@google.com>
Reviewed-by: default avatarMarian Fechete <marianfe@google.com>
Commit-Queue: Clemens Arbesser <arbesser@google.com>
Cr-Commit-Position: refs/heads/master@{#824793}
parent b680e487
...@@ -192,6 +192,8 @@ static_library("browser") { ...@@ -192,6 +192,8 @@ static_library("browser") {
"trigger_scripts/trigger_script_coordinator.cc", "trigger_scripts/trigger_script_coordinator.cc",
"trigger_scripts/trigger_script_coordinator.h", "trigger_scripts/trigger_script_coordinator.h",
"ui_delegate.h", "ui_delegate.h",
"url_utils.cc",
"url_utils.h",
"user_action.cc", "user_action.cc",
"user_action.h", "user_action.h",
"user_data.cc", "user_data.cc",
...@@ -353,6 +355,7 @@ source_set("unit_tests") { ...@@ -353,6 +355,7 @@ source_set("unit_tests") {
"trigger_scripts/static_trigger_conditions_unittest.cc", "trigger_scripts/static_trigger_conditions_unittest.cc",
"trigger_scripts/trigger_script_coordinator_unittest.cc", "trigger_scripts/trigger_script_coordinator_unittest.cc",
"trigger_scripts/trigger_script_unittest.cc", "trigger_scripts/trigger_script_unittest.cc",
"url_utils_unittest.cc",
"user_data_util_unittest.cc", "user_data_util_unittest.cc",
"user_model_unittest.cc", "user_model_unittest.cc",
"value_util_unittest.cc", "value_util_unittest.cc",
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "components/autofill_assistant/browser/protocol_utils.h" #include "components/autofill_assistant/browser/protocol_utils.h"
#include "components/autofill_assistant/browser/service/service_impl.h" #include "components/autofill_assistant/browser/service/service_impl.h"
#include "components/autofill_assistant/browser/trigger_context.h" #include "components/autofill_assistant/browser/trigger_context.h"
#include "components/autofill_assistant/browser/url_utils.h"
#include "components/autofill_assistant/browser/user_data.h" #include "components/autofill_assistant/browser/user_data.h"
#include "components/autofill_assistant/browser/view_layout.pb.h" #include "components/autofill_assistant/browser/view_layout.pb.h"
#include "components/google/core/common/google_util.h" #include "components/google/core/common/google_util.h"
...@@ -89,31 +90,6 @@ bool StateNeedsUiInLiteScript(AutofillAssistantState state) { ...@@ -89,31 +90,6 @@ bool StateNeedsUiInLiteScript(AutofillAssistantState state) {
} }
} }
// Check whether a domain is a subdomain of another domain.
bool IsSubdomainOf(const std::string& subdomain,
const std::string& parent_domain) {
return base::EndsWith(base::StringPiece(subdomain),
base::StringPiece("." + parent_domain),
base::CompareCase::INSENSITIVE_ASCII);
}
// Check whether two URLs have the same domain.
bool HasSameDomainAs(const GURL& a, const GURL& b) {
return a.host() == b.host();
}
// Check whether |subdomain| is a subdomain of a set of domains in |allowlist|.
bool IsInAllowlist(const std::string& subdomain,
const std::vector<std::string> allowlist) {
const GURL subdomain_gurl = GURL(subdomain);
for (const std::string& parent_domain : allowlist) {
if (HasSameDomainAs(subdomain_gurl, GURL(parent_domain)) ||
IsSubdomainOf(subdomain, parent_domain))
return true;
}
return false;
}
} // namespace } // namespace
Controller::Controller(content::WebContents* web_contents, Controller::Controller(content::WebContents* web_contents,
...@@ -834,7 +810,7 @@ void Controller::GetOrCheckScripts() { ...@@ -834,7 +810,7 @@ void Controller::GetOrCheckScripts() {
return; return;
const GURL& url = GetCurrentURL(); const GURL& url = GetCurrentURL();
if (!HasSameDomainAs(script_url_, url)) { if (script_url_.host() != url.host()) {
StopPeriodicScriptChecks(); StopPeriodicScriptChecks();
script_url_ = url; script_url_ = url;
#ifdef NDEBUG #ifdef NDEBUG
...@@ -908,7 +884,7 @@ void Controller::OnGetScripts(const GURL& url, ...@@ -908,7 +884,7 @@ void Controller::OnGetScripts(const GURL& url,
// If the domain of the current URL changed since the request was sent, the // If the domain of the current URL changed since the request was sent, the
// response is not relevant anymore and can be safely discarded. // response is not relevant anymore and can be safely discarded.
if (!HasSameDomainAs(script_url_, url)) if (script_url_.host() != url.host())
return; return;
if (http_status != net::HTTP_OK) { if (http_status != net::HTTP_OK) {
...@@ -1638,7 +1614,7 @@ void Controller::OnFatalError(const std::string& error_message, ...@@ -1638,7 +1614,7 @@ void Controller::OnFatalError(const std::string& error_message,
// never will. // never will.
MaybeReportFirstCheckDone(); MaybeReportFirstCheckDone();
if (tracking_ && HasSameDomainAs(script_url_, GetCurrentURL())) { if (tracking_ && script_url_.host() == GetCurrentURL().host()) {
// When tracking the controller should stays until the browser has navigated // When tracking the controller should stays until the browser has navigated
// away from the last domain that was checked to be able to tell callers // away from the last domain that was checked to be able to tell callers
// that the set of user actions is empty. // that the set of user actions is empty.
...@@ -1675,7 +1651,7 @@ void Controller::OnStop(const std::string& message, ...@@ -1675,7 +1651,7 @@ void Controller::OnStop(const std::string& message,
void Controller::PerformDelayedShutdownIfNecessary() { void Controller::PerformDelayedShutdownIfNecessary() {
if (delayed_shutdown_reason_ && if (delayed_shutdown_reason_ &&
!HasSameDomainAs(script_url_, GetCurrentURL())) { script_url_.host() != GetCurrentURL().host()) {
Metrics::DropOutReason reason = delayed_shutdown_reason_.value(); Metrics::DropOutReason reason = delayed_shutdown_reason_.value();
delayed_shutdown_reason_ = base::nullopt; delayed_shutdown_reason_ = base::nullopt;
tracking_ = false; tracking_ = false;
...@@ -1899,11 +1875,9 @@ void Controller::DidFinishNavigation( ...@@ -1899,11 +1875,9 @@ void Controller::DidFinishNavigation(
// from the original assisted domain. Subdomains of the original domain are // from the original assisted domain. Subdomains of the original domain are
// supported. // supported.
if (state_ == AutofillAssistantState::BROWSE) { if (state_ == AutofillAssistantState::BROWSE) {
auto current_host = web_contents()->GetLastCommittedURL().host(); if (!url_utils::IsInDomainOrSubDomain(GetCurrentURL(), script_url_) &&
auto script_host = script_url_.host(); !url_utils::IsInDomainOrSubDomain(GetCurrentURL(),
if (current_host != script_host && browse_domains_allowlist_)) {
!IsSubdomainOf(current_host, script_host) &&
!IsInAllowlist(current_host, browse_domains_allowlist_)) {
OnScriptError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_GIVE_UP), OnScriptError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_GIVE_UP),
Metrics::DropOutReason::DOMAIN_CHANGE_DURING_BROWSE_MODE); Metrics::DropOutReason::DOMAIN_CHANGE_DURING_BROWSE_MODE);
} }
......
// 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 "components/autofill_assistant/browser/url_utils.h"
#include <algorithm>
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
namespace {
bool IsInSubDomain(const GURL& url, const std::string& domain) {
return base::EndsWith(base::StringPiece(url.host()),
base::StringPiece("." + domain),
base::CompareCase::INSENSITIVE_ASCII);
}
} // namespace
namespace autofill_assistant {
namespace url_utils {
bool IsInDomainOrSubDomain(const GURL& url, const GURL& domain) {
if (url.host() == domain.host()) {
return true;
}
return IsInSubDomain(url, domain.host());
}
bool IsInDomainOrSubDomain(const GURL& url,
const std::vector<std::string>& allowed_domains) {
return std::find_if(allowed_domains.begin(), allowed_domains.end(),
[url](const std::string& allowed_domain) {
return url.host() == allowed_domain ||
IsInSubDomain(url, allowed_domain);
}) != allowed_domains.end();
}
} // namespace url_utils
} // namespace autofill_assistant
// 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.
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_URL_UTILS_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_URL_UTILS_H_
#include <string>
#include <vector>
#include "url/gurl.h"
namespace autofill_assistant {
namespace url_utils {
// Check whether |url| is in |domain| or in a subdomain of |domain|.
bool IsInDomainOrSubDomain(const GURL& url, const GURL& domain);
// Same as above, but checks against a vector of domains instead. Returns true
// if |url| is in |allowed_domains| or a subdomain of |allowed_domains|.
// NOTE: Domains should be specified without leading spec, e.g., "example.com".
bool IsInDomainOrSubDomain(const GURL& url,
const std::vector<std::string>& allowed_domains);
} // namespace url_utils
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_URL_UTILS_H_
// 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 "components/autofill_assistant/browser/url_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace autofill_assistant {
namespace url_utils {
namespace {
TEST(UrlUtilsTest, IsInDomainOrSubDomain) {
std::vector<std::string> allowed_domains = {"example.com",
"other-example.com"};
EXPECT_TRUE(IsInDomainOrSubDomain(GURL("http://a.example.com/"),
GURL("http://example.com")));
EXPECT_TRUE(
IsInDomainOrSubDomain(GURL("http://a.example.com/"), allowed_domains));
EXPECT_FALSE(IsInDomainOrSubDomain(GURL("http://other-example.com/"),
GURL("http://example.com")));
EXPECT_TRUE(IsInDomainOrSubDomain(GURL("http://other-example.com/"),
allowed_domains));
EXPECT_FALSE(IsInDomainOrSubDomain(GURL("http://sub.other-example.com/"),
GURL("http://example.com")));
EXPECT_TRUE(IsInDomainOrSubDomain(GURL("http://sub.other-example.com/"),
allowed_domains));
EXPECT_FALSE(IsInDomainOrSubDomain(GURL("http://example.different.com/"),
GURL("http://example.com")));
EXPECT_FALSE(IsInDomainOrSubDomain(GURL("http://example.different.com/"),
allowed_domains));
}
} // namespace
} // namespace url_utils
} // namespace autofill_assistant
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment