• 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 "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