summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsergiu@chromium.org <sergiu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-09 15:56:03 +0000
committersergiu@chromium.org <sergiu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-09 15:56:03 +0000
commit8991d81b8f54f155cce6bdfbaeee9863cc9a8546 (patch)
treef977bb69c14b13c5c7c10066342c3193245e5ffe
parent2f92de9aa2b3df7f9697698262c78bac6328579c (diff)
downloadchromium_src-8991d81b8f54f155cce6bdfbaeee9863cc9a8546.zip
chromium_src-8991d81b8f54f155cce6bdfbaeee9863cc9a8546.tar.gz
chromium_src-8991d81b8f54f155cce6bdfbaeee9863cc9a8546.tar.bz2
Adds support for manual whitelist and blacklist, previewing a page and
adding it to the whitelist for managed users. This CL adds two user preferences (kManagedModeWhitelist and kManagedModeBlacklist) which contain URL patterns which should be allowed or blocked. The user preferences are used only to persistently store the lists and the checking is done by the ManagedModeURLFilter, which uses policy::URLBlacklist objects. The code takes care that the preferences and the URLFilter are kept in sync all the time. It also contains the functions needed to interact with these lists (adding, removing or checking). It also adds a preview infobar which pops up when the user clicks Preview on the interstitial. If the user clicks allow then the website is added to the whitelist. The domain gets added plus all redirects that lead to that page. The user is able to click navigate around the website without getting another interstitial as long as he does not navigate to a different host name. BUG=168772 Review URL: https://chromiumcodereview.appspot.com/11299035 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175806 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd9
-rw-r--r--chrome/browser/managed_mode/managed_mode.cc122
-rw-r--r--chrome/browser/managed_mode/managed_mode.h56
-rw-r--r--chrome/browser/managed_mode/managed_mode_interstitial.cc5
-rw-r--r--chrome/browser/managed_mode/managed_mode_navigation_observer.cc324
-rw-r--r--chrome/browser/managed_mode/managed_mode_navigation_observer.h81
-rw-r--r--chrome/browser/managed_mode/managed_mode_resource_throttle.cc73
-rw-r--r--chrome/browser/managed_mode/managed_mode_resource_throttle.h20
-rw-r--r--chrome/browser/managed_mode/managed_mode_url_filter.cc56
-rw-r--r--chrome/browser/managed_mode/managed_mode_url_filter.h19
-rw-r--r--chrome/common/pref_names.cc5
-rw-r--r--chrome/common/pref_names.h2
12 files changed, 747 insertions, 25 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 78411ab..f4a460b 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -15617,6 +15617,15 @@ Some features may be unavailable. Please check that the profile exists and you
<message name="IDS_MANAGED_MODE_GO_BACK_ACTION" desc="Label for the button that goes back to a 'safe' page.">
Take me back!
</message>
+ <message name="IDS_MANAGED_MODE_PREVIEW_MESSAGE" desc="Text of the infobar shown while a website is previewed.">
+ Do you want to add this website to the whitelist?
+ </message>
+ <message name="IDS_MANAGED_MODE_PREVIEW_ACCEPT" desc="Label for the button that adds the website to the manual whitelist.">
+ Add to whitelist.
+ </message>
+ <message name="IDS_MANAGED_MODE_ALREADY_ADDED_MESSAGE" desc="Text of the message that indicates that the website was already on one of the whitelists.">
+ This website was already on the whitelist so it was not added again.
+ </message>
<!-- Password generation strings -->
<message name="IDS_PASSWORD_GENERATION_BUBBLE_TITLE" desc="The title of the bubble asking users if they would like Chrome to generate a password for them on an account creation page.">
diff --git a/chrome/browser/managed_mode/managed_mode.cc b/chrome/browser/managed_mode/managed_mode.cc
index f1acb3b..df06143 100644
--- a/chrome/browser/managed_mode/managed_mode.cc
+++ b/chrome/browser/managed_mode/managed_mode.cc
@@ -12,7 +12,9 @@
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/managed_mode/managed_mode_site_list.h"
#include "chrome/browser/managed_mode/managed_mode_url_filter.h"
+#include "chrome/browser/policy/url_blacklist_manager.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
@@ -63,6 +65,26 @@ class ManagedMode::URLFilterContext {
base::Bind(&base::DoNothing)));
}
+ void SetManualLists(scoped_ptr<ListValue> whitelist,
+ scoped_ptr<ListValue> blacklist) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&ManagedModeURLFilter::SetManualLists,
+ base::Unretained(&url_filter_),
+ base::Passed(&whitelist),
+ base::Passed(&blacklist)));
+ }
+
+ void AddURLPatternToManualList(bool is_whitelist,
+ const std::string& url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&ManagedModeURLFilter::AddURLPatternToManualList,
+ base::Unretained(&url_filter_),
+ is_whitelist,
+ url));
+ }
+
void ShutdownOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
bool result = task_runner_->DeleteSoon(FROM_HERE, this);
@@ -91,6 +113,10 @@ void ManagedMode::RegisterUserPrefs(PrefServiceSyncable* prefs) {
prefs->RegisterIntegerPref(prefs::kDefaultManagedModeFilteringBehavior,
2,
PrefServiceSyncable::UNSYNCABLE_PREF);
+ prefs->RegisterListPref(prefs::kManagedModeWhitelist,
+ PrefServiceSyncable::UNSYNCABLE_PREF);
+ prefs->RegisterListPref(prefs::kManagedModeBlacklist,
+ PrefServiceSyncable::UNSYNCABLE_PREF);
}
// static
@@ -213,6 +239,78 @@ const ManagedModeURLFilter* ManagedMode::GetURLFilterForUIThreadImpl() {
return ui_url_filter_context_->url_filter();
}
+// static
+void ManagedMode::AddToManualList(bool is_whitelist,
+ const base::ListValue& list) {
+ GetInstance()->AddToManualListImpl(is_whitelist, list);
+}
+
+void ManagedMode::AddToManualListImpl(bool is_whitelist,
+ const base::ListValue& list) {
+ if (!managed_profile_)
+ return;
+
+ ListPrefUpdate pref_update(managed_profile_->GetPrefs(),
+ is_whitelist ? prefs::kManagedModeWhitelist :
+ prefs::kManagedModeBlacklist);
+ ListValue* pref_list = pref_update.Get();
+
+ for (size_t i = 0; i < list.GetSize(); ++i) {
+ std::string url_pattern;
+ list.GetString(i, &url_pattern);
+
+ if (!IsInManualList(is_whitelist, url_pattern)) {
+ pref_list->AppendString(url_pattern);
+ AddURLPatternToManualList(is_whitelist, url_pattern);
+ }
+ }
+}
+
+// static
+void ManagedMode::RemoveFromManualList(bool is_whitelist,
+ const base::ListValue& list) {
+ GetInstance()->RemoveFromManualListImpl(is_whitelist, list);
+}
+
+void ManagedMode::RemoveFromManualListImpl(bool is_whitelist,
+ const base::ListValue& list) {
+ ListPrefUpdate pref_update(managed_profile_->GetPrefs(),
+ is_whitelist ? prefs::kManagedModeWhitelist :
+ prefs::kManagedModeBlacklist);
+ ListValue* pref_list = pref_update.Get();
+
+ for (size_t i = 0; i < list.GetSize(); ++i) {
+ std::string pattern;
+ size_t out_index;
+ list.GetString(i, &pattern);
+ StringValue value_to_remove(pattern);
+
+ pref_list->Remove(value_to_remove, &out_index);
+ }
+}
+
+// static
+bool ManagedMode::IsInManualList(bool is_whitelist,
+ const std::string& url_pattern) {
+ return GetInstance()->IsInManualListImpl(is_whitelist, url_pattern);
+}
+
+bool ManagedMode::IsInManualListImpl(bool is_whitelist,
+ const std::string& url_pattern) {
+ StringValue pattern(url_pattern);
+ const ListValue* list = managed_profile_->GetPrefs()->GetList(
+ is_whitelist ? prefs::kManagedModeWhitelist :
+ prefs::kManagedModeBlacklist);
+ return list->Find(pattern) != list->end();
+}
+
+// static
+scoped_ptr<base::ListValue> ManagedMode::GetBlacklist() {
+ return scoped_ptr<base::ListValue>(
+ GetInstance()->managed_profile_->GetPrefs()->GetList(
+ prefs::kManagedModeBlacklist)->DeepCopy()).Pass();
+}
+
std::string ManagedMode::GetDebugPolicyProviderName() const {
// Save the string space in official builds.
#ifdef NDEBUG
@@ -385,7 +483,7 @@ void ManagedMode::SetInManagedMode(Profile* newly_managed_profile) {
g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode,
in_managed_mode);
if (in_managed_mode)
- UpdateWhitelist();
+ UpdateManualListsImpl();
// This causes the avatar and the profile menu to get updated.
content::NotificationService::current()->Notify(
@@ -412,7 +510,27 @@ void ManagedMode::OnDefaultFilteringBehaviorChanged() {
ui_url_filter_context_->SetDefaultFilteringBehavior(behavior);
}
-void ManagedMode::UpdateWhitelist() {
+// Static
+void ManagedMode::UpdateManualLists() {
+ GetInstance()->UpdateManualListsImpl();
+}
+
+void ManagedMode::UpdateManualListsImpl() {
io_url_filter_context_->LoadWhitelists(GetActiveSiteLists());
ui_url_filter_context_->LoadWhitelists(GetActiveSiteLists());
+ io_url_filter_context_->SetManualLists(GetWhitelist(), GetBlacklist());
+ ui_url_filter_context_->SetManualLists(GetWhitelist(), GetBlacklist());
+}
+
+scoped_ptr<base::ListValue> ManagedMode::GetWhitelist() {
+ return make_scoped_ptr(
+ managed_profile_->GetPrefs()->GetList(
+ prefs::kManagedModeWhitelist)->DeepCopy());
+}
+
+void ManagedMode::AddURLPatternToManualList(
+ bool is_whitelist,
+ const std::string& url_pattern) {
+ io_url_filter_context_->AddURLPatternToManualList(true, url_pattern);
+ ui_url_filter_context_->AddURLPatternToManualList(true, url_pattern);
}
diff --git a/chrome/browser/managed_mode/managed_mode.h b/chrome/browser/managed_mode/managed_mode.h
index 1c8eba9..b725015 100644
--- a/chrome/browser/managed_mode/managed_mode.h
+++ b/chrome/browser/managed_mode/managed_mode.h
@@ -28,6 +28,10 @@ class PrefServiceSimple;
class PrefServiceSyncable;
class Profile;
+namespace policy{
+class URLBlacklist;
+}
+
// Managed mode allows one person to manage the Chrome experience for another
// person by pre-configuring and then locking a managed User profile.
// The ManagedMode class provides methods to check whether the browser is in
@@ -62,6 +66,34 @@ class ManagedMode : public chrome::BrowserListObserver,
// This method should only be called on the UI thread.
static const ManagedModeURLFilter* GetURLFilterForUIThread();
+ // The functions that handle manual whitelists use |url_pattern| or lists
+ // of "url patterns". An "url pattern" is a pattern in the format used by the
+ // policy::URLBlacklist filter. A description of the format used can be found
+ // here: http://dev.chromium.org/administrators/url-blacklist-filter-format.
+ // They all receive the |is_whitelist| parameter which dictates whether they
+ // act on the whitelist (for |is_whitelist| == true) or on the blacklist (for
+ // |is_whitelist| == false).
+
+ // Checks if the |url_pattern| is in the manual whitelist.
+ static bool IsInManualList(const bool is_whitelist,
+ const std::string& url_pattern);
+
+ // Appends |list| to the manual white/black list (according to |is_whitelist|)
+ // both in URL filter and in preferences.
+ static void AddToManualList(const bool is_whitelist,
+ const base::ListValue& list);
+
+ // Removes |list| from the manual white/black list (according to
+ // |is_whitelist|) both in URL filter and in preferences.
+ static void RemoveFromManualList(const bool is_whitelist,
+ const base::ListValue& list);
+
+ // Updates the whitelist and the blacklist from the prefs.
+ static void UpdateManualLists();
+
+ // Returns the profile blacklist.
+ static scoped_ptr<base::ListValue> GetBlacklist();
+
// ExtensionManagementPolicy::Provider implementation:
virtual std::string GetDebugPolicyProviderName() const OVERRIDE;
virtual bool UserMayLoad(const extensions::Extension* extension,
@@ -132,7 +164,29 @@ class ManagedMode : public chrome::BrowserListObserver,
void OnDefaultFilteringBehaviorChanged();
- void UpdateWhitelist();
+ void UpdateManualListsImpl();
+
+ // Returns a copy of the manual whitelist which is stored in each profile.
+ scoped_ptr<base::ListValue> GetWhitelist();
+
+ // The following functions use |is_whitelist| to select between the whitelist
+ // and the blacklist as the target of the function. If |is_whitelist| is true
+ // |url_pattern| is added to the whitelist, otherwise it is added to the
+ // blacklist.
+
+ void RemoveFromManualListImpl(const bool is_whitelist,
+ const base::ListValue& whitelist);
+
+ // Adds the |url_pattern| to the manual lists in the URL filter. This is used
+ // by AddToManualListImpl().
+ void AddURLPatternToManualList(const bool is_whitelist,
+ const std::string& url_pattern);
+
+ void AddToManualListImpl(const bool is_whitelist,
+ const base::ListValue& whitelist);
+
+ bool IsInManualListImpl(const bool is_whitelist,
+ const std::string& url_pattern);
content::NotificationRegistrar registrar_;
scoped_ptr<PrefChangeRegistrar> pref_change_registrar_;
diff --git a/chrome/browser/managed_mode/managed_mode_interstitial.cc b/chrome/browser/managed_mode/managed_mode_interstitial.cc
index 9684b2d..dfd222f 100644
--- a/chrome/browser/managed_mode/managed_mode_interstitial.cc
+++ b/chrome/browser/managed_mode/managed_mode_interstitial.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/managed_mode/managed_mode_interstitial.h"
#include "base/i18n/rtl.h"
+#include "chrome/browser/managed_mode/managed_mode_navigation_observer.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
@@ -39,6 +40,10 @@ void ShowInterstitialOnUIThread(int render_process_host_id,
return;
}
+ ManagedModeNavigationObserver* navigation_observer =
+ ManagedModeNavigationObserver::FromWebContents(web_contents);
+ navigation_observer->SetStateToRecordingAfterPreview();
+
new ManagedModeInterstitial(web_contents, url, callback);
}
diff --git a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
index d344d1e..dd17b0f 100644
--- a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
+++ b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
@@ -4,30 +4,48 @@
#include "chrome/browser/managed_mode/managed_mode_navigation_observer.h"
+#include "base/bind.h"
+#include "base/i18n/rtl.h"
+#include "base/string_number_conversions.h"
#include "chrome/browser/api/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/api/infobars/infobar_service.h"
+#include "chrome/browser/api/infobars/simple_alert_infobar_delegate.h"
#include "chrome/browser/managed_mode/managed_mode.h"
+#include "chrome/browser/managed_mode/managed_mode_interstitial.h"
+#include "chrome/browser/managed_mode/managed_mode_resource_throttle.h"
#include "chrome/browser/managed_mode/managed_mode_url_filter.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
+#include "chrome/common/jstemplate_builder.h"
+#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/frame_navigate_params.h"
#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
#include "ui/base/l10n/l10n_util.h"
+using content::BrowserThread;
+
namespace {
class ManagedModeWarningInfobarDelegate : public ConfirmInfoBarDelegate {
public:
// Creates a managed mode warning delegate and adds it to |infobar_service|.
// Returns the delegate if it was successfully added.
- static InfoBarDelegate* Create(InfoBarService* infobar_service);
+ static InfoBarDelegate* Create(InfoBarService* infobar_service,
+ int last_allowed_page);
private:
- explicit ManagedModeWarningInfobarDelegate(InfoBarService* infobar_service);
+ explicit ManagedModeWarningInfobarDelegate(InfoBarService* infobar_service,
+ int last_allowed_page);
virtual ~ManagedModeWarningInfobarDelegate();
// ConfirmInfoBarDelegate overrides:
@@ -42,6 +60,8 @@ class ManagedModeWarningInfobarDelegate : public ConfirmInfoBarDelegate {
const content::LoadCommittedDetails& details) const OVERRIDE;
virtual void InfoBarDismissed() OVERRIDE;
+ int last_allowed_page_;
+
DISALLOW_COPY_AND_ASSIGN(ManagedModeWarningInfobarDelegate);
};
@@ -69,14 +89,17 @@ void GoBackToSafety(content::WebContents* web_contents) {
// static
InfoBarDelegate* ManagedModeWarningInfobarDelegate::Create(
- InfoBarService* infobar_service) {
- return infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
- new ManagedModeWarningInfobarDelegate(infobar_service)));
+ InfoBarService* infobar_service, int last_allowed_page) {
+ scoped_ptr<InfoBarDelegate> delegate(
+ new ManagedModeWarningInfobarDelegate(infobar_service, last_allowed_page));
+ return infobar_service->AddInfoBar(delegate.Pass());
}
ManagedModeWarningInfobarDelegate::ManagedModeWarningInfobarDelegate(
- InfoBarService* infobar_service)
- : ConfirmInfoBarDelegate(infobar_service) {}
+ InfoBarService* infobar_service,
+ int last_allowed_page)
+ : ConfirmInfoBarDelegate(infobar_service),
+ last_allowed_page_(last_allowed_page) {}
ManagedModeWarningInfobarDelegate::~ManagedModeWarningInfobarDelegate() {}
@@ -117,23 +140,279 @@ void ManagedModeWarningInfobarDelegate::InfoBarDismissed() {
observer->WarnInfobarDismissed();
}
+class ManagedModePreviewInfobarDelegate : public ConfirmInfoBarDelegate {
+ public:
+ // Creates a managed mode preview delegate and adds it to |infobar_service|.
+ // Returns the delegate if it was successfully added.
+ static InfoBarDelegate* Create(InfoBarService* infobar_service);
+
+ private:
+ explicit ManagedModePreviewInfobarDelegate(InfoBarService* infobar_service);
+ virtual ~ManagedModePreviewInfobarDelegate();
+
+ // ConfirmInfoBarDelegate overrides:
+ virtual string16 GetMessageText() const OVERRIDE;
+ virtual int GetButtons() const OVERRIDE;
+ virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
+ virtual bool Accept() OVERRIDE;
+ virtual bool Cancel() OVERRIDE;
+
+ // InfoBarDelegate override:
+ virtual bool ShouldExpire(
+ const content::LoadCommittedDetails& details) const OVERRIDE;
+ virtual void InfoBarDismissed() OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(ManagedModePreviewInfobarDelegate);
+};
+
+// static
+InfoBarDelegate* ManagedModePreviewInfobarDelegate::Create(
+ InfoBarService* infobar_service) {
+ scoped_ptr<InfoBarDelegate> delegate(
+ new ManagedModePreviewInfobarDelegate(infobar_service));
+ return infobar_service->AddInfoBar(delegate.Pass());
+}
+
+ManagedModePreviewInfobarDelegate::ManagedModePreviewInfobarDelegate(
+ InfoBarService* infobar_service)
+ : ConfirmInfoBarDelegate(infobar_service) {}
+
+ManagedModePreviewInfobarDelegate::~ManagedModePreviewInfobarDelegate() {}
+
+string16 ManagedModePreviewInfobarDelegate::GetMessageText() const {
+ return l10n_util::GetStringUTF16(IDS_MANAGED_MODE_PREVIEW_MESSAGE);
+}
+
+int ManagedModePreviewInfobarDelegate::GetButtons() const {
+ return BUTTON_OK | BUTTON_CANCEL;
+}
+
+string16 ManagedModePreviewInfobarDelegate::GetButtonLabel(
+ InfoBarButton button) const {
+ return l10n_util::GetStringUTF16(
+ (button == BUTTON_OK) ? IDS_MANAGED_MODE_PREVIEW_ACCEPT
+ : IDS_MANAGED_MODE_GO_BACK_ACTION);
+}
+
+bool ManagedModePreviewInfobarDelegate::Accept() {
+ ManagedModeNavigationObserver* observer =
+ ManagedModeNavigationObserver::FromWebContents(
+ owner()->GetWebContents());
+ observer->AddSavedURLsToWhitelistAndClearState();
+ return true;
+}
+
+bool ManagedModePreviewInfobarDelegate::Cancel() {
+ GoBackToSafety(owner()->GetWebContents());
+ return false;
+}
+
+bool ManagedModePreviewInfobarDelegate::ShouldExpire(
+ const content::LoadCommittedDetails& details) const {
+ // ManagedModeNavigationObserver removes us below.
+ return false;
+}
+
+void ManagedModePreviewInfobarDelegate::InfoBarDismissed() {
+ ManagedModeNavigationObserver* observer =
+ ManagedModeNavigationObserver::FromWebContents(
+ owner()->GetWebContents());
+ observer->PreviewInfobarDismissed();
+}
+
} // namespace
DEFINE_WEB_CONTENTS_USER_DATA_KEY(ManagedModeNavigationObserver);
-ManagedModeNavigationObserver::~ManagedModeNavigationObserver() {}
+ManagedModeNavigationObserver::~ManagedModeNavigationObserver() {
+ RemoveTemporaryException();
+}
ManagedModeNavigationObserver::ManagedModeNavigationObserver(
content::WebContents* web_contents)
: WebContentsObserver(web_contents),
url_filter_(ManagedMode::GetURLFilterForUIThread()),
- warn_infobar_delegate_(NULL) {}
+ warn_infobar_delegate_(NULL),
+ preview_infobar_delegate_(NULL),
+ state_(RECORDING_URLS_BEFORE_PREVIEW),
+ last_allowed_page_(-1) {}
+
+void ManagedModeNavigationObserver::AddTemporaryException() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(web_contents());
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ManagedModeResourceThrottle::AddTemporaryException,
+ web_contents()->GetRenderProcessHost()->GetID(),
+ web_contents()->GetRenderViewHost()->GetRoutingID(),
+ last_url_));
+}
+
+void ManagedModeNavigationObserver::RemoveTemporaryException() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // When closing the browser web_contents() may return NULL so guard against
+ // that.
+ if (!web_contents())
+ return;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ManagedModeResourceThrottle::RemoveTemporaryException,
+ web_contents()->GetRenderProcessHost()->GetID(),
+ web_contents()->GetRenderViewHost()->GetRoutingID()));
+}
void ManagedModeNavigationObserver::WarnInfobarDismissed() {
DCHECK(warn_infobar_delegate_);
warn_infobar_delegate_ = NULL;
}
+void ManagedModeNavigationObserver::PreviewInfobarDismissed() {
+ DCHECK(preview_infobar_delegate_);
+ preview_infobar_delegate_ = NULL;
+}
+
+void ManagedModeNavigationObserver::AddSavedURLsToWhitelistAndClearState() {
+ ListValue whitelist;
+ for (std::set<GURL>::const_iterator it = navigated_urls_.begin();
+ it != navigated_urls_.end();
+ ++it) {
+ whitelist.AppendString(it->scheme() + "://." + it->host() + it->path());
+ }
+ if (last_url_.is_valid()) {
+ if (last_url_.SchemeIs("https")) {
+ whitelist.AppendString("https://" + last_url_.host());
+ } else {
+ whitelist.AppendString(last_url_.host());
+ }
+ }
+ ManagedMode::AddToManualList(true, whitelist);
+ ClearObserverState();
+}
+
+void ManagedModeNavigationObserver::AddURLToPatternList(const GURL& url) {
+ DCHECK(state_ != NOT_RECORDING_URLS);
+ navigated_urls_.insert(url);
+}
+
+void ManagedModeNavigationObserver::AddURLAsLastPattern(const GURL& url) {
+ DCHECK(state_ != NOT_RECORDING_URLS);
+
+ // Erase the last |url| if it is present in the |navigated_urls_|. This stops
+ // us from having both http://.www.google.com (exact URL from the pattern
+ // list) and www.google.com (hostname from the last URL pattern) in the list.
+ navigated_urls_.erase(url);
+ last_url_ = url;
+}
+
+void ManagedModeNavigationObserver::SetStateToRecordingAfterPreview() {
+ state_ = RECORDING_URLS_AFTER_PREVIEW;
+}
+
+bool ManagedModeNavigationObserver::CanTemporarilyNavigateHost(
+ const GURL& url) {
+ if (last_url_.scheme() == "https") {
+ return url.scheme() == "https" && last_url_.host() == url.host();
+ }
+ return last_url_.host() == url.host();
+}
+
+void ManagedModeNavigationObserver::ClearObserverState() {
+ if (state_ == NOT_RECORDING_URLS && preview_infobar_delegate_) {
+ InfoBarService* infobar_service =
+ InfoBarService::FromWebContents(web_contents());
+ infobar_service->RemoveInfoBar(preview_infobar_delegate_);
+ preview_infobar_delegate_ = NULL;
+ }
+ navigated_urls_.clear();
+ last_url_ = GURL();
+ state_ = RECORDING_URLS_BEFORE_PREVIEW;
+ RemoveTemporaryException();
+}
+
+void ManagedModeNavigationObserver::NavigateToPendingEntry(
+ const GURL& url,
+ content::NavigationController::ReloadType reload_type) {
+
+ // This method gets called first when a user navigates to a (new) URL.
+ // This means that the data related to the list of URLs needs to be cleared
+ // in certain circumstances.
+ if (web_contents()->GetController().GetCurrentEntryIndex() <
+ last_allowed_page_ || !CanTemporarilyNavigateHost(url)) {
+ ClearObserverState();
+ }
+}
+
+void ManagedModeNavigationObserver::DidNavigateMainFrame(
+ const content::LoadCommittedDetails& details,
+ const content::FrameNavigateParams& params) {
+
+ ManagedModeURLFilter::FilteringBehavior behavior =
+ url_filter_->GetFilteringBehaviorForURL(params.url);
+
+ // If the user just saw an interstitial this is the final URL so it is
+ // recorded. Checking for filtering behavior here isn't useful because
+ // although this specific URL can be allowed the hostname will be added which
+ // is more general. The hostname will be checked later when it is
+ // added to the actual whitelist to see if it is already present.
+ if (behavior == ManagedModeURLFilter::BLOCK && state_ != NOT_RECORDING_URLS)
+ AddURLAsLastPattern(params.url);
+
+ if (behavior == ManagedModeURLFilter::ALLOW &&
+ state_ != RECORDING_URLS_BEFORE_PREVIEW) {
+ // The initial page that triggered the interstitial was blocked but the
+ // final page is already in the whitelist so add the series of URLs
+ // which lead to the final page to the whitelist as well.
+ AddSavedURLsToWhitelistAndClearState();
+ SimpleAlertInfoBarDelegate::Create(
+ InfoBarService::FromWebContents(web_contents()),
+ NULL,
+ l10n_util::GetStringUTF16(IDS_MANAGED_MODE_ALREADY_ADDED_MESSAGE),
+ true);
+ return;
+ }
+
+ if (state_ == RECORDING_URLS_AFTER_PREVIEW) {
+ // A temporary exception should be added only if an interstitial was shown,
+ // the user clicked preview and the final page was not allowed. This
+ // temporary exception stops the interstitial from showing on further
+ // navigations to that host so that the user can navigate around to
+ // inspect it.
+ state_ = NOT_RECORDING_URLS;
+ AddTemporaryException();
+ }
+}
+
+void ManagedModeNavigationObserver::DidStartProvisionalLoadForFrame(
+ int64 frame_id,
+ int64 parent_frame_id,
+ bool is_main_frame,
+ const GURL& validated_url,
+ bool is_error_page,
+ bool is_iframe_srcdoc,
+ content::RenderViewHost* render_view_host) {
+ if (!is_main_frame)
+ return;
+}
+
+void ManagedModeNavigationObserver::ProvisionalChangeToMainFrameUrl(
+ const GURL& url,
+ content::RenderViewHost* render_view_host) {
+ // This function is the last one to be called before the resource throttle
+ // shows the interstitial if the URL must be blocked.
+ ManagedModeURLFilter::FilteringBehavior behavior =
+ url_filter_->GetFilteringBehaviorForURL(url);
+
+ if (state_ == NOT_RECORDING_URLS && !CanTemporarilyNavigateHost(url))
+ ClearObserverState();
+
+ if (behavior == ManagedModeURLFilter::BLOCK && state_ != NOT_RECORDING_URLS)
+ AddURLToPatternList(url);
+}
+
void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
int64 frame_id,
bool is_main_frame,
@@ -149,15 +428,38 @@ void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
if (behavior == ManagedModeURLFilter::WARN) {
if (!warn_infobar_delegate_) {
warn_infobar_delegate_ = ManagedModeWarningInfobarDelegate::Create(
- InfoBarService::FromWebContents(web_contents()));
+ InfoBarService::FromWebContents(web_contents()), last_allowed_page_);
}
} else {
if (warn_infobar_delegate_) {
InfoBarService* infobar_service =
InfoBarService::FromWebContents(web_contents());
infobar_service->RemoveInfoBar(warn_infobar_delegate_);
- warn_infobar_delegate_= NULL;
+ warn_infobar_delegate_ = NULL;
+ }
+ }
+
+ if (behavior == ManagedModeURLFilter::BLOCK) {
+ switch (state_) {
+ case RECORDING_URLS_BEFORE_PREVIEW:
+ // Should not be in this state with a blocked URL.
+ NOTREACHED();
+ break;
+ case RECORDING_URLS_AFTER_PREVIEW:
+ // Add the infobar.
+ if (!preview_infobar_delegate_) {
+ preview_infobar_delegate_ =
+ ManagedModePreviewInfobarDelegate::Create(
+ InfoBarService::FromWebContents(web_contents()));
+ }
+ break;
+ case NOT_RECORDING_URLS:
+ // Check that the infobar is present.
+ DCHECK(preview_infobar_delegate_);
+ break;
}
}
+ if (behavior == ManagedModeURLFilter::ALLOW)
+ last_allowed_page_ = web_contents()->GetController().GetCurrentEntryIndex();
}
diff --git a/chrome/browser/managed_mode/managed_mode_navigation_observer.h b/chrome/browser/managed_mode/managed_mode_navigation_observer.h
index 06e0f84..53ab1c9 100644
--- a/chrome/browser/managed_mode/managed_mode_navigation_observer.h
+++ b/chrome/browser/managed_mode/managed_mode_navigation_observer.h
@@ -5,6 +5,9 @@
#ifndef CHROME_BROWSER_MANAGED_MODE_MANAGED_MODE_NAVIGATION_OBSERVER_H_
#define CHROME_BROWSER_MANAGED_MODE_MANAGED_MODE_NAVIGATION_OBSERVER_H_
+#include <set>
+
+#include "base/values.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
@@ -17,14 +20,85 @@ class ManagedModeNavigationObserver
public:
virtual ~ManagedModeNavigationObserver();
+ // Sets the specific infobar as dismissed.
void WarnInfobarDismissed();
+ void PreviewInfobarDismissed();
+
+ // Sets the state of the Observer from the outside.
+ void SetStateToRecordingAfterPreview();
+
+ // Returns whether the user should be allowed to navigate to this URL after
+ // he has clicked "Preview" on the interstitial.
+ bool CanTemporarilyNavigateHost(const GURL& url);
+
+ // Clears the state recorded in the observer.
+ void ClearObserverState();
+
+ // Whitelists exact URLs for redirects and host patterns for the final URL.
+ // If the URL uses HTTPS, whitelists only the host on HTTPS. Clears the
+ // observer state after adding the URLs.
+ void AddSavedURLsToWhitelistAndClearState();
private:
+ // An observer can be in one of the following states:
+ // - RECORDING_URLS_BEFORE_PREVIEW: This is the initial state when the user
+ // navigates to a new page. In this state the navigated URLs that should be
+ // blocked are recorded. The Observer moves to the next state when an
+ // interstitial was shown and the user clicked "Preview" on the interstitial.
+ // - RECORDING_URLS_AFTER_PREVIEW: URLs that should be blocked are
+ // still recorded while the page redirects. The Observer moves to the next
+ // state after the page finished redirecting (DidNavigateMainFrame gets
+ // called).
+ // - NOT_RECORDING_URLS: The redirects have completed and blocked URLs are
+ // no longer being recorded.
+ enum ObserverState {
+ RECORDING_URLS_BEFORE_PREVIEW,
+ RECORDING_URLS_AFTER_PREVIEW,
+ NOT_RECORDING_URLS,
+ };
+
friend class content::WebContentsUserData<ManagedModeNavigationObserver>;
explicit ManagedModeNavigationObserver(content::WebContents* web_contents);
+ // Adding the temporary exception stops the ResourceThrottle from showing
+ // an interstitial for this RenderView. This allows the user to navigate
+ // around on the website after clicking preview.
+ void AddTemporaryException();
+ void RemoveTemporaryException();
+
+ void AddURLToPatternList(const GURL& url);
+ void AddURLAsLastPattern(const GURL& url);
+
// content::WebContentsObserver implementation.
+ // An example regarding the order in which these events take place for
+ // google.com in our case is as follows:
+ // 1. User types in google.com and clicks enter.
+ // -> NavigateToPendingEntry: http://google.com
+ // -> DidStartProvisionalLoadForFrame http://google.com
+ // -> ProvisionalChangeToMainFrameUrl http://google.com
+ // 2. Interstitial is shown to the user. User clicks "Preview".
+ // -> ProvisionalChangeToMainFrameUrl http://www.google.com (redirect)
+ // -> DidCommitProvisionalLoadForFrame http://www.google.com (redirect)
+ // -> DidNavigateMainFrame http://www.google.com
+ // 3. Page is shown.
+ virtual void NavigateToPendingEntry(
+ const GURL& url,
+ content::NavigationController::ReloadType reload_type) OVERRIDE;
+ virtual void DidNavigateMainFrame(
+ const content::LoadCommittedDetails& details,
+ const content::FrameNavigateParams& params) OVERRIDE;
+ virtual void DidStartProvisionalLoadForFrame(
+ int64 frame_id,
+ int64 parent_frame_id,
+ bool is_main_frame,
+ const GURL& validated_url,
+ bool is_error_page,
+ bool is_iframe_srcdoc,
+ content::RenderViewHost* render_view_host) OVERRIDE;
+ virtual void ProvisionalChangeToMainFrameUrl(
+ const GURL& url,
+ content::RenderViewHost* render_view_host) OVERRIDE;
virtual void DidCommitProvisionalLoadForFrame(
int64 frame_id,
bool is_main_frame,
@@ -37,6 +111,13 @@ class ManagedModeNavigationObserver
// Owned by the InfoBarService, which has the same lifetime as this object.
InfoBarDelegate* warn_infobar_delegate_;
+ InfoBarDelegate* preview_infobar_delegate_;
+
+ ObserverState state_;
+ std::set<GURL> navigated_urls_;
+ GURL last_url_;
+
+ int last_allowed_page_;
DISALLOW_COPY_AND_ASSIGN(ManagedModeNavigationObserver);
};
diff --git a/chrome/browser/managed_mode/managed_mode_resource_throttle.cc b/chrome/browser/managed_mode/managed_mode_resource_throttle.cc
index 5d95d09..a8f60eea 100644
--- a/chrome/browser/managed_mode/managed_mode_resource_throttle.cc
+++ b/chrome/browser/managed_mode/managed_mode_resource_throttle.cc
@@ -4,12 +4,24 @@
#include "chrome/browser/managed_mode/managed_mode_resource_throttle.h"
+#include "base/lazy_instance.h"
#include "chrome/browser/managed_mode/managed_mode.h"
#include "chrome/browser/managed_mode/managed_mode_interstitial.h"
#include "chrome/browser/managed_mode/managed_mode_url_filter.h"
#include "content/public/browser/resource_controller.h"
#include "net/url_request/url_request.h"
+namespace {
+
+// This map contains <render_process_host_id_, render_view_id> pairs mapped
+// to hostnames which identify individual tabs. If a hostname
+// is present for a specific pair then the user clicked preview, is
+// navigating around and has not clicked one of the options on the infobar.
+typedef std::map<std::pair<int, int>, std::string> PreviewMap;
+base::LazyInstance<PreviewMap> g_in_preview_mode = LAZY_INSTANCE_INITIALIZER;
+
+}
+
ManagedModeResourceThrottle::ManagedModeResourceThrottle(
const net::URLRequest* request,
int render_process_host_id,
@@ -20,27 +32,72 @@ ManagedModeResourceThrottle::ManagedModeResourceThrottle(
render_process_host_id_(render_process_host_id),
render_view_id_(render_view_id),
is_main_frame_(is_main_frame),
+ temporarily_allowed_(false),
url_filter_(ManagedMode::GetURLFilterForIOThread()) {}
ManagedModeResourceThrottle::~ManagedModeResourceThrottle() {}
-void ManagedModeResourceThrottle::WillStartRequest(bool* defer) {
- if (url_filter_->GetFilteringBehaviorForURL(request_->url()) !=
+// static
+void ManagedModeResourceThrottle::AddTemporaryException(
+ int render_process_host_id,
+ int render_view_id,
+ const GURL& url) {
+ g_in_preview_mode.Get()[std::make_pair(render_process_host_id,
+ render_view_id)] = url.host();
+}
+
+// static
+void ManagedModeResourceThrottle::RemoveTemporaryException(
+ int render_process_host_id,
+ int render_view_id) {
+ g_in_preview_mode.Get().erase(std::make_pair(render_process_host_id,
+ render_view_id));
+}
+
+void ManagedModeResourceThrottle::ShowInterstitialIfNeeded(bool is_redirect,
+ const GURL& url,
+ bool* defer) {
+ // Only treat main frame requests for now (ignoring subresources).
+ if (!is_main_frame_)
+ return;
+
+ if (url_filter_->GetFilteringBehaviorForURL(url) !=
ManagedModeURLFilter::BLOCK) {
return;
}
- if (is_main_frame_) {
- *defer = true;
- ManagedModeInterstitial::ShowInterstitial(
- render_process_host_id_, render_view_id_, request_->url(),
- base::Bind(&ManagedModeResourceThrottle::OnInterstitialResult,
- weak_ptr_factory_.GetWeakPtr()));
+ // Do not show interstitial for redirects in preview mode and URLs which have
+ // the same hostname as the one on which the user clicked "Preview" on.
+ PreviewMap* preview_map = g_in_preview_mode.Pointer();
+ if (temporarily_allowed_) {
+ DCHECK(is_redirect);
+ return;
}
+
+ PreviewMap::iterator it = preview_map->find(
+ std::make_pair(render_process_host_id_, render_view_id_));
+ if (it != preview_map->end() && url.host() == it->second)
+ return;
+
+ *defer = true;
+ ManagedModeInterstitial::ShowInterstitial(
+ render_process_host_id_, render_view_id_, url,
+ base::Bind(&ManagedModeResourceThrottle::OnInterstitialResult,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ManagedModeResourceThrottle::WillStartRequest(bool* defer) {
+ ShowInterstitialIfNeeded(false, request_->url(), defer);
+}
+
+void ManagedModeResourceThrottle::WillRedirectRequest(const GURL& new_url,
+ bool* defer) {
+ ShowInterstitialIfNeeded(true, new_url, defer);
}
void ManagedModeResourceThrottle::OnInterstitialResult(bool continue_request) {
if (continue_request) {
+ temporarily_allowed_ = true;
controller()->Resume();
} else {
controller()->Cancel();
diff --git a/chrome/browser/managed_mode/managed_mode_resource_throttle.h b/chrome/browser/managed_mode/managed_mode_resource_throttle.h
index acefa96..1a33e66 100644
--- a/chrome/browser/managed_mode/managed_mode_resource_throttle.h
+++ b/chrome/browser/managed_mode/managed_mode_resource_throttle.h
@@ -15,8 +15,6 @@ namespace net {
class URLRequest;
}
-// This class temporarily blocks network requests that aren't whitelisted,
-// and allows resuming them later.
class ManagedModeResourceThrottle : public content::ResourceThrottle {
public:
ManagedModeResourceThrottle(const net::URLRequest* request,
@@ -25,10 +23,27 @@ class ManagedModeResourceThrottle : public content::ResourceThrottle {
bool is_main_frame);
virtual ~ManagedModeResourceThrottle();
+ // Adds/removes a temporary exception to filtering for a
+ // render_process_host_id and render_view_id pair (which identify a tab)
+ // to the preview map. Adding saves the last approved hostname in the map,
+ // which is then used to allow the user to browse on that hostname without
+ // getting an interstitial. See managed_mode_resource_throttle.cc for more
+ // details on the preview map.
+ static void AddTemporaryException(int render_process_host_id,
+ int render_view_id,
+ const GURL& url);
+ static void RemoveTemporaryException(int render_process_host_id,
+ int render_view_id);
+
// content::ResourceThrottle implementation:
virtual void WillStartRequest(bool* defer) OVERRIDE;
+ virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE;
+
private:
+ void ShowInterstitialIfNeeded(bool is_redirect,
+ const GURL& url,
+ bool* defer);
void OnInterstitialResult(bool continue_request);
base::WeakPtrFactory<ManagedModeResourceThrottle> weak_ptr_factory_;
@@ -36,6 +51,7 @@ class ManagedModeResourceThrottle : public content::ResourceThrottle {
int render_process_host_id_;
int render_view_id_;
bool is_main_frame_;
+ bool temporarily_allowed_;
const ManagedModeURLFilter* url_filter_;
DISALLOW_COPY_AND_ASSIGN(ManagedModeResourceThrottle);
diff --git a/chrome/browser/managed_mode/managed_mode_url_filter.cc b/chrome/browser/managed_mode/managed_mode_url_filter.cc
index a77e180..321eebe 100644
--- a/chrome/browser/managed_mode/managed_mode_url_filter.cc
+++ b/chrome/browser/managed_mode/managed_mode_url_filter.cc
@@ -159,7 +159,13 @@ scoped_ptr<ManagedModeURLFilter::Contents> LoadWhitelistsOnBlockingPoolThread(
ManagedModeURLFilter::ManagedModeURLFilter()
: ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
default_behavior_(ALLOW),
- contents_(new Contents()) {
+ contents_(new Contents()),
+ url_manual_list_allow_(new policy::URLBlacklist()),
+ url_manual_list_block_(new policy::URLBlacklist()) {
+ // Set empty manual lists in the begining.
+ scoped_ptr<base::ListValue> whitelist(new base::ListValue());
+ scoped_ptr<base::ListValue> blacklist(new base::ListValue());
+ SetManualLists(whitelist.Pass(), blacklist.Pass());
// Detach from the current thread so we can be constructed on a different
// thread than the one where we're used.
DetachFromThread();
@@ -191,6 +197,14 @@ ManagedModeURLFilter::GetFilteringBehaviorForURL(const GURL& url) const {
return ALLOW;
#endif
+ // TODO(sergiu): Find a less confusing way to do this. Options include
+ // renaming the functions in policy::URLBlacklist or adding a function that
+ // checks if the URL is allowed instead of blocked.
+ if (!url_manual_list_allow_->IsURLBlocked(url))
+ return ALLOW;
+ if (url_manual_list_block_->IsURLBlocked(url))
+ return BLOCK;
+
// Check the list of URL patterns.
std::set<URLMatcherConditionSet::ID> matching_ids =
contents_->url_matcher.MatchURL(url);
@@ -266,6 +280,46 @@ void ManagedModeURLFilter::SetFromPatterns(
weak_ptr_factory_.GetWeakPtr(), continuation));
}
+void ManagedModeURLFilter::SetManualLists(scoped_ptr<ListValue> whitelist,
+ scoped_ptr<ListValue> blacklist){
+ DCHECK(CalledOnValidThread());
+ url_manual_list_block_.reset(new policy::URLBlacklist);
+ url_manual_list_allow_.reset(new policy::URLBlacklist);
+ url_manual_list_block_->Block(blacklist.get());
+ ListValue all_sites;
+ all_sites.Append(new base::StringValue("*"));
+ url_manual_list_allow_->Allow(whitelist.get());
+ url_manual_list_allow_->Block(&all_sites);
+
+ // Debug
+ DVLOG(1) << "Loaded whitelist: ";
+ for (ListValue::iterator it = whitelist->begin();
+ it != whitelist->end(); ++it){
+ std::string item;
+ (*it)->GetAsString(&item);
+ DVLOG(1) << item;
+ }
+ DVLOG(1) << "Loaded blacklist: ";
+ for (ListValue::iterator it = blacklist->begin();
+ it != blacklist->end(); ++it){
+ std::string item;
+ (*it)->GetAsString(&item);
+ DVLOG(1) << item;
+ }
+}
+
+void ManagedModeURLFilter::AddURLPatternToManualList(
+ const bool is_whitelist,
+ const std::string& url) {
+ DCHECK(CalledOnValidThread());
+ ListValue list;
+ list.AppendString(url);
+ if (is_whitelist)
+ url_manual_list_allow_->Allow(&list);
+ else
+ url_manual_list_block_->Block(&list);
+}
+
void ManagedModeURLFilter::SetContents(const base::Closure& continuation,
scoped_ptr<Contents> contents) {
DCHECK(CalledOnValidThread());
diff --git a/chrome/browser/managed_mode/managed_mode_url_filter.h b/chrome/browser/managed_mode/managed_mode_url_filter.h
index 93adff9..6537af9 100644
--- a/chrome/browser/managed_mode/managed_mode_url_filter.h
+++ b/chrome/browser/managed_mode/managed_mode_url_filter.h
@@ -13,6 +13,10 @@
#include "base/values.h"
#include "chrome/browser/managed_mode/managed_mode_site_list.h"
+namespace policy {
+class URLBlacklist;
+} // namespace policy
+
class FilePath;
class GURL;
@@ -56,6 +60,15 @@ class ManagedModeURLFilter : public base::NonThreadSafe {
void SetFromPatterns(const std::vector<std::string>& patterns,
const base::Closure& continuation);
+ // Sets the manual lists.
+ void SetManualLists(scoped_ptr<ListValue> whitelist,
+ scoped_ptr<ListValue> blacklist);
+
+ // Adds a pattern to a manual list. If |is_whitelist| is true it gets added
+ // to the whitelist, else to the blacklist.
+ void AddURLPatternToManualList(const bool is_whitelist,
+ const std::string& url_pattern);
+
private:
void SetContents(const base::Closure& callback,
scoped_ptr<Contents> url_matcher);
@@ -64,6 +77,12 @@ class ManagedModeURLFilter : public base::NonThreadSafe {
FilteringBehavior default_behavior_;
scoped_ptr<Contents> contents_;
+ // The |url_manual_list_allow_| blocks all URLs except the ones that are
+ // added while the |url_manual_list_block_| blocks only the URLs that are
+ // added to it.
+ scoped_ptr<policy::URLBlacklist> url_manual_list_allow_;
+ scoped_ptr<policy::URLBlacklist> url_manual_list_block_;
+
DISALLOW_COPY_AND_ASSIGN(ManagedModeURLFilter);
};
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index fb670a8..e4474d8 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -33,6 +33,11 @@ const char kHomePageChanged[] = "homepage_changed";
// Does this user have a Google+ Profile?
const char kIsGooglePlusUser[] = "is_google_plus_user";
+// List of pages that are manually approved.
+const char kManagedModeWhitelist[] = "profile.managed.whitelist";
+// List of pages that are manually blocked.
+const char kManagedModeBlacklist[] = "profile.managed.blacklist";
+
// Used to determine if the last session exited cleanly. Set to false when
// first opened, and to true when closing. On startup if the value is false,
// it means the profile didn't exit cleanly.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index a1bad52..bb9f352 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -20,6 +20,8 @@ extern const char kHomePageIsNewTabPage[];
extern const char kHomePage[];
extern const char kHomePageChanged[];
extern const char kIsGooglePlusUser[];
+extern const char kManagedModeWhitelist[];
+extern const char kManagedModeBlacklist[];
extern const char kSessionExitedCleanly[];
extern const char kSessionExitType[];
extern const char kRestoreOnStartup[];