blob: 06275e9b1727954c24893feede0a4e84ecf9b558 [file] [log] [blame]
// Copyright 2017 The Chromium OS 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 <unordered_set>
#include <base/strings/string_util.h>
#include <components/policy/core/common/registry_dict.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "authpolicy/policy/device_policy_encoder.h"
#include "authpolicy/policy/policy_encoder_test_base.h"
#include "bindings/chrome_device_policy.pb.h"
#include "bindings/policy_constants.h"
namespace em = enterprise_management;
namespace policy {
namespace {
// Converts a repeated string field to a vector.
std::vector<std::string> ToVector(
const google::protobuf::RepeatedPtrField<std::string>& repeated_field) {
return std::vector<std::string>(repeated_field.begin(), repeated_field.end());
}
// Converts a repeated int field to a vector.
std::vector<int> ToVector(
const google::protobuf::RepeatedField<int>& repeated_field) {
return std::vector<int>(repeated_field.begin(), repeated_field.end());
}
} // namespace
// Checks whether all device policies are properly encoded from RegistryDict
// into em::ChromeDeviceSettingsProto. Makes sure no device policy is missing.
class DevicePolicyEncoderTest
: public PolicyEncoderTestBase<em::ChromeDeviceSettingsProto> {
public:
DevicePolicyEncoderTest() {}
~DevicePolicyEncoderTest() override {}
protected:
void EncodeDict(em::ChromeDeviceSettingsProto* policy,
const RegistryDict* dict) override {
DevicePolicyEncoder encoder(dict);
*policy = em::ChromeDeviceSettingsProto();
encoder.EncodePolicy(policy);
}
void MarkHandled(const char* key) override {
handled_policy_keys_.insert(key);
}
// Returns a vector of all policy keys that were not encoded or otherwise
// marked handled (e.g. unsupported policies).
std::vector<std::string> GetUnhandledPolicyKeys() const {
std::vector<std::string> unhandled_policy_keys;
for (const char** key = kDevicePolicyKeys; *key; ++key) {
if (handled_policy_keys_.find(*key) == handled_policy_keys_.end())
unhandled_policy_keys.push_back(*key);
}
return unhandled_policy_keys;
}
private:
// Keeps track of handled device policies. Used to detect device policies that
// device_policy_encoder forgets to encode.
std::unordered_set<std::string> handled_policy_keys_;
DISALLOW_COPY_AND_ASSIGN(DevicePolicyEncoderTest);
};
TEST_F(DevicePolicyEncoderTest, TestEncoding) {
// Note that kStringList can't be constexpr, so we put them all here.
const bool kBool = true;
const int kInt = 123;
const std::string kString = "val1";
const std::vector<std::string> kStringList = {"val1", "val2", "val3"};
em::ChromeDeviceSettingsProto policy;
//
// Login policies.
//
EncodeBoolean(&policy, key::kDeviceGuestModeEnabled, kBool);
EXPECT_EQ(kBool, policy.guest_mode_enabled().guest_mode_enabled());
EncodeBoolean(&policy, key::kDeviceRebootOnShutdown, kBool);
EXPECT_EQ(kBool, policy.reboot_on_shutdown().reboot_on_shutdown());
EncodeBoolean(&policy, key::kDeviceShowUserNamesOnSignin, kBool);
EXPECT_EQ(kBool, policy.show_user_names().show_user_names());
EncodeBoolean(&policy, key::kDeviceAllowNewUsers, kBool);
EXPECT_EQ(kBool, policy.allow_new_users().allow_new_users());
EncodeStringList(&policy, key::kDeviceUserWhitelist, kStringList);
EXPECT_EQ(kStringList, ToVector(policy.user_whitelist().user_whitelist()));
EncodeBoolean(&policy, key::kDeviceEphemeralUsersEnabled, kBool);
EXPECT_EQ(kBool, policy.ephemeral_users_enabled().ephemeral_users_enabled());
// Unsupported, see device_policy_encoder.cc for explanation, simply mark
// handled.
MarkHandled(key::kDeviceLocalAccounts);
EncodeString(&policy, key::kDeviceLocalAccountAutoLoginId, kString);
EXPECT_EQ(kString, policy.device_local_accounts().auto_login_id());
EncodeInteger(&policy, key::kDeviceLocalAccountAutoLoginDelay, kInt);
EXPECT_EQ(kInt, policy.device_local_accounts().auto_login_delay());
EncodeBoolean(
&policy, key::kDeviceLocalAccountAutoLoginBailoutEnabled, kBool);
EXPECT_EQ(kBool, policy.device_local_accounts().enable_auto_login_bailout());
EncodeBoolean(
&policy, key::kDeviceLocalAccountPromptForNetworkWhenOffline, kBool);
EXPECT_EQ(kBool,
policy.device_local_accounts().prompt_for_network_when_offline());
EncodeBoolean(&policy, key::kSupervisedUsersEnabled, kBool);
EXPECT_EQ(kBool,
policy.supervised_users_settings().supervised_users_enabled());
EncodeBoolean(&policy, key::kDeviceTransferSAMLCookies, kBool);
EXPECT_EQ(kBool, policy.saml_settings().transfer_saml_cookies());
// The encoder of this policy converts ints to LoginBehavior enums.
EncodeInteger(&policy,
key::kLoginAuthenticationBehavior,
em::LoginAuthenticationBehaviorProto::SAML_INTERSTITIAL);
EXPECT_EQ(
em::LoginAuthenticationBehaviorProto::SAML_INTERSTITIAL,
policy.login_authentication_behavior().login_authentication_behavior());
EncodeBoolean(&policy, key::kDeviceAllowBluetooth, kBool);
EXPECT_EQ(kBool, policy.allow_bluetooth().allow_bluetooth());
EncodeStringList(&policy, key::kLoginVideoCaptureAllowedUrls, kStringList);
EXPECT_EQ(kStringList,
ToVector(policy.login_video_capture_allowed_urls().urls()));
EncodeStringList(&policy, key::kDeviceLoginScreenAppInstallList, kStringList);
EXPECT_EQ(kStringList,
ToVector(policy.device_login_screen_app_install_list()
.device_login_screen_app_install_list()));
EncodeStringList(&policy, key::kDeviceLoginScreenLocales, kStringList);
EXPECT_EQ(kStringList,
ToVector(policy.login_screen_locales().login_screen_locales()));
EncodeStringList(&policy, key::kDeviceLoginScreenInputMethods, kStringList);
EXPECT_EQ(
kStringList,
ToVector(
policy.login_screen_input_methods().login_screen_input_methods()));
//
// Network policies.
//
EncodeBoolean(&policy, key::kDeviceDataRoamingEnabled, kBool);
EXPECT_EQ(kBool, policy.data_roaming_enabled().data_roaming_enabled());
// The encoder of this policy converts a json string to separate values.
EncodeString(&policy,
key::kNetworkThrottlingEnabled,
"{\"enabled\":true,"
" \"upload_rate_kbits\":128,"
" \"download_rate_kbits\":256}");
EXPECT_EQ(true, policy.network_throttling().enabled());
EXPECT_EQ(128, policy.network_throttling().upload_rate_kbits());
EXPECT_EQ(256, policy.network_throttling().download_rate_kbits());
EncodeString(&policy, key::kDeviceOpenNetworkConfiguration, kString);
EXPECT_EQ(kString,
policy.open_network_configuration().open_network_configuration());
//
// Reporting policies.
//
EncodeBoolean(&policy, key::kReportDeviceVersionInfo, kBool);
EXPECT_EQ(kBool, policy.device_reporting().report_version_info());
EncodeBoolean(&policy, key::kReportDeviceActivityTimes, kBool);
EXPECT_EQ(kBool, policy.device_reporting().report_activity_times());
EncodeBoolean(&policy, key::kReportDeviceBootMode, kBool);
EXPECT_EQ(kBool, policy.device_reporting().report_boot_mode());
EncodeBoolean(&policy, key::kReportDeviceLocation, kBool);
EXPECT_EQ(kBool, policy.device_reporting().report_location());
EncodeBoolean(&policy, key::kReportDeviceNetworkInterfaces, kBool);
EXPECT_EQ(kBool, policy.device_reporting().report_network_interfaces());
EncodeBoolean(&policy, key::kReportDeviceUsers, kBool);
EXPECT_EQ(kBool, policy.device_reporting().report_users());
EncodeBoolean(&policy, key::kReportDeviceHardwareStatus, kBool);
EXPECT_EQ(kBool, policy.device_reporting().report_hardware_status());
EncodeBoolean(&policy, key::kReportDeviceSessionStatus, kBool);
EXPECT_EQ(kBool, policy.device_reporting().report_session_status());
EncodeBoolean(&policy, key::kReportUploadFrequency, kBool);
EXPECT_EQ(kBool, policy.device_reporting().device_status_frequency());
EncodeBoolean(&policy, key::kHeartbeatEnabled, kBool);
EXPECT_EQ(kBool, policy.device_heartbeat_settings().heartbeat_enabled());
EncodeInteger(&policy, key::kHeartbeatFrequency, kInt);
EXPECT_EQ(kInt, policy.device_heartbeat_settings().heartbeat_frequency());
EncodeBoolean(&policy, key::kLogUploadEnabled, kBool);
EXPECT_EQ(kBool,
policy.device_log_upload_settings().system_log_upload_enabled());
//
// Auto update policies.
//
EncodeString(&policy, key::kChromeOsReleaseChannel, kString);
EXPECT_EQ(kString, policy.release_channel().release_channel());
EncodeBoolean(&policy, key::kChromeOsReleaseChannelDelegated, kBool);
EXPECT_EQ(kBool, policy.release_channel().release_channel_delegated());
EncodeBoolean(&policy, key::kDeviceAutoUpdateDisabled, kBool);
EXPECT_EQ(kBool, policy.auto_update_settings().update_disabled());
EncodeString(&policy, key::kDeviceTargetVersionPrefix, kString);
EXPECT_EQ(kString, policy.auto_update_settings().target_version_prefix());
EncodeInteger(&policy, key::kDeviceUpdateScatterFactor, kInt);
EXPECT_EQ(kInt, policy.auto_update_settings().scatter_factor_in_seconds());
// The encoder of this policy converts connection type strings to enums.
std::vector<std::string> str_types;
std::vector<int> enum_types;
for (size_t n = 0; n < kConnectionTypesSize; ++n) {
str_types.push_back(kConnectionTypes[n].first);
enum_types.push_back(kConnectionTypes[n].second);
}
EncodeStringList(
&policy, key::kDeviceUpdateAllowedConnectionTypes, str_types);
EXPECT_EQ(enum_types,
ToVector(policy.auto_update_settings().allowed_connection_types()));
EncodeBoolean(&policy, key::kDeviceUpdateHttpDownloadsEnabled, kBool);
EXPECT_EQ(kBool, policy.auto_update_settings().http_downloads_enabled());
EncodeBoolean(&policy, key::kRebootAfterUpdate, kBool);
EXPECT_EQ(kBool, policy.auto_update_settings().reboot_after_update());
EncodeBoolean(&policy, key::kDeviceAutoUpdateP2PEnabled, kBool);
EXPECT_EQ(kBool, policy.auto_update_settings().p2p_enabled());
EncodeBoolean(&policy, key::kAllowKioskAppControlChromeVersion, kBool);
EXPECT_EQ(kBool,
policy.allow_kiosk_app_control_chrome_version()
.allow_kiosk_app_control_chrome_version());
//
// Accessibility policies.
//
EncodeBoolean(
&policy, key::kDeviceLoginScreenDefaultLargeCursorEnabled, kBool);
EXPECT_EQ(kBool,
policy.accessibility_settings()
.login_screen_default_large_cursor_enabled());
EncodeBoolean(
&policy, key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled, kBool);
EXPECT_EQ(kBool,
policy.accessibility_settings()
.login_screen_default_spoken_feedback_enabled());
EncodeBoolean(
&policy, key::kDeviceLoginScreenDefaultHighContrastEnabled, kBool);
EXPECT_EQ(kBool,
policy.accessibility_settings()
.login_screen_default_high_contrast_enabled());
// The encoder of this policy converts ints to ScreenMagnifierType enums.
EncodeInteger(&policy,
key::kDeviceLoginScreenDefaultScreenMagnifierType,
em::AccessibilitySettingsProto::SCREEN_MAGNIFIER_TYPE_FULL);
EXPECT_EQ(em::AccessibilitySettingsProto::SCREEN_MAGNIFIER_TYPE_FULL,
policy.accessibility_settings()
.login_screen_default_screen_magnifier_type());
EncodeBoolean(
&policy, key::kDeviceLoginScreenDefaultVirtualKeyboardEnabled, kBool);
EXPECT_EQ(kBool,
policy.accessibility_settings()
.login_screen_default_virtual_keyboard_enabled());
//
// Generic policies.
//
EncodeInteger(&policy, key::kDevicePolicyRefreshRate, kInt);
EXPECT_EQ(kInt,
policy.device_policy_refresh_rate().device_policy_refresh_rate());
EncodeBoolean(&policy, key::kDeviceMetricsReportingEnabled, kBool);
EXPECT_EQ(kBool, policy.metrics_enabled().metrics_enabled());
EncodeString(&policy, key::kSystemTimezone, kString);
EXPECT_EQ(kString, policy.system_timezone().timezone());
// The encoder of this policy converts ints to AutomaticTimezoneDetectionType
// enums.
EncodeInteger(&policy,
key::kSystemTimezoneAutomaticDetection,
em::SystemTimezoneProto::IP_ONLY);
EXPECT_EQ(em::SystemTimezoneProto::IP_ONLY,
policy.system_timezone().timezone_detection_type());
EncodeBoolean(&policy, key::kSystemUse24HourClock, kBool);
EXPECT_EQ(kBool, policy.use_24hour_clock().use_24hour_clock());
EncodeBoolean(
&policy, key::kDeviceAllowRedeemChromeOsRegistrationOffers, kBool);
EXPECT_EQ(kBool, policy.allow_redeem_offers().allow_redeem_offers());
EncodeInteger(&policy, key::kUptimeLimit, kInt);
EXPECT_EQ(kInt, policy.uptime_limit().uptime_limit());
EncodeStringList(&policy, key::kDeviceStartUpFlags, kStringList);
EXPECT_EQ(kStringList, ToVector(policy.start_up_flags().flags()));
EncodeString(&policy, key::kDeviceVariationsRestrictParameter, kString);
EXPECT_EQ(kString, policy.variations_parameter().parameter());
EncodeBoolean(&policy, key::kAttestationEnabledForDevice, kBool);
EXPECT_EQ(kBool, policy.attestation_settings().attestation_enabled());
EncodeBoolean(&policy, key::kAttestationForContentProtectionEnabled, kBool);
EXPECT_EQ(kBool, policy.attestation_settings().content_protection_enabled());
EncodeString(&policy, key::kDeviceLoginScreenPowerManagement, kString);
EXPECT_EQ(
kString,
policy.login_screen_power_management().login_screen_power_management());
EncodeBoolean(&policy, key::kDeviceBlockDevmode, kBool);
EXPECT_EQ(kBool, policy.system_settings().block_devmode());
EncodeInteger(&policy, key::kExtensionCacheSize, kInt);
EXPECT_EQ(kInt, policy.extension_cache_size().extension_cache_size());
EncodeString(&policy, key::kDeviceLoginScreenDomainAutoComplete, kString);
EXPECT_EQ(kString,
policy.login_screen_domain_auto_complete()
.login_screen_domain_auto_complete());
// The encoder of this policy converts ints to Rotation enums.
EncodeInteger(&policy,
key::kDisplayRotationDefault,
em::DisplayRotationDefaultProto::ROTATE_180);
EXPECT_EQ(em::DisplayRotationDefaultProto::ROTATE_180,
policy.display_rotation_default().display_rotation_default());
// The encoder of this policy converts a json string to separate values.
EncodeStringList(&policy,
key::kUsbDetachableWhitelist,
{"{\"vendor_id\":123, \"product_id\":234}",
"{\"vendor_id\":345, \"product_id\":456}"});
const auto& whitelist_proto = policy.usb_detachable_whitelist();
EXPECT_EQ(123, whitelist_proto.id().Get(0).vendor_id());
EXPECT_EQ(234, whitelist_proto.id().Get(0).product_id());
EXPECT_EQ(345, whitelist_proto.id().Get(1).vendor_id());
EXPECT_EQ(456, whitelist_proto.id().Get(1).product_id());
EncodeBoolean(&policy, key::kDeviceQuirksDownloadEnabled, kBool);
EXPECT_EQ(kBool, policy.quirks_download_enabled().quirks_download_enabled());
EncodeString(&policy, key::kDeviceWallpaperImage, kString);
EXPECT_EQ(kString, policy.device_wallpaper_image().device_wallpaper_image());
//
// Check whether all device policies have been handled.
//
std::vector<std::string> unhandled_policy_keys = GetUnhandledPolicyKeys();
EXPECT_TRUE(unhandled_policy_keys.empty())
<< "Unhandled policy detected.\n"
<< "Please handle the following policies in "
<< "device_policy_encoder.cc and device_policy_encoder_unittest.cc:\n"
<< " " << base::JoinString(unhandled_policy_keys, "\n ");
}
} // namespace policy