| // Copyright 2019 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_PERMISSIONS_CROWD_DENY_PRELOAD_DATA_H_ |
| #define CHROME_BROWSER_PERMISSIONS_CROWD_DENY_PRELOAD_DATA_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <queue> |
| #include <utility> |
| |
| #include "base/containers/flat_map.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/version.h" |
| #include "chrome/browser/permissions/crowd_deny.pb.h" |
| #include "url/origin.h" |
| |
| namespace base { |
| class SequencedTaskRunner; |
| class FilePath; |
| } |
| |
| namespace testing { |
| class ScopedCrowdDenyPreloadDataOverride; |
| } |
| |
| namespace { |
| struct PendingOrigin { |
| PendingOrigin( |
| url::Origin origin, |
| base::OnceCallback<void(const chrome_browser_crowd_deny::SiteReputation*)> |
| callback); |
| ~PendingOrigin(); |
| |
| url::Origin origin; |
| base::OnceCallback<void(const chrome_browser_crowd_deny::SiteReputation*)> |
| callback; |
| }; |
| } // namespace |
| |
| // Stores information relevant for making permission decision on popular sites. |
| // |
| // The preloaded list contains reputation data for popular sites, and is |
| // distributed to Chrome clients ahead of time through the component updater. |
| // The purpose is to reduce the frequency of on-demand pings to Safe Browsing. |
| class CrowdDenyPreloadData { |
| public: |
| using SiteReputation = chrome_browser_crowd_deny::SiteReputation; |
| using DomainToReputationMap = base::flat_map<std::string, SiteReputation>; |
| using PreloadData = chrome_browser_crowd_deny::PreloadData; |
| |
| using SiteReputationCallback = |
| base::OnceCallback<void(const SiteReputation*)>; |
| |
| CrowdDenyPreloadData(); |
| |
| CrowdDenyPreloadData(const CrowdDenyPreloadData&) = delete; |
| CrowdDenyPreloadData& operator=(const CrowdDenyPreloadData&) = delete; |
| |
| ~CrowdDenyPreloadData(); |
| |
| static CrowdDenyPreloadData* GetInstance(); |
| |
| // Delivers preloaded site reputation data for |origin| via |callback|. |
| // |
| // Because there is no way to establish the identity of insecure origins, |
| // reputation data is only ever provided if |origin| has HTTPS scheme. The |
| // port of |origin| is ignored. |
| void GetReputationDataForSiteAsync(const url::Origin& origin, |
| SiteReputationCallback callback); |
| |
| // Parses a single instance of chrome_browser_crowd_deny::PreloadData message |
| // in binary wire format from the file at |preload_data_path|. |
| void LoadFromDisk(const base::FilePath& preload_data_path, |
| const base::Version& version); |
| |
| inline const std::optional<base::Version>& version_on_disk() { |
| return version_on_disk_; |
| } |
| |
| inline void set_is_ready_to_use_for_testing(bool is_ready) { |
| is_ready_to_use_ = is_ready; |
| } |
| |
| inline int get_pending_origins_queue_size_for_testing() { |
| return origins_pending_verification_.size(); |
| } |
| |
| inline bool IsReadyToUse() { return is_ready_to_use_; } |
| |
| private: |
| friend class testing::ScopedCrowdDenyPreloadDataOverride; |
| friend class CrowdDenyPreloadDataTest; |
| |
| const SiteReputation* GetReputationDataForSite( |
| const url::Origin& origin) const; |
| void SetSiteReputations(DomainToReputationMap map); |
| void CheckOriginsPendingVerification(); |
| DomainToReputationMap TakeSiteReputations(); |
| // The only moment when CrowdDenyPreloadData is not ready to use is during |
| // loading from disk. |
| bool is_ready_to_use_ = true; |
| DomainToReputationMap domain_to_reputation_map_; |
| scoped_refptr<base::SequencedTaskRunner> loading_task_runner_; |
| std::optional<base::Version> version_on_disk_; |
| std::queue<PendingOrigin> origins_pending_verification_; |
| |
| base::WeakPtrFactory<CrowdDenyPreloadData> weak_factory_{this}; |
| }; |
| |
| namespace testing { |
| |
| // Overrides the production preload list, while the instance is in scope, with |
| // a testing list that is initially empty. |
| class ScopedCrowdDenyPreloadDataOverride { |
| public: |
| using SiteReputation = CrowdDenyPreloadData::SiteReputation; |
| using DomainToReputationMap = CrowdDenyPreloadData::DomainToReputationMap; |
| |
| ScopedCrowdDenyPreloadDataOverride(); |
| ~ScopedCrowdDenyPreloadDataOverride(); |
| |
| ScopedCrowdDenyPreloadDataOverride( |
| const ScopedCrowdDenyPreloadDataOverride&) = delete; |
| ScopedCrowdDenyPreloadDataOverride& operator=( |
| const ScopedCrowdDenyPreloadDataOverride&) = delete; |
| |
| void SetOriginReputation(const url::Origin& origin, |
| SiteReputation site_reputation); |
| void ClearAllReputations(); |
| |
| private: |
| DomainToReputationMap old_map_; |
| }; |
| |
| } // namespace testing |
| |
| #endif // CHROME_BROWSER_PERMISSIONS_CROWD_DENY_PRELOAD_DATA_H_ |