OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/extensions/features/simple_feature.h" | 5 #include "chrome/common/extensions/features/simple_feature.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 std::set<std::string> string_set; | 128 std::set<std::string> string_set; |
129 ParseSet(value, property, &string_set); | 129 ParseSet(value, property, &string_set); |
130 for (std::set<std::string>::iterator iter = string_set.begin(); | 130 for (std::set<std::string>::iterator iter = string_set.begin(); |
131 iter != string_set.end(); ++iter) { | 131 iter != string_set.end(); ++iter) { |
132 T enum_value = static_cast<T>(0); | 132 T enum_value = static_cast<T>(0); |
133 ParseEnum(*iter, &enum_value, mapping); | 133 ParseEnum(*iter, &enum_value, mapping); |
134 enum_set->insert(enum_value); | 134 enum_set->insert(enum_value); |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
138 void ParseURLPatterns(const DictionaryValue* value, | |
139 const std::string& key, | |
140 URLPatternSet* set) { | |
141 const ListValue* matches = NULL; | |
142 if (value->GetList(key, &matches)) { | |
143 for (size_t i = 0; i < matches->GetSize(); ++i) { | |
144 std::string pattern; | |
145 DCHECK(matches->GetString(i, &pattern)); | |
146 set->AddPattern(URLPattern(URLPattern::SCHEME_ALL, pattern)); | |
147 } | |
148 } | |
149 } | |
150 | |
138 // Gets a human-readable name for the given extension type. | 151 // Gets a human-readable name for the given extension type. |
139 std::string GetDisplayTypeName(Manifest::Type type) { | 152 std::string GetDisplayTypeName(Manifest::Type type) { |
140 switch (type) { | 153 switch (type) { |
141 case Manifest::TYPE_UNKNOWN: | 154 case Manifest::TYPE_UNKNOWN: |
142 return "unknown"; | 155 return "unknown"; |
143 case Manifest::TYPE_EXTENSION: | 156 case Manifest::TYPE_EXTENSION: |
144 return "extension"; | 157 return "extension"; |
145 case Manifest::TYPE_HOSTED_APP: | 158 case Manifest::TYPE_HOSTED_APP: |
146 return "hosted app"; | 159 return "hosted app"; |
147 case Manifest::TYPE_LEGACY_PACKAGED_APP: | 160 case Manifest::TYPE_LEGACY_PACKAGED_APP: |
(...skipping 17 matching lines...) Expand all Loading... | |
165 platform_(UNSPECIFIED_PLATFORM), | 178 platform_(UNSPECIFIED_PLATFORM), |
166 min_manifest_version_(0), | 179 min_manifest_version_(0), |
167 max_manifest_version_(0), | 180 max_manifest_version_(0), |
168 channel_(VersionInfo::CHANNEL_UNKNOWN) { | 181 channel_(VersionInfo::CHANNEL_UNKNOWN) { |
169 } | 182 } |
170 | 183 |
171 SimpleFeature::SimpleFeature(const SimpleFeature& other) | 184 SimpleFeature::SimpleFeature(const SimpleFeature& other) |
172 : whitelist_(other.whitelist_), | 185 : whitelist_(other.whitelist_), |
173 extension_types_(other.extension_types_), | 186 extension_types_(other.extension_types_), |
174 contexts_(other.contexts_), | 187 contexts_(other.contexts_), |
188 matches_(other.matches_), | |
175 location_(other.location_), | 189 location_(other.location_), |
176 platform_(other.platform_), | 190 platform_(other.platform_), |
177 min_manifest_version_(other.min_manifest_version_), | 191 min_manifest_version_(other.min_manifest_version_), |
178 max_manifest_version_(other.max_manifest_version_), | 192 max_manifest_version_(other.max_manifest_version_), |
179 channel_(other.channel_) { | 193 channel_(other.channel_) { |
180 } | 194 } |
181 | 195 |
182 SimpleFeature::~SimpleFeature() { | 196 SimpleFeature::~SimpleFeature() { |
183 } | 197 } |
184 | 198 |
185 bool SimpleFeature::Equals(const SimpleFeature& other) const { | 199 bool SimpleFeature::Equals(const SimpleFeature& other) const { |
186 return whitelist_ == other.whitelist_ && | 200 return whitelist_ == other.whitelist_ && |
187 extension_types_ == other.extension_types_ && | 201 extension_types_ == other.extension_types_ && |
188 contexts_ == other.contexts_ && | 202 contexts_ == other.contexts_ && |
203 matches_ == other.matches_ && | |
189 location_ == other.location_ && | 204 location_ == other.location_ && |
190 platform_ == other.platform_ && | 205 platform_ == other.platform_ && |
191 min_manifest_version_ == other.min_manifest_version_ && | 206 min_manifest_version_ == other.min_manifest_version_ && |
192 max_manifest_version_ == other.max_manifest_version_ && | 207 max_manifest_version_ == other.max_manifest_version_ && |
193 channel_ == other.channel_; | 208 channel_ == other.channel_; |
194 } | 209 } |
195 | 210 |
196 void SimpleFeature::Parse(const DictionaryValue* value) { | 211 void SimpleFeature::Parse(const DictionaryValue* value) { |
212 ParseURLPatterns(value, "matches", &matches_); | |
197 ParseSet(value, "whitelist", &whitelist_); | 213 ParseSet(value, "whitelist", &whitelist_); |
198 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, | 214 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, |
199 g_mappings.Get().extension_types); | 215 g_mappings.Get().extension_types); |
200 ParseEnumSet<Context>(value, "contexts", &contexts_, | 216 ParseEnumSet<Context>(value, "contexts", &contexts_, |
201 g_mappings.Get().contexts); | 217 g_mappings.Get().contexts); |
202 ParseEnum<Location>(value, "location", &location_, | 218 ParseEnum<Location>(value, "location", &location_, |
203 g_mappings.Get().locations); | 219 g_mappings.Get().locations); |
204 ParseEnum<Platform>(value, "platform", &platform_, | 220 ParseEnum<Platform>(value, "platform", &platform_, |
205 g_mappings.Get().platforms); | 221 g_mappings.Get().platforms); |
206 value->GetInteger("min_manifest_version", &min_manifest_version_); | 222 value->GetInteger("min_manifest_version", &min_manifest_version_); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 | 271 |
256 if (channel_ < Feature::GetCurrentChannel()) | 272 if (channel_ < Feature::GetCurrentChannel()) |
257 return CreateAvailability(UNSUPPORTED_CHANNEL, type); | 273 return CreateAvailability(UNSUPPORTED_CHANNEL, type); |
258 | 274 |
259 return CreateAvailability(IS_AVAILABLE, type); | 275 return CreateAvailability(IS_AVAILABLE, type); |
260 } | 276 } |
261 | 277 |
262 Feature::Availability SimpleFeature::IsAvailableToContext( | 278 Feature::Availability SimpleFeature::IsAvailableToContext( |
263 const Extension* extension, | 279 const Extension* extension, |
264 SimpleFeature::Context context, | 280 SimpleFeature::Context context, |
281 const GURL& url, | |
265 SimpleFeature::Platform platform) const { | 282 SimpleFeature::Platform platform) const { |
266 Availability result = IsAvailableToManifest( | 283 if (extension) { |
267 extension->id(), | 284 Availability result = IsAvailableToManifest( |
268 extension->GetType(), | 285 extension->id(), |
269 ConvertLocation(extension->location()), | 286 extension->GetType(), |
270 extension->manifest_version(), | 287 ConvertLocation(extension->location()), |
271 platform); | 288 extension->manifest_version(), |
272 if (!result.is_available()) | 289 platform); |
273 return result; | 290 if (!result.is_available()) |
291 return result; | |
292 } | |
274 | 293 |
275 if (!contexts_.empty() && | 294 if (!contexts_.empty() && contexts_.find(context) == contexts_.end()) { |
276 contexts_.find(context) == contexts_.end()) { | 295 return extension ? |
277 return CreateAvailability(INVALID_CONTEXT, extension->GetType()); | 296 CreateAvailability(INVALID_CONTEXT, extension->GetType()) : |
297 CreateAvailability(INVALID_CONTEXT); | |
278 } | 298 } |
279 | 299 |
300 if (!matches_.is_empty() && !matches_.MatchesURL(url)) | |
301 return CreateAvailability(INVALID_URL, url); | |
302 | |
280 return CreateAvailability(IS_AVAILABLE); | 303 return CreateAvailability(IS_AVAILABLE); |
281 } | 304 } |
282 | 305 |
283 std::string SimpleFeature::GetAvailabilityMessage( | 306 std::string SimpleFeature::GetAvailabilityMessage( |
284 AvailabilityResult result, Manifest::Type type) const { | 307 AvailabilityResult result, Manifest::Type type, const GURL& url) const { |
285 switch (result) { | 308 switch (result) { |
286 case IS_AVAILABLE: | 309 case IS_AVAILABLE: |
287 return ""; | 310 return ""; |
288 case NOT_FOUND_IN_WHITELIST: | 311 case NOT_FOUND_IN_WHITELIST: |
289 return base::StringPrintf( | 312 return base::StringPrintf( |
290 "'%s' is not allowed for specified extension ID.", | 313 "'%s' is not allowed for specified extension ID.", |
291 name().c_str()); | 314 name().c_str()); |
315 case INVALID_URL: | |
not at google - send to devlin
2013/03/22 22:10:12
CHECK(url..)?
cduvall
2013/03/22 22:52:29
Done.
| |
316 return base::StringPrintf("'%s' is not allowed on %s.", | |
317 name().c_str(), url.spec().c_str()); | |
292 case INVALID_TYPE: { | 318 case INVALID_TYPE: { |
293 std::string allowed_type_names; | 319 std::string allowed_type_names; |
294 // Turn the set of allowed types into a vector so that it's easier to | 320 // Turn the set of allowed types into a vector so that it's easier to |
295 // inject the appropriate separator into the display string. | 321 // inject the appropriate separator into the display string. |
296 std::vector<Manifest::Type> extension_types( | 322 std::vector<Manifest::Type> extension_types( |
297 extension_types_.begin(), extension_types_.end()); | 323 extension_types_.begin(), extension_types_.end()); |
298 for (size_t i = 0; i < extension_types.size(); i++) { | 324 for (size_t i = 0; i < extension_types.size(); i++) { |
299 // Pluralize type name. | 325 // Pluralize type name. |
300 allowed_type_names += GetDisplayTypeName(extension_types[i]) + "s"; | 326 allowed_type_names += GetDisplayTypeName(extension_types[i]) + "s"; |
301 if (i == extension_types_.size() - 2) { | 327 if (i == extension_types_.size() - 2) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
347 GetChannelName(GetCurrentChannel()).c_str()); | 373 GetChannelName(GetCurrentChannel()).c_str()); |
348 } | 374 } |
349 | 375 |
350 NOTREACHED(); | 376 NOTREACHED(); |
351 return ""; | 377 return ""; |
352 } | 378 } |
353 | 379 |
354 Feature::Availability SimpleFeature::CreateAvailability( | 380 Feature::Availability SimpleFeature::CreateAvailability( |
355 AvailabilityResult result) const { | 381 AvailabilityResult result) const { |
356 return Availability( | 382 return Availability( |
357 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN)); | 383 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL())); |
358 } | 384 } |
359 | 385 |
360 Feature::Availability SimpleFeature::CreateAvailability( | 386 Feature::Availability SimpleFeature::CreateAvailability( |
361 AvailabilityResult result, Manifest::Type type) const { | 387 AvailabilityResult result, Manifest::Type type) const { |
362 return Availability(result, GetAvailabilityMessage(result, type)); | 388 return Availability(result, GetAvailabilityMessage(result, type, GURL())); |
389 } | |
390 | |
391 Feature::Availability SimpleFeature::CreateAvailability( | |
392 AvailabilityResult result, | |
393 const GURL& url) const { | |
394 return Availability( | |
395 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url)); | |
363 } | 396 } |
364 | 397 |
365 std::set<Feature::Context>* SimpleFeature::GetContexts() { | 398 std::set<Feature::Context>* SimpleFeature::GetContexts() { |
366 return &contexts_; | 399 return &contexts_; |
367 } | 400 } |
368 | 401 |
369 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { | 402 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { |
370 // An empty whitelist means the absence of a whitelist, rather than a | 403 // An empty whitelist means the absence of a whitelist, rather than a |
371 // whitelist that allows no ID through. This could be surprising behavior, so | 404 // whitelist that allows no ID through. This could be surprising behavior, so |
372 // we force the caller to handle it explicitly. A DCHECK should be sufficient | 405 // we force the caller to handle it explicitly. A DCHECK should be sufficient |
(...skipping 19 matching lines...) Expand all Loading... | |
392 DCHECK(id_hash.length() == base::kSHA1Length); | 425 DCHECK(id_hash.length() == base::kSHA1Length); |
393 const std::string hexencoded_id_hash = base::HexEncode(id_hash.c_str(), | 426 const std::string hexencoded_id_hash = base::HexEncode(id_hash.c_str(), |
394 id_hash.length()); | 427 id_hash.length()); |
395 if (whitelist_.find(hexencoded_id_hash) != whitelist_.end()) | 428 if (whitelist_.find(hexencoded_id_hash) != whitelist_.end()) |
396 return true; | 429 return true; |
397 | 430 |
398 return false; | 431 return false; |
399 } | 432 } |
400 | 433 |
401 } // namespace extensions | 434 } // namespace extensions |
OLD | NEW |