Skip to content

Commit

Permalink
Introduce PolicyValueAndStatusAggregator class
Browse files Browse the repository at this point in the history
PolicyValueAndStatusAggregator will initialize available
PolicyStatusProviders and PolicyValueProviders according to the platform
and will collect policy values and status information from those.
Replace the calls to individual PolicyStatusProviders and
PolicyValueProviders in PolicyUIHandler to calls to
PolicyValueAndStatusAggregator.
See go/policy-status-provider-refactor for more details.

Bug: b:233209041
Change-Id: Ic962e739aa3b23f2c1b541ccf8bda581f795b552
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3904814
Reviewed-by: Denis Kuznetsov <antrim@chromium.org>
Reviewed-by: Pavol Marko <pmarko@chromium.org>
Commit-Queue: Irem Uguz <iremuguz@google.com>
Cr-Commit-Position: refs/heads/main@{#1052335}
  • Loading branch information
Irem Uguz authored and Chromium LUCI CQ committed Sep 28, 2022
1 parent 217b7d4 commit a1b7e1b
Show file tree
Hide file tree
Showing 6 changed files with 486 additions and 349 deletions.
2 changes: 2 additions & 0 deletions chrome/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,8 @@ static_library("browser") {
"policy/messaging_layer/util/user_dm_token_retriever.h",
"policy/policy_ui_utils.cc",
"policy/policy_ui_utils.h",
"policy/policy_value_and_status_aggregator.cc",
"policy/policy_value_and_status_aggregator.h",
"policy/profile_policy_connector.cc",
"policy/profile_policy_connector.h",
"policy/profile_policy_connector_builder.cc",
Expand Down
330 changes: 330 additions & 0 deletions chrome/browser/policy/policy_value_and_status_aggregator.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
// 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/policy/policy_value_and_status_aggregator.h"

#include <memory>
#include <utility>

#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/browser/policy/value_provider/chrome_policies_value_provider.h"
#include "chrome/browser/policy/value_provider/policy_value_provider.h"
#include "components/policy/core/browser/webui/policy_status_provider.h"
#include "components/policy/core/browser/webui/policy_webui_constants.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/policy/active_directory/active_directory_policy_manager.h"
#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
#include "chrome/browser/ash/policy/core/device_local_account_policy_service.h"
#include "chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/browser_process_platform_part_ash.h"
#include "chrome/browser/policy/status_provider/device_active_directory_policy_status_provider.h"
#include "chrome/browser/policy/status_provider/device_cloud_policy_status_provider_chromeos.h"
#include "chrome/browser/policy/status_provider/device_local_account_policy_status_provider.h"
#include "chrome/browser/policy/status_provider/user_active_directory_policy_status_provider.h"
#include "chrome/browser/policy/status_provider/user_cloud_policy_status_provider_chromeos.h"
#include "components/user_manager/user_manager.h"
#else
#include "chrome/browser/policy/status_provider/user_cloud_policy_status_provider.h"
#include "components/enterprise/browser/controller/browser_dm_token_storage.h"
#include "components/enterprise/browser/reporting/common_pref_names.h"
#include "components/policy/core/browser/webui/machine_level_user_cloud_policy_status_provider.h"
#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
#include "components/prefs/pref_service.h"
#endif // BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/policy/status_provider/ash_lacros_policy_stack_bridge.h"
#include "chrome/browser/policy/status_provider/user_policy_status_provider_lacros.h"
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)

#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
#include "chrome/browser/policy/status_provider/updater_status_and_value_provider.h"
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/policy/value_provider/extension_policies_value_provider.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS)

