-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create new UrlParamClassificationComponentInstaller class.
This class will receive classification lists and validate them. If the list is valid, it will be provided to the url_param_filter::ClassificationsLoader. The validation of classification lists occurs in VerifyInstallation, and the results of this are outputted to a new "Navigation.UrlParamFilter. ClassificationListValidationResult" histogram. Change-Id: Ic1cacf585c7dd61992919dd9f9e4f278496d3f11 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3537547 Reviewed-by: Matt Reichhoff <mreichhoff@chromium.org> Reviewed-by: Joshua Pawlicki <waffles@chromium.org> Reviewed-by: Ben Kelly <wanderview@chromium.org> Commit-Queue: Kirubel Aklilu <kaklilu@chromium.org> Cr-Commit-Position: refs/heads/main@{#987087}
- Loading branch information
Kirubel Aklilu
authored and
Chromium LUCI CQ
committed
Mar 30, 2022
1 parent
cf5bdde
commit 355b5e4
Showing
10 changed files
with
692 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
213 changes: 213 additions & 0 deletions
213
chrome/browser/component_updater/url_param_classification_component_installer.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/component_updater/url_param_classification_component_installer.h" | ||
|
||
#include "base/bind.h" | ||
#include "base/callback.h" | ||
#include "base/files/file_path.h" | ||
#include "base/files/file_util.h" | ||
#include "base/logging.h" | ||
#include "base/memory/ref_counted.h" | ||
#include "base/metrics/histogram_functions.h" | ||
#include "base/path_service.h" | ||
#include "base/task/post_task.h" | ||
#include "base/task/task_traits.h" | ||
#include "base/task/thread_pool.h" | ||
#include "base/version.h" | ||
#include "chrome/browser/url_param_filter/url_param_classifications_loader.h" | ||
#include "chrome/common/chrome_features.h" | ||
#include "components/component_updater/component_updater_paths.h" | ||
#include "content/public/browser/browser_task_traits.h" | ||
#include "third_party/abseil-cpp/absl/types/optional.h" | ||
|
||
using component_updater::ComponentUpdateService; | ||
|
||
namespace { | ||
|
||
const base::FilePath::CharType kUrlParamClassificationsFileName[] = | ||
FILE_PATH_LITERAL("url_param_classifications.pb"); | ||
|
||
// The SHA256 of the SubjectPublicKeyInfo used to sign the extension. | ||
// The extension id is: dnhnnofocefcglhjeigmkhcgfoaipbaa | ||
const uint8_t kUrlParamClassificationsPublicKeySHA256[32] = { | ||
0x3d, 0x7d, 0xde, 0x5e, 0x24, 0x52, 0x6b, 0x79, 0x48, 0x6c, 0xa7, | ||
0x26, 0x5e, 0x08, 0xf1, 0x00, 0x82, 0x56, 0x69, 0xb1, 0xca, 0xfc, | ||
0x8a, 0x25, 0x50, 0x06, 0x6b, 0x5f, 0xa1, 0xd5, 0xeb, 0x80}; | ||
|
||
const char kUrlParamClassificationManifestName[] = "Url Param Classifications"; | ||
|
||
// Runs on a thread pool. | ||
absl::optional<std::string> LoadFileFromDisk(const base::FilePath& pb_path) { | ||
VLOG(1) << "Reading Url Param Classifications from file: " << pb_path.value(); | ||
std::string file_contents; | ||
if (!base::ReadFileToString(pb_path, &file_contents)) { | ||
// The file won't exist on new installations, so this is not always an | ||
// error. | ||
VLOG(1) << "Failed reading from " << pb_path.value(); | ||
return absl::nullopt; | ||
} | ||
return file_contents; | ||
} | ||
|
||
// Writes a metric denoting the |result| of validating a classification list. | ||
// | ||
// This method is called in VerifyInstallation which returns false (on an error) | ||
// or true (if the whole list is valid), so the metrics will be populated at | ||
// most once per version installed. | ||
void WriteMetrics( | ||
component_updater::UrlParamClassificationComponentInstallerPolicy:: | ||
ClassificationListValidationResult result) { | ||
base::UmaHistogramEnumeration( | ||
"Navigation.UrlParamFilter.ClassificationListValidationResult", result); | ||
} | ||
|
||
} // namespace | ||
|
||
namespace component_updater { | ||
|
||
UrlParamClassificationComponentInstallerPolicy:: | ||
UrlParamClassificationComponentInstallerPolicy( | ||
component_updater::OnUrlParamClassificationComponentReady | ||
on_component_ready) | ||
: on_component_ready_(on_component_ready) {} | ||
|
||
UrlParamClassificationComponentInstallerPolicy:: | ||
~UrlParamClassificationComponentInstallerPolicy() = default; | ||
|
||
bool UrlParamClassificationComponentInstallerPolicy:: | ||
SupportsGroupPolicyEnabledComponentUpdates() const { | ||
return true; | ||
} | ||
|
||
bool UrlParamClassificationComponentInstallerPolicy::RequiresNetworkEncryption() | ||
const { | ||
return false; | ||
} | ||
|
||
update_client::CrxInstaller::Result | ||
UrlParamClassificationComponentInstallerPolicy::OnCustomInstall( | ||
const base::Value& manifest, | ||
const base::FilePath& install_dir) { | ||
return update_client::CrxInstaller::Result(0); // Nothing custom here. | ||
} | ||
|
||
void UrlParamClassificationComponentInstallerPolicy::OnCustomUninstall() {} | ||
|
||
base::FilePath UrlParamClassificationComponentInstallerPolicy::GetInstalledPath( | ||
const base::FilePath& base) { | ||
return base.Append(kUrlParamClassificationsFileName); | ||
} | ||
|
||
void UrlParamClassificationComponentInstallerPolicy::ComponentReady( | ||
const base::Version& version, | ||
const base::FilePath& install_dir, | ||
base::Value manifest) { | ||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | ||
VLOG(1) << "Component ready, version " << version.GetString() << " in " | ||
<< install_dir.value(); | ||
if (base::FeatureList::IsEnabled(features::kIncognitoParamFilterEnabled)) { | ||
// Given BEST_EFFORT since we don't need to be USER_BLOCKING. | ||
base::ThreadPool::PostTaskAndReplyWithResult( | ||
FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, | ||
base::BindOnce(&LoadFileFromDisk, GetInstalledPath(install_dir)), | ||
base::BindOnce( | ||
[](OnUrlParamClassificationComponentReady callback, | ||
const absl::optional<std::string>& maybe_file) { | ||
if (maybe_file.has_value()) | ||
callback.Run(maybe_file.value()); | ||
}, | ||
on_component_ready_)); | ||
} | ||
} | ||
|
||
// Called during startup and installation before ComponentReady(). | ||
bool UrlParamClassificationComponentInstallerPolicy::VerifyInstallation( | ||
const base::Value& manifest, | ||
const base::FilePath& install_dir) const { | ||
if (!base::PathExists(GetInstalledPath(install_dir))) { | ||
WriteMetrics( | ||
ClassificationListValidationResult::kMissingClassificationsFile); | ||
return false; | ||
} | ||
|
||
std::string file_contents; | ||
if (!base::ReadFileToString(GetInstalledPath(install_dir), &file_contents)) { | ||
WriteMetrics( | ||
ClassificationListValidationResult::kReadingClassificationsFileFailed); | ||
return false; | ||
} | ||
|
||
url_param_filter::FilterClassifications classification_list; | ||
if (!classification_list.ParseFromString(file_contents)) { | ||
WriteMetrics(ClassificationListValidationResult::kParsingToProtoFailed); | ||
return false; | ||
} | ||
|
||
std::vector<url_param_filter::FilterClassification> source_classifications, | ||
destination_classifications; | ||
for (const url_param_filter::FilterClassification& fc : | ||
classification_list.classifications()) { | ||
if (!fc.has_site()) { | ||
WriteMetrics( | ||
ClassificationListValidationResult::kClassificationMissingSite); | ||
return false; | ||
} | ||
|
||
if (!fc.has_site_role()) { | ||
WriteMetrics( | ||
ClassificationListValidationResult::kClassificationMissingSiteRole); | ||
return false; | ||
} | ||
|
||
if (fc.site_role() == | ||
url_param_filter::FilterClassification_SiteRole_SOURCE) { | ||
source_classifications.push_back(fc); | ||
} | ||
|
||
if (fc.site_role() == | ||
url_param_filter::FilterClassification_SiteRole_DESTINATION) { | ||
destination_classifications.push_back(fc); | ||
} | ||
} | ||
|
||
WriteMetrics(ClassificationListValidationResult::kSuccessful); | ||
return true; | ||
} | ||
|
||
base::FilePath | ||
UrlParamClassificationComponentInstallerPolicy::GetRelativeInstallDir() const { | ||
return base::FilePath(FILE_PATH_LITERAL("UrlParamClassifications")); | ||
} | ||
|
||
void UrlParamClassificationComponentInstallerPolicy::GetHash( | ||
std::vector<uint8_t>* hash) const { | ||
hash->assign(std::begin(kUrlParamClassificationsPublicKeySHA256), | ||
std::end(kUrlParamClassificationsPublicKeySHA256)); | ||
} | ||
|
||
std::string UrlParamClassificationComponentInstallerPolicy::GetName() const { | ||
return kUrlParamClassificationManifestName; | ||
} | ||
|
||
update_client::InstallerAttributes | ||
UrlParamClassificationComponentInstallerPolicy::GetInstallerAttributes() const { | ||
return update_client::InstallerAttributes(); | ||
} | ||
|
||
void RegisterUrlParamClassificationComponent(ComponentUpdateService* cus) { | ||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | ||
// Register the component even if feature isn't enabled so that when it is | ||
// enabled in the future, the component is already installed. | ||
VLOG(1) << "Registering Url Param Classifications component."; | ||
auto installer = base::MakeRefCounted<ComponentInstaller>( | ||
std::make_unique<UrlParamClassificationComponentInstallerPolicy>( | ||
base::BindRepeating([](std::string raw_classifications) { | ||
url_param_filter::ClassificationsLoader::GetInstance() | ||
->ReadClassifications(raw_classifications); | ||
}))); | ||
installer->Register(cus, base::OnceClosure()); | ||
} | ||
|
||
} // namespace component_updater |
87 changes: 87 additions & 0 deletions
87
chrome/browser/component_updater/url_param_classification_component_installer.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_COMPONENT_UPDATER_URL_PARAM_CLASSIFICATION_COMPONENT_INSTALLER_H_ | ||
#define CHROME_BROWSER_COMPONENT_UPDATER_URL_PARAM_CLASSIFICATION_COMPONENT_INSTALLER_H_ | ||
|
||
#include "base/callback.h" | ||
#include "base/files/file_path.h" | ||
#include "base/values.h" | ||
#include "components/component_updater/component_installer.h" | ||
|
||
namespace component_updater { | ||
|
||
class ComponentUpdateService; | ||
|
||
using OnUrlParamClassificationComponentReady = | ||
base::RepeatingCallback<void(std::string)>; | ||
|
||
class UrlParamClassificationComponentInstallerPolicy | ||
: public ComponentInstallerPolicy { | ||
public: | ||
// The result of reading and validating the UrlParamFilterClassification list | ||
// from Component Updater. | ||
// | ||
// These values are persisted to logs. Entries should not be renumbered and | ||
// numeric values should never be reused. | ||
enum class ClassificationListValidationResult { | ||
// No invalid classifications were found in the list. | ||
kSuccessful = 0, | ||
// The file wasn't present. | ||
kMissingClassificationsFile = 1, | ||
// Reading from the classifications file failed. | ||
kReadingClassificationsFileFailed = 2, | ||
// The raw classifications string was unabled to be parsed into the proto. | ||
kParsingToProtoFailed = 3, | ||
// Classification was ignored due to missing required site name. | ||
kClassificationMissingSite = 4, | ||
// Classification was ignored due to missing required site role. | ||
kClassificationMissingSiteRole = 5, | ||
kMaxValue = kClassificationMissingSiteRole, | ||
}; | ||
|
||
explicit UrlParamClassificationComponentInstallerPolicy( | ||
OnUrlParamClassificationComponentReady on_component_ready); | ||
~UrlParamClassificationComponentInstallerPolicy() override; | ||
|
||
UrlParamClassificationComponentInstallerPolicy( | ||
const UrlParamClassificationComponentInstallerPolicy&) = delete; | ||
UrlParamClassificationComponentInstallerPolicy& operator=( | ||
const UrlParamClassificationComponentInstallerPolicy&) = delete; | ||
|
||
private: | ||
FRIEND_TEST_ALL_PREFIXES(UrlParamClassificationComponentInstallerTest, | ||
VerifyAttributes); | ||
|
||
// The following methods override ComponentInstallerPolicy. | ||
bool SupportsGroupPolicyEnabledComponentUpdates() const override; | ||
bool RequiresNetworkEncryption() const override; | ||
update_client::CrxInstaller::Result OnCustomInstall( | ||
const base::Value& manifest, | ||
const base::FilePath& install_dir) override; | ||
void OnCustomUninstall() override; | ||
bool VerifyInstallation(const base::Value& manifest, | ||
const base::FilePath& install_dir) const override; | ||
void ComponentReady(const base::Version& version, | ||
const base::FilePath& install_dir, | ||
base::Value manifest) override; | ||
base::FilePath GetRelativeInstallDir() const override; | ||
void GetHash(std::vector<uint8_t>* hash) const override; | ||
std::string GetName() const override; | ||
update_client::InstallerAttributes GetInstallerAttributes() const override; | ||
|
||
static base::FilePath GetInstalledPath(const base::FilePath& base); | ||
void MaybeFireCallback( | ||
const absl::optional<std::string>& maybe_classifications); | ||
|
||
OnUrlParamClassificationComponentReady on_component_ready_; | ||
}; | ||
|
||
// Call once during startup to make the component update service aware of | ||
// the Url Param Classification component. | ||
void RegisterUrlParamClassificationComponent(ComponentUpdateService* cus); | ||
|
||
} // namespace component_updater | ||
|
||
#endif // CHROME_BROWSER_COMPONENT_UPDATER_URL_PARAM_CLASSIFICATION_COMPONENT_INSTALLER_H_ |
Oops, something went wrong.