• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetResourcesInfo(const Extension & extension)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:
PartitionItem(const std::string & partition_pattern)35   explicit PartitionItem(const std::string& partition_pattern)
36       : partition_pattern_(partition_pattern) {
37   }
38 
~PartitionItem()39   virtual ~PartitionItem() {
40   }
41 
Matches(const std::string & partition_id) const42   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.
AddPattern(const URLPattern & pattern)48   bool AddPattern(const URLPattern& pattern) {
49     return accessible_resources_.AddPattern(pattern);
50   }
51 
accessible_resources() const52   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 
WebviewInfo()64 WebviewInfo::WebviewInfo() {
65 }
66 
~WebviewInfo()67 WebviewInfo::~WebviewInfo() {
68 }
69 
70 // static
IsResourceWebviewAccessible(const Extension * extension,const std::string & partition_id,const std::string & relative_path)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 
AddPartitionItem(scoped_ptr<PartitionItem> item)94 void WebviewInfo::AddPartitionItem(scoped_ptr<PartitionItem> item) {
95   partition_items_.push_back(item.release());
96 }
97 
WebviewHandler()98 WebviewHandler::WebviewHandler() {
99 }
100 
~WebviewHandler()101 WebviewHandler::~WebviewHandler() {
102 }
103 
Parse(Extension * extension,base::string16 * error)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 
Keys() const178 const std::vector<std::string> WebviewHandler::Keys() const {
179   return SingleKey(keys::kWebview);
180 }
181 
182 }  // namespace extensions
183