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