| // Copyright 2020 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_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_H_ |
| #define COMPONENTS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_H_ |
| |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/time/time.h" |
| #include "components/keyed_service/core/keyed_service.h" |
| #include "components/prefs/pref_change_registrar.h" |
| #include "components/privacy_sandbox/canonical_topic.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| class HostContentSettingsMap; |
| class PrefService; |
| class GURL; |
| |
| namespace content_settings { |
| class CookieSettings; |
| } |
| |
| namespace url { |
| class Origin; |
| } |
| |
| namespace privacy_sandbox { |
| |
| // A service which acts as a intermediary between Privacy Sandbox APIs and the |
| // preferences and content settings which define when they are allowed to be |
| // accessed. Privacy Sandbox APIs, regardless of where they live (renderer, |
| // browser, network etc), must consult this service to determine when |
| // they are allowed to run. While a basic on/off control is provided by this |
| // service, embedders are expected to achieve fine-grained control though |
| // the underlying preferences and content settings separately. |
| class PrivacySandboxSettings : public KeyedService { |
| public: |
| class Observer { |
| public: |
| virtual void OnTopicsDataAccessibleSinceUpdated() {} |
| |
| // Fired when Trust Token blocking has changed because of a change to the |
| // Privacy Sandbox preference. Does not account for changes to third-party |
| // cookie blocking, which may result in the Privacy Sandbox being disabled. |
| // Trust tokens thus additionally independently consult Cookie settings. |
| // TODO(crbug.com/1304132): Unify this so Trust Tokens only need to consult |
| // a single source of truth. |
| virtual void OnTrustTokenBlockingChanged(bool blocked) {} |
| |
| // Fired when the First-Party Sets changes to being `enabled` as a result of |
| // the kPrivacySandboxFirstPartySets preference changing. |
| virtual void OnFirstPartySetsEnabledChanged(bool enabled) {} |
| }; |
| |
| class Delegate { |
| public: |
| virtual ~Delegate() = default; |
| |
| // Allows the delegate to restrict access to the Privacy Sandbox. When |
| // the Privacy Sandbox is restricted, all API access is disabled. This is |
| // consulted on every access check, and it is acceptable for this to change |
| // return value over the life of the service. |
| virtual bool IsPrivacySandboxRestricted() const = 0; |
| |
| // Whether the current profile is Incognito or not. For Incognito, the |
| // privacy sandbox APIs are restricted. |
| virtual bool IsIncognitoProfile() const = 0; |
| }; |
| |
| PrivacySandboxSettings( |
| std::unique_ptr<Delegate> delegate, |
| HostContentSettingsMap* host_content_settings_map, |
| scoped_refptr<content_settings::CookieSettings> cookie_settings, |
| PrefService* pref_service); |
| ~PrivacySandboxSettings() override; |
| |
| // Returns whether the Topics API is allowed at all. If false, Topics API |
| // calculations should not occur. If true, the more specific function, |
| // IsTopicsApiAllowedForContext(), should be consulted for the relevant |
| // context. |
| bool IsTopicsAllowed() const; |
| |
| // Determines whether the Topics API is allowable in a particular context. |
| // |top_frame_origin| is used to check for content settings which could both |
| // affect 1P and 3P contexts. |
| bool IsTopicsAllowedForContext(const url::Origin& top_frame_origin, |
| const GURL& url) const; |
| |
| // Returns whether |topic| can be either considered as a top topic for the |
| // current epoch, or provided to a website as a previous / current epochs |
| // site assigned topic. |
| bool IsTopicAllowed(const CanonicalTopic& topic); |
| |
| // Sets |topic| to |allowed|. Whether a topic is allowed or not is made |
| // available through IsTopicAllowed(). |
| void SetTopicAllowed(const CanonicalTopic& topic, bool allowed); |
| |
| // Removes all Topic settings with creation times between |start_time| |
| // and |end_time|. This allows for integration with the existing browsing data |
| // remover, such as the one powering Clear Browser Data. |
| void ClearTopicSettings(base::Time start_time, base::Time end_time); |
| |
| // Returns the point in time from which history is eligible to be used when |
| // calculating a user's Topics API topics. Reset when a user clears all |
| // cookies, or when the browser restarts with "Clear on exit" enabled. The |
| // returned time will have been fuzzed for local privacy, and so may be in the |
| // future, in which case no history is eligible. |
| base::Time TopicsDataAccessibleSince() const; |
| |
| // Determines whether Attribution Reporting is allowable in a particular |
| // context. Should be called at both source and trigger registration. At each |
| // of these points |top_frame_origin| is the same as either the source origin |
| // or the destination origin respectively. |
| bool IsAttributionReportingAllowed(const url::Origin& top_frame_origin, |
| const url::Origin& reporting_origin) const; |
| |
| // Called before sending the associated attribution report to |
| // |reporting_origin|. Re-checks that |reporting_origin| is allowable as a 3P |
| // on both |source_origin| and |destination_origin|. |
| bool MaySendAttributionReport(const url::Origin& source_origin, |
| const url::Origin& destination_origin, |
| const url::Origin& reporting_origin) const; |
| |
| // Sets the ability for |top_frame_etld_plus1| to join the profile to interest |
| // groups to |allowed|. This information is stored in preferences, and is made |
| // available to the API via IsFledgeJoiningAllowed(). |top_frame_etld_plus1| |
| // should in most circumstances be a valid eTLD+1, but hosts are accepted to |
| // allow for shifts in private registries. Entries are converted into wildcard |
| // subdomain ContentSettingsPattern before comparison. |
| void SetFledgeJoiningAllowed(const std::string& top_frame_etld_plus1, |
| bool allowed); |
| |
| // Clears any FLEDGE joining block settings with creation times between |
| // |start_time| and |end_time|. |
| void ClearFledgeJoiningAllowedSettings(base::Time start_time, |
| base::Time end_time); |
| |
| // Determines whether the user may be joined to FLEDGE interest groups on, or |
| // by, |top_frame_origin|. This is an additional check that must be |
| // combined with the more generic IsFledgeAllowed(). |
| bool IsFledgeJoiningAllowed(const url::Origin& top_frame_origin) const; |
| |
| // Determine whether |auction_party| can register an interest group, or sell |
| // buy in an auction, on |top_frame_origin|. |
| bool IsFledgeAllowed(const url::Origin& top_frame_origin, |
| const url::Origin& auction_party) const; |
| |
| // Determines whether Shared Storage is allowable in a particular context. |
| // `top_frame_origin` can be the same as `accessing_origin` in the case of a |
| // top-level document calling Shared Storage. |
| bool IsSharedStorageAllowed(const url::Origin& top_frame_origin, |
| const url::Origin& accessing_origin) const; |
| |
| // Controls whether Shared Storage SelectURL is allowable for |
| // `accessing_origin` in the context of `top_frame_origin`. Does not override |
| // a false return value from IsSharedStorageAllowed. |
| // TODO(crbug.com/1378703): This just redirects to the general |
| // IsSharedStorageAllowed(). The implementation needs to be updated to reflect |
| // the M1 preferences when release 4 is enabled. |
| bool IsSharedStorageSelectURLAllowed( |
| const url::Origin& top_frame_origin, |
| const url::Origin& accessing_origin) const; |
| |
| // Determines whether the Private Aggregation API is allowable in a particular |
| // context. `top_frame_origin` is the associated top-frame origin of the |
| // calling context. Applicable to all uses of Private Aggregation. |
| bool IsPrivateAggregationAllowed(const url::Origin& top_frame_origin, |
| const url::Origin& reporting_origin) const; |
| |
| // Returns whether the profile has the Privacy Sandbox enabled. This consults |
| // the main preference, as well as the delegate to check whether the sandbox |
| // is restricted. It does not consider any cookie settings. A return value of |
| // false means that no Privacy Sandbox operations can occur. A return value of |
| // true must be followed up with the appropriate IsXAllowed() call. |
| bool IsPrivacySandboxEnabled() const; |
| |
| // Allows all Privacy Sandbox prefs for testing. This should be used if tests |
| // don't depend on specific access control and just would like to have Privacy |
| // Sandbox allowed. Doesn't affect other non-default settings which might |
| // disallow APIs e.g. site data exceptions. |
| void SetAllPrivacySandboxAllowedForTesting(); |
| |
| // Blocks Topics pref for testing. |
| void SetTopicsBlockedForTesting(); |
| |
| // Disables the Privacy Sandbox completely if |enabled| is false, if |enabled| |
| // is true, more granular checks will still be performed, and the delegate |
| // consulted, to determine if specific APIs are available in specific |
| // contexts. |
| // DEPRECATED: Use `SetAllPrivacySandboxAllowedForTesting()` to allow all |
| // Privacy Sandbox prefs or per-API block-for-testing functions. |
| void SetPrivacySandboxEnabled(bool enabled); |
| |
| // Returns whether Trust Tokens are "generally" available. A return value of |
| // false is authoritative, while a value of true must be followed by the |
| // appropriate context specific check. |
| bool IsTrustTokensAllowed(); |
| |
| // Returns whether the Privacy Sandbox is being restricted by the associated |
| // delegate. Forwards directly to the corresponding delegate function. |
| // Virtual to allow mocking in tests. |
| virtual bool IsPrivacySandboxRestricted() const; |
| |
| // Called when there's a broad cookies clearing action. For example, this |
| // should be called on "Clear browsing data", but shouldn't be called on the |
| // Clear-Site-Data header, as it's restricted to a specific site. |
| void OnCookiesCleared(); |
| |
| // Called when the main privacy sandbox preference is changed. |
| void OnPrivacySandboxPrefChanged(); |
| |
| // Called when the First-Party Sets enabled preference is changed. |
| void OnFirstPartySetsEnabledPrefChanged(); |
| |
| void AddObserver(Observer* observer); |
| void RemoveObserver(Observer* observer); |
| |
| // Overrides the internal delegate for test purposes. |
| void SetDelegateForTesting(std::unique_ptr<Delegate> delegate); |
| |
| protected: |
| // Protected default constructor to allow mocking in tests. |
| PrivacySandboxSettings(); |
| |
| // Determines based on the current features, preferences and provided |
| // |cookie_settings| whether Privacy Sandbox APIs are generally allowable for |
| // |url| on |top_frame_origin|. Individual APIs may perform additional checks |
| // for allowability (such as incognito) ontop of this. |cookie_settings| is |
| // provided as a parameter to allow callers to cache it between calls. |
| bool IsPrivacySandboxEnabledForContext( |
| const absl::optional<url::Origin>& top_frame_origin, |
| const GURL& url) const; |
| |
| void SetTopicsDataAccessibleFromNow() const; |
| |
| private: |
| friend class PrivacySandboxSettingsM1Test; |
| |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class Status { |
| kAllowed, |
| kRestricted, |
| kIncognitoProfile, |
| kApisDisabled, |
| kSiteDataAccessBlocked, |
| kMaxValue = kSiteDataAccessBlocked, |
| }; |
| |
| static bool IsAllowed(Status status); |
| |
| // Whether the site associated with the URL is allowed to access privacy |
| // sandbox APIs within the context of |top_frame_origin|. |
| Status GetSiteAccessAllowedStatus(const url::Origin& top_frame_origin, |
| const GURL& url) const; |
| |
| // Whether the privacy sandbox APIs can be allowed given the current |
| // environment. For example, the privacy sandbox is always disabled in |
| // Incognito and for restricted accounts. |
| Status GetPrivacySandboxAllowedStatus() const; |
| |
| // Whether the privacy sandbox associated with the |pref_name| is enabled. |
| // For individual sites, check as well with GetSiteAccessAllowedStatus. |
| Status GetM1PrivacySandboxApiEnabledStatus( |
| const std::string& pref_name) const; |
| |
| // Whether the Topics API can be allowed given the current |
| // environment or the reason why it is not allowed. |
| Status GetM1TopicAllowedStatus() const; |
| |
| // Whether Attribution Reporting API can be allowed given the current |
| // environment or the reason why it is not allowed. |
| Status GetM1AttributionReportingAllowedStatus( |
| const url::Origin& top_frame_origin, |
| const url::Origin& reporting_origin) const; |
| |
| // Whether Fledge can be allowed given the current environment or the reason |
| // why it is not allowed. |
| Status GetM1FledgeAllowedStatus(const url::Origin& top_frame_origin, |
| const url::Origin& accessing_origin) const; |
| |
| base::ObserverList<Observer>::Unchecked observers_; |
| |
| std::unique_ptr<Delegate> delegate_; |
| raw_ptr<HostContentSettingsMap, DanglingUntriaged> host_content_settings_map_; |
| scoped_refptr<content_settings::CookieSettings> cookie_settings_; |
| raw_ptr<PrefService, DanglingUntriaged> pref_service_; |
| PrefChangeRegistrar pref_change_registrar_; |
| }; |
| |
| } // namespace privacy_sandbox |
| |
| #endif // COMPONENTS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_SETTINGS_H_ |