namespace {
void AppendPolicyIdsToList(const base::Value::Dict& policy_values,
base::Value::List& policy_ids) {
for (const auto id_policy_pair : policy_values) {
policy_ids.Append(id_policy_pair.first);
}
}

// Appends the ID of `policy_values` to `policy_ids` and merges it to
// `out_policy_values`.
void MergePolicyValuesAndIds(base::Value::Dict policy_values,
base::Value::Dict& out_policy_values,
base::Value::List& out_policy_ids) {
AppendPolicyIdsToList(policy_values, out_policy_ids);
out_policy_values.Merge(std::move(policy_values));
}

// Returns the PolicyStatusProvider for user policies for the current platform.
std::unique_ptr<policy::PolicyStatusProvider> GetUserPolicyStatusProvider(
Profile* profile) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
policy::BrowserPolicyConnectorAsh* connector =
g_browser_process->platform_part()->browser_policy_connector_ash();
const user_manager::UserManager* user_manager =
user_manager::UserManager::Get();
policy::DeviceLocalAccountPolicyService* local_account_service =
user_manager->IsLoggedInAsPublicAccount()
? connector->GetDeviceLocalAccountPolicyService()
: nullptr;
policy::UserCloudPolicyManagerAsh* user_cloud_policy =
profile->GetUserCloudPolicyManagerAsh();
policy::ActiveDirectoryPolicyManager* active_directory_policy =
profile->GetActiveDirectoryPolicyManager();
if (local_account_service) {
return std::make_unique<DeviceLocalAccountPolicyStatusProvider>(
user_manager->GetActiveUser()->GetAccountId().GetUserEmail(),
local_account_service);
} else if (user_cloud_policy) {
return std::make_unique<UserCloudPolicyStatusProviderChromeOS>(
user_cloud_policy->core(), profile);
} else if (active_directory_policy) {
return std::make_unique<UserActiveDirectoryPolicyStatusProvider>(
active_directory_policy, profile);
}
#else // BUILDFLAG(IS_CHROMEOS_ASH)
policy::UserCloudPolicyManager* user_cloud_policy_manager =
profile->GetUserCloudPolicyManager();
if (user_cloud_policy_manager) {
return std::make_unique<UserCloudPolicyStatusProvider>(
user_cloud_policy_manager->core(), profile);
} else {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
if (profile->IsMainProfile()) {
return std::make_unique<UserPolicyStatusProviderLacros>(
g_browser_process->browser_policy_connector()
->device_account_policy_loader(),
profile);
}
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
return std::make_unique<policy::PolicyStatusProvider>();
}

#if BUILDFLAG(IS_CHROMEOS_ASH)
// Returns the PolicyStatusProvider for ChromeOS device policies.
std::unique_ptr<policy::PolicyStatusProvider>
GetChromeOSDevicePolicyStatusProvider(
Profile* profile,
policy::BrowserPolicyConnectorAsh* connector) {
if (connector->GetDeviceActiveDirectoryPolicyManager()) {
return std::make_unique<DeviceActiveDirectoryPolicyStatusProvider>(
connector->GetDeviceActiveDirectoryPolicyManager(),
connector->GetEnterpriseDomainManager());
}
return std::make_unique<DeviceCloudPolicyStatusProviderChromeOS>(connector);
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)

#if !BUILDFLAG(IS_CHROMEOS_ASH)
// Returns policy status provider for machine policies for non-ChromeOS
// platforms.
std::unique_ptr<policy::PolicyStatusProvider> GetMachinePolicyStatusProvider(
policy::MachineLevelUserCloudPolicyManager* manager) {
policy::BrowserDMTokenStorage* dmTokenStorage =
policy::BrowserDMTokenStorage::Get();

base::Time lastCloudReportSent;
PrefService* prefService = g_browser_process->local_state();

if (prefService->HasPrefPath(
enterprise_reporting::kLastUploadSucceededTimestamp)) {
lastCloudReportSent = prefService->GetTime(
enterprise_reporting::kLastUploadSucceededTimestamp);
}

return std::make_unique<policy::MachineLevelUserCloudPolicyStatusProvider>(
manager->core(),
new policy::MachineLevelUserCloudPolicyContext(
{dmTokenStorage->RetrieveEnrollmentToken(),
dmTokenStorage->RetrieveClientId(), lastCloudReportSent}));
}
#endif // !BUILDFLAG(IS_CHROMEOS_ASH)

} // namespace

namespace policy {

constexpr char kUserStatusKey[] = "user";

#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
constexpr char kDeviceStatusKey[] = "device";
#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)

#if !BUILDFLAG(IS_CHROMEOS_ASH)
constexpr char kMachineStatusKey[] = "machine";
#endif // !BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
constexpr char kUpdaterStatusKey[] = "updater";
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)

std::unique_ptr<PolicyValueAndStatusAggregator>
PolicyValueAndStatusAggregator::CreateDefaultPolicyValueAndStatusAggregator(
Profile* profile) {
std::unique_ptr<PolicyValueAndStatusAggregator> aggregator =
base::WrapUnique(new PolicyValueAndStatusAggregator());

// Add PolicyValueProviders.
aggregator->AddPolicyValueProvider(
std::make_unique<ChromePoliciesValueProvider>(profile));
#if BUILDFLAG(ENABLE_EXTENSIONS)
aggregator->AddPolicyValueProvider(
std::make_unique<ExtensionPoliciesValueProvider>(profile));
#endif // BUILDFLAG(ENABLE_EXTENSIONS)

// Add PolicyStatusProviders.
// User policies.
aggregator->AddPolicyStatusProvider(kUserStatusKey,
GetUserPolicyStatusProvider(profile));

// Device policies.
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Add status provider for ChromeOS device policies if the device is managed.
policy::BrowserPolicyConnectorAsh* connector =
g_browser_process->platform_part()->browser_policy_connector_ash();
if (connector->IsDeviceEnterpriseManaged())
aggregator->AddPolicyStatusProvider(
kDeviceStatusKey,
GetChromeOSDevicePolicyStatusProvider(profile, connector));
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#if BUILDFLAG(IS_CHROMEOS_LACROS)
// We will use AshLacrosPolicyStackBridge to retrieve device policies in
// Lacros.
aggregator->AddPolicyStatusAndValueProvider(
kDeviceStatusKey, std::make_unique<AshLacrosPolicyStackBridge>());
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)

