Commit 73d4b9c4 authored by yilkal's avatar yilkal Committed by Commit Bot

Update WebTimeLimit url filter

This cl does the following:
1. Adds PrefChangeRegistrar to AppTimeController to enable it
to be notified when user policy has changed.
2. Enables prefs::kPerAppTimeLimitsWhitelistPolicy policy to be
used in WebtimeLimitEnforcer.

Bug: 1015661
Change-Id: Ifd5e0ddc3df9f564ffb018244e652c8b88586865
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1946936
Commit-Queue: Yilkal Abe <yilkal@chromium.org>
Reviewed-by: default avatarAga Wronska <agawronska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#729598}
parent 7076daa4
...@@ -808,6 +808,8 @@ source_set("chromeos") { ...@@ -808,6 +808,8 @@ source_set("chromeos") {
"child_accounts/time_limits/app_service_wrapper.h", "child_accounts/time_limits/app_service_wrapper.h",
"child_accounts/time_limits/app_time_controller.cc", "child_accounts/time_limits/app_time_controller.cc",
"child_accounts/time_limits/app_time_controller.h", "child_accounts/time_limits/app_time_controller.h",
"child_accounts/time_limits/app_time_limits_whitelist_policy_wrapper.cc",
"child_accounts/time_limits/app_time_limits_whitelist_policy_wrapper.h",
"child_accounts/time_limits/app_types.cc", "child_accounts/time_limits/app_types.cc",
"child_accounts/time_limits/app_types.h", "child_accounts/time_limits/app_types.h",
"child_accounts/time_limits/web_time_limit_enforcer.cc", "child_accounts/time_limits/web_time_limit_enforcer.cc",
......
...@@ -4,14 +4,20 @@ ...@@ -4,14 +4,20 @@
#include "chrome/browser/chromeos/child_accounts/time_limits/app_time_controller.h" #include "chrome/browser/chromeos/child_accounts/time_limits/app_time_controller.h"
#include "base/bind.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_activity_registry.h" #include "chrome/browser/chromeos/child_accounts/time_limits/app_activity_registry.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_service_wrapper.h" #include "chrome/browser/chromeos/child_accounts/time_limits/app_service_wrapper.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_time_limits_whitelist_policy_wrapper.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_enforcer.h" #include "chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_enforcer.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
namespace chromeos { namespace chromeos {
namespace app_time { namespace app_time {
...@@ -34,10 +40,54 @@ AppTimeController::AppTimeController(Profile* profile) ...@@ -34,10 +40,54 @@ AppTimeController::AppTimeController(Profile* profile)
DCHECK(profile); DCHECK(profile);
if (WebTimeLimitEnforcer::IsEnabled()) if (WebTimeLimitEnforcer::IsEnabled())
web_time_enforcer_ = std::make_unique<WebTimeLimitEnforcer>(); web_time_enforcer_ = std::make_unique<WebTimeLimitEnforcer>(this);
PrefService* pref_service = profile->GetPrefs();
RegisterProfilePrefObservers(pref_service);
} }
AppTimeController::~AppTimeController() = default; AppTimeController::~AppTimeController() = default;
bool AppTimeController::IsExtensionWhitelisted(
const std::string& extension_id) const {
NOTIMPLEMENTED();
return true;
}
void AppTimeController::RegisterProfilePrefObservers(
PrefService* pref_service) {
pref_registrar_ = std::make_unique<PrefChangeRegistrar>();
pref_registrar_->Init(pref_service);
// Adds callbacks to observe policy pref changes.
// Using base::Unretained(this) is safe here because when |pref_registrar_|
// gets destroyed, it will remove the observers from PrefService.
pref_registrar_->Add(
prefs::kPerAppTimeLimitsPolicy,
base::BindRepeating(&AppTimeController::TimeLimitsPolicyUpdated,
base::Unretained(this)));
pref_registrar_->Add(
prefs::kPerAppTimeLimitsWhitelistPolicy,
base::BindRepeating(&AppTimeController::TimeLimitsWhitelistPolicyUpdated,
base::Unretained(this)));
}
void AppTimeController::TimeLimitsPolicyUpdated(const std::string& pref_name) {
NOTIMPLEMENTED();
}
void AppTimeController::TimeLimitsWhitelistPolicyUpdated(
const std::string& pref_name) {
DCHECK_EQ(pref_name, prefs::kPerAppTimeLimitsWhitelistPolicy);
const base::DictionaryValue* policy = pref_registrar_->prefs()->GetDictionary(
prefs::kPerAppTimeLimitsWhitelistPolicy);
// Figure out a way to avoid cloning
AppTimeLimitsWhitelistPolicyWrapper wrapper(policy);
web_time_enforcer_->OnTimeLimitWhitelistChanged(wrapper);
}
} // namespace app_time } // namespace app_time
} // namespace chromeos } // namespace chromeos
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
class Profile; class Profile;
class PrefRegistrySimple; class PrefRegistrySimple;
class PrefChangeRegistrar;
class PrefService;
class Profile;
namespace chromeos { namespace chromeos {
namespace app_time { namespace app_time {
...@@ -30,6 +33,8 @@ class AppTimeController { ...@@ -30,6 +33,8 @@ class AppTimeController {
AppTimeController& operator=(const AppTimeController&) = delete; AppTimeController& operator=(const AppTimeController&) = delete;
~AppTimeController(); ~AppTimeController();
bool IsExtensionWhitelisted(const std::string& extension_id) const;
const WebTimeLimitEnforcer* web_time_enforcer() const { const WebTimeLimitEnforcer* web_time_enforcer() const {
return web_time_enforcer_.get(); return web_time_enforcer_.get();
} }
...@@ -37,9 +42,16 @@ class AppTimeController { ...@@ -37,9 +42,16 @@ class AppTimeController {
WebTimeLimitEnforcer* web_time_enforcer() { return web_time_enforcer_.get(); } WebTimeLimitEnforcer* web_time_enforcer() { return web_time_enforcer_.get(); }
private: private:
void RegisterProfilePrefObservers(PrefService* pref_service);
void TimeLimitsPolicyUpdated(const std::string& pref_name);
void TimeLimitsWhitelistPolicyUpdated(const std::string& pref_name);
std::unique_ptr<AppServiceWrapper> app_service_wrapper_; std::unique_ptr<AppServiceWrapper> app_service_wrapper_;
std::unique_ptr<AppActivityRegistry> app_registry_; std::unique_ptr<AppActivityRegistry> app_registry_;
std::unique_ptr<WebTimeLimitEnforcer> web_time_enforcer_; std::unique_ptr<WebTimeLimitEnforcer> web_time_enforcer_;
// Used to observe when policy preferences change.
std::unique_ptr<PrefChangeRegistrar> pref_registrar_;
}; };
} // namespace app_time } // namespace app_time
......
// Copyright 2019 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 "chrome/browser/chromeos/child_accounts/time_limits/app_time_limits_whitelist_policy_test_utils.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_time_limits_whitelist_policy_wrapper.h"
namespace chromeos {
namespace app_time {
AppTimeLimitsWhitelistPolicyBuilder::AppTimeLimitsWhitelistPolicyBuilder() =
default;
AppTimeLimitsWhitelistPolicyBuilder::~AppTimeLimitsWhitelistPolicyBuilder() =
default;
void AppTimeLimitsWhitelistPolicyBuilder::SetUp() {
value_ = base::Value(base::Value::Type::DICTIONARY);
value_.SetKey(kUrlList, base::Value(base::Value::Type::LIST));
value_.SetKey(kAppList, base::Value(base::Value::Type::LIST));
}
void AppTimeLimitsWhitelistPolicyBuilder::Clear() {
base::DictionaryValue* dict_value;
value_.GetAsDictionary(&dict_value);
dict_value->Clear();
}
void AppTimeLimitsWhitelistPolicyBuilder::AppendToWhitelistUrlList(
const std::string& scheme) {
AppendToList(kUrlList, base::Value(scheme));
}
void AppTimeLimitsWhitelistPolicyBuilder::AppendToWhitelistAppList(
const AppId& app_id) {
base::Value value_to_append(base::Value::Type::DICTIONARY);
value_to_append.SetKey(kAppId, base::Value(app_id.app_id()));
value_to_append.SetKey(kAppType,
base::Value(AppTypeToString(app_id.app_type())));
AppendToList(kAppList, std::move(value_to_append));
}
void AppTimeLimitsWhitelistPolicyBuilder::AppendToList(const std::string& key,
base::Value value) {
base::Value* list = value_.FindListKey(key);
DCHECK(list);
list->Append(std::move(value));
}
} // namespace app_time
} // namespace chromeos
// Copyright 2019 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 CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TIME_LIMITS_WHITELIST_POLICY_TEST_UTILS_H_
#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TIME_LIMITS_WHITELIST_POLICY_TEST_UTILS_H_
#include <string>
#include "base/values.h"
namespace chromeos {
namespace app_time {
class AppId;
class AppTimeLimitsWhitelistPolicyBuilder {
public:
AppTimeLimitsWhitelistPolicyBuilder();
~AppTimeLimitsWhitelistPolicyBuilder();
AppTimeLimitsWhitelistPolicyBuilder(
const AppTimeLimitsWhitelistPolicyBuilder&) = delete;
AppTimeLimitsWhitelistPolicyBuilder& operator=(
const AppTimeLimitsWhitelistPolicyBuilder&) = delete;
void SetUp();
void Clear();
void AppendToWhitelistUrlList(const std::string& scheme);
void AppendToWhitelistAppList(const AppId& app_id);
const base::Value& value() const { return value_; }
private:
void AppendToList(const std::string& key, base::Value value);
base::Value value_;
};
} // namespace app_time
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TIME_LIMITS_WHITELIST_POLICY_TEST_UTILS_H_
// Copyright 2019 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 "chrome/browser/chromeos/child_accounts/time_limits/app_time_limits_whitelist_policy_wrapper.h"
namespace chromeos {
namespace app_time {
const char kUrlList[] = "url_list";
const char kAppList[] = "app_list";
const char kAppId[] = "app_id";
const char kAppType[] = "app_type";
std::string AppTypeToString(apps::mojom::AppType app_type) {
switch (app_type) {
case apps::mojom::AppType::kArc:
return "ARC";
case apps::mojom::AppType::kBuiltIn:
return "BUILT-IN";
case apps::mojom::AppType::kCrostini:
return "CROSTINI";
case apps::mojom::AppType::kExtension:
return "EXTENSION";
case apps::mojom::AppType::kWeb:
return "WEB";
default:
NOTREACHED();
return "";
}
}
apps::mojom::AppType StringToAppType(const std::string& app_type) {
if (app_type == "ARC")
return apps::mojom::AppType::kArc;
if (app_type == "BUILD-IN")
return apps::mojom::AppType::kBuiltIn;
if (app_type == "CROSTINI")
return apps::mojom::AppType::kCrostini;
if (app_type == "EXTENSION")
return apps::mojom::AppType::kExtension;
if (app_type == "WEB")
return apps::mojom::AppType::kWeb;
NOTREACHED();
return apps::mojom::AppType::kUnknown;
}
AppTimeLimitsWhitelistPolicyWrapper::AppTimeLimitsWhitelistPolicyWrapper(
const base::Value* value)
: value_(value) {}
AppTimeLimitsWhitelistPolicyWrapper::~AppTimeLimitsWhitelistPolicyWrapper() =
default;
std::vector<std::string>
AppTimeLimitsWhitelistPolicyWrapper::GetWhitelistURLList() const {
const base::Value* list = value_->FindListKey(kUrlList);
DCHECK(list);
base::Value::ConstListView list_view = list->GetList();
std::vector<std::string> return_value;
for (const base::Value& value : list_view) {
return_value.push_back(value.GetString());
}
return return_value;
}
std::vector<AppId> AppTimeLimitsWhitelistPolicyWrapper::GetWhitelistAppList()
const {
const base::Value* app_list = value_->FindListKey(kAppList);
DCHECK(app_list);
base::Value::ConstListView list_view = app_list->GetList();
std::vector<AppId> return_value;
for (const base::Value& value : list_view) {
const std::string* app_id = value.FindStringKey(kAppId);
DCHECK(app_id);
const std::string* app_type = value.FindStringKey(kAppType);
DCHECK(app_type);
return_value.push_back(AppId(StringToAppType(*app_type), *app_id));
}
return return_value;
}
} // namespace app_time
} // namespace chromeos
// Copyright 2019 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 CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TIME_LIMITS_WHITELIST_POLICY_WRAPPER_H_
#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TIME_LIMITS_WHITELIST_POLICY_WRAPPER_H_
#include <string>
#include <vector>
#include "base/values.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_types.h"
namespace chromeos {
namespace app_time {
class AppId;
extern const char kUrlList[];
extern const char kAppList[];
extern const char kAppId[];
extern const char kAppType[];
std::string AppTypeToString(apps::mojom::AppType app_type);
apps::mojom::AppType StringToAppType(const std::string& app_type);
class AppTimeLimitsWhitelistPolicyWrapper {
public:
explicit AppTimeLimitsWhitelistPolicyWrapper(const base::Value* value);
~AppTimeLimitsWhitelistPolicyWrapper();
// Delete copy constructor and copy assign operator.
AppTimeLimitsWhitelistPolicyWrapper(
const AppTimeLimitsWhitelistPolicyWrapper&) = delete;
AppTimeLimitsWhitelistPolicyWrapper& operator=(
const AppTimeLimitsWhitelistPolicyWrapper&) = delete;
std::vector<std::string> GetWhitelistURLList() const;
std::vector<AppId> GetWhitelistAppList() const;
private:
const base::Value* value_;
};
} // namespace app_time
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMITS_APP_TIME_LIMITS_WHITELIST_POLICY_WRAPPER_H_
...@@ -8,10 +8,16 @@ ...@@ -8,10 +8,16 @@
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/values.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_time_controller.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_time_limits_whitelist_policy_wrapper.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_types.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "components/url_matcher/url_matcher.h"
#include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_controller.h"
#include "content/public/browser/reload_type.h" #include "content/public/browser/reload_type.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -19,28 +25,15 @@ ...@@ -19,28 +25,15 @@
namespace chromeos { namespace chromeos {
namespace app_time { namespace app_time {
namespace {
// URL schemes not on this list: (e.g., file:// and chrome://,
// chrome-extension:// ...) will always be allowed.
const char* const kFilteredSchemes[] = {"http", "https", "ftp", "ws", "wss"};
bool IsSchemeFiltered(const GURL& url) {
for (const auto* i : kFilteredSchemes) {
if (i == url.scheme())
return true;
}
return false;
}
} // namespace
// static // static
bool WebTimeLimitEnforcer::IsEnabled() { bool WebTimeLimitEnforcer::IsEnabled() {
return base::FeatureList::IsEnabled(features::kWebTimeLimits); return base::FeatureList::IsEnabled(features::kWebTimeLimits);
} }
WebTimeLimitEnforcer::WebTimeLimitEnforcer() = default; WebTimeLimitEnforcer::WebTimeLimitEnforcer(
AppTimeController* app_time_controller)
: app_time_controller_(app_time_controller) {}
WebTimeLimitEnforcer::~WebTimeLimitEnforcer() = default; WebTimeLimitEnforcer::~WebTimeLimitEnforcer() = default;
void WebTimeLimitEnforcer::OnWebTimeLimitReached() { void WebTimeLimitEnforcer::OnWebTimeLimitReached() {
...@@ -59,27 +52,44 @@ void WebTimeLimitEnforcer::OnWebTimeLimitEnded() { ...@@ -59,27 +52,44 @@ void WebTimeLimitEnforcer::OnWebTimeLimitEnded() {
ReloadAllWebContents(); ReloadAllWebContents();
} }
void WebTimeLimitEnforcer::OnWhitelistAdded(const GURL& url) { void WebTimeLimitEnforcer::OnTimeLimitWhitelistChanged(
auto result = whitelisted_urls_.insert(url); const AppTimeLimitsWhitelistPolicyWrapper& wrapper) {
bool inserted = result.second; std::vector<std::string> whitelisted_urls = wrapper.GetWhitelistURLList();
if (inserted && blocked())
ReloadAllWebContents(); // clean up |url_matcher_|;
} url_matcher_ = std::make_unique<url_matcher::URLMatcher>();
url_matcher::URLMatcherConditionSet::Vector condition_set_vector;
auto* condition_factory = url_matcher_->condition_factory();
int id = 0;
for (const auto& url : whitelisted_urls) {
url_matcher::URLMatcherCondition condition =
condition_factory->CreateURLMatchesCondition(url);
url_matcher::URLMatcherConditionSet::Conditions conditions;
conditions.insert(condition);
condition_set_vector.push_back(
base::MakeRefCounted<url_matcher::URLMatcherConditionSet>(id++,
conditions));
}
void WebTimeLimitEnforcer::OnWhitelistRemoved(const GURL& url) { url_matcher_->AddConditionSets(condition_set_vector);
if (!base::Contains(whitelisted_urls_, url))
return;
whitelisted_urls_.erase(url); // Filters have been updated. Now reload all WebContents.
if (blocked()) ReloadAllWebContents();
ReloadAllWebContents();
} }
bool WebTimeLimitEnforcer::IsURLWhitelisted(const GURL& url) const { bool WebTimeLimitEnforcer::IsURLWhitelisted(const GURL& url) const {
if (!IsSchemeFiltered(url)) // Block everything if |scheme_filter_| and |domain_matcher_| are not
return true; // instantiated yet.
if (!url_matcher_)
return false;
if (web_app::IsValidExtensionUrl(url))
return app_time_controller_->IsExtensionWhitelisted(url.host());
return base::Contains(whitelisted_urls_, url); auto matching_set_size = url_matcher_->MatchURL(url).size();
return matching_set_size > 0;
} }
void WebTimeLimitEnforcer::ReloadAllWebContents() { void WebTimeLimitEnforcer::ReloadAllWebContents() {
......
...@@ -13,14 +13,21 @@ ...@@ -13,14 +13,21 @@
class GURL; class GURL;
namespace url_matcher {
class URLMatcher;
} // namespace url_matcher
namespace chromeos { namespace chromeos {
namespace app_time { namespace app_time {
class AppTimeLimitsWhitelistPolicyWrapper;
class AppTimeController;
class WebTimeLimitEnforcer { class WebTimeLimitEnforcer {
public: public:
static bool IsEnabled(); static bool IsEnabled();
WebTimeLimitEnforcer(); explicit WebTimeLimitEnforcer(AppTimeController* controller);
~WebTimeLimitEnforcer(); ~WebTimeLimitEnforcer();
// Delete copy constructor and copy assignment operator. // Delete copy constructor and copy assignment operator.
...@@ -32,8 +39,8 @@ class WebTimeLimitEnforcer { ...@@ -32,8 +39,8 @@ class WebTimeLimitEnforcer {
// observer pattern has been set up for this. // observer pattern has been set up for this.
void OnWebTimeLimitReached(); void OnWebTimeLimitReached();
void OnWebTimeLimitEnded(); void OnWebTimeLimitEnded();
void OnWhitelistAdded(const GURL& url); void OnTimeLimitWhitelistChanged(
void OnWhitelistRemoved(const GURL& url); const AppTimeLimitsWhitelistPolicyWrapper& value);
bool IsURLWhitelisted(const GURL& url) const; bool IsURLWhitelisted(const GURL& url) const;
...@@ -47,7 +54,10 @@ class WebTimeLimitEnforcer { ...@@ -47,7 +54,10 @@ class WebTimeLimitEnforcer {
bool chrome_blocked_ = false; bool chrome_blocked_ = false;
base::TimeDelta time_limit_; base::TimeDelta time_limit_;
std::set<GURL> whitelisted_urls_; // |app_time_controller_| is owned by ChildUserService.
AppTimeController* const app_time_controller_;
std::unique_ptr<url_matcher::URLMatcher> url_matcher_;
}; };
} // namespace app_time } // namespace app_time
......
...@@ -6,16 +6,26 @@ ...@@ -6,16 +6,26 @@
#include <set> #include <set>
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/json/json_writer.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "chrome/browser/chromeos/child_accounts/child_user_service.h" #include "chrome/browser/chromeos/child_accounts/child_user_service.h"
#include "chrome/browser/chromeos/child_accounts/child_user_service_factory.h" #include "chrome/browser/chromeos/child_accounts/child_user_service_factory.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_time_controller.h" #include "chrome/browser/chromeos/child_accounts/time_limits/app_time_controller.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_time_limits_whitelist_policy_test_utils.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/app_types.h"
#include "chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_enforcer.h" #include "chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_enforcer.h"
#include "chrome/browser/chromeos/login/test/scoped_policy_update.h"
#include "chrome/browser/chromeos/login/test/user_policy_mixin.h"
#include "chrome/browser/chromeos/policy/user_policy_test_helper.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/supervised_user/logged_in_user_mixin.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/mixin_based_in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
...@@ -27,6 +37,7 @@ ...@@ -27,6 +37,7 @@
namespace { namespace {
constexpr char kExampleHost[] = "www.example.com"; constexpr char kExampleHost[] = "www.example.com";
constexpr char kSettingsPage[] = "chrome://settings";
class LoadFinishedWaiter : public content::WebContentsObserver { class LoadFinishedWaiter : public content::WebContentsObserver {
public: public:
...@@ -64,23 +75,29 @@ void LoadFinishedWaiter::DidFinishLoad( ...@@ -64,23 +75,29 @@ void LoadFinishedWaiter::DidFinishLoad(
run_loop_.Quit(); run_loop_.Quit();
} }
} }
} // namespace } // namespace
class WebTimeLimitEnforcerThrottleTest : public InProcessBrowserTest { class WebTimeLimitEnforcerThrottleTest : public MixinBasedInProcessBrowserTest {
protected: protected:
WebTimeLimitEnforcerThrottleTest() = default;
~WebTimeLimitEnforcerThrottleTest() override = default;
void SetUp() override; void SetUp() override;
void TearDown() override;
void SetUpOnMainThread() override; void SetUpOnMainThread() override;
bool IsErrorPageBeingShownInWebContents(content::WebContents* tab); bool IsErrorPageBeingShownInWebContents(content::WebContents* tab);
void WhitelistHost(const GURL& url); void WhitelistUrlRegx(const std::string& host);
void WhitelistApp(const chromeos::app_time::AppId& app_id);
void BlockWeb(); void BlockWeb();
chromeos::app_time::WebTimeLimitEnforcer* GetWebTimeLimitEnforcer(); chromeos::app_time::WebTimeLimitEnforcer* GetWebTimeLimitEnforcer();
private: private:
void UpdatePolicy();
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
chromeos::app_time::AppTimeLimitsWhitelistPolicyBuilder builder_;
chromeos::LoggedInUserMixin logged_in_user_mixin_{
&mixin_host_, chromeos::LoggedInUserMixin::LogInType::kChild,
embedded_test_server(), this};
}; };
void WebTimeLimitEnforcerThrottleTest::SetUp() { void WebTimeLimitEnforcerThrottleTest::SetUp() {
...@@ -88,16 +105,26 @@ void WebTimeLimitEnforcerThrottleTest::SetUp() { ...@@ -88,16 +105,26 @@ void WebTimeLimitEnforcerThrottleTest::SetUp() {
/* enabled_features */ {{features::kPerAppTimeLimits, /* enabled_features */ {{features::kPerAppTimeLimits,
features::kWebTimeLimits}}, features::kWebTimeLimits}},
/* disabled_features */ {{}}); /* disabled_features */ {{}});
InProcessBrowserTest::SetUp(); builder_.SetUp();
MixinBasedInProcessBrowserTest::SetUp();
}
void WebTimeLimitEnforcerThrottleTest::TearDown() {
builder_.Clear();
MixinBasedInProcessBrowserTest::TearDown();
} }
void WebTimeLimitEnforcerThrottleTest::SetUpOnMainThread() { void WebTimeLimitEnforcerThrottleTest::SetUpOnMainThread() {
InProcessBrowserTest::SetUpOnMainThread(); MixinBasedInProcessBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(embedded_test_server()->Started());
// Resolve everything to localhost. // Resolve everything to localhost.
host_resolver()->AddIPLiteralRule("*", "127.0.0.1", "localhost"); host_resolver()->AddIPLiteralRule("*", "127.0.0.1", "localhost");
logged_in_user_mixin_.LogInUser(false /*issue_any_scope_token*/,
true /*wait_for_active_session*/,
true /*request_policy_update*/);
} }
bool WebTimeLimitEnforcerThrottleTest::IsErrorPageBeingShownInWebContents( bool WebTimeLimitEnforcerThrottleTest::IsErrorPageBeingShownInWebContents(
...@@ -115,8 +142,16 @@ bool WebTimeLimitEnforcerThrottleTest::IsErrorPageBeingShownInWebContents( ...@@ -115,8 +142,16 @@ bool WebTimeLimitEnforcerThrottleTest::IsErrorPageBeingShownInWebContents(
return value; return value;
} }
void WebTimeLimitEnforcerThrottleTest::WhitelistHost(const GURL& url) { void WebTimeLimitEnforcerThrottleTest::WhitelistUrlRegx(
GetWebTimeLimitEnforcer()->OnWhitelistAdded(url); const std::string& url) {
builder_.AppendToWhitelistUrlList(url);
UpdatePolicy();
}
void WebTimeLimitEnforcerThrottleTest::WhitelistApp(
const chromeos::app_time::AppId& app_id) {
builder_.AppendToWhitelistAppList(app_id);
UpdatePolicy();
} }
void WebTimeLimitEnforcerThrottleTest::BlockWeb() { void WebTimeLimitEnforcerThrottleTest::BlockWeb() {
...@@ -135,6 +170,26 @@ WebTimeLimitEnforcerThrottleTest::GetWebTimeLimitEnforcer() { ...@@ -135,6 +170,26 @@ WebTimeLimitEnforcerThrottleTest::GetWebTimeLimitEnforcer() {
return child_user_service.web_time_enforcer(); return child_user_service.web_time_enforcer();
} }
void WebTimeLimitEnforcerThrottleTest::UpdatePolicy() {
std::string policy_value;
base::JSONWriter::Write(builder_.value(), &policy_value);
logged_in_user_mixin_.GetUserPolicyMixin()
->RequestPolicyUpdate()
->policy_payload()
->mutable_perapptimelimitswhitelist()
->set_value(policy_value);
const user_manager::UserManager* const user_manager =
user_manager::UserManager::Get();
Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(
user_manager->GetActiveUser());
logged_in_user_mixin_.GetUserPolicyTestHelper()->RefreshPolicyAndWait(
profile);
}
IN_PROC_BROWSER_TEST_F(WebTimeLimitEnforcerThrottleTest, IN_PROC_BROWSER_TEST_F(WebTimeLimitEnforcerThrottleTest,
WebBlockedBeforeBrowser) { WebBlockedBeforeBrowser) {
// Alright let's block the browser. // Alright let's block the browser.
...@@ -205,8 +260,7 @@ IN_PROC_BROWSER_TEST_F(WebTimeLimitEnforcerThrottleTest, ...@@ -205,8 +260,7 @@ IN_PROC_BROWSER_TEST_F(WebTimeLimitEnforcerThrottleTest,
WhitelistedURLNotBlocked) { WhitelistedURLNotBlocked) {
GURL url = embedded_test_server()->GetURL(kExampleHost, GURL url = embedded_test_server()->GetURL(kExampleHost,
"/supervised_user/simple.html"); "/supervised_user/simple.html");
WhitelistUrlRegx(kExampleHost);
GetWebTimeLimitEnforcer()->OnWhitelistAdded(url);
// Alright let's block the browser. // Alright let's block the browser.
GetWebTimeLimitEnforcer()->OnWebTimeLimitReached(); GetWebTimeLimitEnforcer()->OnWebTimeLimitReached();
...@@ -240,8 +294,29 @@ IN_PROC_BROWSER_TEST_F(WebTimeLimitEnforcerThrottleTest, ...@@ -240,8 +294,29 @@ IN_PROC_BROWSER_TEST_F(WebTimeLimitEnforcerThrottleTest,
LoadFinishedWaiter waiter(web_contents, url); LoadFinishedWaiter waiter(web_contents, url);
GetWebTimeLimitEnforcer()->OnWhitelistAdded(url); WhitelistUrlRegx(kExampleHost);
waiter.Wait(); waiter.Wait();
EXPECT_FALSE(IsErrorPageBeingShownInWebContents(web_contents)); EXPECT_FALSE(IsErrorPageBeingShownInWebContents(web_contents));
} }
IN_PROC_BROWSER_TEST_F(WebTimeLimitEnforcerThrottleTest,
WhitelistedSchemesNotBlocked) {
GURL url = GURL(kSettingsPage);
GetWebTimeLimitEnforcer()->OnWebTimeLimitReached();
NavigateParams params(browser(), url,
ui::PageTransition::PAGE_TRANSITION_LINK);
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
// Navigates and waits for loading to finish.
ui_test_utils::NavigateToURL(&params);
auto* web_contents = params.navigated_or_inserted_contents;
EXPECT_TRUE(IsErrorPageBeingShownInWebContents(web_contents));
// Whitelist the chrome scheme and ensure that the settings page is not
// blocked
LoadFinishedWaiter waiter(web_contents, url);
WhitelistUrlRegx("chrome://*");
waiter.Wait();
EXPECT_FALSE(IsErrorPageBeingShownInWebContents(web_contents));
}
...@@ -2114,6 +2114,8 @@ if (!is_android) { ...@@ -2114,6 +2114,8 @@ if (!is_android) {
"../browser/chromeos/child_accounts/parent_access_code/parent_access_test_utils.h", "../browser/chromeos/child_accounts/parent_access_code/parent_access_test_utils.h",
"../browser/chromeos/child_accounts/screen_time_controller_browsertest.cc", "../browser/chromeos/child_accounts/screen_time_controller_browsertest.cc",
"../browser/chromeos/child_accounts/time_limit_test_utils.cc", "../browser/chromeos/child_accounts/time_limit_test_utils.cc",
"../browser/chromeos/child_accounts/time_limits/app_time_limits_whitelist_policy_test_utils.cc",
"../browser/chromeos/child_accounts/time_limits/app_time_limits_whitelist_policy_test_utils.h",
"../browser/chromeos/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc", "../browser/chromeos/child_accounts/time_limits/web_time_limit_enforcer_browsertest.cc",
"../browser/chromeos/chrome_content_browser_client_chromeos_part_browsertest.cc", "../browser/chromeos/chrome_content_browser_client_chromeos_part_browsertest.cc",
"../browser/chromeos/customization/customization_document_browsertest.cc", "../browser/chromeos/customization/customization_document_browsertest.cc",
......
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