Home | History | Annotate | Download | only in webui
      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.
      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"
     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"
     25 
     26 namespace {
     27 
     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";
     33 
     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";
     46 
     47 const char kKeyAccessed[] = "accessed";
     48 const char kKeyCreated[] = "created";
     49 const char kKeyExpires[] = "expires";
     50 const char kKeyModified[] = "modified";
     51 
     52 const char kKeyPersistent[] = "persistent";
     53 const char kKeyTemporary[] = "temporary";
     54 
     55 const char kKeyTotalUsage[] = "totalUsage";
     56 const char kKeyTemporaryUsage[] = "temporaryUsage";
     57 const char kKeyPersistentUsage[] = "persistentUsage";
     58 
     59 const char kKeyCertType[] = "certType";
     60 
     61 const int64 kNegligibleUsage = 1024;  // 1KiB
     62 
     63 std::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);
     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);
     71     default:
     72       return base::IntToString(type);
     73   }
     74 }
     75 
     76 }  // namespace
     77 
     78 CookiesTreeModelUtil::CookiesTreeModelUtil() {
     79 }
     80 
     81 CookiesTreeModelUtil::~CookiesTreeModelUtil() {
     82 }
     83 
     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);
     88 
     89   int32 new_id = id_map_.Add(node);
     90   node_map_[node] = new_id;
     91   return base::IntToString(new_id);
     92 }
     93 
     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());
    101 
    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");
    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, 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));
    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, base::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, base::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, base::UTF16ToUTF8(
    177           base::TimeFormatFriendlyDateAndTime(appcache_info.creation_time)));
    178       dict->SetString(kKeyAccessed, base::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 
    187       const content::IndexedDBInfo& indexed_db_info =
    188           *node.GetDetailedInfo().indexed_db_info;
    189 
    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_)));
    194 
    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;
    203       const fileapi::FileSystemType kPerm = fileapi::kFileSystemTypePersistent;
    204       const fileapi::FileSystemType kTemp = fileapi::kFileSystemTypeTemporary;
    205 
    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));
    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                       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)));
    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,
    253                       ClientCertTypeToString(net::CLIENT_CERT_ECDSA_SIGN));
    254       dict->SetString(kKeyCreated, base::UTF16ToUTF8(
    255           base::TimeFormatFriendlyDateAndTime(
    256               server_bound_cert.creation_time())));
    257       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 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);
    282     }
    283     dict->Set(kKeyAppsProtectingThis, app_infos);
    284   }
    285 
    286   return true;
    287 }
    288 
    289 void 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 base::DictionaryValue);
    295     const CookieTreeNode* child = parent->GetChild(start + i);
    296     if (GetCookieTreeNodeDictionary(*child, dict.get()))
    297       nodes->Append(dict.release());
    298   }
    299 }
    300 
    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);
    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 }
    327