1 // Copyright 2019 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 #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_DOCUMENT_POLICY_H_ 6 #define THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_DOCUMENT_POLICY_H_ 7 8 #include <memory> 9 10 #include "base/containers/flat_map.h" 11 #include "base/macros.h" 12 #include "third_party/blink/public/common/common_export.h" 13 #include "third_party/blink/public/common/feature_policy/policy_value.h" 14 #include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom.h" 15 #include "third_party/blink/public/mojom/feature_policy/policy_value.mojom.h" 16 17 namespace blink { 18 19 // Document Policy is a mechanism for controlling the behaviour of web platform 20 // features in a document, and for requesting such changes in embedded frames. 21 // (The specific changes which are made depend on the feature; see the 22 // specification for details). 23 // 24 // Policies can be defined in the HTTP header stream, with the |Document-Policy| 25 // HTTP header, or can be set by the |policy| attributes on the iframe element 26 // which embeds the document. 27 // 28 // See 29 // https://github.com/w3c/webappsec-feature-policy/blob/master/document-policy-explainer.md 30 // 31 // Key concepts: 32 // 33 // Features 34 // -------- 35 // Features which can be controlled by policy are defined by instances of enum 36 // mojom::DocumentPolicyFeature, declared in |document_policy_feature.mojom|. 37 // 38 // Declarations 39 // ------------ 40 // A document policy declaration is a mapping of a feature name to a policy 41 // value. A set of such declarations is a declared policy. The declared policy 42 // is attached to a document. 43 // 44 // Required Policy 45 // ---------------- 46 // In addition to the declared policy (which may be empty), every frame has 47 // an required policy, which is set by the embedding document (or inherited 48 // from its parent). Any document loaded into a frame with a required policy 49 // must have a declared policy which is compatible with it. Frames may add new 50 // requirements to their own subframes, but cannot relax any existing ones. 51 // 52 // Advertised Policy 53 // ----------------- 54 // If a frame has a non-empty required policy, the requirements will be 55 // advertised on the outgoing HTTP request for any document to be loaded in that 56 // frame, in the Sec-Required-Document-Policy HTTP header. 57 // 58 // Defaults 59 // -------- 60 // Each defined feature has a default policy, which determines the threshold 61 // value to use when no policy has been declared. 62 63 class BLINK_COMMON_EXPORT DocumentPolicy { 64 public: 65 using FeatureState = 66 base::flat_map<mojom::DocumentPolicyFeature, PolicyValue>; 67 68 // Mapping of feature to endpoint group. 69 // https://w3c.github.io/reporting/#endpoint-group 70 using FeatureEndpointMap = 71 base::flat_map<mojom::DocumentPolicyFeature, std::string>; 72 73 struct ParsedDocumentPolicy { 74 FeatureState feature_state; 75 FeatureEndpointMap endpoint_map; 76 }; 77 78 static std::unique_ptr<DocumentPolicy> CreateWithHeaderPolicy( 79 const ParsedDocumentPolicy& header_policy); 80 81 // Returns true if the feature is unrestricted (has its default value for the 82 // platform) 83 bool IsFeatureEnabled(mojom::DocumentPolicyFeature feature) const; 84 85 // Returns true if the feature is unrestricted, or is not restricted as much 86 // as the given threshold value. 87 bool IsFeatureEnabled(mojom::DocumentPolicyFeature feature, 88 const PolicyValue& threshold_value) const; 89 90 // Returns true if the feature is being migrated to document policy 91 // TODO(iclelland): remove this method when those features are fully 92 // migrated to document policy. 93 bool IsFeatureSupported(mojom::DocumentPolicyFeature feature) const; 94 95 // Returns the value of the given feature on the given origin. 96 PolicyValue GetFeatureValue(mojom::DocumentPolicyFeature feature) const; 97 98 // Returns the endpoint the given feature should report to. 99 // Returns base::nullopt if the endpoint is unspecified for given feature. 100 const base::Optional<std::string> GetFeatureEndpoint( 101 mojom::DocumentPolicyFeature feature) const; 102 103 // Returns true if the incoming policy is compatible with the given required 104 // policy, i.e. incoming policy is at least as strict as required policy. 105 static bool IsPolicyCompatible(const FeatureState& required_policy, 106 const FeatureState& incoming_policy); 107 108 // Serialize document policy according to http_structured_header. 109 // returns base::nullopt when http structured header serializer encounters 110 // problems, e.g. double value out of the range supported. 111 static base::Optional<std::string> Serialize(const FeatureState& policy); 112 113 114 // Merge two FeatureState map. Take stricter value when there is conflict. 115 static FeatureState MergeFeatureState(const FeatureState& policy1, 116 const FeatureState& policy2); 117 118 private: 119 friend class DocumentPolicyTest; 120 121 DocumentPolicy(const FeatureState& header_policy, 122 const FeatureEndpointMap& endpoint_map, 123 const FeatureState& defaults); 124 static std::unique_ptr<DocumentPolicy> CreateWithHeaderPolicy( 125 const FeatureState& header_policy, 126 const FeatureEndpointMap& endpoint_map, 127 const FeatureState& defaults); 128 129 void UpdateFeatureState(const FeatureState& feature_state); 130 131 // Internal feature state is represented as an array to avoid overhead 132 // in using container classes. 133 PolicyValue internal_feature_state_ 134 [static_cast<size_t>(mojom::DocumentPolicyFeature::kMaxValue) + 1]; 135 136 FeatureEndpointMap endpoint_map_; 137 138 DISALLOW_COPY_AND_ASSIGN(DocumentPolicy); 139 }; 140 141 bool inline operator==(const DocumentPolicy::ParsedDocumentPolicy& lhs, 142 const DocumentPolicy::ParsedDocumentPolicy& rhs) { 143 return std::tie(lhs.feature_state, lhs.endpoint_map) == 144 std::tie(rhs.feature_state, rhs.endpoint_map); 145 } 146 147 } // namespace blink 148 149 #endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_DOCUMENT_POLICY_H_ 150