1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/webui/collected_cookies_ui_delegate.h" 6 7 #include "base/message_loop.h" 8 #include "base/string_util.h" 9 #include "base/values.h" 10 #include "chrome/browser/cookies_tree_model.h" 11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" 13 #include "chrome/browser/ui/webui/constrained_html_ui.h" 14 #include "chrome/browser/ui/webui/cookies_tree_model_util.h" 15 #include "chrome/common/jstemplate_builder.h" 16 #include "chrome/common/url_constants.h" 17 #include "content/browser/tab_contents/tab_contents.h" 18 #include "content/common/notification_service.h" 19 #include "grit/browser_resources.h" 20 #include "grit/generated_resources.h" 21 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/resource/resource_bundle.h" 23 #include "ui/gfx/size.h" 24 25 namespace { 26 27 // TODO(xiyuan): Localize this. 28 const int kDialogWidth = 480; 29 const int kDialogHeight = 470; 30 31 CookieTreeOriginNode* GetOriginNode(CookiesTreeModel* model, 32 const std::string& node_path) { 33 CookieTreeNode* node = cookies_tree_model_util::GetTreeNodeFromPath( 34 model->GetRoot(), node_path); 35 36 while (node && node->GetDetailedInfo().node_type != 37 CookieTreeNode::DetailedInfo::TYPE_ORIGIN) { 38 node = node->parent(); 39 } 40 41 return static_cast<CookieTreeOriginNode*>(node); 42 } 43 44 std::string GetInfobarLabel(ContentSetting setting, 45 const string16& domain_name) { 46 switch (setting) { 47 case CONTENT_SETTING_BLOCK: 48 return l10n_util::GetStringFUTF8( 49 IDS_COLLECTED_COOKIES_BLOCK_RULE_CREATED, domain_name); 50 51 case CONTENT_SETTING_ALLOW: 52 return l10n_util::GetStringFUTF8( 53 IDS_COLLECTED_COOKIES_ALLOW_RULE_CREATED, domain_name); 54 55 case CONTENT_SETTING_SESSION_ONLY: 56 return l10n_util::GetStringFUTF8( 57 IDS_COLLECTED_COOKIES_SESSION_RULE_CREATED, domain_name); 58 59 default: 60 NOTREACHED() << "Unknown ContentSetting, " << setting; 61 return std::string(); 62 } 63 } 64 65 class CollectedCookiesSource : public ChromeURLDataManager::DataSource { 66 public: 67 explicit CollectedCookiesSource(bool block_third_party_cookies) 68 : DataSource(chrome::kChromeUICollectedCookiesHost, 69 MessageLoop::current()), 70 block_third_party_cookies_(block_third_party_cookies) { 71 } 72 73 virtual void StartDataRequest(const std::string& path, 74 bool is_incognito, 75 int request_id); 76 77 virtual std::string GetMimeType(const std::string& path) const { 78 return "text/html"; 79 } 80 81 private: 82 virtual ~CollectedCookiesSource() {} 83 84 bool block_third_party_cookies_; 85 86 DISALLOW_COPY_AND_ASSIGN(CollectedCookiesSource); 87 }; 88 89 void CollectedCookiesSource::StartDataRequest(const std::string& path, 90 bool is_incognito, 91 int request_id) { 92 DictionaryValue localized_strings; 93 localized_strings.SetString("title", 94 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE)); 95 96 localized_strings.SetString("title", 97 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_DIALOG_TITLE)); 98 localized_strings.SetString("allowedCookies", 99 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_LABEL)); 100 localized_strings.SetString("blockButton", 101 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON)); 102 103 localized_strings.SetString("blockedCookies", 104 l10n_util::GetStringUTF16(block_third_party_cookies_ ? 105 IDS_COLLECTED_COOKIES_BLOCKED_THIRD_PARTY_BLOCKING_ENABLED : 106 IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_LABEL)); 107 108 localized_strings.SetString("allowButton", 109 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON)); 110 localized_strings.SetString("allowThisSessionButton", 111 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON)); 112 localized_strings.SetString("closeButton", 113 l10n_util::GetStringUTF16(IDS_CLOSE)); 114 115 SetFontAndTextDirection(&localized_strings); 116 117 static const base::StringPiece html( 118 ResourceBundle::GetSharedInstance().GetRawDataResource( 119 IDR_COLLECTED_COOKIES_HTML)); 120 const std::string response = jstemplate_builder::GetI18nTemplateHtml( 121 html, &localized_strings); 122 123 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); 124 html_bytes->data.resize(response.size()); 125 std::copy(response.begin(), response.end(), html_bytes->data.begin()); 126 127 SendResponse(request_id, html_bytes); 128 } 129 130 } // namespace 131 132 // static 133 void CollectedCookiesUIDelegate::Show(TabContents* tab_contents) { 134 CollectedCookiesUIDelegate* delegate = 135 new CollectedCookiesUIDelegate(tab_contents); 136 ConstrainedHtmlUI::CreateConstrainedHtmlDialog(tab_contents->profile(), 137 delegate, 138 tab_contents); 139 } 140 141 CollectedCookiesUIDelegate::CollectedCookiesUIDelegate( 142 TabContents* tab_contents) 143 : tab_contents_(tab_contents), 144 closed_(false) { 145 TabSpecificContentSettings* content_settings = 146 tab_contents->GetTabSpecificContentSettings(); 147 HostContentSettingsMap* host_content_settings_map = 148 tab_contents_->profile()->GetHostContentSettingsMap(); 149 150 registrar_.Add(this, NotificationType::COLLECTED_COOKIES_SHOWN, 151 Source<TabSpecificContentSettings>(content_settings)); 152 153 allowed_cookies_tree_model_.reset( 154 content_settings->GetAllowedCookiesTreeModel()); 155 blocked_cookies_tree_model_.reset( 156 content_settings->GetBlockedCookiesTreeModel()); 157 158 CollectedCookiesSource* source = new CollectedCookiesSource( 159 host_content_settings_map->BlockThirdPartyCookies()); 160 tab_contents->profile()->GetChromeURLDataManager()->AddDataSource(source); 161 } 162 163 CollectedCookiesUIDelegate::~CollectedCookiesUIDelegate() { 164 } 165 166 bool CollectedCookiesUIDelegate::IsDialogModal() const { 167 return false; 168 } 169 170 std::wstring CollectedCookiesUIDelegate::GetDialogTitle() const { 171 return std::wstring(); 172 } 173 174 GURL CollectedCookiesUIDelegate::GetDialogContentURL() const { 175 return GURL(chrome::kChromeUICollectedCookiesURL); 176 } 177 178 void CollectedCookiesUIDelegate::GetWebUIMessageHandlers( 179 std::vector<WebUIMessageHandler*>* handlers) const { 180 const WebUIMessageHandler* handler = this; 181 handlers->push_back(const_cast<WebUIMessageHandler*>(handler)); 182 } 183 184 void CollectedCookiesUIDelegate::GetDialogSize(gfx::Size* size) const { 185 size->set_width(kDialogWidth); 186 size->set_height(kDialogHeight); 187 } 188 189 std::string CollectedCookiesUIDelegate::GetDialogArgs() const { 190 return std::string(); 191 } 192 193 void CollectedCookiesUIDelegate::OnDialogClosed( 194 const std::string& json_retval) { 195 closed_ = true; 196 } 197 198 bool CollectedCookiesUIDelegate::ShouldShowDialogTitle() const { 199 return true; 200 } 201 202 void CollectedCookiesUIDelegate::RegisterMessages() { 203 web_ui_->RegisterMessageCallback("BindCookiesTreeModel", 204 NewCallback(this, &CollectedCookiesUIDelegate::BindCookiesTreeModel)); 205 web_ui_->RegisterMessageCallback("Block", 206 NewCallback(this, &CollectedCookiesUIDelegate::Block)); 207 web_ui_->RegisterMessageCallback("Allow", 208 NewCallback(this, &CollectedCookiesUIDelegate::Allow)); 209 web_ui_->RegisterMessageCallback("AllowThisSession", 210 NewCallback(this, &CollectedCookiesUIDelegate::AllowThisSession)); 211 212 allowed_cookies_adapter_.Init(web_ui_); 213 blocked_cookies_adapter_.Init(web_ui_); 214 } 215 216 void CollectedCookiesUIDelegate::CloseDialog() { 217 if (!closed_ && web_ui_) 218 web_ui_->CallJavascriptFunction("closeDialog"); 219 } 220 221 void CollectedCookiesUIDelegate::SetInfobarLabel(const std::string& text) { 222 StringValue string(text); 223 web_ui_->CallJavascriptFunction("setInfobarLabel", string); 224 } 225 226 void CollectedCookiesUIDelegate::AddContentException( 227 CookieTreeOriginNode* origin_node, ContentSetting setting) { 228 if (origin_node->CanCreateContentException()) { 229 origin_node->CreateContentException( 230 tab_contents_->profile()->GetHostContentSettingsMap(), setting); 231 232 SetInfobarLabel(GetInfobarLabel(setting, origin_node->GetTitle())); 233 } 234 } 235 236 void CollectedCookiesUIDelegate::Observe(NotificationType type, 237 const NotificationSource& source, 238 const NotificationDetails& details) { 239 DCHECK_EQ(type.value, NotificationType::COLLECTED_COOKIES_SHOWN); 240 DCHECK_EQ(Source<TabSpecificContentSettings>(source).ptr(), 241 tab_contents_->GetTabSpecificContentSettings()); 242 CloseDialog(); 243 } 244 245 void CollectedCookiesUIDelegate::BindCookiesTreeModel(const ListValue* args) { 246 allowed_cookies_adapter_.Bind("allowed-cookies", 247 allowed_cookies_tree_model_.get()); 248 blocked_cookies_adapter_.Bind("blocked-cookies", 249 blocked_cookies_tree_model_.get()); 250 } 251 252 void CollectedCookiesUIDelegate::Block(const ListValue* args) { 253 std::string node_path; 254 if (!args->GetString(0, &node_path)) 255 return; 256 257 CookieTreeOriginNode* origin_node = GetOriginNode( 258 allowed_cookies_tree_model_.get(), node_path); 259 if (!origin_node) 260 return; 261 262 AddContentException(origin_node, CONTENT_SETTING_BLOCK); 263 } 264 265 void CollectedCookiesUIDelegate::Allow(const ListValue* args) { 266 std::string node_path; 267 if (!args->GetString(0, &node_path)) 268 return; 269 270 CookieTreeOriginNode* origin_node = GetOriginNode( 271 blocked_cookies_tree_model_.get(), node_path); 272 if (!origin_node) 273 return; 274 275 AddContentException(origin_node, CONTENT_SETTING_ALLOW); 276 } 277 278 void CollectedCookiesUIDelegate::AllowThisSession(const ListValue* args) { 279 std::string node_path; 280 if (!args->GetString(0, &node_path)) 281 return; 282 283 CookieTreeOriginNode* origin_node = GetOriginNode( 284 blocked_cookies_tree_model_.get(), node_path); 285 if (!origin_node) 286 return; 287 288 AddContentException(origin_node, CONTENT_SETTING_SESSION_ONLY); 289 } 290