Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1443)

Unified Diff: content/common/feature_policy/feature_policy.cc

Issue 2655663004: Introduce content-side Feature Policy object and maintain in parallel with renderer policy. (Closed)
Patch Set: Rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/feature_policy/feature_policy.cc
diff --git a/content/common/feature_policy/feature_policy.cc b/content/common/feature_policy/feature_policy.cc
index a8204daa5021e845062c11360d561311959145d3..73bab5483c93255fc4b40bc41c97ca8f50c03532 100644
--- a/content/common/feature_policy/feature_policy.cc
+++ b/content/common/feature_policy/feature_policy.cc
@@ -4,8 +4,69 @@
#include "content/common/feature_policy/feature_policy.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+
namespace content {
+namespace {
+
+// Given a string name, return the matching feature struct, or nullptr if it is
+// not the name of a policy-controlled feature.
+blink::WebFeaturePolicyFeature FeatureForName(
+ std::string feature_name,
+ const FeaturePolicy::FeatureList& features) {
+ for (const auto& feature_mapping : features) {
+ if (feature_name == feature_mapping.second->feature_name)
+ return feature_mapping.first;
+ }
+ return blink::WebFeaturePolicyFeature::NotFound;
+}
+
+// Definitions of all features controlled by Feature Policy should appear here.
+const FeaturePolicy::Feature kDocumentCookie{
+ "cookie", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kDocumentDomain{
+ "domain", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kDocumentWrite{
+ "docwrite", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kFullscreenFeature{
+ "fullscreen", FeaturePolicy::FeatureDefault::EnableForSelf};
+const FeaturePolicy::Feature kGeolocationFeature{
+ "geolocation", FeaturePolicy::FeatureDefault::EnableForSelf};
+const FeaturePolicy::Feature kMidiFeature{
+ "midi", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kNotificationsFeature{
+ "notifications", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kPaymentFeature{
+ "payment", FeaturePolicy::FeatureDefault::EnableForSelf};
+const FeaturePolicy::Feature kPushFeature{
+ "push", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kSyncScript{
+ "sync-script", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kSyncXHR{
+ "sync-xhr", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kUsermedia{
+ "usermedia", FeaturePolicy::FeatureDefault::EnableForAll};
+const FeaturePolicy::Feature kVibrateFeature{
+ "vibrate", FeaturePolicy::FeatureDefault::EnableForSelf};
+const FeaturePolicy::Feature kWebRTC{
+ "webrtc", FeaturePolicy::FeatureDefault::EnableForAll};
+
+// 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.
+std::unique_ptr<FeaturePolicy::Whitelist> WhitelistFromDeclaration(
+ const ParsedFeaturePolicyDeclaration& parsed_declaration) {
+ std::unique_ptr<FeaturePolicy::Whitelist> result =
+ base::WrapUnique(new FeaturePolicy::Whitelist());
+ if (parsed_declaration.matches_all_origins)
+ result->AddAll();
+ for (const auto& origin : parsed_declaration.origins)
+ result->Add(origin);
+ return result;
+}
+
+} // namespace
+
ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration()
: matches_all_origins(false) {}
@@ -22,4 +83,120 @@ ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration(
ParsedFeaturePolicyDeclaration::~ParsedFeaturePolicyDeclaration() {}
+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.
+FeaturePolicy::Whitelist::~Whitelist() = default;
+
+void FeaturePolicy::Whitelist::Add(const url::Origin& origin) {
+ origins_.push_back(origin);
+}
+
+void FeaturePolicy::Whitelist::AddAll() {
+ matches_all_origins_ = true;
+}
+
+bool FeaturePolicy::Whitelist::Contains(const url::Origin& origin) const {
+ if (matches_all_origins_)
+ return true;
+ for (const auto& targetOrigin : origins_) {
+ if (targetOrigin.IsSameOriginWith(origin))
+ return true;
+ }
+ return false;
+}
+
+// static
+std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromParentPolicy(
+ const FeaturePolicy* parent_policy,
+ url::Origin origin) {
+ return CreateFromParentPolicy(parent_policy, origin, getDefaultFeatureList());
+}
+
+bool FeaturePolicy::IsFeatureEnabledForOrigin(
+ blink::WebFeaturePolicyFeature feature,
+ url::Origin origin) const {
+ DCHECK(feature_list_.count(feature));
raymes 2017/02/01 22:42:21 Instead of count we tend to use ContainsKey from b
+ const FeaturePolicy::Feature* feature_definition = feature_list_.at(feature);
+ DCHECK(inherited_policies_.count(feature));
+ 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
+ return false;
+ }
+ 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.
+ return whitelists_.at(feature)->Contains(origin);
+ }
+ if (feature_definition->default_policy ==
+ FeaturePolicy::FeatureDefault::EnableForAll) {
+ return true;
+ }
+ if (feature_definition->default_policy ==
+ FeaturePolicy::FeatureDefault::EnableForSelf) {
+ return origin_.IsSameOriginWith(origin);
+ }
+ return false;
+}
+
+bool FeaturePolicy::IsFeatureEnabled(
+ blink::WebFeaturePolicyFeature feature) const {
+ return IsFeatureEnabledForOrigin(feature, origin_);
+}
+
+void FeaturePolicy::SetHeaderPolicy(
+ const ParsedFeaturePolicyHeader& parsed_header) {
+ DCHECK(whitelists_.empty());
+ for (const ParsedFeaturePolicyDeclaration& parsed_declaration :
+ parsed_header) {
+ blink::WebFeaturePolicyFeature feature =
+ FeatureForName(parsed_declaration.feature_name, feature_list_);
+ if (feature == blink::WebFeaturePolicyFeature::NotFound)
+ continue;
+ whitelists_[feature] = WhitelistFromDeclaration(parsed_declaration);
+ }
+}
+
+FeaturePolicy::FeaturePolicy(url::Origin origin,
+ const FeatureList& feature_list)
+ : origin_(origin), feature_list_(feature_list) {}
raymes 2017/02/01 22:42:21 nit: newline
iclelland 2017/02/03 16:38:29 Done.
+FeaturePolicy::FeaturePolicy(url::Origin origin)
+ : origin_(origin), feature_list_(getDefaultFeatureList()) {}
raymes 2017/02/01 22:42:21 nit: newline
iclelland 2017/02/03 16:38:29 Done.
+FeaturePolicy::~FeaturePolicy() {}
+
+// static
+std::unique_ptr<FeaturePolicy> FeaturePolicy::CreateFromParentPolicy(
+ const FeaturePolicy* parent_policy,
+ url::Origin origin,
+ const FeaturePolicy::FeatureList& features) {
+ std::unique_ptr<FeaturePolicy> newPolicy =
+ base::WrapUnique(new FeaturePolicy(origin, features));
+ for (const auto& feature : features) {
+ if (!parent_policy ||
+ parent_policy->IsFeatureEnabledForOrigin(feature.first, origin)) {
+ newPolicy->inherited_policies_[feature.first] = true;
+ } else {
+ newPolicy->inherited_policies_[feature.first] = false;
+ }
+ }
+ return newPolicy;
+}
+
+// static
+const FeaturePolicy::FeatureList& FeaturePolicy::getDefaultFeatureList() {
+ // 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 :)
+ CR_DEFINE_STATIC_LOCAL(
+ FeatureList, defaultFeatureList,
+ ({{blink::WebFeaturePolicyFeature::DocumentCookie, &kDocumentCookie},
+ {blink::WebFeaturePolicyFeature::DocumentDomain, &kDocumentDomain},
+ {blink::WebFeaturePolicyFeature::DocumentWrite, &kDocumentWrite},
+ {blink::WebFeaturePolicyFeature::Fullscreen, &kFullscreenFeature},
+ {blink::WebFeaturePolicyFeature::Geolocation, &kGeolocationFeature},
+ {blink::WebFeaturePolicyFeature::MidiFeature, &kMidiFeature},
+ {blink::WebFeaturePolicyFeature::Notifications, &kNotificationsFeature},
+ {blink::WebFeaturePolicyFeature::Payment, &kPaymentFeature},
+ {blink::WebFeaturePolicyFeature::Push, &kPushFeature},
+ {blink::WebFeaturePolicyFeature::SyncScript, &kSyncScript},
+ {blink::WebFeaturePolicyFeature::SyncXHR, &kSyncXHR},
+ {blink::WebFeaturePolicyFeature::Usermedia, &kUsermedia},
+ {blink::WebFeaturePolicyFeature::Vibrate, &kVibrateFeature},
+ {blink::WebFeaturePolicyFeature::WebRTC, &kWebRTC}}));
+ return defaultFeatureList;
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698