blob: f699733f0a6b3115619f9c3e7f2c13741534617a [file] [log] [blame]
// Copyright 2019 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 "components/enterprise/browser/reporting/policy_info.h"
#include <string>
#include "base/json/json_writer.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/policy/core/browser/policy_conversions.h"
#include "components/policy/core/common/cloud/cloud_policy_client.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h"
#include "components/policy/core/common/policy_types.h"
#include "components/strings/grit/components_strings.h"
namespace em = enterprise_management;
namespace enterprise_reporting {
namespace {
em::Policy_PolicyLevel GetLevel(const base::Value& policy) {
switch (static_cast<policy::PolicyLevel>(*policy.FindIntKey("level"))) {
case policy::POLICY_LEVEL_RECOMMENDED:
return em::Policy_PolicyLevel_LEVEL_RECOMMENDED;
case policy::POLICY_LEVEL_MANDATORY:
return em::Policy_PolicyLevel_LEVEL_MANDATORY;
}
NOTREACHED() << "Invalid policy level: " << *policy.FindIntKey("level");
return em::Policy_PolicyLevel_LEVEL_UNKNOWN;
}
em::Policy_PolicyScope GetScope(const base::Value& policy) {
switch (static_cast<policy::PolicyScope>(*policy.FindIntKey("scope"))) {
case policy::POLICY_SCOPE_USER:
return em::Policy_PolicyScope_SCOPE_USER;
case policy::POLICY_SCOPE_MACHINE:
return em::Policy_PolicyScope_SCOPE_MACHINE;
}
NOTREACHED() << "Invalid policy scope: " << *policy.FindIntKey("scope");
return em::Policy_PolicyScope_SCOPE_UNKNOWN;
}
em::Policy_PolicySource GetSource(const base::Value& policy) {
switch (static_cast<policy::PolicySource>(*policy.FindIntKey("source"))) {
case policy::POLICY_SOURCE_ENTERPRISE_DEFAULT:
return em::Policy_PolicySource_SOURCE_ENTERPRISE_DEFAULT;
case policy::POLICY_SOURCE_COMMAND_LINE:
return em::Policy_PolicySource_SOURCE_COMMAND_LINE;
case policy::POLICY_SOURCE_CLOUD:
return em::Policy_PolicySource_SOURCE_CLOUD;
case policy::POLICY_SOURCE_ACTIVE_DIRECTORY:
return em::Policy_PolicySource_SOURCE_ACTIVE_DIRECTORY;
case policy::POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED:
return em::
Policy_PolicySource_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED;
case policy::POLICY_SOURCE_PLATFORM:
return em::Policy_PolicySource_SOURCE_PLATFORM;
case policy::POLICY_SOURCE_PRIORITY_CLOUD:
return em::Policy_PolicySource_SOURCE_PRIORITY_CLOUD;
case policy::POLICY_SOURCE_MERGED:
return em::Policy_PolicySource_SOURCE_MERGED;
case policy::POLICY_SOURCE_CLOUD_FROM_ASH:
return em::Policy_PolicySource_SOURCE_CLOUD_FROM_ASH;
case policy::POLICY_SOURCE_COUNT:
NOTREACHED();
return em::Policy_PolicySource_SOURCE_UNKNOWN;
}
NOTREACHED() << "Invalid policy source: " << *policy.FindIntKey("source");
return em::Policy_PolicySource_SOURCE_UNKNOWN;
}
void UpdatePolicyInfo(em::Policy* policy_info,
const std::string& policy_name,
const base::Value& policy) {
policy_info->set_name(policy_name);
policy_info->set_level(GetLevel(policy));
policy_info->set_scope(GetScope(policy));
policy_info->set_source(GetSource(policy));
base::JSONWriter::Write(*policy.FindKey("value"),
policy_info->mutable_value());
const std::string* error = policy.FindStringKey("error");
std::string deprecated_error;
std::string future_error;
// Because server side use keyword "deprecated" to determine policy
// deprecation error. Using l10n string actually causing issue.
if (policy.FindBoolKey("deprecated"))
deprecated_error = "This policy has been deprecated";
if (policy.FindBoolKey("future"))
future_error = "This policy hasn't been released";
if (error && !deprecated_error.empty())
policy_info->set_error(
base::JoinString({*error, deprecated_error, future_error}, "\n"));
else if (error)
policy_info->set_error(*error);
else if (!deprecated_error.empty())
policy_info->set_error(deprecated_error);
}
} // namespace
void AppendChromePolicyInfoIntoProfileReport(
const base::Value& policies,
em::ChromeUserProfileInfo* profile_info) {
for (auto policy_iter : policies.FindKey("chromePolicies")->DictItems()) {
UpdatePolicyInfo(profile_info->add_chrome_policies(), policy_iter.first,
policy_iter.second);
}
}
void AppendExtensionPolicyInfoIntoProfileReport(
const base::Value& policies,
em::ChromeUserProfileInfo* profile_info) {
if (!policies.FindKey("extensionPolicies")) {
// Android and iOS don't support extensions and their policies.
return;
}
for (auto extension_iter :
policies.FindKey("extensionPolicies")->DictItems()) {
const base::Value& policies = extension_iter.second;
if (policies.DictSize() == 0)
continue;
auto* extension = profile_info->add_extension_policies();
extension->set_extension_id(extension_iter.first);
for (auto policy_iter : policies.DictItems()) {
UpdatePolicyInfo(extension->add_policies(), policy_iter.first,
policy_iter.second);
}
}
}
void AppendMachineLevelUserCloudPolicyFetchTimestamp(
em::ChromeUserProfileInfo* profile_info,
policy::MachineLevelUserCloudPolicyManager* manager) {
#if !BUILDFLAG(IS_CHROMEOS_ASH)
if (!manager || !manager->IsClientRegistered())
return;
auto* timestamp = profile_info->add_policy_fetched_timestamps();
timestamp->set_type(
policy::dm_protocol::kChromeMachineLevelExtensionCloudPolicyType);
timestamp->set_timestamp(
manager->core()->client()->last_policy_timestamp().ToJavaTime());
#endif // !BUILDFLAG(IS_CHROMEOS_ASH)
}
} // namespace enterprise_reporting