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