OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "content/common/feature_policy/feature_policy.h" | 5 #include "content/common/feature_policy/feature_policy.h" |
6 | 6 |
7 #include "base/macros.h" | |
8 #include "base/memory/ptr_util.h" | |
9 | |
7 namespace content { | 10 namespace content { |
8 | 11 |
12 namespace { | |
13 | |
14 // Given a string name, return the matching feature struct, or nullptr if it is | |
15 // not the name of a policy-controlled feature. | |
16 blink::WebFeaturePolicyFeature FeatureForName( | |
17 std::string feature_name, | |
18 const FeaturePolicy::FeatureList& features) { | |
19 for (const auto& feature_mapping : features) { | |
20 if (feature_name == feature_mapping.second->feature_name) | |
21 return feature_mapping.first; | |
22 } | |
23 return blink::WebFeaturePolicyFeature::NotFound; | |
24 } | |
25 | |
26 // Definitions of all features controlled by Feature Policy should appear here. | |
27 const FeaturePolicy::Feature kDocumentCookie{ | |
28 "cookie", FeaturePolicy::FeatureDefault::EnableForAll}; | |
29 const FeaturePolicy::Feature kDocumentDomain{ | |
30 "domain", FeaturePolicy::FeatureDefault::EnableForAll}; | |
31 const FeaturePolicy::Feature kDocumentWrite{ | |
32 "docwrite", FeaturePolicy::FeatureDefault::EnableForAll}; | |
33 const FeaturePolicy::Feature kFullscreenFeature{ | |
34 "fullscreen", FeaturePolicy::FeatureDefault::EnableForSelf}; | |
35 const FeaturePolicy::Feature kGeolocationFeature{ | |
36 "geolocation", FeaturePolicy::FeatureDefault::EnableForSelf}; | |
37 const FeaturePolicy::Feature kMidiFeature{ | |
38 "midi", FeaturePolicy::FeatureDefault::EnableForAll}; | |
39 const FeaturePolicy::Feature kNotificationsFeature{ | |
40 "notifications", FeaturePolicy::FeatureDefault::EnableForAll}; | |
41 const FeaturePolicy::Feature kPaymentFeature{ | |
42 "payment", FeaturePolicy::FeatureDefault::EnableForSelf}; | |
43 const FeaturePolicy::Feature kPushFeature{ | |
44 "push", FeaturePolicy::FeatureDefault::EnableForAll}; | |
45 const FeaturePolicy::Feature kSyncScript{ | |
46 "sync-script", FeaturePolicy::FeatureDefault::EnableForAll}; | |
47 const FeaturePolicy::Feature kSyncXHR{ | |
48 "sync-xhr", FeaturePolicy::FeatureDefault::EnableForAll}; | |
49 const FeaturePolicy::Feature kUsermedia{ | |
50 "usermedia", FeaturePolicy::FeatureDefault::EnableForAll}; | |
51 const FeaturePolicy::Feature kVibrateFeature{ | |
52 "vibrate", FeaturePolicy::FeatureDefault::EnableForSelf}; | |
53 const FeaturePolicy::Feature kWebRTC{ | |
54 "webrtc", FeaturePolicy::FeatureDefault::EnableForAll}; | |
55 | |
56 // Extracts a Whitelist from a ParsedFeaturePolicyDeclaration | |
raymes
2017/02/01 22:42:21
nit: . at end of sentence.
iclelland
2017/02/03 16:38:29
Done.
| |
57 std::unique_ptr<FeaturePolicy::Whitelist> WhitelistFromDeclaration( | |
58 const ParsedFeaturePolicyDeclaration& parsed_declaration) { | |
59 std::unique_ptr<FeaturePolicy::Whitelist> result = | |
60 base::WrapUnique(new FeaturePolicy::Whitelist()); | |
61 if (parsed_declaration.matches_all_origins) | |
62 result->AddAll(); | |
63 for (const auto& origin : parsed_declaration.origins) | |
64 result->Add(origin); | |
65 return result; | |
66 } | |
67 | |
68 } // namespace | |
69 | |
9 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration() | 70 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration() |
10 : matches_all_origins(false) {} | 71 : matches_all_origins(false) {} |
11 | 72 |
12 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration( | 73 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration( |
13 std::string feature_name, | 74 std::string feature_name, |
14 bool matches_all_origins, | 75 bool matches_all_origins, |
15 std::vector<url::Origin> origins) | 76 std::vector<url::Origin> origins) |
16 : feature_name(feature_name), | 77 : feature_name(feature_name), |
17 matches_all_origins(matches_all_origins), | 78 matches_all_origins(matches_all_origins), |
18 origins(origins) {} | 79 origins(origins) {} |
19 | 80 |
20 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration( | 81 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration( |
21 const ParsedFeaturePolicyDeclaration& rhs) = default; | 82 const ParsedFeaturePolicyDeclaration& rhs) = default; |
22 | 83 |
23 ParsedFeaturePolicyDeclaration::~ParsedFeaturePolicyDeclaration() {} | 84 ParsedFeaturePolicyDeclaration::~ParsedFeaturePolicyDeclaration() {} |
24 | 85 |
86 FeaturePolicy::Whitelist::Whitelist() : matches_all_origins_(false) {} | |
raymes
2017/02/01 22:42:21
nit: newline after
iclelland
2017/02/03 16:38:29
Done.
| |
87 FeaturePolicy::Whitelist::~Whitelist() = default; | |
88 | |
89 void FeaturePolicy::Whitelist::Add(const url::Origin& origin) { | |
90 origins_.push_back(origin); | |
91 } | |
92 | |
93 void FeaturePolicy::Whitelist::AddAll() { | |
94 matches_all_origins_ = true; | |
95 } | |
96 | |
97 bool FeaturePolicy::Whitelist::Contains(const url::Origin& origin) const { | |
98 if (matches_all_origins_) | |
99 return true; | |
100 for (const auto& targetOrigin : origins_) { | |
101 if (targetOrigin.IsSameOriginWith(origin)) | |
102 return true; | |
103 } | |
104 return false; | |
105 } | |
106 | |
107 // static | |
108 std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromParentPolicy( | |
109 const FeaturePolicy* parent_policy, | |
110 url::Origin origin) { | |
111 return CreateFromParentPolicy(parent_policy, origin, getDefaultFeatureList()); | |
112 } | |
113 | |
114 bool FeaturePolicy::IsFeatureEnabledForOrigin( | |
115 blink::WebFeaturePolicyFeature feature, | |
116 url::Origin origin) const { | |
117 DCHECK(feature_list_.count(feature)); | |
raymes
2017/02/01 22:42:21
Instead of count we tend to use ContainsKey from b
| |
118 const FeaturePolicy::Feature* feature_definition = feature_list_.at(feature); | |
119 DCHECK(inherited_policies_.count(feature)); | |
120 if (!inherited_policies_.at(feature)) { | |
raymes
2017/02/01 22:42:21
nit: (here and below) We tend to use [] instead of
iclelland
2017/02/03 16:38:29
I don't think I can use [], since it returns a non
| |
121 return false; | |
122 } | |
123 if (whitelists_.count(feature)) { | |
raymes
2017/02/01 22:42:21
nit: in this case it's probably slightly better to
iclelland
2017/02/03 16:38:29
That's a good idea, thanks.
| |
124 return whitelists_.at(feature)->Contains(origin); | |
125 } | |
126 if (feature_definition->default_policy == | |
127 FeaturePolicy::FeatureDefault::EnableForAll) { | |
128 return true; | |
129 } | |
130 if (feature_definition->default_policy == | |
131 FeaturePolicy::FeatureDefault::EnableForSelf) { | |
132 return origin_.IsSameOriginWith(origin); | |
133 } | |
134 return false; | |
135 } | |
136 | |
137 bool FeaturePolicy::IsFeatureEnabled( | |
138 blink::WebFeaturePolicyFeature feature) const { | |
139 return IsFeatureEnabledForOrigin(feature, origin_); | |
140 } | |
141 | |
142 void FeaturePolicy::SetHeaderPolicy( | |
143 const ParsedFeaturePolicyHeader& parsed_header) { | |
144 DCHECK(whitelists_.empty()); | |
145 for (const ParsedFeaturePolicyDeclaration& parsed_declaration : | |
146 parsed_header) { | |
147 blink::WebFeaturePolicyFeature feature = | |
148 FeatureForName(parsed_declaration.feature_name, feature_list_); | |
149 if (feature == blink::WebFeaturePolicyFeature::NotFound) | |
150 continue; | |
151 whitelists_[feature] = WhitelistFromDeclaration(parsed_declaration); | |
152 } | |
153 } | |
154 | |
155 FeaturePolicy::FeaturePolicy(url::Origin origin, | |
156 const FeatureList& feature_list) | |
157 : origin_(origin), feature_list_(feature_list) {} | |
raymes
2017/02/01 22:42:21
nit: newline
iclelland
2017/02/03 16:38:29
Done.
| |
158 FeaturePolicy::FeaturePolicy(url::Origin origin) | |
159 : origin_(origin), feature_list_(getDefaultFeatureList()) {} | |
raymes
2017/02/01 22:42:21
nit: newline
iclelland
2017/02/03 16:38:29
Done.
| |
160 FeaturePolicy::~FeaturePolicy() {} | |
161 | |
162 // static | |
163 std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromParentPolicy( | |
164 const FeaturePolicy* parent_policy, | |
165 url::Origin origin, | |
166 const FeaturePolicy::FeatureList& features) { | |
167 std::unique_ptr<FeaturePolicy> newPolicy = | |
168 base::WrapUnique(new FeaturePolicy(origin, features)); | |
169 for (const auto& feature : features) { | |
170 if (!parent_policy || | |
171 parent_policy->IsFeatureEnabledForOrigin(feature.first, origin)) { | |
172 newPolicy->inherited_policies_[feature.first] = true; | |
173 } else { | |
174 newPolicy->inherited_policies_[feature.first] = false; | |
175 } | |
176 } | |
177 return newPolicy; | |
178 } | |
179 | |
180 // static | |
181 const FeaturePolicy::FeatureList& FeaturePolicy::getDefaultFeatureList() { | |
182 // TODO: See if this should use lazy_instance instead | |
raymes
2017/02/01 22:42:21
nit: remove this, the way you're doing it is proba
iclelland
2017/02/03 16:38:29
Done, thanks for confirming :)
| |
183 CR_DEFINE_STATIC_LOCAL( | |
184 FeatureList, defaultFeatureList, | |
185 ({{blink::WebFeaturePolicyFeature::DocumentCookie, &kDocumentCookie}, | |
186 {blink::WebFeaturePolicyFeature::DocumentDomain, &kDocumentDomain}, | |
187 {blink::WebFeaturePolicyFeature::DocumentWrite, &kDocumentWrite}, | |
188 {blink::WebFeaturePolicyFeature::Fullscreen, &kFullscreenFeature}, | |
189 {blink::WebFeaturePolicyFeature::Geolocation, &kGeolocationFeature}, | |
190 {blink::WebFeaturePolicyFeature::MidiFeature, &kMidiFeature}, | |
191 {blink::WebFeaturePolicyFeature::Notifications, &kNotificationsFeature}, | |
192 {blink::WebFeaturePolicyFeature::Payment, &kPaymentFeature}, | |
193 {blink::WebFeaturePolicyFeature::Push, &kPushFeature}, | |
194 {blink::WebFeaturePolicyFeature::SyncScript, &kSyncScript}, | |
195 {blink::WebFeaturePolicyFeature::SyncXHR, &kSyncXHR}, | |
196 {blink::WebFeaturePolicyFeature::Usermedia, &kUsermedia}, | |
197 {blink::WebFeaturePolicyFeature::Vibrate, &kVibrateFeature}, | |
198 {blink::WebFeaturePolicyFeature::WebRTC, &kWebRTC}})); | |
199 return defaultFeatureList; | |
200 } | |
201 | |
25 } // namespace content | 202 } // namespace content |
OLD | NEW |