| // 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/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 "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: |
| FloatingSsoService(PrefService* prefs, |
| std::unique_ptr<FloatingSsoSyncBridge> bridge, |
| network::mojom::CookieManager* cookie_manager); |
| 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; |
| |
| base::WeakPtr<syncer::DataTypeControllerDelegate> GetControllerDelegate(); |
| |
| 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(); |
| |
| bool IsFloatingSsoEnabled(); |
| void MaybeStartListening(); |
| void StopListening(); |
| void BindToCookieManager(); |
| void OnCookiesLoaded(const net::CookieList& cookies); |
| bool ShouldSyncCookie(const net::CanonicalCookie& cookie) const; |
| void OnConnectionError(); |
| bool IsDomainAllowed(const net::CanonicalCookie& cookie) const; |
| |
| raw_ptr<PrefService> prefs_ = nullptr; |
| const raw_ptr<network::mojom::CookieManager> cookie_manager_; |
| 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; |
| |
| 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_ |