blob: bb1ac1a8f4225f6ac2777bb6592a7df050b769d7 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// Copyright (c) 2012 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/cookies_tree_model_util.h"
6
7#include <vector>
8
9#include "base/i18n/time_formatting.h"
10#include "base/memory/scoped_ptr.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010011#include "base/stl_util.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000012#include "base/strings/string_number_conversions.h"
13#include "base/strings/string_split.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010014#include "base/strings/string_util.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000015#include "base/values.h"
16#include "chrome/browser/browsing_data/cookies_tree_model.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010017#include "content/public/browser/indexed_db_context.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000018#include "grit/generated_resources.h"
19#include "net/cookies/canonical_cookie.h"
Ben Murdochbb1529c2013-08-08 10:24:53 +010020#include "net/ssl/ssl_client_cert_type.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000021#include "ui/base/l10n/l10n_util.h"
22#include "ui/base/text/bytes_formatting.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010023#include "webkit/common/fileapi/file_system_types.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024
25namespace {
26
27const char kKeyId[] = "id";
28const char kKeyTitle[] = "title";
29const char kKeyIcon[] = "icon";
30const char kKeyType[] = "type";
31const char kKeyHasChildren[] = "hasChildren";
32
Torne (Richard Coles)58218062012-11-14 11:43:16 +000033const char kKeyAppsProtectingThis[] = "appsProtectingThis";
34const char kKeyName[] = "name";
35const char kKeyContent[] = "content";
36const char kKeyDomain[] = "domain";
37const char kKeyPath[] = "path";
38const char kKeySendFor[] = "sendfor";
39const char kKeyAccessibleToScript[] = "accessibleToScript";
40const char kKeyDesc[] = "desc";
41const char kKeySize[] = "size";
42const char kKeyOrigin[] = "origin";
43const char kKeyManifest[] = "manifest";
44const char kKeyServerId[] = "serverId";
45
46const char kKeyAccessed[] = "accessed";
47const char kKeyCreated[] = "created";
48const char kKeyExpires[] = "expires";
49const char kKeyModified[] = "modified";
50
51const char kKeyPersistent[] = "persistent";
52const char kKeyTemporary[] = "temporary";
53
54const char kKeyTotalUsage[] = "totalUsage";
55const char kKeyTemporaryUsage[] = "temporaryUsage";
56const char kKeyPersistentUsage[] = "persistentUsage";
57const char kKeyPersistentQuota[] = "persistentQuota";
58
59const char kKeyCertType[] = "certType";
60
61const int64 kNegligibleUsage = 1024; // 1KiB
62
63std::string ClientCertTypeToString(net::SSLClientCertType type) {
64 switch (type) {
65 case net::CLIENT_CERT_RSA_SIGN:
66 return l10n_util::GetStringUTF8(IDS_CLIENT_CERT_RSA_SIGN);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000067 case net::CLIENT_CERT_DSS_SIGN:
68 return l10n_util::GetStringUTF8(IDS_CLIENT_CERT_DSS_SIGN);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000069 case net::CLIENT_CERT_ECDSA_SIGN:
70 return l10n_util::GetStringUTF8(IDS_CLIENT_CERT_ECDSA_SIGN);
71 default:
72 return base::IntToString(type);
73 }
74}
75
76} // namespace
77
78CookiesTreeModelUtil::CookiesTreeModelUtil() {
79}
80
81CookiesTreeModelUtil::~CookiesTreeModelUtil() {
82}
83
84std::string CookiesTreeModelUtil::GetTreeNodeId(const CookieTreeNode* node) {
85 CookieTreeNodeMap::const_iterator iter = node_map_.find(node);
86 if (iter != node_map_.end())
87 return base::IntToString(iter->second);
88
89 int32 new_id = id_map_.Add(node);
90 node_map_[node] = new_id;
91 return base::IntToString(new_id);
92}
93
94bool CookiesTreeModelUtil::GetCookieTreeNodeDictionary(
95 const CookieTreeNode& node,
96 base::DictionaryValue* dict) {
97 // Use node's address as an id for WebUI to look it up.
98 dict->SetString(kKeyId, GetTreeNodeId(&node));
99 dict->SetString(kKeyTitle, node.GetTitle());
100 dict->SetBoolean(kKeyHasChildren, !node.empty());
101
102 switch (node.GetDetailedInfo().node_type) {
103 case CookieTreeNode::DetailedInfo::TYPE_HOST: {
104 dict->SetString(kKeyType, "origin");
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000105#if defined(OS_MACOSX)
106 dict->SetString(kKeyIcon, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER");
107#endif
108 break;
109 }
110 case CookieTreeNode::DetailedInfo::TYPE_COOKIE: {
111 dict->SetString(kKeyType, "cookie");
112 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_ICON");
113
114 const net::CanonicalCookie& cookie = *node.GetDetailedInfo().cookie;
115
116 dict->SetString(kKeyName, cookie.Name());
117 dict->SetString(kKeyContent, cookie.Value());
118 dict->SetString(kKeyDomain, cookie.Domain());
119 dict->SetString(kKeyPath, cookie.Path());
120 dict->SetString(kKeySendFor, cookie.IsSecure() ?
121 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_SENDFOR_SECURE) :
122 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_SENDFOR_ANY));
123 std::string accessible = cookie.IsHttpOnly() ?
124 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_NO) :
125 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_YES);
126 dict->SetString(kKeyAccessibleToScript, accessible);
127 dict->SetString(kKeyCreated, UTF16ToUTF8(
128 base::TimeFormatFriendlyDateAndTime(cookie.CreationDate())));
129 dict->SetString(kKeyExpires, cookie.IsPersistent() ? UTF16ToUTF8(
130 base::TimeFormatFriendlyDateAndTime(cookie.ExpiryDate())) :
131 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_EXPIRES_SESSION));
132
133 break;
134 }
135 case CookieTreeNode::DetailedInfo::TYPE_DATABASE: {
136 dict->SetString(kKeyType, "database");
137 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
138
139 const BrowsingDataDatabaseHelper::DatabaseInfo& database_info =
140 *node.GetDetailedInfo().database_info;
141
142 dict->SetString(kKeyName, database_info.database_name.empty() ?
143 l10n_util::GetStringUTF8(IDS_COOKIES_WEB_DATABASE_UNNAMED_NAME) :
144 database_info.database_name);
145 dict->SetString(kKeyDesc, database_info.description);
146 dict->SetString(kKeySize, ui::FormatBytes(database_info.size));
147 dict->SetString(kKeyModified, UTF16ToUTF8(
148 base::TimeFormatFriendlyDateAndTime(database_info.last_modified)));
149
150 break;
151 }
152 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: {
153 dict->SetString(kKeyType, "local_storage");
154 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
155
156 const BrowsingDataLocalStorageHelper::LocalStorageInfo&
157 local_storage_info = *node.GetDetailedInfo().local_storage_info;
158
159 dict->SetString(kKeyOrigin, local_storage_info.origin_url.spec());
160 dict->SetString(kKeySize, ui::FormatBytes(local_storage_info.size));
161 dict->SetString(kKeyModified, UTF16ToUTF8(
162 base::TimeFormatFriendlyDateAndTime(
163 local_storage_info.last_modified)));
164
165 break;
166 }
167 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE: {
168 dict->SetString(kKeyType, "app_cache");
169 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
170
171 const appcache::AppCacheInfo& appcache_info =
172 *node.GetDetailedInfo().appcache_info;
173
174 dict->SetString(kKeyManifest, appcache_info.manifest_url.spec());
175 dict->SetString(kKeySize, ui::FormatBytes(appcache_info.size));
176 dict->SetString(kKeyCreated, UTF16ToUTF8(
177 base::TimeFormatFriendlyDateAndTime(appcache_info.creation_time)));
178 dict->SetString(kKeyAccessed, UTF16ToUTF8(
179 base::TimeFormatFriendlyDateAndTime(appcache_info.last_access_time)));
180
181 break;
182 }
183 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB: {
184 dict->SetString(kKeyType, "indexed_db");
185 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
186
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100187 const content::IndexedDBInfo& indexed_db_info =
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000188 *node.GetDetailedInfo().indexed_db_info;
189
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100190 dict->SetString(kKeyOrigin, indexed_db_info.origin_.spec());
191 dict->SetString(kKeySize, ui::FormatBytes(indexed_db_info.size_));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000192 dict->SetString(kKeyModified, UTF16ToUTF8(
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100193 base::TimeFormatFriendlyDateAndTime(indexed_db_info.last_modified_)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000194
195 break;
196 }
197 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM: {
198 dict->SetString(kKeyType, "file_system");
199 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
200
201 const BrowsingDataFileSystemHelper::FileSystemInfo& file_system_info =
202 *node.GetDetailedInfo().file_system_info;
Ben Murdocheb525c52013-07-10 11:40:50 +0100203 const fileapi::FileSystemType kPerm = fileapi::kFileSystemTypePersistent;
204 const fileapi::FileSystemType kTemp = fileapi::kFileSystemTypeTemporary;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000205
206 dict->SetString(kKeyOrigin, file_system_info.origin.spec());
207 dict->SetString(kKeyPersistent,
Ben Murdocheb525c52013-07-10 11:40:50 +0100208 ContainsKey(file_system_info.usage_map, kPerm) ?
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000209 UTF16ToUTF8(ui::FormatBytes(
Ben Murdocheb525c52013-07-10 11:40:50 +0100210 file_system_info.usage_map.find(kPerm)->second)) :
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000211 l10n_util::GetStringUTF8(
212 IDS_COOKIES_FILE_SYSTEM_USAGE_NONE));
213 dict->SetString(kKeyTemporary,
Ben Murdocheb525c52013-07-10 11:40:50 +0100214 ContainsKey(file_system_info.usage_map, kTemp) ?
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000215 UTF16ToUTF8(ui::FormatBytes(
Ben Murdocheb525c52013-07-10 11:40:50 +0100216 file_system_info.usage_map.find(kTemp)->second)) :
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000217 l10n_util::GetStringUTF8(
218 IDS_COOKIES_FILE_SYSTEM_USAGE_NONE));
219 break;
220 }
221 case CookieTreeNode::DetailedInfo::TYPE_QUOTA: {
222 dict->SetString(kKeyType, "quota");
223 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
224
225 const BrowsingDataQuotaHelper::QuotaInfo& quota_info =
226 *node.GetDetailedInfo().quota_info;
227 if (quota_info.temporary_usage + quota_info.persistent_usage <=
228 kNegligibleUsage)
229 return false;
230
231 dict->SetString(kKeyOrigin, quota_info.host);
232 dict->SetString(kKeyTotalUsage,
233 UTF16ToUTF8(ui::FormatBytes(
234 quota_info.temporary_usage +
235 quota_info.persistent_usage)));
236 dict->SetString(kKeyTemporaryUsage,
237 UTF16ToUTF8(ui::FormatBytes(
238 quota_info.temporary_usage)));
239 dict->SetString(kKeyPersistentUsage,
240 UTF16ToUTF8(ui::FormatBytes(
241 quota_info.persistent_usage)));
242 break;
243 }
244 case CookieTreeNode::DetailedInfo::TYPE_SERVER_BOUND_CERT: {
245 dict->SetString(kKeyType, "server_bound_cert");
246 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_ICON");
247
248 const net::ServerBoundCertStore::ServerBoundCert& server_bound_cert =
249 *node.GetDetailedInfo().server_bound_cert;
250
251 dict->SetString(kKeyServerId, server_bound_cert.server_identifier());
252 dict->SetString(kKeyCertType,
Ben Murdochbb1529c2013-08-08 10:24:53 +0100253 ClientCertTypeToString(net::CLIENT_CERT_ECDSA_SIGN));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000254 dict->SetString(kKeyCreated, UTF16ToUTF8(
255 base::TimeFormatFriendlyDateAndTime(
256 server_bound_cert.creation_time())));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000257 break;
258 }
259 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO: {
260 dict->SetString(kKeyType, "flash_lso");
261 dict->SetString(kKeyIcon, "chrome://theme/IDR_COOKIE_ICON");
262
263 dict->SetString(kKeyDomain, node.GetDetailedInfo().flash_lso_domain);
264 }
265 default:
266#if defined(OS_MACOSX)
267 dict->SetString(kKeyIcon, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER");
268#endif
269 break;
270 }
271
272 const ExtensionSet* protecting_apps =
273 node.GetModel()->ExtensionsProtectingNode(node);
274 if (protecting_apps && !protecting_apps->is_empty()) {
275 base::ListValue* app_infos = new base::ListValue;
276 for (ExtensionSet::const_iterator it = protecting_apps->begin();
277 it != protecting_apps->end(); ++it) {
278 base::DictionaryValue* app_info = new base::DictionaryValue();
279 app_info->SetString(kKeyId, (*it)->id());
280 app_info->SetString(kKeyName, (*it)->name());
281 app_infos->Append(app_info);
282 }
283 dict->Set(kKeyAppsProtectingThis, app_infos);
284 }
285
286 return true;
287}
288
289void CookiesTreeModelUtil::GetChildNodeList(const CookieTreeNode* parent,
290 int start,
291 int count,
292 base::ListValue* nodes) {
293 for (int i = 0; i < count; ++i) {
294 scoped_ptr<base::DictionaryValue> dict(new DictionaryValue);
295 const CookieTreeNode* child = parent->GetChild(start + i);
296 if (GetCookieTreeNodeDictionary(*child, dict.get()))
297 nodes->Append(dict.release());
298 }
299}
300
301const CookieTreeNode* CookiesTreeModelUtil::GetTreeNodeFromPath(
302 const CookieTreeNode* root,
303 const std::string& path) {
304 std::vector<std::string> node_ids;
305 base::SplitString(path, ',', &node_ids);
306
307 const CookieTreeNode* child = NULL;
308 const CookieTreeNode* parent = root;
309 int child_index = -1;
310
311 // Validate the tree path and get the node pointer.
312 for (size_t i = 0; i < node_ids.size(); ++i) {
313 int32 node_id = 0;
314 if (!base::StringToInt(node_ids[i], &node_id))
315 break;
316
317 child = id_map_.Lookup(node_id);
318 child_index = parent->GetIndexOf(child);
319 if (child_index == -1)
320 break;
321
322 parent = child;
323 }
324
325 return child_index >= 0 ? child : NULL;
326}