Commit 027b1a7c authored by Ian Clelland's avatar Ian Clelland Committed by Commit Bot

Add methods for manipulating policies under construction

This is used immediately for clearing up the logic around allowfullscreen
and allowpayment request, and can also be used for more complex
container policy logic in the future.

Change-Id: I9cc702e0344d86d56a91894dc7a5a25bcdc26424
Reviewed-on: https://chromium-review.googlesource.com/1136909
Commit-Queue: Ian Clelland <iclelland@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575538}
parent 8413c2fc
...@@ -239,44 +239,21 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy( ...@@ -239,44 +239,21 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
// If allowfullscreen attribute is present and no fullscreen policy is set, // If allowfullscreen attribute is present and no fullscreen policy is set,
// enable the feature for all origins. // enable the feature for all origins.
if (AllowFullscreen()) { if (AllowFullscreen()) {
bool has_fullscreen_policy = false; bool policy_changed = AllowFeatureEverywhereIfNotPresent(
for (const auto& declaration : container_policy) { mojom::FeaturePolicyFeature::kFullscreen, container_policy);
if (declaration.feature == mojom::FeaturePolicyFeature::kFullscreen) { if (!policy_changed && messages) {
has_fullscreen_policy = true; messages->push_back(
if (messages) { "Allow attribute will take precedence over 'allowfullscreen'.");
messages->push_back(
"allow attribute is overriding 'allowfullscreen'.");
}
break;
}
}
if (!has_fullscreen_policy) {
ParsedFeaturePolicyDeclaration whitelist;
whitelist.feature = mojom::FeaturePolicyFeature::kFullscreen;
whitelist.matches_all_origins = true;
container_policy.push_back(whitelist);
} }
} }
// If the allowpaymentrequest attribute is present and no 'payment' policy is // If the allowpaymentrequest attribute is present and no 'payment' policy is
// set, enable the feature for all origins. // set, enable the feature for all origins.
if (AllowPaymentRequest()) { if (AllowPaymentRequest()) {
bool has_payment_policy = false; bool policy_changed = AllowFeatureEverywhereIfNotPresent(
for (const auto& declaration : container_policy) { mojom::FeaturePolicyFeature::kPayment, container_policy);
if (declaration.feature == mojom::FeaturePolicyFeature::kPayment) { if (!policy_changed && messages) {
has_payment_policy = true; messages->push_back(
if (messages) { "Allow attribute will take precedence over 'allowpaymentrequest'.");
messages->push_back(
"allow attribute is overriding 'allowpaymentrequest'.");
}
break;
}
}
if (!has_payment_policy) {
ParsedFeaturePolicyDeclaration whitelist;
whitelist.feature = mojom::FeaturePolicyFeature::kPayment;
whitelist.matches_all_origins = true;
whitelist.origins = std::vector<url::Origin>(0UL);
container_policy.push_back(whitelist);
} }
} }
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include "third_party/blink/renderer/platform/feature_policy/feature_policy.h" #include "third_party/blink/renderer/platform/feature_policy/feature_policy.h"
#include <algorithm>
#include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h" #include "third_party/blink/renderer/platform/network/http_parsers.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
...@@ -135,6 +137,62 @@ ParsedFeaturePolicy ParseFeaturePolicy( ...@@ -135,6 +137,62 @@ ParsedFeaturePolicy ParseFeaturePolicy(
return allowlists; return allowlists;
} }
bool IsFeatureDeclared(mojom::FeaturePolicyFeature feature,
const ParsedFeaturePolicy& policy) {
return std::any_of(policy.begin(), policy.end(),
[feature](const auto& declaration) {
return declaration.feature == feature;
});
}
bool RemoveFeatureIfPresent(mojom::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
auto new_end = std::remove_if(policy.begin(), policy.end(),
[feature](const auto& declaration) {
return declaration.feature == feature;
});
if (new_end == policy.end())
return false;
policy.erase(new_end, policy.end());
return true;
}
bool DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
if (IsFeatureDeclared(feature, policy))
return false;
ParsedFeaturePolicyDeclaration allowlist;
allowlist.feature = feature;
allowlist.matches_all_origins = false;
allowlist.matches_opaque_src = false;
policy.push_back(allowlist);
return true;
}
bool AllowFeatureEverywhereIfNotPresent(mojom::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
if (IsFeatureDeclared(feature, policy))
return false;
ParsedFeaturePolicyDeclaration allowlist;
allowlist.feature = feature;
allowlist.matches_all_origins = true;
allowlist.matches_opaque_src = true;
policy.push_back(allowlist);
return true;
}
void DisallowFeature(mojom::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
RemoveFeatureIfPresent(feature, policy);
DisallowFeatureIfNotPresent(feature, policy);
}
void AllowFeatureEverywhere(mojom::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
RemoveFeatureIfPresent(feature, policy);
AllowFeatureEverywhereIfNotPresent(feature, policy);
}
// This method defines the feature names which will be recognized by the parser // This method defines the feature names which will be recognized by the parser
// for the Feature-Policy HTTP header and the <iframe> "allow" attribute, as // for the Feature-Policy HTTP header and the <iframe> "allow" attribute, as
// well as the features which will be recognized by the document or iframe // well as the features which will be recognized by the document or iframe
......
...@@ -58,6 +58,38 @@ ParseFeaturePolicy(const String& policy, ...@@ -58,6 +58,38 @@ ParseFeaturePolicy(const String& policy,
Vector<String>* messages, Vector<String>* messages,
const FeatureNameMap& feature_names); const FeatureNameMap& feature_names);
// Returns true iff any declaration in the policy is for the given feature.
PLATFORM_EXPORT bool IsFeatureDeclared(mojom::FeaturePolicyFeature,
const ParsedFeaturePolicy&);
// Removes any declaration in the policy for the given feature. Returns true if
// the policy was modified.
PLATFORM_EXPORT bool RemoveFeatureIfPresent(mojom::FeaturePolicyFeature,
ParsedFeaturePolicy&);
// If no declaration in the policy exists already for the feature, adds a
// declaration which disallows the feature in all origins. Returns true if the
// policy was modified.
PLATFORM_EXPORT bool DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature,
ParsedFeaturePolicy&);
// If no declaration in the policy exists already for the feature, adds a
// declaration which allows the feature in all origins. Returns true if the
// policy was modified.
PLATFORM_EXPORT bool AllowFeatureEverywhereIfNotPresent(
mojom::FeaturePolicyFeature,
ParsedFeaturePolicy&);
// Replaces any existing declarations in the policy for the given feature with
// a declaration which disallows the feature in all origins.
PLATFORM_EXPORT void DisallowFeature(mojom::FeaturePolicyFeature,
ParsedFeaturePolicy&);
// Replaces any existing declarations in the policy for the given feature with
// a declaration which allows the feature in all origins.
PLATFORM_EXPORT void AllowFeatureEverywhere(mojom::FeaturePolicyFeature,
ParsedFeaturePolicy&);
} // namespace blink } // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FEATURE_POLICY_FEATURE_POLICY_H_ #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FEATURE_POLICY_FEATURE_POLICY_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment