OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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. |
| 4 |
| 5 #include "content/common/feature_policy/feature_policy.h" |
| 6 |
| 7 #include "base/macros.h" |
| 8 #include "base/memory/ptr_util.h" |
| 9 |
| 10 namespace content { |
| 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 } // namespace |
| 57 |
| 58 FeaturePolicyParsedDeclaration::FeaturePolicyParsedDeclaration() |
| 59 : matches_all_origins(false) {} |
| 60 |
| 61 FeaturePolicyParsedDeclaration::FeaturePolicyParsedDeclaration( |
| 62 std::string feature_name, |
| 63 bool matches_all_origins, |
| 64 std::vector<url::Origin> origins) |
| 65 : feature_name(feature_name), |
| 66 matches_all_origins(matches_all_origins), |
| 67 origins(origins) {} |
| 68 |
| 69 FeaturePolicyParsedDeclaration::FeaturePolicyParsedDeclaration( |
| 70 const FeaturePolicyParsedDeclaration& rhs) = default; |
| 71 |
| 72 FeaturePolicyParsedDeclaration::~FeaturePolicyParsedDeclaration() {} |
| 73 |
| 74 FeaturePolicy::Whitelist::Whitelist() : matches_all_origins_(false) {} |
| 75 FeaturePolicy::Whitelist::~Whitelist() = default; |
| 76 |
| 77 void FeaturePolicy::Whitelist::Add(const url::Origin& origin) { |
| 78 origins_.push_back(origin); |
| 79 } |
| 80 |
| 81 void FeaturePolicy::Whitelist::AddAll() { |
| 82 matches_all_origins_ = true; |
| 83 } |
| 84 |
| 85 bool FeaturePolicy::Whitelist::Contains(const url::Origin& origin) const { |
| 86 if (matches_all_origins_) |
| 87 return true; |
| 88 for (const auto& targetOrigin : origins_) { |
| 89 if (targetOrigin.IsSameOriginWith(origin)) |
| 90 return true; |
| 91 } |
| 92 return false; |
| 93 } |
| 94 |
| 95 // static |
| 96 std::unique_ptr<FeaturePolicy::Whitelist> |
| 97 FeaturePolicy::Whitelist::FromDeclaration( |
| 98 const FeaturePolicyParsedDeclaration& parsed_declaration) { |
| 99 std::unique_ptr<Whitelist> result = |
| 100 base::WrapUnique(new FeaturePolicy::Whitelist()); |
| 101 result->matches_all_origins_ = parsed_declaration.matches_all_origins; |
| 102 result->origins_ = parsed_declaration.origins; |
| 103 return result; |
| 104 } |
| 105 |
| 106 // static |
| 107 std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromParentPolicy( |
| 108 const FeaturePolicy* parent_policy, |
| 109 url::Origin origin) { |
| 110 return CreateFromParentPolicy(parent_policy, origin, getDefaultFeatureList()); |
| 111 } |
| 112 |
| 113 bool FeaturePolicy::IsFeatureEnabledForOrigin( |
| 114 blink::WebFeaturePolicyFeature feature, |
| 115 url::Origin origin) const { |
| 116 DCHECK(feature_list_.count(feature)); |
| 117 const FeaturePolicy::Feature* feature_definition = feature_list_.at(feature); |
| 118 DCHECK(inherited_policies_.count(feature)); |
| 119 if (!inherited_policies_.at(feature)) { |
| 120 return false; |
| 121 } |
| 122 if (whitelists_.count(feature)) { |
| 123 return whitelists_.at(feature)->Contains(origin); |
| 124 } |
| 125 if (feature_definition->default_policy == |
| 126 FeaturePolicy::FeatureDefault::EnableForAll) { |
| 127 return true; |
| 128 } |
| 129 if (feature_definition->default_policy == |
| 130 FeaturePolicy::FeatureDefault::EnableForSelf) { |
| 131 return origin_.IsSameOriginWith(origin); |
| 132 } |
| 133 return false; |
| 134 } |
| 135 |
| 136 bool FeaturePolicy::IsFeatureEnabled( |
| 137 blink::WebFeaturePolicyFeature feature) const { |
| 138 return IsFeatureEnabledForOrigin(feature, origin_); |
| 139 } |
| 140 |
| 141 void FeaturePolicy::SetHeaderPolicy(const FeaturePolicyHeader& parsed_header) { |
| 142 DCHECK(whitelists_.empty()); |
| 143 for (const FeaturePolicyParsedDeclaration& parsed_declaration : |
| 144 parsed_header) { |
| 145 blink::WebFeaturePolicyFeature feature = |
| 146 FeatureForName(parsed_declaration.feature_name, feature_list_); |
| 147 if (feature == blink::WebFeaturePolicyFeature::NotFound) |
| 148 continue; |
| 149 whitelists_[feature] = Whitelist::FromDeclaration(parsed_declaration); |
| 150 } |
| 151 } |
| 152 |
| 153 FeaturePolicy::FeaturePolicy(url::Origin origin, |
| 154 const FeatureList& feature_list) |
| 155 : origin_(origin), feature_list_(feature_list) {} |
| 156 FeaturePolicy::FeaturePolicy(url::Origin origin) |
| 157 : origin_(origin), feature_list_(getDefaultFeatureList()) {} |
| 158 FeaturePolicy::~FeaturePolicy() {} |
| 159 |
| 160 // static |
| 161 std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromParentPolicy( |
| 162 const FeaturePolicy* parent_policy, |
| 163 url::Origin origin, |
| 164 const FeaturePolicy::FeatureList& features) { |
| 165 std::unique_ptr<FeaturePolicy> newPolicy = |
| 166 base::WrapUnique(new FeaturePolicy(origin, features)); |
| 167 for (const auto& feature : features) { |
| 168 if (!parent_policy || |
| 169 parent_policy->IsFeatureEnabledForOrigin(feature.first, origin)) { |
| 170 newPolicy->inherited_policies_[feature.first] = true; |
| 171 } else { |
| 172 newPolicy->inherited_policies_[feature.first] = false; |
| 173 } |
| 174 } |
| 175 return newPolicy; |
| 176 } |
| 177 |
| 178 // static |
| 179 const FeaturePolicy::FeatureList& FeaturePolicy::getDefaultFeatureList() { |
| 180 // TODO: See if this should use lazy_instance instead |
| 181 CR_DEFINE_STATIC_LOCAL( |
| 182 FeatureList, defaultFeatureList, |
| 183 ({{blink::WebFeaturePolicyFeature::DocumentCookie, &kDocumentCookie}, |
| 184 {blink::WebFeaturePolicyFeature::DocumentDomain, &kDocumentDomain}, |
| 185 {blink::WebFeaturePolicyFeature::DocumentWrite, &kDocumentWrite}, |
| 186 {blink::WebFeaturePolicyFeature::Fullscreen, &kFullscreenFeature}, |
| 187 {blink::WebFeaturePolicyFeature::Geolocation, &kGeolocationFeature}, |
| 188 {blink::WebFeaturePolicyFeature::MidiFeature, &kMidiFeature}, |
| 189 {blink::WebFeaturePolicyFeature::Notifications, &kNotificationsFeature}, |
| 190 {blink::WebFeaturePolicyFeature::Payment, &kPaymentFeature}, |
| 191 {blink::WebFeaturePolicyFeature::Push, &kPushFeature}, |
| 192 {blink::WebFeaturePolicyFeature::SyncScript, &kSyncScript}, |
| 193 {blink::WebFeaturePolicyFeature::SyncXHR, &kSyncXHR}, |
| 194 {blink::WebFeaturePolicyFeature::Usermedia, &kUsermedia}, |
| 195 {blink::WebFeaturePolicyFeature::Vibrate, &kVibrateFeature}, |
| 196 {blink::WebFeaturePolicyFeature::WebRTC, &kWebRTC}})); |
| 197 return defaultFeatureList; |
| 198 } |
| 199 |
| 200 } // namespace content |
OLD | NEW |