Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1791)

Unified Diff: chrome/browser/managed_mode/managed_mode_navigation_observer.cc

Issue 11299035: Support manual (white|black)list, previewing and allowing after interstitial (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix bad text in generated_resources.grd and rebase to ToT Created 7 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/managed_mode/managed_mode_navigation_observer.cc
diff --git a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
index 945802e00775bd7d86f96329b65f083ec592234f..208bf619bfd9a9e7ae19b46ae7d48efb22a66af0 100644
--- a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
+++ b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
@@ -4,25 +4,43 @@
#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:
- explicit ManagedModeWarningInfobarDelegate(InfoBarService* infobar_service);
+ explicit ManagedModeWarningInfobarDelegate(
+ InfoBarService* infobar_service,
+ int last_allowed_page);
private:
virtual ~ManagedModeWarningInfobarDelegate();
@@ -39,6 +57,8 @@ class ManagedModeWarningInfobarDelegate : public ConfirmInfoBarDelegate {
const content::LoadCommittedDetails& details) const OVERRIDE;
virtual void InfoBarDismissed() OVERRIDE;
+ int last_allowed_page_;
+
DISALLOW_COPY_AND_ASSIGN(ManagedModeWarningInfobarDelegate);
};
@@ -65,8 +85,10 @@ void GoBackToSafety(content::WebContents* web_contents) {
}
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() {}
@@ -107,23 +129,275 @@ void ManagedModeWarningInfobarDelegate::InfoBarDismissed() {
observer->WarnInfobarDismissed();
}
+class ManagedModePreviewInfobarDelegate : public ConfirmInfoBarDelegate {
+ public:
+ explicit ManagedModePreviewInfobarDelegate(
+ InfoBarService* infobar_service);
+
+ private:
+ 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);
+};
+
+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) {
+ DLOG(ERROR) << "NavigateToPendingEntry: " << url;
Bernhard Bauer 2013/01/07 12:34:19 Remove these log statements before committing.
Sergiu 2013/01/07 16:25:05 Done.
+
+ // 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) {
+ DLOG(ERROR) << "DidNavigateMainFrame: " << params.url;
+
+ 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();
+ InfoBarService* infobar_service =
+ InfoBarService::FromWebContents(web_contents());
+ infobar_service->AddInfoBar(new SimpleAlertInfoBarDelegate(
+ infobar_service,
+ 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& url,
+ bool is_error_page,
+ content::RenderViewHost* render_view_host) {
+ if (!is_main_frame)
+ return;
+
+ DLOG(ERROR) << "DidStartProvisionalLoadForFrame: " << url;
+}
+
+void ManagedModeNavigationObserver::ProvisionalChangeToMainFrameUrl(
+ const GURL& url,
+ content::RenderViewHost* render_view_host) {
+ DLOG(ERROR) << "ProvisionalChangeToMainFrameUrl: " << url;
+ // 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,
@@ -133,6 +407,7 @@ void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
if (!is_main_frame)
return;
+ DLOG(ERROR) << "DidCommitProvisionalLoadForFrame: " << url;
ManagedModeURLFilter::FilteringBehavior behavior =
url_filter_->GetFilteringBehaviorForURL(url);
@@ -141,7 +416,8 @@ void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
InfoBarService* infobar_service =
InfoBarService::FromWebContents(web_contents());
warn_infobar_delegate_ =
- new ManagedModeWarningInfobarDelegate(infobar_service);
+ new ManagedModeWarningInfobarDelegate(infobar_service,
+ last_allowed_page_);
infobar_service->AddInfoBar(warn_infobar_delegate_);
}
} else {
@@ -149,8 +425,36 @@ void ManagedModeNavigationObserver::DidCommitProvisionalLoadForFrame(
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_) {
+ InfoBarService* infobar_service =
+ InfoBarService::FromWebContents(web_contents());
+ preview_infobar_delegate_ =
+ new ManagedModePreviewInfobarDelegate(infobar_service);
+ infobar_service->AddInfoBar(preview_infobar_delegate_);
+ }
+ break;
+ case NOT_RECORDING_URLS:
+ // Check that the infobar is present.
+ DCHECK(preview_infobar_delegate_);
+ break;
+ default:
Bernhard Bauer 2013/01/07 12:34:19 The compiler will check for you that you handle al
Sergiu 2013/01/07 16:25:05 Done.
+ NOTREACHED();
+ }
+ }
+
+ if (behavior == ManagedModeURLFilter::ALLOW) {
Bernhard Bauer 2013/01/07 12:34:19 Nit: Braces aren't necessary.
Sergiu 2013/01/07 16:25:05 Done.
+ last_allowed_page_ = web_contents()->GetController().GetCurrentEntryIndex();
+ }
}

Powered by Google App Engine
This is Rietveld 408576698