| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/enterprise/incognito/incognito_navigation_throttle.h" |
| |
| #include "base/i18n/message_formatter.h" |
| #include "base/numerics/safe_conversions.h" |
| #include "base/strings/stringprintf.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/grit/browser_resources.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "content/public/browser/browser_context.h" |
| #include "content/public/browser/navigation_handle.h" |
| #include "content/public/browser/navigation_throttle.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/url_constants.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/browser/extension_util.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/base/webui/jstemplate_builder.h" |
| #include "ui/base/webui/web_ui_util.h" |
| #include "ui/strings/grit/ui_strings.h" |
| |
| namespace enterprise_incognito { |
| namespace { |
| std::string GetIncognitoNavigationBlockedErrorPage( |
| base::Value::List blocking_extension, |
| base::Value::List missing_extension) { |
| auto strings = |
| base::Value::Dict() |
| .Set("incognitoBlockedPageTitle", |
| l10n_util::GetPluralStringFUTF16( |
| IDS_INCOGNITO_NAVIGATION_BLOCKED_PAGE_TITLE, |
| blocking_extension.size())) |
| .Set("incognitoBlockedMessage", |
| l10n_util::GetPluralStringFUTF16( |
| IDS_INCOGNITO_NAVIGATION_MESSAGE, blocking_extension.size())) |
| .Set("incognitoBlockedInstructions", |
| l10n_util::GetStringUTF16(IDS_INCOGNITO_NAVIGATION_INSTRUCTIONS)) |
| .Set("incognitoBlockedInstructionsStep1", |
| l10n_util::GetStringUTF16( |
| IDS_INCOGNITO_NAVIGATION_INSTRUCTIONS_STEP_1)) |
| .Set("incognitoBlockedInstructionsStep2", |
| l10n_util::GetStringUTF16( |
| IDS_INCOGNITO_NAVIGATION_INSTRUCTIONS_STEP_2)) |
| .Set("incognitoBlockedInstructionsStep3", |
| l10n_util::GetStringUTF16( |
| IDS_INCOGNITO_NAVIGATION_INSTRUCTIONS_STEP_3)) |
| .Set("incognitoBlockedInstructionsStep4", |
| l10n_util::GetStringUTF16( |
| IDS_INCOGNITO_NAVIGATION_INSTRUCTIONS_STEP_4)) |
| .Set("incognitoBlockedMissingExtensionsTitle", |
| l10n_util::GetPluralStringFUTF16( |
| IDS_INCOGNITO_NAVIGATION_MISSING_TITLE, |
| missing_extension.size())) |
| .Set("incognitoBlockedMissingExtensionsMessage", |
| l10n_util::GetPluralStringFUTF16( |
| IDS_INCOGNITO_NAVIGATION_MISSING_EXTENSIONS, |
| missing_extension.size())) |
| .Set("blockingExtensions", std::move(blocking_extension)) |
| .Set("missingExtensions", std::move(missing_extension)); |
| |
| std::string html = |
| ui::ResourceBundle::GetSharedInstance().LoadDataResourceString( |
| IDR_INCOGNITO_NAVIGATION_BLOCKED_PAGE_HTML); |
| const std::string& app_locale = g_browser_process->GetApplicationLocale(); |
| webui::SetLoadTimeDataDefaults(app_locale, &strings); |
| |
| return webui::GetI18nTemplateHtml(html, strings); |
| } |
| |
| } // namespace |
| |
| // static |
| void IncognitoNavigationThrottle::MaybeCreateAndAdd( |
| content::NavigationThrottleRegistry& registry) { |
| content::BrowserContext* browser_context = |
| registry.GetNavigationHandle().GetWebContents()->GetBrowserContext(); |
| Profile* profile = Profile::FromBrowserContext(browser_context); |
| if (!profile->IsIncognitoProfile()) { |
| return; |
| } |
| const base::Value::List& mandatory_extensions = profile->GetPrefs()->GetList( |
| prefs::kMandatoryExtensionsForIncognitoNavigation); |
| if (mandatory_extensions.empty()) { |
| return; |
| } |
| registry.AddThrottle( |
| std::make_unique<IncognitoNavigationThrottle>(registry, profile)); |
| } |
| |
| IncognitoNavigationThrottle::IncognitoNavigationThrottle( |
| content::NavigationThrottleRegistry& registry, |
| Profile* profile) |
| : content::NavigationThrottle(registry), profile_(profile) {} |
| |
| IncognitoNavigationThrottle::~IncognitoNavigationThrottle() = default; |
| |
| content::NavigationThrottle::ThrottleCheckResult |
| IncognitoNavigationThrottle::WillStartRequest() { |
| ReadMandatoryExtensionsStatus(); |
| if (blocking_extensions_.empty() && missing_extensions_.empty()) { |
| return content::NavigationThrottle::PROCEED; |
| } |
| return ThrottleCheckResult( |
| content::NavigationThrottle::CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR, |
| GetIncognitoNavigationBlockedErrorPage(std::move(blocking_extensions_), |
| std::move(missing_extensions_))); |
| } |
| |
| content::NavigationThrottle::ThrottleCheckResult |
| IncognitoNavigationThrottle::WillRedirectRequest() { |
| return WillStartRequest(); |
| } |
| |
| const char* IncognitoNavigationThrottle::GetNameForLogging() { |
| return "IncognitoNavigationThrottle"; |
| } |
| |
| void IncognitoNavigationThrottle::ReadMandatoryExtensionsStatus() { |
| DCHECK(profile_); |
| blocking_extensions_.clear(); |
| missing_extensions_.clear(); |
| extensions::ExtensionRegistry* registry = |
| extensions::ExtensionRegistry::Get(profile_); |
| const base::Value::List& mandatory_extensions = profile_->GetPrefs()->GetList( |
| prefs::kMandatoryExtensionsForIncognitoNavigation); |
| if (mandatory_extensions.empty()) { |
| return; |
| } |
| for (const auto& val : mandatory_extensions) { |
| if (!val.is_string()) { |
| continue; |
| } |
| const std::string id = val.GetString(); |
| auto* ext = registry->GetInstalledExtension(id); |
| if (ext) { |
| if (!extensions::util::IsIncognitoEnabled(id, profile_)) { |
| blocking_extensions_.Append(ext->name()); |
| } |
| } else { |
| missing_extensions_.Append(id); |
| } |
| } |
| } |
| |
| } // namespace enterprise_incognito |