Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / extensions / common / manifest_handlers / content_capabilities_handler.cc
blobcfae3120c742e7c478c035915903af0f343d5b8c
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.
5 #include "extensions/common/manifest_handlers/content_capabilities_handler.h"
7 #include "base/command_line.h"
8 #include "base/lazy_instance.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "content/public/common/content_switches.h"
14 #include "extensions/common/api/extensions_manifest_types.h"
15 #include "extensions/common/error_utils.h"
16 #include "extensions/common/install_warning.h"
17 #include "extensions/common/manifest_constants.h"
18 #include "extensions/common/permissions/permissions_info.h"
19 #include "extensions/common/url_pattern.h"
21 namespace extensions {
23 namespace keys = manifest_keys;
24 namespace errors = manifest_errors;
26 using api::extensions_manifest_types::ContentCapabilities;
28 ContentCapabilitiesInfo::ContentCapabilitiesInfo() {
31 ContentCapabilitiesInfo::~ContentCapabilitiesInfo() {
34 static base::LazyInstance<ContentCapabilitiesInfo>
35 g_empty_content_capabilities_info = LAZY_INSTANCE_INITIALIZER;
37 // static
38 const ContentCapabilitiesInfo& ContentCapabilitiesInfo::Get(
39 const Extension* extension) {
40 ContentCapabilitiesInfo* info = static_cast<ContentCapabilitiesInfo*>(
41 extension->GetManifestData(keys::kContentCapabilities));
42 return info ? *info : g_empty_content_capabilities_info.Get();
45 ContentCapabilitiesHandler::ContentCapabilitiesHandler() {
48 ContentCapabilitiesHandler::~ContentCapabilitiesHandler() {
51 bool ContentCapabilitiesHandler::Parse(Extension* extension,
52 base::string16* error) {
53 scoped_ptr<ContentCapabilitiesInfo> info(new ContentCapabilitiesInfo);
55 const base::Value* value = NULL;
56 if (!extension->manifest()->Get(keys::kContentCapabilities, &value)) {
57 *error = base::ASCIIToUTF16(errors::kInvalidContentCapabilities);
58 return false;
61 scoped_ptr<ContentCapabilities> capabilities(ContentCapabilities::FromValue(
62 *value, error));
63 if (!capabilities)
64 return false;
66 int supported_schemes = URLPattern::SCHEME_HTTPS;
67 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) {
68 // We don't have a suitable HTTPS test server, so this will have to do.
69 supported_schemes |= URLPattern::SCHEME_HTTP;
72 std::string url_error;
73 URLPatternSet potential_url_patterns;
74 if (!potential_url_patterns.Populate(capabilities->matches, supported_schemes,
75 false /* allow_file_access */,
76 &url_error)) {
77 *error = ErrorUtils::FormatErrorMessageUTF16(
78 errors::kInvalidContentCapabilitiesMatch, url_error);
79 return false;
82 // Filter wildcard URL patterns and emit warnings for them.
83 std::set<URLPattern> valid_url_patterns;
84 for (const URLPattern& pattern : potential_url_patterns) {
85 if (pattern.match_subdomains() || pattern.ImpliesAllHosts()) {
86 extension->AddInstallWarning(InstallWarning(
87 errors::kInvalidContentCapabilitiesMatchOrigin));
88 } else {
89 valid_url_patterns.insert(pattern);
92 info->url_patterns = URLPatternSet(valid_url_patterns);
94 // Filter invalid permissions and emit warnings for them.
95 for (const std::string& permission_name : capabilities->permissions) {
96 const APIPermissionInfo* permission_info = PermissionsInfo::GetInstance()
97 ->GetByName(permission_name);
98 if (!permission_info || !permission_info->supports_content_capabilities()) {
99 extension->AddInstallWarning(InstallWarning(
100 errors::kInvalidContentCapabilitiesPermission,
101 keys::kContentCapabilities,
102 permission_name));
103 } else {
104 info->permissions.insert(permission_info->CreateAPIPermission());
108 extension->SetManifestData(keys::kContentCapabilities, info.release());
109 return true;
112 const std::vector<std::string> ContentCapabilitiesHandler::Keys()
113 const {
114 return SingleKey(keys::kContentCapabilities);
117 } // namespace extensions