1 // Copyright 2022 The Chromium Authors 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 NET_FIRST_PARTY_SETS_GLOBAL_FIRST_PARTY_SETS_H_ 6 #define NET_FIRST_PARTY_SETS_GLOBAL_FIRST_PARTY_SETS_H_ 7 8 #include <optional> 9 10 #include "base/containers/flat_map.h" 11 #include "base/containers/flat_set.h" 12 #include "base/functional/function_ref.h" 13 #include "base/types/optional_ref.h" 14 #include "base/version.h" 15 #include "net/base/net_export.h" 16 #include "net/base/schemeful_site.h" 17 #include "net/first_party_sets/first_party_set_entry.h" 18 #include "net/first_party_sets/first_party_set_entry_override.h" 19 #include "net/first_party_sets/first_party_sets_context_config.h" 20 #include "net/first_party_sets/local_set_declaration.h" 21 #include "net/first_party_sets/sets_mutation.h" 22 23 namespace mojo { 24 template <typename DataViewType, typename T> 25 struct StructTraits; 26 } // namespace mojo 27 namespace network::mojom { 28 class GlobalFirstPartySetsDataView; 29 } // namespace network::mojom 30 31 namespace net { 32 33 class FirstPartySetMetadata; 34 35 // This class holds all of the info associated with the First-Party Sets known 36 // to this browser, after they've been parsed. This is suitable for plumbing 37 // from the browser process to the network service, or for answering queries. 38 // This class does not contain per-BrowserContext customizations, but supports 39 // application of those customizations. 40 class NET_EXPORT GlobalFirstPartySets { 41 public: 42 GlobalFirstPartySets(); 43 GlobalFirstPartySets( 44 base::Version public_sets_version, 45 base::flat_map<SchemefulSite, FirstPartySetEntry> entries, 46 base::flat_map<SchemefulSite, SchemefulSite> aliases); 47 48 GlobalFirstPartySets(GlobalFirstPartySets&&); 49 GlobalFirstPartySets& operator=(GlobalFirstPartySets&&); 50 51 ~GlobalFirstPartySets(); 52 53 bool operator==(const GlobalFirstPartySets& other) const; 54 bool operator!=(const GlobalFirstPartySets& other) const; 55 56 // Creates a clone of this instance. 57 GlobalFirstPartySets Clone() const; 58 59 // Returns a FirstPartySetsContextConfig that respects the overrides given by 60 // `mutation`, relative to this instance's state. 61 FirstPartySetsContextConfig ComputeConfig(const SetsMutation& mutation) const; 62 63 // Returns the entry corresponding to the given `site`, if one exists. 64 // Respects any customization/overlay specified by `config`. This is 65 // semi-agnostic to scheme: it just cares whether the scheme is secure or 66 // insecure. 67 std::optional<FirstPartySetEntry> FindEntry( 68 const SchemefulSite& site, 69 const FirstPartySetsContextConfig& config) const; 70 71 // Batched version of `FindEntry`. Where `FindEntry` would have returned 72 // nullopt, this just omits from the result map. 73 base::flat_map<SchemefulSite, FirstPartySetEntry> FindEntries( 74 const base::flat_set<SchemefulSite>& sites, 75 const FirstPartySetsContextConfig& config) const; 76 77 // Computes the First-Party Set metadata related to the given request context. 78 FirstPartySetMetadata ComputeMetadata( 79 const SchemefulSite& site, 80 base::optional_ref<const SchemefulSite> top_frame_site, 81 const FirstPartySetsContextConfig& fps_context_config) const; 82 83 // Modifies this instance such that it will respect the given 84 // manually-specified set. 85 void ApplyManuallySpecifiedSet( 86 const LocalSetDeclaration& local_set_declaration); 87 88 // Directly sets this instance's manual config. This is unsafe, because it 89 // assumes that the config was computed by this instance (or one with 90 // identical data), but cannot enforce that as a precondition. 91 // 92 // This must be public since at least one caller is above the //net layer, so 93 // we can't refer to the caller's type here (and therefore can't "friend" it 94 // and also can't use a base::Passkey). 95 // 96 // Must not be called if the manual config has already been set. 97 void UnsafeSetManualConfig(FirstPartySetsContextConfig manual_config); 98 99 // Synchronously iterate over all entries in the public sets (i.e. not 100 // including any manual set entries). Returns early if any of the iterations 101 // returns false. Returns false if iteration was incomplete; true if all 102 // iterations returned true. No guarantees are made re: iteration order. 103 // Aliases are included. 104 bool ForEachPublicSetEntry( 105 base::FunctionRef<bool(const SchemefulSite&, const FirstPartySetEntry&)> 106 f) const; 107 108 // Synchronously iterate over the manual config. Returns early if any of the 109 // iterations returns false. Returns false if iteration was incomplete; true 110 // if all iterations returned true. No guarantees are made re: iteration 111 // order. 112 bool ForEachManualConfigEntry( 113 base::FunctionRef<bool(const SchemefulSite&, 114 const FirstPartySetEntryOverride&)> f) const; 115 116 // Synchronously iterate over all the effective entries (i.e. anything that 117 // could be returned by `FindEntry` using this instance and `config`, 118 // including the manual set, policy sets, and aliases). Returns early if any 119 // of the iterations returns false. Returns false if iteration was incomplete; 120 // true if all iterations returned true. No guarantees are made re: iteration 121 // order. 122 bool ForEachEffectiveSetEntry( 123 const FirstPartySetsContextConfig& config, 124 base::FunctionRef<bool(const SchemefulSite&, const FirstPartySetEntry&)> 125 f) const; 126 127 // Whether the global sets are empty. empty()128 bool empty() const { return entries_.empty() && manual_config_.empty(); } 129 public_sets_version()130 const base::Version& public_sets_version() const { 131 return public_sets_version_; 132 } 133 134 private: 135 // mojo (de)serialization needs access to private details. 136 friend struct mojo::StructTraits<network::mojom::GlobalFirstPartySetsDataView, 137 GlobalFirstPartySets>; 138 139 friend NET_EXPORT std::ostream& operator<<(std::ostream& os, 140 const GlobalFirstPartySets& sets); 141 142 GlobalFirstPartySets( 143 base::Version public_sets_version, 144 base::flat_map<SchemefulSite, FirstPartySetEntry> entries, 145 base::flat_map<SchemefulSite, SchemefulSite> aliases, 146 FirstPartySetsContextConfig manual_config, 147 base::flat_map<SchemefulSite, SchemefulSite> manual_aliases); 148 149 // Same as the public version of FindEntry, but is allowed to omit the 150 // `config` argument (i.e. pass nullptr instead of a reference). 151 std::optional<FirstPartySetEntry> FindEntry( 152 const SchemefulSite& site, 153 const FirstPartySetsContextConfig* config) const; 154 155 using FlattenedSets = base::flat_map<SchemefulSite, FirstPartySetEntry>; 156 157 // Finds the existing primary sites whose sets are affected by a set of custom 158 // additions. 159 base::flat_map<SchemefulSite, FirstPartySetEntry> 160 FindPrimariesAffectedByAdditions(const FlattenedSets& additions) const; 161 162 // Finds the existing primary sites whose sets are affected by a set of custom 163 // replacements. 164 // 165 // Returns the set of existing primaries that may become a singleton (along 166 // with the sites in their set that have left due to the replacements); and 167 // the set of existing primaries that themselves were in a replacement set. 168 std::pair<base::flat_map<SchemefulSite, base::flat_set<SchemefulSite>>, 169 base::flat_set<SchemefulSite>> 170 FindPrimariesAffectedByReplacements( 171 const FlattenedSets& replacements, 172 const FlattenedSets& additions, 173 const base::flat_map<SchemefulSite, FirstPartySetEntry>& 174 addition_intersected_primaries) const; 175 176 // Preprocesses a collection of "addition" sets, such that any sets that 177 // transitively overlap (when taking the current `entries_` of this map, plus 178 // the manual config, into account) are unioned together. I.e., this ensures 179 // that at most one addition set intersects with any given global set. 180 std::vector<base::flat_map<SchemefulSite, FirstPartySetEntry>> 181 NormalizeAdditionSets( 182 const std::vector<base::flat_map<SchemefulSite, FirstPartySetEntry>>& 183 addition_sets) const; 184 185 // Same as the public version of ForEachEffectiveSetEntry, but is allowed to 186 // omit the `config` argument (i.e. pass nullptr instead of a reference). 187 bool ForEachEffectiveSetEntry( 188 const FirstPartySetsContextConfig* config, 189 base::FunctionRef<bool(const SchemefulSite&, const FirstPartySetEntry&)> 190 f) const; 191 192 // Iterates over the mappings in `manual_aliases_` and `aliases_` (skipping 193 // entries of `aliases_` that are shadowed), invoking `f` for each `alias, 194 // canonical` pair. 195 void ForEachAlias(base::FunctionRef<void(const SchemefulSite&, 196 const SchemefulSite&)> f) const; 197 198 // Synchronously iterate over all the effective entries. Returns true iff all 199 // the entries are valid. 200 bool IsValid(const FirstPartySetsContextConfig* config = nullptr) const; 201 202 // The version associated with the component_updater-provided public sets. 203 // This may be invalid if the "First-Party Sets" component has not been 204 // installed yet, or has been corrupted. Entries and aliases from invalid 205 // components are ignored. 206 base::Version public_sets_version_; 207 208 // Represents the mapping of site -> entry, where keys are sites within sets, 209 // and values are entries of the sets. 210 base::flat_map<SchemefulSite, FirstPartySetEntry> entries_; 211 212 // The site aliases. Used to normalize a given SchemefulSite into its 213 // canonical representative, before looking it up in `entries_`. 214 base::flat_map<SchemefulSite, SchemefulSite> aliases_; 215 216 // Stores the customizations induced by the manually-specified set. May be 217 // empty if no switch was provided. 218 FirstPartySetsContextConfig manual_config_; 219 220 // Stores the aliases contained in the manually-specified set. (Note that the 221 // aliases are *also* stored in `manual_config_`.) 222 base::flat_map<SchemefulSite, SchemefulSite> manual_aliases_; 223 }; 224 225 NET_EXPORT std::ostream& operator<<(std::ostream& os, 226 const GlobalFirstPartySets& sets); 227 228 } // namespace net 229 230 #endif // NET_FIRST_PARTY_SETS_GLOBAL_FIRST_PARTY_SETS_H_ 231