Home | History | Annotate | Download | only in extensions
      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/extensions/extension_warning_set.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/browser/chrome_notification_types.h"
     10 #include "content/public/browser/browser_thread.h"
     11 #include "extensions/common/extension.h"
     12 #include "extensions/common/extension_set.h"
     13 #include "grit/chromium_strings.h"
     14 #include "grit/generated_resources.h"
     15 #include "net/base/escape.h"
     16 #include "ui/base/l10n/l10n_util.h"
     17 
     18 using content::BrowserThread;
     19 
     20 namespace {
     21 // Prefix for message parameters indicating that the parameter needs to
     22 // be translated from an extension id to the extension name.
     23 const char kTranslate[] = "TO_TRANSLATE:";
     24 const size_t kMaxNumberOfParameters = 4;
     25 }
     26 
     27 namespace extensions {
     28 
     29 //
     30 // ExtensionWarning
     31 //
     32 
     33 ExtensionWarning::ExtensionWarning(
     34     WarningType type,
     35     const std::string& extension_id,
     36     int message_id,
     37     const std::vector<std::string>& message_parameters)
     38     : type_(type),
     39       extension_id_(extension_id),
     40       message_id_(message_id),
     41       message_parameters_(message_parameters) {
     42   // These are invalid here because they do not have corresponding warning
     43   // messages in the UI.
     44   CHECK_NE(type, kInvalid);
     45   CHECK_NE(type, kMaxWarningType);
     46   CHECK_LE(message_parameters.size(), kMaxNumberOfParameters);
     47 }
     48 
     49 ExtensionWarning::ExtensionWarning(const ExtensionWarning& other)
     50   : type_(other.type_),
     51     extension_id_(other.extension_id_),
     52     message_id_(other.message_id_),
     53     message_parameters_(other.message_parameters_) {}
     54 
     55 ExtensionWarning::~ExtensionWarning() {
     56 }
     57 
     58 ExtensionWarning& ExtensionWarning::operator=(const ExtensionWarning& other) {
     59   type_ = other.type_;
     60   extension_id_ = other.extension_id_;
     61   message_id_ = other.message_id_;
     62   message_parameters_ = other.message_parameters_;
     63   return *this;
     64 }
     65 
     66 // static
     67 ExtensionWarning ExtensionWarning::CreateNetworkDelayWarning(
     68     const std::string& extension_id) {
     69   std::vector<std::string> message_parameters;
     70   message_parameters.push_back(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME));
     71   return ExtensionWarning(
     72       kNetworkDelay,
     73       extension_id,
     74       IDS_EXTENSION_WARNINGS_NETWORK_DELAY,
     75       message_parameters);
     76 }
     77 
     78 // static
     79 ExtensionWarning ExtensionWarning::CreateNetworkConflictWarning(
     80     const std::string& extension_id) {
     81   std::vector<std::string> message_parameters;
     82   return ExtensionWarning(
     83       kNetworkConflict,
     84       extension_id,
     85       IDS_EXTENSION_WARNINGS_NETWORK_CONFLICT,
     86       message_parameters);
     87 }
     88 
     89 // static
     90 ExtensionWarning ExtensionWarning::CreateRedirectConflictWarning(
     91     const std::string& extension_id,
     92     const std::string& winning_extension_id,
     93     const GURL& attempted_redirect_url,
     94     const GURL& winning_redirect_url) {
     95   std::vector<std::string> message_parameters;
     96   message_parameters.push_back(attempted_redirect_url.spec());
     97   message_parameters.push_back(kTranslate + winning_extension_id);
     98   message_parameters.push_back(winning_redirect_url.spec());
     99   return ExtensionWarning(
    100       kRedirectConflict,
    101       extension_id,
    102       IDS_EXTENSION_WARNINGS_REDIRECT_CONFLICT,
    103       message_parameters);
    104 }
    105 
    106 // static
    107 ExtensionWarning ExtensionWarning::CreateRequestHeaderConflictWarning(
    108     const std::string& extension_id,
    109     const std::string& winning_extension_id,
    110     const std::string& conflicting_header) {
    111   std::vector<std::string> message_parameters;
    112   message_parameters.push_back(conflicting_header);
    113   message_parameters.push_back(kTranslate + winning_extension_id);
    114   return ExtensionWarning(
    115       kNetworkConflict,
    116       extension_id,
    117       IDS_EXTENSION_WARNINGS_REQUEST_HEADER_CONFLICT,
    118       message_parameters);
    119 }
    120 
    121 // static
    122 ExtensionWarning ExtensionWarning::CreateResponseHeaderConflictWarning(
    123     const std::string& extension_id,
    124     const std::string& winning_extension_id,
    125     const std::string& conflicting_header) {
    126   std::vector<std::string> message_parameters;
    127   message_parameters.push_back(conflicting_header);
    128   message_parameters.push_back(kTranslate + winning_extension_id);
    129   return ExtensionWarning(
    130       kNetworkConflict,
    131       extension_id,
    132       IDS_EXTENSION_WARNINGS_RESPONSE_HEADER_CONFLICT,
    133       message_parameters);
    134 }
    135 
    136 // static
    137 ExtensionWarning ExtensionWarning::CreateCredentialsConflictWarning(
    138     const std::string& extension_id,
    139     const std::string& winning_extension_id) {
    140   std::vector<std::string> message_parameters;
    141   message_parameters.push_back(kTranslate + winning_extension_id);
    142   return ExtensionWarning(
    143       kNetworkConflict,
    144       extension_id,
    145       IDS_EXTENSION_WARNINGS_CREDENTIALS_CONFLICT,
    146       message_parameters);
    147 }
    148 
    149 // static
    150 ExtensionWarning ExtensionWarning::CreateRepeatedCacheFlushesWarning(
    151     const std::string& extension_id) {
    152   std::vector<std::string> message_parameters;
    153   message_parameters.push_back(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME));
    154   return ExtensionWarning(
    155       kRepeatedCacheFlushes,
    156       extension_id,
    157       IDS_EXTENSION_WARNINGS_NETWORK_DELAY,
    158       message_parameters);
    159 }
    160 
    161 // static
    162 ExtensionWarning ExtensionWarning::CreateDownloadFilenameConflictWarning(
    163     const std::string& losing_extension_id,
    164     const std::string& winning_extension_id,
    165     const base::FilePath& losing_filename,
    166     const base::FilePath& winning_filename) {
    167   std::vector<std::string> message_parameters;
    168   message_parameters.push_back(base::UTF16ToUTF8(
    169       losing_filename.LossyDisplayName()));
    170   message_parameters.push_back(kTranslate + winning_extension_id);
    171   message_parameters.push_back(base::UTF16ToUTF8(
    172       winning_filename.LossyDisplayName()));
    173   return ExtensionWarning(
    174       kDownloadFilenameConflict,
    175       losing_extension_id,
    176       IDS_EXTENSION_WARNINGS_DOWNLOAD_FILENAME_CONFLICT,
    177       message_parameters);
    178 }
    179 
    180 // static
    181 ExtensionWarning ExtensionWarning::CreateReloadTooFrequentWarning(
    182     const std::string& extension_id) {
    183   std::vector<std::string> message_parameters;
    184   return ExtensionWarning(kReloadTooFrequent,
    185                           extension_id,
    186                           IDS_EXTENSION_WARNING_RELOAD_TOO_FREQUENT,
    187                           message_parameters);
    188 }
    189 
    190 std::string ExtensionWarning::GetLocalizedMessage(
    191     const ExtensionSet* extensions) const {
    192   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    193 
    194   // These parameters may be unsafe (URLs and Extension names) and need
    195   // to be HTML-escaped before being embedded in the UI. Also extension IDs
    196   // are translated to full extension names.
    197   std::vector<base::string16> final_parameters;
    198   for (size_t i = 0; i < message_parameters_.size(); ++i) {
    199     std::string message = message_parameters_[i];
    200     if (StartsWithASCII(message, kTranslate, true)) {
    201       std::string extension_id = message.substr(sizeof(kTranslate) - 1);
    202       const extensions::Extension* extension =
    203           extensions->GetByID(extension_id);
    204       message = extension ? extension->name() : extension_id;
    205     }
    206     final_parameters.push_back(base::UTF8ToUTF16(net::EscapeForHTML(message)));
    207   }
    208 
    209   COMPILE_ASSERT(kMaxNumberOfParameters == 4u, YouNeedToAddMoreCaseStatements);
    210   switch (final_parameters.size()) {
    211     case 0:
    212       return l10n_util::GetStringUTF8(message_id_);
    213     case 1:
    214       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0]);
    215     case 2:
    216       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
    217           final_parameters[1]);
    218     case 3:
    219       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
    220           final_parameters[1], final_parameters[2]);
    221     case 4:
    222       return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
    223           final_parameters[1], final_parameters[2], final_parameters[3]);
    224     default:
    225       NOTREACHED();
    226       return std::string();
    227   }
    228 }
    229 
    230 bool operator<(const ExtensionWarning& a, const ExtensionWarning& b) {
    231   if (a.extension_id() != b.extension_id())
    232     return a.extension_id() < b.extension_id();
    233   return a.warning_type() < b.warning_type();
    234 }
    235 
    236 }  // namespace extensions
    237