xref: /aosp_15_r20/external/cronet/net/first_party_sets/global_first_party_sets.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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