// Machine policies.
#if !BUILDFLAG(IS_CHROMEOS_ASH)
policy::MachineLevelUserCloudPolicyManager* manager =
g_browser_process->browser_policy_connector()
->machine_level_user_cloud_policy_manager();
if (manager)
aggregator->AddPolicyStatusProvider(
kMachineStatusKey, GetMachinePolicyStatusProvider(manager));
#endif // !BUILDFLAG(IS_CHROMEOS_ASH)

// Updater policies.
#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
aggregator->AddPolicyStatusAndValueProvider(
kUpdaterStatusKey,
std::make_unique<UpdaterStatusAndValueProvider>(profile));
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
return aggregator;
}

PolicyValueAndStatusAggregator::PolicyValueAndStatusAggregator() = default;
PolicyValueAndStatusAggregator::~PolicyValueAndStatusAggregator() = default;

base::Value::Dict PolicyValueAndStatusAggregator::GetAggregatedPolicyStatus() {
base::Value::Dict status;
for (auto& status_provider_description_pair : status_providers_) {
status.Set(status_provider_description_pair.first,
status_provider_description_pair.second->GetStatus());
}
return status;
}

base::Value::Dict PolicyValueAndStatusAggregator::GetAggregatedPolicyValues() {
base::Value::Dict policy_values;
base::Value::List policy_ids;
for (auto& value_provider : value_providers_) {
MergePolicyValuesAndIds(value_provider->GetValues(), policy_values,
policy_ids);
}

for (auto* value_provider : value_providers_unowned_) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
// We only merge policy values for Lacros since policy ID is the same as
// Chrome policies.
policy_values.Merge(value_provider->GetValues());
#else
MergePolicyValuesAndIds(value_provider->GetValues(), policy_values,
policy_ids);
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
}
base::Value::Dict dict;
dict.Set(kPolicyValuesKey, std::move(policy_values));
dict.Set(kPolicyIdsKey, std::move(policy_ids));
return dict;
}

base::Value::Dict PolicyValueAndStatusAggregator::GetAggregatedPolicyNames() {
base::Value::Dict policy_names;
for (auto& value_provider : value_providers_) {
policy_names.Merge(value_provider->GetNames());
}
for (auto* value_provider : value_providers_unowned_) {
policy_names.Merge(value_provider->GetNames());
}
return policy_names;
}

void PolicyValueAndStatusAggregator::Refresh() {
for (auto& value_provider : value_providers_) {
value_provider->Refresh();
}
}

void PolicyValueAndStatusAggregator::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}

void PolicyValueAndStatusAggregator::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}

void PolicyValueAndStatusAggregator::OnPolicyValueChanged() {
NotifyValueAndStatusChange();
}

void PolicyValueAndStatusAggregator::OnPolicyStatusChanged() {
NotifyValueAndStatusChange();
}

void PolicyValueAndStatusAggregator::NotifyValueAndStatusChange() {
for (auto& observer : observers_)
observer.OnPolicyValueAndStatusChanged();
}

void PolicyValueAndStatusAggregator::AddPolicyValueProvider(
std::unique_ptr<PolicyValueProvider> value_provider) {
policy_value_provider_observations_.AddObservation(value_provider.get());
value_providers_.push_back(std::move(value_provider));
}

void PolicyValueAndStatusAggregator::AddPolicyStatusProvider(
std::string status_provider_description,
std::unique_ptr<PolicyStatusProvider> status_provider) {
policy_status_provider_observations_.AddObservation(status_provider.get());
status_providers_.emplace(status_provider_description,
std::move(status_provider));
}

void PolicyValueAndStatusAggregator::AddPolicyValueProviderUnowned(
PolicyValueProvider* value_provider) {
policy_value_provider_observations_.AddObservation(value_provider);
value_providers_unowned_.push_back(value_provider);
}

} // namespace policy

0 comments on commit a1b7e1b

Please sign in to comment.