diff options
author | markusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-04 10:00:33 +0000 |
---|---|---|
committer | markusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-04 10:00:33 +0000 |
commit | 0b9fdd76a62d74edb143b100d26f798f8b385c98 (patch) | |
tree | 25c3f579c4477bbdfa7316d0284418dff574428a /chrome | |
parent | b0ab307bc9f7899c3c11b3eba45ea119140a83c7 (diff) | |
download | chromium_src-0b9fdd76a62d74edb143b100d26f798f8b385c98.zip chromium_src-0b9fdd76a62d74edb143b100d26f798f8b385c98.tar.gz chromium_src-0b9fdd76a62d74edb143b100d26f798f8b385c98.tar.bz2 |
Allow users to change site permissions via the WebsiteSettingsUI (GTK only)
BUG=113688
TEST=WebsiteSettingsModel*
Review URL: https://chromiumcodereview.appspot.com/9909017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130586 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/ui/gtk/website_settings_popup_gtk.cc | 146 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/website_settings_popup_gtk.h | 9 | ||||
-rw-r--r-- | chrome/browser/ui/website_settings_ui.cc | 18 | ||||
-rw-r--r-- | chrome/browser/ui/website_settings_ui.h | 55 | ||||
-rw-r--r-- | chrome/browser/website_settings.cc (renamed from chrome/browser/website_settings_model.cc) | 165 | ||||
-rw-r--r-- | chrome/browser/website_settings.h (renamed from chrome/browser/website_settings_model.h) | 69 | ||||
-rw-r--r-- | chrome/browser/website_settings_model_unittest.cc | 233 | ||||
-rw-r--r-- | chrome/browser/website_settings_unittest.cc | 291 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 5 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 2 |
10 files changed, 660 insertions, 333 deletions
diff --git a/chrome/browser/ui/gtk/website_settings_popup_gtk.cc b/chrome/browser/ui/gtk/website_settings_popup_gtk.cc index f6a7ba4..5fe5345 100644 --- a/chrome/browser/ui/gtk/website_settings_popup_gtk.cc +++ b/chrome/browser/ui/gtk/website_settings_popup_gtk.cc @@ -19,6 +19,7 @@ #include "chrome/browser/ui/gtk/theme_service_gtk.h" #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/website_settings.h" #include "chrome/common/url_constants.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" @@ -29,6 +30,40 @@ using content::OpenURLParams; +namespace { + +std::string PermissionTypeToString(ContentSettingsType type) { + switch (type) { + case CONTENT_SETTINGS_TYPE_POPUPS: + return l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TYPE_POPUPS); + case CONTENT_SETTINGS_TYPE_PLUGINS: + return l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TYPE_PLUGINS); + case CONTENT_SETTINGS_TYPE_GEOLOCATION: + return l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TYPE_LOCATION); + case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: + return l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TYPE_NOTIFICATIONS); + default: + NOTREACHED(); + return ""; + } +} + +std::string PermissionValueToString(ContentSetting value) { + switch (value) { + case CONTENT_SETTING_ALLOW: + return l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_PERMISSION_ALLOW); + case CONTENT_SETTING_BLOCK: + return l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_PERMISSION_BLOCK); + case CONTENT_SETTING_ASK: + return l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_PERMISSION_ASK); + default: + NOTREACHED(); + return ""; + } +} + +} // namespace + WebsiteSettingsPopupGtk::WebsiteSettingsPopupGtk( gfx::NativeWindow parent, Profile* profile, @@ -42,7 +77,7 @@ WebsiteSettingsPopupGtk::WebsiteSettingsPopupGtk( site_info_contents_(NULL), cookies_section_contents_(NULL), permissions_section_contents_(NULL), - delegate_(NULL) { + presenter_(NULL) { BrowserWindowGtk* browser_window = BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent); browser_ = browser_window->browser(); @@ -71,14 +106,14 @@ WebsiteSettingsPopupGtk::WebsiteSettingsPopupGtk( WebsiteSettingsPopupGtk::~WebsiteSettingsPopupGtk() { } -void WebsiteSettingsPopupGtk::SetDelegate(WebsiteSettingsUIDelegate* delegate) { - delegate_ = delegate; +void WebsiteSettingsPopupGtk::SetPresenter(WebsiteSettings* presenter) { + presenter_ = presenter; } void WebsiteSettingsPopupGtk::BubbleClosing(BubbleGtk* bubble, bool closed_by_escape) { - if (delegate_) - delegate_->OnUIClosing(); + if (presenter_) + presenter_->OnUIClosing(); } void WebsiteSettingsPopupGtk::InitContents() { @@ -126,7 +161,7 @@ void WebsiteSettingsPopupGtk::ClearContainer(GtkWidget* container) { } } -void WebsiteSettingsPopupGtk::SetSiteInfo(const std::string site_info) { +void WebsiteSettingsPopupGtk::SetSiteInfo(const std::string& site_info) { DCHECK(site_info_contents_); ClearContainer(site_info_contents_); GtkWidget* label = theme_service_->BuildLabel(site_info, @@ -175,7 +210,8 @@ void WebsiteSettingsPopupGtk::SetCookieInfo( ++it) { GtkWidget* cookies_info = gtk_hbox_new(FALSE, 0); - GtkWidget* label = theme_service_->BuildLabel(it->text, ui::kGdkBlack); + GtkWidget* label = theme_service_->BuildLabel(it->cookie_source, + ui::kGdkBlack); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_util::SetLabelWidth(label, 200); // Allow linebreaking in the middle of words if necessary, so that extremely @@ -224,46 +260,64 @@ void WebsiteSettingsPopupGtk::SetPermissionInfo( permission_info_list.begin(); permission != permission_info_list.end(); ++permission) { - std::string permission_text; - switch (permission->type) { - case CONTENT_SETTINGS_TYPE_POPUPS: - permission_text = - l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TYPE_POPUPS); - break; - case CONTENT_SETTINGS_TYPE_PLUGINS: - permission_text = - l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TYPE_PLUGINS); + // Add a label for the permission type. + GtkWidget* label = theme_service_->BuildLabel( + PermissionTypeToString(permission->type), ui::kGdkBlack); + gtk_util::SetLabelWidth(label, 280); + GtkWidget* hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + GtkListStore* store = + gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); + GtkTreeIter iter; + // Add option for permission "Allow" to the combobox model. + std::string setting_str = PermissionValueToString(CONTENT_SETTING_ALLOW); + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1, + CONTENT_SETTING_ALLOW, 2, permission->type, -1); + // Add option for permission "BLOCK" to the combobox model. + setting_str = PermissionValueToString(CONTENT_SETTING_BLOCK); + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1, + CONTENT_SETTING_BLOCK, 2, permission->type, -1); + // Add option for permission "Global Default" to the combobox model. + setting_str = + l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_PERMISSION_DEFAULT); + setting_str += " (" + PermissionValueToString(permission->default_setting); + setting_str += ")"; + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1, + CONTENT_SETTING_DEFAULT, 2, permission->type, -1); + GtkWidget* combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); + // Remove reference to the store to prevent leaking. + g_object_unref(G_OBJECT(store)); + + GtkCellRenderer* cell = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell, TRUE ); + gtk_cell_layout_set_attributes( + GTK_CELL_LAYOUT(combo_box), cell, "text", 0, NULL); + + // Select the combobox entry for the currently configured permission value. + int active = -1; + switch (permission->setting) { + case CONTENT_SETTING_DEFAULT: active = 2; break; - case CONTENT_SETTINGS_TYPE_GEOLOCATION: - permission_text = - l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TYPE_LOCATION); + case CONTENT_SETTING_ALLOW: active = 0; break; - case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: - permission_text = - l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TYPE_NOTIFICATIONS); + case CONTENT_SETTING_BLOCK: active = 1; break; default: - NOTREACHED(); + NOTREACHED() << "Bad content setting:" << permission->setting; break; } - GtkWidget* label = theme_service_->BuildLabel(permission_text, - ui::kGdkBlack); - gtk_util::SetLabelWidth(label, 280); - GtkWidget* hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), active); - GtkWidget* combo_box = gtk_combo_box_new_text(); - std::string permission_str = - l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_PERMISSION_ALLOW); - gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), permission_str.c_str()); - permission_str = - l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_PERMISSION_BLOCK); - gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), permission_str.c_str()); - gtk_combo_box_set_active( - GTK_COMBO_BOX(combo_box), - permission->setting == CONTENT_SETTING_ALLOW ? 0 : 1); + // Add change listener to the combobox. g_signal_connect(combo_box, "changed", G_CALLBACK(OnPermissionChangedThunk), this); + // Once the popup (window) for a combobox is shown, the bubble container + // (window) loses it's focus. Therefore it necessary to reset the focus to + // the bubble container after the combobox popup is closed. g_signal_connect(combo_box, "notify::popup-shown", G_CALLBACK(OnComboBoxShownThunk), this); gtk_box_pack_start(GTK_BOX(hbox), combo_box, FALSE, FALSE, 0); @@ -318,7 +372,17 @@ void WebsiteSettingsPopupGtk::OnPermissionsSettingsLinkClicked( } void WebsiteSettingsPopupGtk::OnPermissionChanged(GtkWidget* widget) { - // TODO(markusheintz): Implement once the backend (|WebsiteSettingsUIDelegate| - // implmentation which is the |WebsiteSettings| class) provides support for - // this. + GtkTreeIter it; + bool has_active = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &it); + DCHECK(has_active); + GtkTreeModel* store = + GTK_TREE_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(widget))); + + int value = -1; + int type = -1; + gtk_tree_model_get(store, &it, 1, &value, 2, &type, -1); + + if (presenter_) + presenter_->OnSitePermissionChanged(ContentSettingsType(type), + ContentSetting(value)); } diff --git a/chrome/browser/ui/gtk/website_settings_popup_gtk.h b/chrome/browser/ui/gtk/website_settings_popup_gtk.h index da41fe0..3cd004a 100644 --- a/chrome/browser/ui/gtk/website_settings_popup_gtk.h +++ b/chrome/browser/ui/gtk/website_settings_popup_gtk.h @@ -17,6 +17,7 @@ class BubbleGtk; class Profile; class TabContentsWrapper; class ThemeServiceGtk; +class WebsiteSettings; // GTK implementation of the website settings UI. The website settings UI is // displayed in a popup that is positioned relative the an anchor element. @@ -29,8 +30,8 @@ class WebsiteSettingsPopupGtk : public WebsiteSettingsUI, virtual ~WebsiteSettingsPopupGtk(); // WebsiteSettingsUI implementations. - virtual void SetDelegate(WebsiteSettingsUIDelegate* delegate) OVERRIDE; - virtual void SetSiteInfo(const std::string site_info) OVERRIDE; + virtual void SetPresenter(WebsiteSettings* presenter) OVERRIDE; + virtual void SetSiteInfo(const std::string& site_info) OVERRIDE; virtual void SetCookieInfo(const CookieInfoList& cookie_info_list) OVERRIDE; virtual void SetPermissionInfo( const PermissionInfoList& permission_info_list) OVERRIDE; @@ -88,7 +89,9 @@ class WebsiteSettingsPopupGtk : public WebsiteSettingsUI, // Container for the permissions section content. GtkWidget* permissions_section_contents_; - WebsiteSettingsUIDelegate* delegate_; + // The UI translates user actions to specific events and forwards them to the + // |presenter_|. The |presenter_| handles these events and updates the UI. + WebsiteSettings* presenter_; DISALLOW_COPY_AND_ASSIGN(WebsiteSettingsPopupGtk); }; diff --git a/chrome/browser/ui/website_settings_ui.cc b/chrome/browser/ui/website_settings_ui.cc new file mode 100644 index 0000000..efb7957 --- /dev/null +++ b/chrome/browser/ui/website_settings_ui.cc @@ -0,0 +1,18 @@ +// Copyright (c) 2012 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/ui/website_settings_ui.h" + +WebsiteSettingsUI::CookieInfo::CookieInfo() + : allowed(-1), blocked(-1) { +} + +WebsiteSettingsUI::PermissionInfo::PermissionInfo() + : type(CONTENT_SETTINGS_TYPE_DEFAULT), + setting(CONTENT_SETTING_DEFAULT), + default_setting(CONTENT_SETTING_DEFAULT) { +} + +WebsiteSettingsUI::~WebsiteSettingsUI() { +} diff --git a/chrome/browser/ui/website_settings_ui.h b/chrome/browser/ui/website_settings_ui.h index 0d3af6f..8368767 100644 --- a/chrome/browser/ui/website_settings_ui.h +++ b/chrome/browser/ui/website_settings_ui.h @@ -13,54 +13,59 @@ #include "chrome/common/content_settings_types.h" #include "ui/gfx/native_widget_types.h" +class CookieInfoList; class GURL; +class PermissionInfoList; class Profile; class TabContentsWrapper; +class WebsiteSettings; namespace content { struct SSLStatus; } -class CookieInfoList; -class PermissionInfoList; - - -class WebsiteSettingsUIDelegate { - public: - virtual ~WebsiteSettingsUIDelegate() {} - - // This method is called when the WebsiteSettingsUI is closed. - virtual void OnUIClosing() = 0; - - // This method is called when ever a permission setting is changed. - virtual void OnSitePermissionChanged(ContentSettingsType type, - ContentSetting value) = 0; -}; - -// The UI for website settings displays information and controlls for site -// specific data (local stored objects like cookies), site specific permissions -// (location, popup, plugin, ... permissions) and site specific information -// (identity, connection status, ...). |WebsiteSettingsUI| specifies the -// platform independent interface of the UI. +// The class |WebsiteSettingsUI| specifies the platform independent +// interface of the website settings UI. The website settings UI displays +// information and controls for site specific data (local stored objects like +// cookies), site specific permissions (location, popup, plugin, etc. +// permissions) and site specific information (identity, connection status, +// etc.). class WebsiteSettingsUI { public: + // |CookieInfo| contains information about the cookies from a specific source. + // A source can for example be a specific origin or an entire domain. struct CookieInfo { - std::string text; + CookieInfo(); + + // String describing the cookie source. + std::string cookie_source; + // The number of allowed cookies. int allowed; + // The number of blocked cookies. int blocked; }; + // |PermissionInfo| contains information about a single permission |type| for + // the current website. struct PermissionInfo { + PermissionInfo(); + + // Site permission |type|. ContentSettingsType type; + // The current value for the permission |type| (e.g. ALLOW or BLOCK). ContentSetting setting; + // The global default settings for this permission |type|. + ContentSetting default_setting; }; - virtual ~WebsiteSettingsUI() {} + virtual ~WebsiteSettingsUI(); - virtual void SetDelegate(WebsiteSettingsUIDelegate* delegate) = 0; + // Sets the |presenter| of the WebsiteSettingsUI that is responsible for + // setting the data to display in the UI. + virtual void SetPresenter(WebsiteSettings* presenter) = 0; // Sets site information. - virtual void SetSiteInfo(const std::string site_info) = 0; + virtual void SetSiteInfo(const std::string& site_info) = 0; // Sets cookie information. virtual void SetCookieInfo(const CookieInfoList& cookie_info_list) = 0; diff --git a/chrome/browser/website_settings_model.cc b/chrome/browser/website_settings.cc index 2c2abfe..9553204 100644 --- a/chrome/browser/website_settings_model.cc +++ b/chrome/browser/website_settings.cc @@ -2,15 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/website_settings_model.h" +#include "chrome/browser/website_settings.h" #include <string> #include <vector> #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" +#include "base/values.h" +#include "chrome/browser/content_settings/content_settings_utils.h" +#include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/ssl_error_info.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/ui/website_settings_ui.h" +#include "chrome/common/content_settings_pattern.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/cert_store.h" #include "content/public/common/ssl_status.h" #include "content/public/common/url_constants.h" @@ -23,26 +30,100 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" -WebsiteSettingsModel::WebsiteSettingsModel(Profile* profile, - const GURL& url, - const content::SSLStatus& ssl, - content::CertStore* cert_store) - : site_identity_status_(SITE_IDENTITY_STATUS_UNKNOWN), +#if defined(TOOLKIT_USES_GTK) +#include "chrome/browser/ui/gtk/website_settings_popup_gtk.h" +#endif + +using content::BrowserThread; + +namespace { + +ContentSettingsType kPermissionType[] = { + CONTENT_SETTINGS_TYPE_POPUPS, + CONTENT_SETTINGS_TYPE_PLUGINS, + CONTENT_SETTINGS_TYPE_NOTIFICATIONS, + CONTENT_SETTINGS_TYPE_GEOLOCATION, +}; + +} // namespace + +WebsiteSettings::WebsiteSettings( + WebsiteSettingsUI* ui, + Profile* profile, + const GURL& url, + const content::SSLStatus& ssl, + content::CertStore* cert_store) + : ui_(ui), + site_url_(url), + site_identity_status_(SITE_IDENTITY_STATUS_UNKNOWN), site_connection_status_(SITE_CONNECTION_STATUS_UNKNOWN), - cert_store_(cert_store) { + cert_store_(cert_store), + content_settings_(profile->GetHostContentSettingsMap()) { + ui_->SetPresenter(this); Init(profile, url, ssl); // After initialization the status about the site's connection // and it's identity must be available. DCHECK_NE(site_identity_status_, SITE_IDENTITY_STATUS_UNKNOWN); DCHECK_NE(site_connection_status_, SITE_CONNECTION_STATUS_UNKNOWN); + + // TODO(markusheintz): Add the strings below to the grd file once a decision + // has been made about the exact wording. + std::string site_info; + switch (site_identity_status_) { + case WebsiteSettings::SITE_IDENTITY_STATUS_CERT: + case WebsiteSettings::SITE_IDENTITY_STATUS_DNSSEC_CERT: + site_info = "Identity verified"; + break; + case WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT: + site_info = UTF16ToUTF8(organization_name()); + site_info += " - Identity verified"; + break; + default: + site_info = "Identity not verified"; + break; + } + ui_->SetSiteInfo(site_info); + + PresentSitePermissions(); +} + +WebsiteSettings::~WebsiteSettings() { } -WebsiteSettingsModel::~WebsiteSettingsModel() { +void WebsiteSettings::PresentSitePermissions() { + PermissionInfoList permission_info_list; + + WebsiteSettingsUI::PermissionInfo permission_info; + for (size_t i = 0; i < arraysize(kPermissionType); ++i) { + permission_info.type = kPermissionType[i]; + + content_settings::SettingInfo info; + scoped_ptr<Value> value(content_settings_->GetWebsiteSetting( + site_url_, site_url_, permission_info.type, "", &info)); + DCHECK(value.get()); + permission_info.setting = + content_settings::ValueToContentSetting(value.get()); + + if (permission_info.setting != CONTENT_SETTING_ASK) { + if (info.primary_pattern == ContentSettingsPattern::Wildcard() && + info.secondary_pattern == ContentSettingsPattern::Wildcard()) { + permission_info.default_setting = permission_info.setting; + permission_info.setting = CONTENT_SETTING_DEFAULT; + } else { + permission_info.default_setting = + content_settings_->GetDefaultContentSetting(permission_info.type, + NULL); + } + permission_info_list.push_back(permission_info); + } + } + + ui_->SetPermissionInfo(permission_info_list); } -void WebsiteSettingsModel::Init(Profile* profile, - const GURL& url, - const content::SSLStatus& ssl) { +void WebsiteSettings::Init(Profile* profile, + const GURL& url, + const content::SSLStatus& ssl) { if (url.SchemeIs(chrome::kChromeUIScheme)) { site_identity_status_ = SITE_IDENTITY_STATUS_INTERNAL_PAGE; site_identity_details_ = @@ -260,3 +341,65 @@ void WebsiteSettingsModel::Init(Profile* profile, } } } + +void WebsiteSettings::OnUIClosing() { + ui_->SetPresenter(NULL); + delete this; +} + +void WebsiteSettings::OnSitePermissionChanged(ContentSettingsType type, + ContentSetting setting) { + ContentSettingsPattern primary_pattern; + ContentSettingsPattern secondary_pattern; + switch (type) { + case CONTENT_SETTINGS_TYPE_GEOLOCATION: + // TODO(markusheintz): The rule we create here should also change the + // location permission for iframed content. + primary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_); + secondary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_); + break; + case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: + primary_pattern = ContentSettingsPattern::FromURLNoWildcard(site_url_); + secondary_pattern = ContentSettingsPattern::Wildcard(); + break; + case CONTENT_SETTINGS_TYPE_PLUGINS: + case CONTENT_SETTINGS_TYPE_POPUPS: + primary_pattern = ContentSettingsPattern::FromURL(site_url_); + secondary_pattern = ContentSettingsPattern::Wildcard(); + break; + default: + NOTREACHED() << "ContentSettingsType " << type << "is not supported."; + break; + } + + // Permission settings are specified via rules. There exists always at least + // one rule for the default setting. Get the rule that currently defines + // the permission for the given permission |type|. Then test whether the + // existing rule is more specific than the rule we are about to create. If + // the existing rule is more specific, than change the existing rule instead + // of creating a new rule that would be hidden behind the existing rule. + content_settings::SettingInfo info; + scoped_ptr<Value> v(content_settings_->GetWebsiteSetting( + site_url_, site_url_, type, "", &info)); + DCHECK(info.source == content_settings::SETTING_SOURCE_USER); + ContentSettingsPattern::Relation r1 = + info.primary_pattern.Compare(primary_pattern); + DCHECK(r1 != ContentSettingsPattern::DISJOINT_ORDER_POST && + r1 != ContentSettingsPattern::DISJOINT_ORDER_PRE); + if (r1 == ContentSettingsPattern::PREDECESSOR) { + primary_pattern = info.primary_pattern; + } else if (r1 == ContentSettingsPattern::IDENTITY) { + ContentSettingsPattern::Relation r2 = + info.secondary_pattern.Compare(secondary_pattern); + DCHECK(r2 != ContentSettingsPattern::DISJOINT_ORDER_POST && + r2 != ContentSettingsPattern::DISJOINT_ORDER_PRE); + if (r2 == ContentSettingsPattern::PREDECESSOR) + secondary_pattern = info.secondary_pattern; + } + + Value* value = NULL; + if (setting != CONTENT_SETTING_DEFAULT) + value = Value::CreateIntegerValue(setting); + content_settings_->SetWebsiteSetting( + primary_pattern, secondary_pattern, type, "", value); +} diff --git a/chrome/browser/website_settings_model.h b/chrome/browser/website_settings.h index bac3d19..9574aca 100644 --- a/chrome/browser/website_settings_model.h +++ b/chrome/browser/website_settings.h @@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_WEBSITE_SETTINGS_MODEL_H_ -#define CHROME_BROWSER_WEBSITE_SETTINGS_MODEL_H_ +#ifndef CHROME_BROWSER_WEBSITE_SETTINGS_H_ +#define CHROME_BROWSER_WEBSITE_SETTINGS_H_ #include "base/string16.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/common/content_settings.h" +#include "chrome/common/content_settings_types.h" #include "googleurl/src/gurl.h" namespace content { @@ -13,13 +16,17 @@ class CertStore; struct SSLStatus; } +class HostContentSettingsMap; class Profile; class TabContentsWrapper; - -// The |WebsiteSettingsModel| provides information about the connection and the -// identity of a website. The |WebsiteSettingsModel| is the backend for the -// WebsiteSettingsUI which displays this information. -class WebsiteSettingsModel { +class WebsiteSettingsUI; + +// The |WebsiteSettings| provides information about a website's permissions, +// connection state and its identity. It owns a UI that displays the +// information and allows users to change the permissions. |WebsiteSettings| +// objects must be created on the heap. They destroy themselves after the UI is +// closed. +class WebsiteSettings { public: // Status of a connection to a website. enum SiteConnectionStatus { @@ -53,14 +60,23 @@ class WebsiteSettingsModel { SITE_IDENTITY_STATUS_INTERNAL_PAGE, }; - // Creates a WebsiteSettingsModel for the passed |url| using the given |ssl| - // status object to determine the status of the site's connection. - WebsiteSettingsModel(Profile* profile, - const GURL& url, - const content::SSLStatus& ssl, - content::CertStore* cert_store); + // Creates a WebsiteSettings for the passed |url| using the given |ssl| status + // object to determine the status of the site's connection. The + // |WebsiteSettings| takes ownership of the |ui|. + WebsiteSettings(WebsiteSettingsUI* ui, + Profile* profile, + const GURL& url, + const content::SSLStatus& ssl, + content::CertStore* cert_store); + + // This method is called when the WebsiteSettingsUI is closed. It triggers + // the destruction of this |WebsiteSettings| object. So it is not safe to use + // this object afterwards. Any pointers to this object will be invalid. + void OnUIClosing(); - virtual ~WebsiteSettingsModel(); + // This method is called when ever a permission setting is changed. + void OnSitePermissionChanged(ContentSettingsType type, + ContentSetting value); // Accessors. SiteConnectionStatus site_connection_status() const { @@ -84,11 +100,26 @@ class WebsiteSettingsModel { } private: - // Initializes the |WebsiteSettingsModel|. + ~WebsiteSettings(); + + // Initializes the |WebsiteSettings|. void Init(Profile* profile, const GURL& url, const content::SSLStatus& ssl); + // Sets (presents) the information about the site's permissions in the |ui_|. + void PresentSitePermissions(); + + // The website settings UI displays information and controls for site + // specific data (local stored objects like cookies), site specific + // permissions (location, popup, plugin, etc. permissions) and site specific + // information (identity, connection status, etc.). + scoped_ptr<WebsiteSettingsUI> ui_; + + // The Omnibox URL of the website for which to display site permissions and + // site information. + GURL site_url_; + // Status of the website's identity verification check. SiteIdentityStatus site_identity_status_; @@ -112,7 +143,11 @@ class WebsiteSettingsModel { // The |CertStore| provides all X509Certificates. content::CertStore* cert_store_; - DISALLOW_COPY_AND_ASSIGN(WebsiteSettingsModel); + // The |HostContentSettingsMap| is the service that provides and manages + // content settings (aka. site permissions). + HostContentSettingsMap* content_settings_; + + DISALLOW_COPY_AND_ASSIGN(WebsiteSettings); }; -#endif // CHROME_BROWSER_WEBSITE_SETTINGS_MODEL_H_ +#endif // CHROME_BROWSER_WEBSITE_SETTINGS_H_ diff --git a/chrome/browser/website_settings_model_unittest.cc b/chrome/browser/website_settings_model_unittest.cc deleted file mode 100644 index 3e09187..0000000 --- a/chrome/browser/website_settings_model_unittest.cc +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) 2012 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/website_settings_model.h" - -#include "base/at_exit.h" -#include "base/message_loop.h" -#include "base/utf_string_conversions.h" -#include "chrome/test/base/testing_profile.h" -#include "content/public/browser/cert_store.h" -#include "content/public/common/ssl_status.h" -#include "content/test/test_browser_thread.h" -#include "net/base/cert_status_flags.h" -#include "net/base/ssl_connection_status_flags.h" -#include "net/base/test_certificate_data.h" -#include "net/base/x509_certificate.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using content::SSLStatus; -using namespace testing; - -namespace { - -// SSL cipher suite like specified in RFC5246 Appendix A.5. "The Cipher Suite". -static int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x3D; - -int SetSSLVersion(int connection_status, int version) { - // Clear SSL version bits (Bits 20, 21 and 22). - connection_status &= - ~(net::SSL_CONNECTION_VERSION_MASK << net::SSL_CONNECTION_VERSION_SHIFT); - int bitmask = version << net::SSL_CONNECTION_VERSION_SHIFT; - return bitmask | connection_status; -} - -int SetSSLCipherSuite(int connection_status, int cipher_suite) { - // Clear cipher suite bits (the 16 lowest bits). - connection_status &= ~net::SSL_CONNECTION_CIPHERSUITE_MASK; - return cipher_suite | connection_status; -} - -class MockCertStore : public content::CertStore { - public: - virtual ~MockCertStore() {} - MOCK_METHOD2(StoreCert, int(net::X509Certificate*, int)); - MOCK_METHOD2(RetrieveCert, bool(int, scoped_refptr<net::X509Certificate>*)); -}; - -class WebsiteSettingsModelTest : public testing::Test { - public: - WebsiteSettingsModelTest() - : testing::Test(), - message_loop_(MessageLoop::TYPE_UI), - ui_thread_(content::BrowserThread::UI, &message_loop_), - file_thread_(content::BrowserThread::FILE, &message_loop_), - profile_(new TestingProfile()), - cert_id_(0) { - } - - virtual ~WebsiteSettingsModelTest() { - } - - virtual void SetUp() { - cert_id_ = 1; - - base::Time start_date = base::Time::Now(); - base::Time expiration_date = base::Time::FromInternalValue( - start_date.ToInternalValue() + base::Time::kMicrosecondsPerWeek); - cert_ = new net::X509Certificate("subject", - "issuer", - start_date, - expiration_date); - - EXPECT_CALL(cert_store_, RetrieveCert(cert_id_, _) ) - .Times(AnyNumber()) - .WillRepeatedly(DoAll(SetArgPointee<1>(cert_), Return(true))); - } - - virtual void TearDown() OVERRIDE { - EXPECT_TRUE(Mock::VerifyAndClear(&cert_store_)); - } - - Profile* profile() const { return profile_.get(); } - - MessageLoop message_loop_; - content::TestBrowserThread ui_thread_; - content::TestBrowserThread file_thread_; - - scoped_ptr<Profile> profile_; - int cert_id_; - scoped_refptr<net::X509Certificate> cert_; - MockCertStore cert_store_; -}; - -} // namespace - -TEST_F(WebsiteSettingsModelTest, HTTPConnection) { - GURL url = GURL("http://www.example.com"); - SSLStatus ssl; - ssl.security_style = content::SECURITY_STYLE_UNAUTHENTICATED; - - scoped_ptr<WebsiteSettingsModel> model( - new WebsiteSettingsModel(profile(), url, ssl, &cert_store_)); - EXPECT_EQ(WebsiteSettingsModel::SITE_CONNECTION_STATUS_UNENCRYPTED, - model->site_connection_status()); - EXPECT_EQ(WebsiteSettingsModel::SITE_IDENTITY_STATUS_NO_CERT, - model->site_identity_status()); - EXPECT_EQ(string16(), model->organization_name()); -} - -TEST_F(WebsiteSettingsModelTest, HTTPSConnection) { - GURL url = GURL("https://www.example.com"); - - SSLStatus ssl; - ssl.security_style = content::SECURITY_STYLE_AUTHENTICATED; - ssl.cert_id = cert_id_; - ssl.cert_status = 0; - ssl.security_bits = 81; // No error if > 80. - int status = 0; - status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); - status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); - ssl.connection_status = status; - - scoped_ptr<WebsiteSettingsModel> model( - new WebsiteSettingsModel(profile(), url, ssl, &cert_store_)); - EXPECT_EQ(WebsiteSettingsModel::SITE_CONNECTION_STATUS_ENCRYPTED, - model->site_connection_status()); - EXPECT_EQ(WebsiteSettingsModel::SITE_IDENTITY_STATUS_CERT, - model->site_identity_status()); - EXPECT_EQ(string16(), model->organization_name()); -} - -TEST_F(WebsiteSettingsModelTest, HTTPSMixedContent) { - GURL url = GURL("https://www.example.com"); - - SSLStatus ssl; - ssl.security_style = content::SECURITY_STYLE_AUTHENTICATED; - ssl.cert_id = cert_id_; - ssl.cert_status = 0; - ssl.security_bits = 81; // No error if > 80. - ssl.content_status = SSLStatus::DISPLAYED_INSECURE_CONTENT; - int status = 0; - status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); - status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); - ssl.connection_status = status; - - scoped_ptr<WebsiteSettingsModel> model( - new WebsiteSettingsModel(profile(), url, ssl, &cert_store_)); - EXPECT_EQ(WebsiteSettingsModel::SITE_CONNECTION_STATUS_MIXED_CONTENT, - model->site_connection_status()); - EXPECT_EQ(WebsiteSettingsModel::SITE_IDENTITY_STATUS_CERT, - model->site_identity_status()); - EXPECT_EQ(string16(), model->organization_name()); -} - -TEST_F(WebsiteSettingsModelTest, HTTPSEVCert) { - GURL url = GURL("https://www.example.com"); - - scoped_refptr<net::X509Certificate> ev_cert = - net::X509Certificate::CreateFromBytes( - reinterpret_cast<const char*>(google_der), - sizeof(google_der)); - int ev_cert_id = 1; - MockCertStore tmp_cert_store; - EXPECT_CALL(tmp_cert_store, RetrieveCert(ev_cert_id, _) ).WillRepeatedly( - DoAll(SetArgPointee<1>(ev_cert), - Return(true))); - - SSLStatus ssl; - ssl.security_style = content::SECURITY_STYLE_AUTHENTICATED; - ssl.cert_id = ev_cert_id; - ssl.cert_status = net::CERT_STATUS_IS_EV; - ssl.security_bits = 81; // No error if > 80. - ssl.content_status = SSLStatus::DISPLAYED_INSECURE_CONTENT; - int status = 0; - status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); - status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); - ssl.connection_status = status; - - scoped_ptr<WebsiteSettingsModel> model( - new WebsiteSettingsModel(profile(), url, ssl, &tmp_cert_store)); - EXPECT_EQ(WebsiteSettingsModel::SITE_CONNECTION_STATUS_MIXED_CONTENT, - model->site_connection_status()); - EXPECT_EQ(WebsiteSettingsModel::SITE_IDENTITY_STATUS_EV_CERT, - model->site_identity_status()); - EXPECT_EQ(UTF8ToUTF16("Google Inc"), model->organization_name()); - EXPECT_TRUE(Mock::VerifyAndClear(&tmp_cert_store)); -} - -TEST_F(WebsiteSettingsModelTest, HTTPSRevocationError) { - GURL url = GURL("https://www.example.com"); - - SSLStatus ssl; - ssl.security_style = content::SECURITY_STYLE_AUTHENTICATED; - ssl.cert_id = cert_id_; - ssl.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; - ssl.security_bits = 81; // No error if > 80. - int status = 0; - status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); - status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); - ssl.connection_status = status; - - scoped_ptr<WebsiteSettingsModel> model( - new WebsiteSettingsModel(profile(), url, ssl, &cert_store_)); - EXPECT_EQ(WebsiteSettingsModel::SITE_CONNECTION_STATUS_ENCRYPTED, - model->site_connection_status()); - EXPECT_EQ(WebsiteSettingsModel::SITE_IDENTITY_STATUS_CERT_REVOCATION_UNKNOWN, - model->site_identity_status()); - EXPECT_EQ(string16(), model->organization_name()); -} - -TEST_F(WebsiteSettingsModelTest, HTTPSConnectionError) { - GURL url = GURL("https://www.example.com"); - - SSLStatus ssl; - ssl.security_style = content::SECURITY_STYLE_AUTHENTICATED; - ssl.cert_id = cert_id_; - ssl.cert_status = 0; - ssl.security_bits = 1; - int status = 0; - status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); - status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); - ssl.connection_status = status; - - scoped_ptr<WebsiteSettingsModel> model( - new WebsiteSettingsModel(profile(), url, ssl, &cert_store_)); - EXPECT_EQ(WebsiteSettingsModel::SITE_CONNECTION_STATUS_ENCRYPTED_ERROR, - model->site_connection_status()); - EXPECT_EQ(WebsiteSettingsModel::SITE_IDENTITY_STATUS_CERT, - model->site_identity_status()); - EXPECT_EQ(string16(), model->organization_name()); -} diff --git a/chrome/browser/website_settings_unittest.cc b/chrome/browser/website_settings_unittest.cc new file mode 100644 index 0000000..42978da --- /dev/null +++ b/chrome/browser/website_settings_unittest.cc @@ -0,0 +1,291 @@ +// Copyright (c) 2012 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/website_settings.h" + +#include "base/at_exit.h" +#include "base/message_loop.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/content_settings/host_content_settings_map.h" +#include "chrome/browser/ui/website_settings_ui.h" +#include "chrome/common/content_settings.h" +#include "chrome/common/content_settings_types.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/browser/cert_store.h" +#include "content/public/common/ssl_status.h" +#include "content/test/test_browser_thread.h" +#include "net/base/cert_status_flags.h" +#include "net/base/ssl_connection_status_flags.h" +#include "net/base/test_certificate_data.h" +#include "net/base/x509_certificate.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using content::SSLStatus; +using namespace testing; + +namespace { + +// SSL cipher suite like specified in RFC5246 Appendix A.5. "The Cipher Suite". +static int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x3D; + +int SetSSLVersion(int connection_status, int version) { + // Clear SSL version bits (Bits 20, 21 and 22). + connection_status &= + ~(net::SSL_CONNECTION_VERSION_MASK << net::SSL_CONNECTION_VERSION_SHIFT); + int bitmask = version << net::SSL_CONNECTION_VERSION_SHIFT; + return bitmask | connection_status; +} + +int SetSSLCipherSuite(int connection_status, int cipher_suite) { + // Clear cipher suite bits (the 16 lowest bits). + connection_status &= ~net::SSL_CONNECTION_CIPHERSUITE_MASK; + return cipher_suite | connection_status; +} + +class MockCertStore : public content::CertStore { + public: + virtual ~MockCertStore() {} + MOCK_METHOD2(StoreCert, int(net::X509Certificate*, int)); + MOCK_METHOD2(RetrieveCert, bool(int, scoped_refptr<net::X509Certificate>*)); +}; + +class MockWebsiteSettingsUI : public WebsiteSettingsUI { + public: + virtual ~MockWebsiteSettingsUI() {} + MOCK_METHOD1(SetPresenter, void(WebsiteSettings* presenter)); + MOCK_METHOD1(SetSiteInfo, void(const std::string& site_info)); + MOCK_METHOD1(SetCookieInfo, void(const CookieInfoList& cookie_info_list)); + MOCK_METHOD1(SetPermissionInfo, + void(const PermissionInfoList& permission_info_list)); +}; + +class WebsiteSettingsTest : public testing::Test { + public: + WebsiteSettingsTest() + : testing::Test(), + message_loop_(MessageLoop::TYPE_UI), + ui_thread_(content::BrowserThread::UI, &message_loop_), + file_thread_(content::BrowserThread::FILE, &message_loop_), + profile_(new TestingProfile()), + cert_id_(0), + url_("http://www.example.com"), + website_settings_(NULL) { + } + + virtual ~WebsiteSettingsTest() { + } + + virtual void SetUp() { + // Setup stub SSLStatus. + ssl_.security_style = content::SECURITY_STYLE_UNAUTHENTICATED; + + // Create the certificate. + cert_id_ = 1; + base::Time start_date = base::Time::Now(); + base::Time expiration_date = base::Time::FromInternalValue( + start_date.ToInternalValue() + base::Time::kMicrosecondsPerWeek); + cert_ = new net::X509Certificate("subject", + "issuer", + start_date, + expiration_date); + + // Setup the mock cert store. + EXPECT_CALL(cert_store_, RetrieveCert(cert_id_, _) ) + .Times(AnyNumber()) + .WillRepeatedly(DoAll(SetArgPointee<1>(cert_), Return(true))); + } + + virtual void TearDown() { + ASSERT_TRUE(website_settings_) << "No WebsiteSettings instance created."; + // Call OnUIClosing to destroy the |website_settings| object. + website_settings_->OnUIClosing(); + } + + WebsiteSettingsUI* CreateMockUI() { + MockWebsiteSettingsUI* ui = new MockWebsiteSettingsUI(); + EXPECT_CALL(*ui, SetPermissionInfo(_)).Times(AnyNumber()); + EXPECT_CALL(*ui, SetSiteInfo(_)).Times(AnyNumber()); + EXPECT_CALL(*ui, SetPresenter(_)).Times(AnyNumber()); + EXPECT_CALL(*ui, SetCookieInfo(_)).Times(AnyNumber()); + return ui; + } + + Profile* profile() const { return profile_.get(); } + + MessageLoop message_loop_; + content::TestBrowserThread ui_thread_; + content::TestBrowserThread file_thread_; + + scoped_ptr<Profile> profile_; + int cert_id_; + scoped_refptr<net::X509Certificate> cert_; + MockCertStore cert_store_; + GURL url_; + SSLStatus ssl_; + WebsiteSettings* website_settings_; +}; + +} // namespace + +TEST_F(WebsiteSettingsTest, OnPermissionsChanged) { + MockWebsiteSettingsUI* ui = new MockWebsiteSettingsUI(); + EXPECT_CALL(*ui, SetPermissionInfo(_)); + EXPECT_CALL(*ui, SetSiteInfo(_)); + EXPECT_CALL(*ui, SetPresenter(_)).Times(2); + + HostContentSettingsMap* content_settings = + profile()->GetHostContentSettingsMap(); + ContentSetting setting = content_settings->GetContentSetting( + url_, url_, CONTENT_SETTINGS_TYPE_POPUPS, ""); + EXPECT_EQ(setting, CONTENT_SETTING_BLOCK); + setting = content_settings->GetContentSetting( + url_, url_, CONTENT_SETTINGS_TYPE_PLUGINS, ""); + EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); + setting = content_settings->GetContentSetting( + url_, url_, CONTENT_SETTINGS_TYPE_GEOLOCATION, ""); + EXPECT_EQ(setting, CONTENT_SETTING_ASK); + setting = content_settings->GetContentSetting( + url_, url_, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, ""); + EXPECT_EQ(setting, CONTENT_SETTING_ASK); + + website_settings_ = new WebsiteSettings(ui, profile(), url_, ssl_, + &cert_store_); + website_settings_->OnSitePermissionChanged(CONTENT_SETTINGS_TYPE_POPUPS, + CONTENT_SETTING_ALLOW); + website_settings_->OnSitePermissionChanged(CONTENT_SETTINGS_TYPE_PLUGINS, + CONTENT_SETTING_BLOCK); + website_settings_->OnSitePermissionChanged(CONTENT_SETTINGS_TYPE_GEOLOCATION, + CONTENT_SETTING_ALLOW); + website_settings_->OnSitePermissionChanged( + CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_ALLOW); + + setting = content_settings->GetContentSetting( + url_, url_, CONTENT_SETTINGS_TYPE_POPUPS, ""); + EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); + setting = content_settings->GetContentSetting( + url_, url_, CONTENT_SETTINGS_TYPE_PLUGINS, ""); + EXPECT_EQ(setting, CONTENT_SETTING_BLOCK); + setting = content_settings->GetContentSetting( + url_, url_, CONTENT_SETTINGS_TYPE_GEOLOCATION, ""); + EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); + setting = content_settings->GetContentSetting( + url_, url_, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, ""); + EXPECT_EQ(setting, CONTENT_SETTING_ALLOW); +} + +TEST_F(WebsiteSettingsTest, HTTPConnection) { + website_settings_ = new WebsiteSettings(CreateMockUI(), profile(), url_, ssl_, + &cert_store_); + EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_UNENCRYPTED, + website_settings_->site_connection_status()); + EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_NO_CERT, + website_settings_->site_identity_status()); + EXPECT_EQ(string16(), website_settings_->organization_name()); +} + +TEST_F(WebsiteSettingsTest, HTTPSConnection) { + ssl_.security_style = content::SECURITY_STYLE_AUTHENTICATED; + ssl_.cert_id = cert_id_; + ssl_.cert_status = 0; + ssl_.security_bits = 81; // No error if > 80. + int status = 0; + status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); + status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); + ssl_.connection_status = status; + + website_settings_ = new WebsiteSettings(CreateMockUI(), profile(), url_, ssl_, + &cert_store_); + EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED, + website_settings_->site_connection_status()); + EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_CERT, + website_settings_->site_identity_status()); + EXPECT_EQ(string16(), website_settings_->organization_name()); +} + +TEST_F(WebsiteSettingsTest, HTTPSMixedContent) { + ssl_.security_style = content::SECURITY_STYLE_AUTHENTICATED; + ssl_.cert_id = cert_id_; + ssl_.cert_status = 0; + ssl_.security_bits = 81; // No error if > 80. + ssl_.content_status = SSLStatus::DISPLAYED_INSECURE_CONTENT; + int status = 0; + status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); + status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); + ssl_.connection_status = status; + + website_settings_ = new WebsiteSettings(CreateMockUI(), profile(), url_, ssl_, + &cert_store_); + EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_MIXED_CONTENT, + website_settings_->site_connection_status()); + EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_CERT, + website_settings_->site_identity_status()); + EXPECT_EQ(string16(), website_settings_->organization_name()); +} + +TEST_F(WebsiteSettingsTest, HTTPSEVCert) { + scoped_refptr<net::X509Certificate> ev_cert = + net::X509Certificate::CreateFromBytes( + reinterpret_cast<const char*>(google_der), + sizeof(google_der)); + int ev_cert_id = 1; + EXPECT_CALL(cert_store_, RetrieveCert(ev_cert_id, _)).WillRepeatedly( + DoAll(SetArgPointee<1>(ev_cert), Return(true))); + + ssl_.security_style = content::SECURITY_STYLE_AUTHENTICATED; + ssl_.cert_id = ev_cert_id; + ssl_.cert_status = net::CERT_STATUS_IS_EV; + ssl_.security_bits = 81; // No error if > 80. + ssl_.content_status = SSLStatus::DISPLAYED_INSECURE_CONTENT; + int status = 0; + status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); + status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); + ssl_.connection_status = status; + + website_settings_ = new WebsiteSettings(CreateMockUI(), profile(), url_, ssl_, + &cert_store_); + EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_MIXED_CONTENT, + website_settings_->site_connection_status()); + EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT, + website_settings_->site_identity_status()); + EXPECT_EQ(UTF8ToUTF16("Google Inc"), website_settings_->organization_name()); +} + +TEST_F(WebsiteSettingsTest, HTTPSRevocationError) { + ssl_.security_style = content::SECURITY_STYLE_AUTHENTICATED; + ssl_.cert_id = cert_id_; + ssl_.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; + ssl_.security_bits = 81; // No error if > 80. + int status = 0; + status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); + status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); + ssl_.connection_status = status; + + website_settings_ = new WebsiteSettings(CreateMockUI(), profile(), url_, ssl_, + &cert_store_); + EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED, + website_settings_->site_connection_status()); + EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_CERT_REVOCATION_UNKNOWN, + website_settings_->site_identity_status()); + EXPECT_EQ(string16(), website_settings_->organization_name()); +} + +TEST_F(WebsiteSettingsTest, HTTPSConnectionError) { + ssl_.security_style = content::SECURITY_STYLE_AUTHENTICATED; + ssl_.cert_id = cert_id_; + ssl_.cert_status = 0; + ssl_.security_bits = 1; + int status = 0; + status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); + status = SetSSLCipherSuite(status, TLS_RSA_WITH_AES_256_CBC_SHA256); + ssl_.connection_status = status; + + website_settings_ = new WebsiteSettings(CreateMockUI(), profile(), url_, ssl_, + &cert_store_); + EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED_ERROR, + website_settings_->site_connection_status()); + EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_CERT, + website_settings_->site_identity_status()); + EXPECT_EQ(string16(), website_settings_->organization_name()); +} diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index fb56aee..8d196f8 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3246,6 +3246,7 @@ 'browser/ui/touch/status_bubble_touch.cc', 'browser/ui/touch/status_bubble_touch.h', 'browser/ui/view_ids.h', + 'browser/ui/website_settings_ui.cc', 'browser/ui/website_settings_ui.h', 'browser/ui/views/about_chrome_view.cc', 'browser/ui/views/about_chrome_view.h', @@ -4023,8 +4024,8 @@ 'browser/webdata/web_database_table.h', 'browser/webdata/web_intents_table.cc', 'browser/webdata/web_intents_table.h', - 'browser/website_settings_model.cc', - 'browser/website_settings_model.h', + 'browser/website_settings.cc', + 'browser/website_settings.h', # These files are generated by GRIT. '<(grit_out_dir)/grit/component_extension_resources_map.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index cd1ee0e..095cb17 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -2028,7 +2028,7 @@ 'browser/webdata/web_data_service_unittest.cc', 'browser/webdata/web_database_migration_unittest.cc', 'browser/webdata/web_intents_table_unittest.cc', - 'browser/website_settings_model_unittest.cc', + 'browser/website_settings_unittest.cc', 'common/bzip2_unittest.cc', 'common/child_process_logging_mac_unittest.mm', 'common/chrome_paths_unittest.cc', |