File: fetcher_config.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 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 (260 lines) | stat: -rw-r--r-- 10,505 bytes parent folder | download | duplicates (3)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SUPERVISED_USER_CORE_BROWSER_FETCHER_CONFIG_H_
#define COMPONENTS_SUPERVISED_USER_CORE_BROWSER_FETCHER_CONFIG_H_

#include <optional>
#include <string>
#include <string_view>
#include <variant>
#include <vector>

#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/types/strong_alias.h"
#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
#include "google_apis/gaia/gaia_constants.h"
#include "net/base/backoff_entry.h"
#include "net/base/request_priority.h"
#include "net/traffic_annotation/network_traffic_annotation.h"

namespace supervised_user {

BASE_DECLARE_FEATURE(kSupervisedUserProtoFetcherConfig);

namespace annotations {
// Traffic annotations can only live in cc/mm files.
net::NetworkTrafficAnnotationTag ClassifyUrlTag();
net::NetworkTrafficAnnotationTag ListFamilyMembersTag();
net::NetworkTrafficAnnotationTag CreatePermissionRequestTag();
}  // namespace annotations

struct AccessTokenConfig {
  enum class CredentialsRequirement {
    // This endpoint requires user credentials. If an access token cannot be
    // obtained, the request will be failed (with no request sent to the
    // server).
    kStrict,

    // End user credentials are preferred, but not required, for this endpoint.
    // If an access token cannot be obtained, the request will be sent to the
    // server with no credentials.
    kBestEffort
  };
  CredentialsRequirement credentials_requirement;

  // Must be set in actual configs. See
  // signin::PrimaryAccountAccessTokenFetcher::Mode docs.
  std::optional<signin::PrimaryAccountAccessTokenFetcher::Mode> mode;

  // The OAuth 2.0 permission scope to request the authorization token.
  std::string_view oauth2_scope;
};

// Configuration bundle for the ProtoFetcher.
struct FetcherConfig {
  using PathArgs = std::vector<std::string>;
  using PathTemplate =
      base::StrongAlias<class PathTemplateTag, std::string_view>;

  enum class Method { kUndefined, kGet, kPost };

  // Primary endpoint of the fetcher. May be overridden with feature flags.
  base::FeatureParam<std::string> service_endpoint{
      &kSupervisedUserProtoFetcherConfig, "service_endpoint",
      "https://kidsmanagement-pa.googleapis.com"};

  // Path of the service or a template of such path.
  //
  // In the path mode, it is used literally. Template is substituted with values
  // from supervised_user::CreateFetcher's `args` argument. Use
  // `::StaticServicePath()` and `::ServicePath(const PathArgs&)` accessors to
  // extract the right value.
  //
  // Example templated path: /path/to/{}/my/{}/resource
  //
  // See the service specification at
  // google3/google/internal/kids/chrome/v1/kidschromemanagement.proto for
  // examples.
  std::variant<std::string_view, PathTemplate> service_path;

  // HTTP method used to communicate with the service.
  const Method method = Method::kUndefined;

  // Basename for histograms. When unset, metrics won't be emitted.
  std::optional<std::string_view> histogram_basename;

  net::NetworkTrafficAnnotationTag (*const traffic_annotation)() = nullptr;

  // Policy for retrying patterns that will be applied to transient errors.
  std::optional<net::BackoffEntry::Policy> backoff_policy;

  // When set, the fetcher will attach an access token to the request, using
  // the specified configuration. When not set, no access token will be
  // attached.
  std::optional<AccessTokenConfig> access_token_config;

  net::RequestPriority request_priority;

  std::string GetHttpMethod() const;

  // Returns the non-template service_path or crashes for templated one.
  std::string_view StaticServicePath() const;

  // Returns the static (non-template) service path or interpolated template
  // path.
  // If the `service_path` is static (not `::PathTemplate`), `args` must
  // be empty; otherwise this function crashes.
  // For service_path which is `::PathTemplate`, args are inserted in
  // place of placeholders and then exhausted. If there is no arg to be put, an
  // empty string is used instead.
  //
  // Examples for "/path/{}{}/with/template/" template:
  //
  // ServicePath({}) -> /path//with/template/
  // ServicePath({"a"}) -> /path/a/with/template/
  // ServicePath({"a", "b"}) -> /path/ab/with/template/
  // ServicePath({"a", "b", "c"}) -> /path/ab/with/template/c
  // ServicePath({"a", "b", "c", "d"}) -> /path/ab/with/template/cd
  std::string ServicePath(const PathArgs& args) const;

