1 // 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.
5 #include "chrome/browser/ui/webui/cookies_tree_model_util.h"
9 #include "base/i18n/time_formatting.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/stl_util.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/values.h"
16 #include "chrome/browser/browsing_data/cookies_tree_model.h"
17 #include "content/public/browser/indexed_db_context.h"
18 #include "extensions/common/extension_set.h"
19 #include "grit/generated_resources.h"
20 #include "net/cookies/canonical_cookie.h"
21 #include "net/ssl/ssl_client_cert_type.h"
22 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/base/text/bytes_formatting.h"
24 #include "webkit/common/fileapi/file_system_types.h"
28 const char kKeyId
[] = "id";
29 const char kKeyTitle
[] = "title";
30 const char kKeyIcon
[] = "icon";
31 const char kKeyType
[] = "type";
32 const char kKeyHasChildren
[] = "hasChildren";
34 const char kKeyAppsProtectingThis
[] = "appsProtectingThis";
35 const char kKeyName
[] = "name";
36 const char kKeyContent
[] = "content";
37 const char kKeyDomain
[] = "domain";
38 const char kKeyPath
[] = "path";
39 const char kKeySendFor
[] = "sendfor";
40 const char kKeyAccessibleToScript
[] = "accessibleToScript";
41 const char kKeyDesc
[] = "desc";
42 const char kKeySize
[] = "size";
43 const char kKeyOrigin
[] = "origin";
44 const char kKeyManifest
[] = "manifest";
45 const char kKeyServerId
[] = "serverId";
47 const char kKeyAccessed
[] = "accessed";
48 const char kKeyCreated
[] = "created";
49 const char kKeyExpires
[] = "expires";
50 const char kKeyModified
[] = "modified";
52 const char kKeyPersistent
[] = "persistent";
53 const char kKeyTemporary
[] = "temporary";
55 const char kKeyTotalUsage
[] = "totalUsage";
56 const char kKeyTemporaryUsage
[] = "temporaryUsage";
57 const char kKeyPersistentUsage
[] = "persistentUsage";
59 const char kKeyCertType
[] = "certType";
61 const int64 kNegligibleUsage
= 1024; // 1KiB
63 std::string
ClientCertTypeToString(net::SSLClientCertType type
) {
65 case net::CLIENT_CERT_RSA_SIGN
:
66 return l10n_util::GetStringUTF8(IDS_CLIENT_CERT_RSA_SIGN
);
67 case net::CLIENT_CERT_DSS_SIGN
:
68 return l10n_util::GetStringUTF8(IDS_CLIENT_CERT_DSS_SIGN
);
69 case net::CLIENT_CERT_ECDSA_SIGN
:
70 return l10n_util::GetStringUTF8(IDS_CLIENT_CERT_ECDSA_SIGN
);
72 return base::IntToString(type
);
78 CookiesTreeModelUtil::CookiesTreeModelUtil() {
81 CookiesTreeModelUtil::~CookiesTreeModelUtil() {
84 std::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
);
89 int32 new_id
= id_map_
.Add(node
);
90 node_map_
[node
] = new_id
;
91 return base::IntToString(new_id
);
94 bool 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());
102 switch (node
.GetDetailedInfo().node_type
) {
103 case CookieTreeNode::DetailedInfo::TYPE_HOST
: {
104 dict
->SetString(kKeyType
, "origin");
105 #if defined(OS_MACOSX)
106 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER");
110 case CookieTreeNode::DetailedInfo::TYPE_COOKIE
: {
111 dict
->SetString(kKeyType
, "cookie");
112 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_ICON");
114 const net::CanonicalCookie
& cookie
= *node
.GetDetailedInfo().cookie
;
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
, base::UTF16ToUTF8(
128 base::TimeFormatFriendlyDateAndTime(cookie
.CreationDate())));
129 dict
->SetString(kKeyExpires
, cookie
.IsPersistent() ? base::UTF16ToUTF8(
130 base::TimeFormatFriendlyDateAndTime(cookie
.ExpiryDate())) :
131 l10n_util::GetStringUTF8(IDS_COOKIES_COOKIE_EXPIRES_SESSION
));
135 case CookieTreeNode::DetailedInfo::TYPE_DATABASE
: {
136 dict
->SetString(kKeyType
, "database");
137 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
139 const BrowsingDataDatabaseHelper::DatabaseInfo
& database_info
=
140 *node
.GetDetailedInfo().database_info
;
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
, base::UTF16ToUTF8(
148 base::TimeFormatFriendlyDateAndTime(database_info
.last_modified
)));
152 case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE
: {
153 dict
->SetString(kKeyType
, "local_storage");
154 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
156 const BrowsingDataLocalStorageHelper::LocalStorageInfo
&
157 local_storage_info
= *node
.GetDetailedInfo().local_storage_info
;
159 dict
->SetString(kKeyOrigin
, local_storage_info
.origin_url
.spec());
160 dict
->SetString(kKeySize
, ui::FormatBytes(local_storage_info
.size
));
161 dict
->SetString(kKeyModified
, base::UTF16ToUTF8(
162 base::TimeFormatFriendlyDateAndTime(
163 local_storage_info
.last_modified
)));
167 case CookieTreeNode::DetailedInfo::TYPE_APPCACHE
: {
168 dict
->SetString(kKeyType
, "app_cache");
169 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
171 const appcache::AppCacheInfo
& appcache_info
=
172 *node
.GetDetailedInfo().appcache_info
;
174 dict
->SetString(kKeyManifest
, appcache_info
.manifest_url
.spec());
175 dict
->SetString(kKeySize
, ui::FormatBytes(appcache_info
.size
));
176 dict
->SetString(kKeyCreated
, base::UTF16ToUTF8(
177 base::TimeFormatFriendlyDateAndTime(appcache_info
.creation_time
)));
178 dict
->SetString(kKeyAccessed
, base::UTF16ToUTF8(
179 base::TimeFormatFriendlyDateAndTime(appcache_info
.last_access_time
)));
183 case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB
: {
184 dict
->SetString(kKeyType
, "indexed_db");
185 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
187 const content::IndexedDBInfo
& indexed_db_info
=
188 *node
.GetDetailedInfo().indexed_db_info
;
190 dict
->SetString(kKeyOrigin
, indexed_db_info
.origin_
.spec());
191 dict
->SetString(kKeySize
, ui::FormatBytes(indexed_db_info
.size_
));
192 dict
->SetString(kKeyModified
, base::UTF16ToUTF8(
193 base::TimeFormatFriendlyDateAndTime(indexed_db_info
.last_modified_
)));
197 case CookieTreeNode::DetailedInfo::TYPE_FILE_SYSTEM
: {
198 dict
->SetString(kKeyType
, "file_system");
199 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
201 const BrowsingDataFileSystemHelper::FileSystemInfo
& file_system_info
=
202 *node
.GetDetailedInfo().file_system_info
;
203 const fileapi::FileSystemType kPerm
= fileapi::kFileSystemTypePersistent
;
204 const fileapi::FileSystemType kTemp
= fileapi::kFileSystemTypeTemporary
;
206 dict
->SetString(kKeyOrigin
, file_system_info
.origin
.spec());
207 dict
->SetString(kKeyPersistent
,
208 ContainsKey(file_system_info
.usage_map
, kPerm
) ?
209 base::UTF16ToUTF8(ui::FormatBytes(
210 file_system_info
.usage_map
.find(kPerm
)->second
)) :
211 l10n_util::GetStringUTF8(
212 IDS_COOKIES_FILE_SYSTEM_USAGE_NONE
));
213 dict
->SetString(kKeyTemporary
,
214 ContainsKey(file_system_info
.usage_map
, kTemp
) ?
215 base::UTF16ToUTF8(ui::FormatBytes(
216 file_system_info
.usage_map
.find(kTemp
)->second
)) :
217 l10n_util::GetStringUTF8(
218 IDS_COOKIES_FILE_SYSTEM_USAGE_NONE
));
221 case CookieTreeNode::DetailedInfo::TYPE_QUOTA
: {
222 dict
->SetString(kKeyType
, "quota");
223 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_STORAGE_ICON");
225 const BrowsingDataQuotaHelper::QuotaInfo
& quota_info
=
226 *node
.GetDetailedInfo().quota_info
;
227 if (quota_info
.temporary_usage
+ quota_info
.persistent_usage
<=
231 dict
->SetString(kKeyOrigin
, quota_info
.host
);
232 dict
->SetString(kKeyTotalUsage
,
233 base::UTF16ToUTF8(ui::FormatBytes(
234 quota_info
.temporary_usage
+
235 quota_info
.persistent_usage
)));
236 dict
->SetString(kKeyTemporaryUsage
,
237 base::UTF16ToUTF8(ui::FormatBytes(
238 quota_info
.temporary_usage
)));
239 dict
->SetString(kKeyPersistentUsage
,
240 base::UTF16ToUTF8(ui::FormatBytes(
241 quota_info
.persistent_usage
)));
244 case CookieTreeNode::DetailedInfo::TYPE_SERVER_BOUND_CERT
: {
245 dict
->SetString(kKeyType
, "server_bound_cert");
246 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_ICON");
248 const net::ServerBoundCertStore::ServerBoundCert
& server_bound_cert
=
249 *node
.GetDetailedInfo().server_bound_cert
;
251 dict
->SetString(kKeyServerId
, server_bound_cert
.server_identifier());
252 dict
->SetString(kKeyCertType
,
253 ClientCertTypeToString(net::CLIENT_CERT_ECDSA_SIGN
));
254 dict
->SetString(kKeyCreated
, base::UTF16ToUTF8(
255 base::TimeFormatFriendlyDateAndTime(
256 server_bound_cert
.creation_time())));
259 case CookieTreeNode::DetailedInfo::TYPE_FLASH_LSO
: {
260 dict
->SetString(kKeyType
, "flash_lso");
261 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_COOKIE_ICON");
263 dict
->SetString(kKeyDomain
, node
.GetDetailedInfo().flash_lso_domain
);
266 #if defined(OS_MACOSX)
267 dict
->SetString(kKeyIcon
, "chrome://theme/IDR_BOOKMARK_BAR_FOLDER");
272 const extensions::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 (extensions::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
);
283 dict
->Set(kKeyAppsProtectingThis
, app_infos
);
289 void CookiesTreeModelUtil::GetChildNodeList(const CookieTreeNode
* parent
,
292 base::ListValue
* nodes
) {
293 for (int i
= 0; i
< count
; ++i
) {
294 scoped_ptr
<base::DictionaryValue
> dict(new base::DictionaryValue
);
295 const CookieTreeNode
* child
= parent
->GetChild(start
+ i
);
296 if (GetCookieTreeNodeDictionary(*child
, dict
.get()))
297 nodes
->Append(dict
.release());
301 const 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
);
307 const CookieTreeNode
* child
= NULL
;
308 const CookieTreeNode
* parent
= root
;
309 int child_index
= -1;
311 // Validate the tree path and get the node pointer.
312 for (size_t i
= 0; i
< node_ids
.size(); ++i
) {
314 if (!base::StringToInt(node_ids
[i
], &node_id
))
317 child
= id_map_
.Lookup(node_id
);
318 child_index
= parent
->GetIndexOf(child
);
319 if (child_index
== -1)
325 return child_index
>= 0 ? child
: NULL
;