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
;
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
);
61 scoped_ptr
<ContentCapabilities
> capabilities(ContentCapabilities::FromValue(
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 */,
77 *error
= ErrorUtils::FormatErrorMessageUTF16(
78 errors::kInvalidContentCapabilitiesMatch
, url_error
);
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
));
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
,
104 info
->permissions
.insert(permission_info
->CreateAPIPermission());
108 extension
->SetManifestData(keys::kContentCapabilities
, info
.release());
112 const std::vector
<std::string
> ContentCapabilitiesHandler::Keys()
114 return SingleKey(keys::kContentCapabilities
);
117 } // namespace extensions