Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(696)

Side by Side Diff: chrome/common/extensions/manifest.cc

Issue 8654001: Reland restrict extension features based on the extension type. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
Aaron Boodman 2011/12/01 21:32:04 This class turned out really tight and clean. Nice
jstritar 2011/12/02 16:26:33 Nice, thanks!
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/common/extensions/manifest.h"
6
7 #include "base/basictypes.h"
8 #include "base/lazy_instance.h"
9 #include "base/logging.h"
10 #include "base/string_split.h"
11 #include "base/values.h"
12 #include "chrome/common/extensions/extension_constants.h"
13 #include "chrome/common/extensions/extension_error_utils.h"
14
15 namespace errors = extension_manifest_errors;
16 namespace keys = extension_manifest_keys;
17
18 namespace extensions {
19
20 namespace {
21
22 typedef std::map<std::string, int> RestrictionMap;
23
24 struct Restrictions {
25 Restrictions() {
26 // Base keys that all manifests can specify.
27 map[keys::kName] = Manifest::kTypeAll;
28 map[keys::kVersion] = Manifest::kTypeAll;
29 map[keys::kManifestVersion] = Manifest::kTypeAll;
30 map[keys::kDescription] = Manifest::kTypeAll;
31 map[keys::kIcons] = Manifest::kTypeAll;
32 map[keys::kCurrentLocale] = Manifest::kTypeAll;
33 map[keys::kDefaultLocale] = Manifest::kTypeAll;
34 map[keys::kSignature] = Manifest::kTypeAll;
35 map[keys::kUpdateURL] = Manifest::kTypeAll;
36 map[keys::kPublicKey] = Manifest::kTypeAll;
37
38 // Type specific.
39 map[keys::kApp] = Manifest::kTypeHostedApp | Manifest::kTypePackagedApp |
40 Manifest::kTypePlatformApp;
41 map[keys::kTheme] = Manifest::kTypeTheme;
42 map[keys::kPlatformApp] = Manifest::kTypePlatformApp;
43
44 // Extensions only.
45 map[keys::kBrowserAction] = Manifest::kTypeExtension;
46 map[keys::kPageAction] = Manifest::kTypeExtension;
47 map[keys::kPageActions] = Manifest::kTypeExtension;
48 map[keys::kChromeURLOverrides] = Manifest::kTypeExtension;
49
50 // Everything except themes.
51 int all_but_themes = Manifest::kTypeAll - Manifest::kTypeTheme;
52 map[keys::kPermissions] = all_but_themes;
53 map[keys::kOptionalPermissions] = all_but_themes;
54 map[keys::kOptionsPage] = all_but_themes;
55 map[keys::kBackground] = all_but_themes;
56 map[keys::kOfflineEnabled] = all_but_themes;
57 map[keys::kMinimumChromeVersion] = all_but_themes;
58 map[keys::kRequirements] = all_but_themes;
59 map[keys::kConvertedFromUserScript] = all_but_themes;
60 map[keys::kNaClModules] = all_but_themes;
61 map[keys::kPlugins] = all_but_themes;
62
63 // Extensions and packaged apps.
64 int ext_and_packaged =
65 Manifest::kTypeExtension | Manifest::kTypePackagedApp;
66 map[keys::kContentScripts] = ext_and_packaged;
67 map[keys::kOmnibox] = ext_and_packaged;
68 map[keys::kDevToolsPage] = ext_and_packaged;
69 map[keys::kSidebar] = ext_and_packaged;
70 map[keys::kHomepageURL] = ext_and_packaged;
71
72 // Extensions, packaged apps and platform apps.
73 int local_apps_and_ext = ext_and_packaged | Manifest::kTypePlatformApp;
74 map[keys::kContentSecurityPolicy] = local_apps_and_ext;
75 map[keys::kFileBrowserHandlers] = local_apps_and_ext;
76 map[keys::kIncognito] = local_apps_and_ext;
77 map[keys::kInputComponents] = local_apps_and_ext;
78 map[keys::kTtsEngine] = local_apps_and_ext;
79 map[keys::kIntents] = local_apps_and_ext;
80 }
81
82 // Returns true if the |key| is recognized.
83 bool IsKnownKey(const std::string& key) const {
84 RestrictionMap::const_iterator i = map.find(key);
85 return i != map.end();
86 }
87
88 // Returns true if the given |key| can be specified by the manifest |type|.
89 bool CanAccessKey(const std::string& key, Manifest::Type type) const {
90 RestrictionMap::const_iterator i = map.find(key);
91 return (i != map.end() && (type & i->second) != 0);
92 }
93
94 RestrictionMap map;
95 };
96
97 base::LazyInstance<Restrictions> g_restrictions;
98
99 } // namespace
100
101 // static
102 std::set<std::string> Manifest::GetAllKnownKeys() {
103 std::set<std::string> keys;
104 const RestrictionMap& map = g_restrictions.Get().map;
105 for (RestrictionMap::const_iterator i = map.begin(); i != map.end(); i++)
106 keys.insert(i->first);
107 return keys;
108 }
109
110 Manifest::Manifest(DictionaryValue* value) : value_(value) {}
111 Manifest::~Manifest() {}
112
113 bool Manifest::ValidateManifest(std::string* error) const {
114 Restrictions restrictions = g_restrictions.Get();
115 Type type = GetType();
116
117 for (DictionaryValue::key_iterator key = value_->begin_keys();
118 key != value_->end_keys(); ++key) {
119 // When validating the extension manifests, we ignore keys that are not
120 // recognized for forward compatibility.
121 if (!restrictions.IsKnownKey(*key)) {
122 // TODO(aa): Consider having an error here in the case of strict error
123 // checking to let developers know when they screw up.
124 continue;
125 }
126
127 if (!restrictions.CanAccessKey(*key, type)) {
128 *error = ExtensionErrorUtils::FormatErrorMessage(
129 errors::kFeatureNotAllowed, *key);
130 return false;
131 }
132 }
133
134 return true;
135 }
136
137 bool Manifest::HasKey(const std::string& key) const {
138 Restrictions restrictions = g_restrictions.Get();
139 return restrictions.CanAccessKey(key, GetType()) && value_->HasKey(key);
140 }
141
142 bool Manifest::Get(
143 const std::string& path, Value** out_value) const {
144 return CanAccessPath(path) && value_->Get(path, out_value);
145 }
146
147 bool Manifest::GetBoolean(
148 const std::string& path, bool* out_value) const {
149 return CanAccessPath(path) && value_->GetBoolean(path, out_value);
150 }
151
152 bool Manifest::GetInteger(
153 const std::string& path, int* out_value) const {
154 return CanAccessPath(path) && value_->GetInteger(path, out_value);
155 }
156
157 bool Manifest::GetString(
158 const std::string& path, std::string* out_value) const {
159 return CanAccessPath(path) && value_->GetString(path, out_value);
160 }
161
162 bool Manifest::GetString(
163 const std::string& path, string16* out_value) const {
164 return CanAccessPath(path) && value_->GetString(path, out_value);
165 }
166
167 bool Manifest::GetDictionary(
168 const std::string& path, DictionaryValue** out_value) const {
169 return CanAccessPath(path) && value_->GetDictionary(path, out_value);
170 }
171
172 bool Manifest::GetList(
173 const std::string& path, ListValue** out_value) const {
174 return CanAccessPath(path) && value_->GetList(path, out_value);
175 }
176
177 Manifest* Manifest::DeepCopy() const {
178 return new Manifest(value_->DeepCopy());
179 }
180
181 bool Manifest::Equals(const Manifest* other) const {
182 return other && value_->Equals(other->value());
183 }
184
185 Manifest::Type Manifest::GetType() const {
186 if (value_->HasKey(keys::kTheme) && value_->GetDictionary(keys::kTheme, NULL))
Aaron Boodman 2011/12/01 21:32:04 Why do you test that the value is a dictionary for
jstritar 2011/12/02 16:26:33 I did that to be consistent with the previous beha
187 return kTypeTheme;
188 if (value_->HasKey(keys::kPlatformApp))
189 return kTypePlatformApp;
190 if (value_->HasKey(keys::kApp)) {
191 if (value_->Get(keys::kWebURLs, NULL) ||
192 value_->Get(keys::kLaunchWebURL, NULL))
193 return kTypeHostedApp;
194 else
195 return kTypePackagedApp;
196 } else {
197 return kTypeExtension;
198 }
199 }
200
201 bool Manifest::IsTheme() const {
202 return GetType() == kTypeTheme;
203 }
204
205 bool Manifest::IsPlatformApp() const {
206 return GetType() == kTypePlatformApp;
207 }
208
209 bool Manifest::IsPackagedApp() const {
210 return GetType() == kTypePackagedApp;
211 }
212
213 bool Manifest::IsHostedApp() const {
214 return GetType() == kTypeHostedApp;
215 }
216
217 bool Manifest::CanAccessPath(const std::string& path) const {
218 std::vector<std::string> components;
219 base::SplitString(path, '.', &components);
220
221 Restrictions restrictions = g_restrictions.Get();
222 return restrictions.CanAccessKey(components[0], GetType());
223 }
224
225 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698