Home | History | Annotate | Download | only in manifest_handlers
      1 // Copyright 2014 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 "extensions/common/manifest_handlers/webview_info.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/strings/string_number_conversions.h"
      9 #include "base/strings/string_util.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "base/values.h"
     12 #include "extensions/common/error_utils.h"
     13 #include "extensions/common/manifest.h"
     14 #include "extensions/common/manifest_constants.h"
     15 
     16 namespace extensions {
     17 
     18 namespace keys = extensions::manifest_keys;
     19 namespace errors = extensions::manifest_errors;
     20 
     21 namespace {
     22 
     23 const WebviewInfo* GetResourcesInfo(
     24     const Extension& extension) {
     25   return static_cast<WebviewInfo*>(
     26       extension.GetManifestData(keys::kWebviewAccessibleResources));
     27 }
     28 
     29 }  // namespace
     30 
     31 // A PartitionItem represents a set of accessible resources given a partition
     32 // ID pattern.
     33 class PartitionItem {
     34  public:
     35   explicit PartitionItem(const std::string& partition_pattern)
     36       : partition_pattern_(partition_pattern) {
     37   }
     38 
     39   virtual ~PartitionItem() {
     40   }
     41 
     42   bool Matches(const std::string& partition_id) const {
     43     return MatchPattern(partition_id, partition_pattern_);
     44   }
     45 
     46   // Adds a pattern to the set. Returns true if a new pattern was inserted,
     47   // false if the pattern was already in the set.
     48   bool AddPattern(const URLPattern& pattern) {
     49     return accessible_resources_.AddPattern(pattern);
     50   }
     51 
     52   const URLPatternSet& accessible_resources() const {
     53     return accessible_resources_;
     54   }
     55  private:
     56   // A pattern string that matches partition IDs.
     57   const std::string partition_pattern_;
     58   // A URL pattern set of resources accessible to the given
     59   // |partition_pattern_|.
     60   URLPatternSet accessible_resources_;
     61 };
     62 
     63 
     64 WebviewInfo::WebviewInfo() {
     65 }
     66 
     67 WebviewInfo::~WebviewInfo() {
     68 }
     69 
     70 // static
     71 bool WebviewInfo::IsResourceWebviewAccessible(
     72     const Extension* extension,
     73     const std::string& partition_id,
     74     const std::string& relative_path) {
     75   if (!extension)
     76     return false;
     77 
     78   const WebviewInfo* info = GetResourcesInfo(*extension);
     79   if (!info)
     80     return false;
     81 
     82   for (size_t i = 0; i < info->partition_items_.size(); ++i) {
     83     const PartitionItem* const item = info->partition_items_[i];
     84     if (item->Matches(partition_id) &&
     85         extension->ResourceMatches(item->accessible_resources(),
     86                                    relative_path)) {
     87       return true;
     88     }
     89   }
     90 
     91   return false;
     92 }
     93 
     94 void WebviewInfo::AddPartitionItem(scoped_ptr<PartitionItem> item) {
     95   partition_items_.push_back(item.release());
     96 }
     97 
     98 WebviewHandler::WebviewHandler() {
     99 }
    100 
    101 WebviewHandler::~WebviewHandler() {
    102 }
    103 
    104 bool WebviewHandler::Parse(Extension* extension, base::string16* error) {
    105   scoped_ptr<WebviewInfo> info(new WebviewInfo());
    106 
    107   const base::DictionaryValue* dict_value = NULL;
    108   if (!extension->manifest()->GetDictionary(keys::kWebview,
    109                                             &dict_value)) {
    110     *error = base::ASCIIToUTF16(errors::kInvalidWebview);
    111     return false;
    112   }
    113 
    114   const base::ListValue* partition_list = NULL;
    115   if (!dict_value->GetList(keys::kWebviewPartitions, &partition_list)) {
    116     *error = base::ASCIIToUTF16(errors::kInvalidWebviewPartitionsList);
    117     return false;
    118   }
    119 
    120   // The partition list must have at least one entry.
    121   if (partition_list->GetSize() == 0) {
    122     *error = base::ASCIIToUTF16(errors::kInvalidWebviewPartitionsList);
    123     return false;
    124   }
    125 
    126   for (size_t i = 0; i < partition_list->GetSize(); ++i) {
    127     const base::DictionaryValue* partition = NULL;
    128     if (!partition_list->GetDictionary(i, &partition)) {
    129       *error = ErrorUtils::FormatErrorMessageUTF16(
    130           errors::kInvalidWebviewPartition, base::IntToString(i));
    131       return false;
    132     }
    133 
    134     std::string partition_pattern;
    135     if (!partition->GetString(keys::kWebviewName, &partition_pattern)) {
    136       *error = ErrorUtils::FormatErrorMessageUTF16(
    137           errors::kInvalidWebviewPartitionName, base::IntToString(i));
    138       return false;
    139     }
    140 
    141     const base::ListValue* url_list = NULL;
    142     if (!partition->GetList(keys::kWebviewAccessibleResources,
    143                             &url_list)) {
    144       *error = base::ASCIIToUTF16(
    145           errors::kInvalidWebviewAccessibleResourcesList);
    146       return false;
    147     }
    148 
    149     // The URL list should have at least one entry.
    150     if (url_list->GetSize() == 0) {
    151       *error = base::ASCIIToUTF16(
    152           errors::kInvalidWebviewAccessibleResourcesList);
    153       return false;
    154     }
    155 
    156     scoped_ptr<PartitionItem> partition_item(
    157         new PartitionItem(partition_pattern));
    158 
    159     for (size_t i = 0; i < url_list->GetSize(); ++i) {
    160       std::string relative_path;
    161       if (!url_list->GetString(i, &relative_path)) {
    162         *error = ErrorUtils::FormatErrorMessageUTF16(
    163             errors::kInvalidWebviewAccessibleResource, base::IntToString(i));
    164         return false;
    165       }
    166       URLPattern pattern(URLPattern::SCHEME_EXTENSION,
    167                          Extension::GetResourceURL(extension->url(),
    168                                                    relative_path).spec());
    169       partition_item->AddPattern(pattern);
    170     }
    171     info->AddPartitionItem(partition_item.Pass());
    172   }
    173 
    174   extension->SetManifestData(keys::kWebviewAccessibleResources, info.release());
    175   return true;
    176 }
    177 
    178 const std::vector<std::string> WebviewHandler::Keys() const {
    179   return SingleKey(keys::kWebview);
    180 }
    181 
    182 }  // namespace extensions
    183