File: interest_group_k_anonymity_manager.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (136 lines) | stat: -rw-r--r-- 5,994 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_K_ANONYMITY_MANAGER_H_
#define CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_K_ANONYMITY_MANAGER_H_

#include <vector>

#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "content/browser/interest_group/interest_group_caching_storage.h"
#include "content/browser/interest_group/interest_group_update.h"
#include "content/browser/interest_group/storage_interest_group.h"
#include "content/common/content_export.h"
#include "content/public/browser/k_anonymity_service_delegate.h"
#include "third_party/blink/public/common/interest_group/interest_group.h"

namespace content {
class InterestGroupManagerImpl;

// Maximum number of IDs to send in a single query call. Public for testing.
constexpr size_t kQueryBatchSizeLimit = 1000;

// Returns whether `last_updated` is less than 7 days ago.
bool CONTENT_EXPORT IsKAnonDataExpired(const base::Time last_updated,
                                       const base::Time now);

// Manages k-anonymity updates. Checks last updated times in the database
// to limit updates (joins and queries) to once per day. Called by the
// InterestGroupManagerImpl for interest group k-anonymity updates. Calls
// The InterestGroupManagerImpl to access interest group storage to perform
// interest group updates.
class CONTENT_EXPORT InterestGroupKAnonymityManager {
 public:
  using GetKAnonymityServiceDelegateCallback =
      base::RepeatingCallback<KAnonymityServiceDelegate*()>;

  InterestGroupKAnonymityManager(
      InterestGroupManagerImpl* interest_group_manager,
      InterestGroupCachingStorage* caching_storage,
      GetKAnonymityServiceDelegateCallback k_anonymity_service_callback);
  ~InterestGroupKAnonymityManager();

  // Requests k-anonymity updates for all interest groups owned by `owners` that
  // haven't been updated in 24 hours or more. Results are passed to
  // interest_group_manager_->UpdateKAnonymity.
  void QueryKAnonymityOfOwners(base::span<const url::Origin> owners);

  // Requests the k-anonymity status of elements of `k_anon_data` that
  // haven't been updated in 24 hours or more. Results are passed to
  // interest_group_manager_->UpdateKAnonymity.
  void QueryKAnonymityData(
      const blink::InterestGroupKey& interest_group_key,
      const InterestGroupKanonUpdateParameter& k_anon_data);

  // Notify the k-anonymity service that these ad keys won an auction.
  // Internally this calls RegisterIDAsJoined().
  void RegisterAdKeysAsJoined(base::flat_set<std::string> hashed_keys);

 private:
  friend class InterestGroupKAnonymityManagerTestPeer;

  struct InProgressQueryState {
    InProgressQueryState(base::Time update_time, bool replace_existing_values);
    InProgressQueryState(const InProgressQueryState&);
    ~InProgressQueryState();
    base::Time update_time;
    bool replace_existing_values;
    size_t remaining_responses{0};
    std::vector<std::string> positive_hashed_keys_from_received_responses;
  };

  // Callback from QueryKAnonymityOfOwners
  void OnGotInterestGroupsOfOwner(scoped_refptr<StorageInterestGroups> groups);

  // Callback from LoadPositiveHashedKAnonymityKeysFromCache
  void FetchUncachedKAnonymityData(
      base::Time update_time,
      const blink::InterestGroupKey& interest_group_key,
      InterestGroupStorage::KAnonymityCacheResponse cache_response);

  // Callback from k-anonymity service QuerySets().
  void QuerySetsCallback(std::vector<std::string> query,
                         base::Time update_time,
                         const blink::InterestGroupKey& interest_group_key,
                         std::vector<bool> status);

  // Starts fetching the LastKAnonymityReported time for `url` from the
  // database.
  void RegisterIDAsJoined(const std::string& hashed_key);

  // Called by the database when the update time for `url` has been retrieved.
  // If the last reported time is too long ago, calls JoinSet() on the
  // k-anonymity service.
  void OnGotLastReportedTime(std::string hashed_key,
                             std::optional<base::Time> last_update_time);

  // Callback from k-anonymity service JoinSet(). Updates the LastReported time
  // for key in the database, regardless of status (fail close).
  void JoinSetCallback(std::string hashed_key, bool status);

  // An unowned pointer to the InterestGroupManagerImpl that owns this
  // InterestGroupUpdateManager. Used as an intermediary to talk to the
  // database.
  raw_ptr<InterestGroupManagerImpl> interest_group_manager_;

  // An unowned pointer to the interest_group_manager_'s
  // InterestGroupCachingStorage. Used to talk to the database directly for
  // fetching and storing cached hashed keys only.
  raw_ptr<InterestGroupCachingStorage> caching_storage_;

  GetKAnonymityServiceDelegateCallback k_anonymity_service_callback_;

  // We keep track of joins in progress because the joins that haven't completed
  // are still marked as eligible but it would be incorrect to join them
  // multiple times. We don't do this for query because the
  // size of the request could expose membership in overlapping groups through
  // traffic analysis.
  base::flat_set<std::string> joins_in_progress_;

  // Keep track of updates for which we have not yet written values back to the
  // database. When we receive a new QueryKAnonymityData for an interest group
  // while there's an outstanding query for the same interest group, we may
  // choose to replace the query in progress or add more k-anonymity keys onto
  // it.
  base::flat_map<blink::InterestGroupKey, InProgressQueryState>
      queries_in_progress_;

  base::WeakPtrFactory<InterestGroupKAnonymityManager> weak_ptr_factory_;
};

}  // namespace content

#endif  // CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_K_ANONYMITY_MANAGER_H_