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