  // Creates backoff entry based on the exact policy from this config.
  std::unique_ptr<net::BackoffEntry> BackoffEntry() const;
};

inline constexpr FetcherConfig kClassifyUrlConfig = {
    .service_path = "/kidsmanagement/v1/people/me:classifyUrl",
    .method = FetcherConfig::Method::kPost,
    .histogram_basename = "FamilyLinkUser.ClassifyUrlRequest",
    .traffic_annotation = annotations::ClassifyUrlTag,
    .access_token_config =
        AccessTokenConfig{
            .credentials_requirement =
                AccessTokenConfig::CredentialsRequirement::kStrict,
            .mode = signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate,
            // TODO(crbug.com/284523446): Refer to GaiaConstants rather than
            // literal.
            .oauth2_scope = "https://www.googleapis.com/auth/kid.permission",
        },
    .request_priority = net::IDLE,
};

inline constexpr FetcherConfig kClassifyUrlConfigWaitUntilAccessTokenAvailable =
    {
        .service_path = "/kidsmanagement/v1/people/me:classifyUrl",
        .method = FetcherConfig::Method::kPost,
        .histogram_basename = "FamilyLinkUser.ClassifyUrlRequest",
        .traffic_annotation = annotations::ClassifyUrlTag,
        .access_token_config =
            AccessTokenConfig{
                .credentials_requirement =
                    AccessTokenConfig::CredentialsRequirement::kStrict,
                .mode = signin::PrimaryAccountAccessTokenFetcher::Mode::
                    kWaitUntilAvailable,
                // TODO(crbug.com/284523446): Refer to GaiaConstants rather than
                // literal.
                .oauth2_scope =
                    "https://www.googleapis.com/auth/kid.permission",
            },
        .request_priority = net::IDLE,
};

inline constexpr FetcherConfig kClassifyUrlConfigBestEffort = {
    .service_path = "/kidsmanagement/v1/people/me:classifyUrl",
    .method = FetcherConfig::Method::kPost,
    .histogram_basename = "FamilyLinkUser.ClassifyUrlRequest",
    .traffic_annotation = annotations::ClassifyUrlTag,
    .access_token_config =
        AccessTokenConfig{
            .credentials_requirement =
                AccessTokenConfig::CredentialsRequirement::kBestEffort,
            .mode = signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate,
            // TODO(crbug.com/284523446): Refer to GaiaConstants rather than
            // literal.
            .oauth2_scope = "https://www.googleapis.com/auth/kid.permission",
        },
    .request_priority = net::IDLE,
};

inline constexpr FetcherConfig kClassifyUrlConfigWithoutCredentials = {
    .service_path = "/kidsmanagement/v1/people/me:classifyUrl",
    .method = FetcherConfig::Method::kPost,
    .histogram_basename = "NonFamilyLinkUser.ClassifyUrlRequest",
    .traffic_annotation = annotations::ClassifyUrlTag,
    .request_priority = net::IDLE,
};

inline constexpr FetcherConfig kListFamilyMembersConfig{
    .service_path = "/kidsmanagement/v1/families/mine/members",
    .method = FetcherConfig::Method::kGet,
    .histogram_basename = "Signin.ListFamilyMembersRequest",
    .traffic_annotation = annotations::ListFamilyMembersTag,
    .backoff_policy =
        net::BackoffEntry::Policy{
            // Number of initial errors (in sequence) to ignore before
            // applying exponential back-off rules.
            .num_errors_to_ignore = 0,

            // Initial delay for exponential backoff in ms.
            .initial_delay_ms = 2000,

            // Factor by which the waiting time will be multiplied.
            .multiply_factor = 2,

            // Fuzzing percentage. ex: 10% will spread requests randomly
            // between 90%-100% of the calculated time.
            .jitter_factor = 0.2,  // 20%

            // Maximum amount of time we are willing to delay our request in
            // ms.
            .maximum_backoff_ms = 1000 * 60 * 60 * 4,  // 4 hours.

            // Time to keep an entry from being discarded even when it
            // has no significant state, -1 to never discard.
            .entry_lifetime_ms = -1,

            // Don't use initial delay unless the last request was an error.
            .always_use_initial_delay = false,
        },
    .access_token_config =
        AccessTokenConfig{
            .credentials_requirement =
                AccessTokenConfig::CredentialsRequirement::kStrict,
            // Wait for the token to be issued. This fetch is asynchronous and
            // not
            // latency sensitive.
            .mode = signin::PrimaryAccountAccessTokenFetcher::Mode::
                kWaitUntilAvailable,

            // TODO(crbug.com/284523446): Refer to GaiaConstants rather than
            // literal.
            .oauth2_scope =
                "https://www.googleapis.com/auth/kid.family.readonly",
        },
    .request_priority = net::IDLE,
};

inline constexpr FetcherConfig kCreatePermissionRequestConfig = {
    .service_path = "/kidsmanagement/v1/people/me/permissionRequests",
    .method = FetcherConfig::Method::kPost,
    .histogram_basename = "FamilyLinkUser.CreatePermissionRequest",
    .traffic_annotation = annotations::CreatePermissionRequestTag,
    .access_token_config =
        AccessTokenConfig{
            .credentials_requirement =
                AccessTokenConfig::CredentialsRequirement::kStrict,
            // Fail the fetch right away when access token is not immediately
            // available.
            .mode = signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate,
            // TODO(crbug.com/284523446): Refer to GaiaConstants rather than
            // literal.
            .oauth2_scope = "https://www.googleapis.com/auth/kid.permission",
        },
    .request_priority = net::IDLE,
};

}  // namespace supervised_user

#endif  // COMPONENTS_SUPERVISED_USER_CORE_BROWSER_FETCHER_CONFIG_H_