File: floating_sso_service.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 (136 lines) | stat: -rw-r--r-- 5,474 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 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_FLOATING_SSO_FLOATING_SSO_SERVICE_H_
#define CHROME_BROWSER_ASH_FLOATING_SSO_FLOATING_SSO_SERVICE_H_

#include <memory>

#include "base/containers/flat_set.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ash/floating_sso/floating_sso_sync_bridge.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/sync/model/data_type_store.h"
#include "components/url_matcher/url_matcher.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_access_result.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"

namespace syncer {
class DataTypeControllerDelegate;
}  // namespace syncer

class PrefService;

namespace ash::floating_sso {

class FloatingSsoService : public KeyedService,
                           public network::mojom::CookieChangeListener,
                           public FloatingSsoSyncBridge::Observer {
 public:
  // Callback used to get a CookieManager.
  using CookieManagerGetter =
      base::RepeatingCallback<network::mojom::CookieManager*()>;

  FloatingSsoService(PrefService* prefs,
                     std::unique_ptr<FloatingSsoSyncBridge> bridge,
                     CookieManagerGetter cookie_manager_getter);
  FloatingSsoService(const FloatingSsoService&) = delete;
  FloatingSsoService& operator=(const FloatingSsoService&) = delete;

  ~FloatingSsoService() override;

  // KeyedService:
  void Shutdown() override;

  // network::mojom::CookieChangeListener:
  void OnCookieChange(const net::CookieChangeInfo& change) override;

  // FloatingSsoSyncBridge::Observer:
  void OnCookiesAddedOrUpdatedRemotely(
      const std::vector<net::CanonicalCookie>& cookies) override;
  void OnCookiesRemovedRemotely(
      const std::vector<net::CanonicalCookie>& cookies) override;

  bool IsFloatingSsoEnabled();
  // `callback` will be run once there are no cookie manager changes in
  // progress. This can be called repeatedly but only the latest callback will
  // be executed.
  void RunWhenCookiesAreReady(base::OnceClosure callback);
  // `callback` will be run once the bridge executes `MergeFullSyncData` method
  // (which can only happen when Sync is being enabled for the first time on
  // this client) and once conditions for `RunWhenCookiesAreReady` are also
  // satisfied.
  void RunWhenCookiesAreReadyOnFirstSync(base::OnceClosure callback);
  base::WeakPtr<syncer::DataTypeControllerDelegate> GetControllerDelegate();

  // Signal that this cookie shouldn't be overridden with remote
  // entities on initial Sync cycle.
  void MarkToNotOverride(const net::CanonicalCookie& cookie);

  bool ShouldSyncCookiesForUrl(const GURL& url) const;

  FloatingSsoSyncBridge* GetBridgeForTesting() { return bridge_.get(); }
  bool IsBoundToCookieManagerForTesting() { return receiver_.is_bound(); }

 private:
  void RegisterPolicyListeners();

  // Map the FloatingSsoDomainBlocklist and FloatingSsoDomainBlocklistExceptions
  // policies to URL matchers.
  void UpdateUrlMatchers();

  // Check if the feature is enabled based on the corresponding enterprise
  // policy. If yes, start observing cookies and uploading them to Sync, and
  // apply cookies from Sync if needed. If not, stop all of the above.
  void StartOrStop();

  void MaybeStartListening();
  void StopListening();
  void BindToCookieManager();
  void OnCookiesLoaded(const net::CookieList& cookies);
  bool ShouldSyncCookie(const net::CanonicalCookie& cookie) const;
  void OnConnectionError();
  bool IsDomainAllowed(const GURL& url) const;
  void OnCookieSet(net::CookieAccessResult result);
  void OnCookieDeleted(bool success);
  void DecrementChangesCountAndMaybeNotify();

  raw_ptr<PrefService> prefs_ = nullptr;
  // TODO(crbug.com/378091718): investigated lifetime issues when using
  // raw_ptr<network::mojom::CookieManager> instead of a callback here.
  CookieManagerGetter cookie_manager_getter_;
  std::unique_ptr<FloatingSsoSyncBridge> bridge_;
  base::ScopedObservation<FloatingSsoSyncBridge,
                          FloatingSsoSyncBridge::Observer>
      scoped_observation_{this};
  std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;

  // We fetch the accumulated cookies the first time the service is started, as
  // well when the service stops listening and resumes due to setting changes.
  // We do not fetch accumulated cookies when the connection to the cookie
  // manager is disrupted because we attempt to reconnect right away.
  bool fetch_accumulated_cookies_ = true;

  // Count of changes (additions or deletions of cookies) currently being
  // performed by `cookie_manager_`.
  // TODO(crbug.com/377471962): Add explicit tests for this counter and for
  // `on_no_changes_in_progress_callback_`.
  int changes_in_progress_count_ = 0;

  base::OnceClosure on_no_changes_in_progress_callback_;

  mojo::Receiver<network::mojom::CookieChangeListener> receiver_{this};

  std::unique_ptr<url_matcher::URLMatcher> block_url_matcher_;
  std::unique_ptr<url_matcher::URLMatcher> except_url_matcher_;
};

}  // namespace ash::floating_sso

#endif  // CHROME_BROWSER_ASH_FLOATING_SSO_FLOATING_SSO_SERVICE_H_