• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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