Commit 0a677f3b authored by Rohit Rao's avatar Rohit Rao Committed by Commit Bot

[ios] Modifies PolicyLoaderIOS to match MDM formatting expectations.

Previous versions of Chrome (M48 and earlier) looked for policy data
under the "ChromePolicy" key, but current MDM vendors do not support
placing policy data in a child dictionary.  This CL updates
PolicyLoaderIOS to read policy data from the top-level dictionary.  In
order to prevent existing configurations from taking effect as we enable
policy support, this CL also adds the requirement that an
"EnableTrustedTesterSupport" key be present and set to true, or else
PolicyLoaderIOS will not load any policy data, even if data is present
in the configuration dictionary.

This CL adds EG tests to verify that policy data is ignored when
the required key is not set.  It also splits the existing tests into
two files and simplifies how policy data is passed on the command line.

BUG=1065261

Change-Id: I4434b863dc9c52e3312c91365487a1fb05dc028e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2123408
Commit-Queue: Rohit Rao <rohitrao@chromium.org>
Reviewed-by: default avatarOwen Min <zmin@chromium.org>
Reviewed-by: default avatarGuillaume Jenkins <gujen@google.com>
Cr-Commit-Position: refs/heads/master@{#755137}
parent d2704a7a
...@@ -265,6 +265,7 @@ jumbo_source_set("internal") { ...@@ -265,6 +265,7 @@ jumbo_source_set("internal") {
"policy_loader_ios.mm", "policy_loader_ios.mm",
] ]
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
frameworks += [ "Foundation.framework" ]
} }
} }
} }
...@@ -351,6 +352,15 @@ source_set("common_constants") { ...@@ -351,6 +352,15 @@ source_set("common_constants") {
"policy_switches.h", "policy_switches.h",
"policy_types.h", "policy_types.h",
] ]
if (is_ios) {
sources += [
"policy_loader_ios_constants.h",
"policy_loader_ios_constants.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
frameworks = [ "Foundation.framework" ]
}
} }
source_set("unit_tests") { source_set("unit_tests") {
...@@ -432,6 +442,7 @@ source_set("unit_tests") { ...@@ -432,6 +442,7 @@ source_set("unit_tests") {
} }
deps = [ deps = [
":common_constants",
":test_support", ":test_support",
"//base", "//base",
"//base/test:test_support", "//base/test:test_support",
......
...@@ -11,10 +11,13 @@ ...@@ -11,10 +11,13 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#import "base/mac/foundation_util.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/strings/sys_string_conversions.h"
#include "components/policy/core/common/mac_util.h" #include "components/policy/core/common/mac_util.h"
#include "components/policy/core/common/policy_bundle.h" #include "components/policy/core/common/policy_bundle.h"
#import "components/policy/core/common/policy_loader_ios_constants.h"
#include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_namespace.h" #include "components/policy/core/common/policy_namespace.h"
#include "components/policy/policy_constants.h" #include "components/policy/policy_constants.h"
...@@ -30,20 +33,6 @@ ...@@ -30,20 +33,6 @@
// "Extending Your Apps for Enterprise and Education Use": // "Extending Your Apps for Enterprise and Education Use":
// https://developer.apple.com/videos/wwdc/2013/?id=301 // https://developer.apple.com/videos/wwdc/2013/?id=301
namespace {
// Key in the NSUserDefaults that contains the managed app configuration.
NSString* const kConfigurationKey = @"com.apple.configuration.managed";
// Key in the managed app configuration that contains the Chrome policy.
NSString* const kChromePolicyKey = @"ChromePolicy";
// Key in the managed app configuration that contains the encoded Chrome policy.
// This is a serialized Property List, encoded in base 64.
NSString* const kEncodedChromePolicyKey = @"EncodedChromePolicy";
} // namespace
// Helper that observes notifications for NSUserDefaults and triggers an update // Helper that observes notifications for NSUserDefaults and triggers an update
// at the loader on the right thread. // at the loader on the right thread.
@interface PolicyNotificationObserver : NSObject { @interface PolicyNotificationObserver : NSObject {
...@@ -114,40 +103,17 @@ void PolicyLoaderIOS::InitOnBackgroundThread() { ...@@ -114,40 +103,17 @@ void PolicyLoaderIOS::InitOnBackgroundThread() {
std::unique_ptr<PolicyBundle> PolicyLoaderIOS::Load() { std::unique_ptr<PolicyBundle> PolicyLoaderIOS::Load() {
std::unique_ptr<PolicyBundle> bundle(new PolicyBundle()); std::unique_ptr<PolicyBundle> bundle(new PolicyBundle());
NSDictionary* configuration = [[NSUserDefaults standardUserDefaults] NSDictionary* configuration = [[NSUserDefaults standardUserDefaults]
dictionaryForKey:kConfigurationKey]; dictionaryForKey:kPolicyLoaderIOSConfigurationKey];
id chromePolicy = configuration[kChromePolicyKey];
id encodedChromePolicy = configuration[kEncodedChromePolicyKey]; // Policies are ignored entirely unless kPolicyLoaderIOSLoadPolicyKey is
// present and evaluates to true. This speed bump will prevent any existing
if (chromePolicy && [chromePolicy isKindOfClass:[NSDictionary class]]) { // policy configurations from taking effect unless a domain administrator
LoadNSDictionaryToPolicyBundle(chromePolicy, bundle.get()); // explicitly opts in, minimizing end-user surprise as new policies are added
// on iOS.
if (encodedChromePolicy) NSNumber* loadPolicy = base::mac::ObjCCast<NSNumber>(
NSLog(@"Ignoring EncodedChromePolicy because ChromePolicy is present."); configuration[kPolicyLoaderIOSLoadPolicyKey]);
} else if (encodedChromePolicy && if (loadPolicy && [loadPolicy boolValue] == YES) {
[encodedChromePolicy isKindOfClass:[NSString class]]) { LoadNSDictionaryToPolicyBundle(configuration, bundle.get());
NSData* data =
[[NSData alloc] initWithBase64EncodedString:encodedChromePolicy
options:0];
if (!data) {
NSLog(@"Invalid Base64 encoding of EncodedChromePolicy");
} else {
NSError* error = nil;
NSDictionary* properties = [NSPropertyListSerialization
propertyListWithData:data
options:NSPropertyListImmutable
format:NULL
error:&error];
if (error) {
NSLog(@"Invalid property list in EncodedChromePolicy: %@", error);
} else if (!properties) {
NSLog(@"Failed to deserialize a valid Property List");
} else if (![properties isKindOfClass:[NSDictionary class]]) {
NSLog(@"Invalid property list in EncodedChromePolicy: expected an "
"NSDictionary but found %@", [properties class]);
} else {
LoadNSDictionaryToPolicyBundle(properties, bundle.get());
}
}
} }
const PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, std::string()); const PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, std::string());
...@@ -179,6 +145,10 @@ void PolicyLoaderIOS::LoadNSDictionaryToPolicyBundle(NSDictionary* dictionary, ...@@ -179,6 +145,10 @@ void PolicyLoaderIOS::LoadNSDictionaryToPolicyBundle(NSDictionary* dictionary,
PropertyToValue((__bridge CFPropertyListRef)(dictionary)); PropertyToValue((__bridge CFPropertyListRef)(dictionary));
base::DictionaryValue* dict = NULL; base::DictionaryValue* dict = NULL;
if (value && value->GetAsDictionary(&dict)) { if (value && value->GetAsDictionary(&dict)) {
// Remove kPolicyLoaderIOSLoadPolicyKey before loading policies.
DCHECK(dict);
dict->RemoveKey(base::SysNSStringToUTF8(kPolicyLoaderIOSLoadPolicyKey));
PolicyMap& map = bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); PolicyMap& map = bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
map.LoadFrom(dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, map.LoadFrom(dict, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
POLICY_SOURCE_PLATFORM); POLICY_SOURCE_PLATFORM);
......
// Copyright 2020 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 COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_IOS_CONSTANTS_H_
#define COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_IOS_CONSTANTS_H_
#import <Foundation/Foundation.h>
// Key in NSUserDefaults that contains the managed app configuration.
extern NSString* const kPolicyLoaderIOSConfigurationKey;
// Key that controls whether policy data is loaded from NSUserDefaults.
extern NSString* const kPolicyLoaderIOSLoadPolicyKey;
#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_LOADER_IOS_CONSTANTS_H_
// Copyright 2020 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.
#import "components/policy/core/common/policy_loader_ios_constants.h"
NSString* const kPolicyLoaderIOSConfigurationKey =
@"com.apple.configuration.managed";
NSString* const kPolicyLoaderIOSLoadPolicyKey = @"EnableTrustedTesterSupport";
...@@ -19,10 +19,12 @@ ...@@ -19,10 +19,12 @@
#include "components/policy/core/common/async_policy_provider.h" #include "components/policy/core/common/async_policy_provider.h"
#include "components/policy/core/common/configuration_policy_provider_test.h" #include "components/policy/core/common/configuration_policy_provider_test.h"
#include "components/policy/core/common/policy_bundle.h" #include "components/policy/core/common/policy_bundle.h"
#import "components/policy/core/common/policy_loader_ios_constants.h"
#include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_test_utils.h" #include "components/policy/core/common/policy_test_utils.h"
#include "components/policy/core/common/policy_types.h" #include "components/policy/core/common/policy_types.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
...@@ -32,14 +34,21 @@ namespace policy { ...@@ -32,14 +34,21 @@ namespace policy {
namespace { namespace {
// Key in the NSUserDefaults that contains the managed app configuration. // Creates a new PolicyLoaderIOS and verifies that it does not load any
NSString* const kConfigurationKey = @"com.apple.configuration.managed"; // policies.
void VerifyNoPoliciesAreLoaded() {
PolicyBundle empty;
scoped_refptr<base::TestSimpleTaskRunner> taskRunner =
new base::TestSimpleTaskRunner();
PolicyLoaderIOS loader(taskRunner);
std::unique_ptr<PolicyBundle> bundle = loader.Load();
ASSERT_TRUE(bundle);
EXPECT_TRUE(bundle->Equals(empty));
}
class TestHarness : public PolicyProviderTestHarness { class TestHarness : public PolicyProviderTestHarness {
public: public:
// If |use_encoded_key| is true then AddPolicies() serializes and encodes TestHarness();
// the policies, and publishes them under the EncodedChromePolicy key.
explicit TestHarness(bool use_encoded_key);
~TestHarness() override; ~TestHarness() override;
void SetUp() override; void SetUp() override;
...@@ -62,34 +71,35 @@ class TestHarness : public PolicyProviderTestHarness { ...@@ -62,34 +71,35 @@ class TestHarness : public PolicyProviderTestHarness {
const base::DictionaryValue* policy_value) override; const base::DictionaryValue* policy_value) override;
static PolicyProviderTestHarness* Create(); static PolicyProviderTestHarness* Create();
static PolicyProviderTestHarness* CreateWithEncodedKey();
private: private:
// Merges the policies in |policy| into the current policy dictionary // Merges the policies in |policy| into the current policy dictionary
// in NSUserDefaults, after making sure that the policy dictionary // in NSUserDefaults, after making sure that the policy dictionary
// exists. // exists.
void AddPolicies(NSDictionary* policy); void AddPolicies(NSDictionary* policy);
void AddChromePolicy(NSDictionary* policy);
void AddEncodedChromePolicy(NSDictionary* policy);
bool use_encoded_key_;
DISALLOW_COPY_AND_ASSIGN(TestHarness); DISALLOW_COPY_AND_ASSIGN(TestHarness);
}; };
TestHarness::TestHarness(bool use_encoded_key) TestHarness::TestHarness()
: PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY,
POLICY_SOURCE_PLATFORM), POLICY_SCOPE_MACHINE,
use_encoded_key_(use_encoded_key) {} POLICY_SOURCE_PLATFORM) {}
TestHarness::~TestHarness() { TestHarness::~TestHarness() {
// Cleanup any policies left from the test. // Cleanup any policies left from the test.
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kConfigurationKey]; [[NSUserDefaults standardUserDefaults]
removeObjectForKey:kPolicyLoaderIOSConfigurationKey];
} }
void TestHarness::SetUp() { void TestHarness::SetUp() {
// Make sure there is no pre-existing policy present. // Make sure there is no pre-existing policy present. Ensure that
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kConfigurationKey]; // kPolicyLoaderIOSLoadPolicyKey is set, or else the loader won't load any
// policy data.
NSDictionary* policy = @{kPolicyLoaderIOSLoadPolicyKey : @YES};
[[NSUserDefaults standardUserDefaults]
setObject:policy
forKey:kPolicyLoaderIOSConfigurationKey];
} }
ConfigurationPolicyProvider* TestHarness::CreateProvider( ConfigurationPolicyProvider* TestHarness::CreateProvider(
...@@ -147,71 +157,23 @@ void TestHarness::InstallDictionaryPolicy( ...@@ -147,71 +157,23 @@ void TestHarness::InstallDictionaryPolicy(
// static // static
PolicyProviderTestHarness* TestHarness::Create() { PolicyProviderTestHarness* TestHarness::Create() {
return new TestHarness(false); return new TestHarness();
}
// static
PolicyProviderTestHarness* TestHarness::CreateWithEncodedKey() {
return new TestHarness(true);
} }
void TestHarness::AddPolicies(NSDictionary* policy) { void TestHarness::AddPolicies(NSDictionary* policy) {
if (use_encoded_key_)
AddEncodedChromePolicy(policy);
else
AddChromePolicy(policy);
}
void TestHarness::AddChromePolicy(NSDictionary* policy) {
NSString* key = @"ChromePolicy";
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary* chromePolicy = [[NSMutableDictionary alloc] init];
NSDictionary* previous = [defaults dictionaryForKey:key];
if (previous)
[chromePolicy addEntriesFromDictionary:previous];
[chromePolicy addEntriesFromDictionary:policy];
NSDictionary* wrapper = @{
key: chromePolicy
};
[[NSUserDefaults standardUserDefaults] setObject:wrapper
forKey:kConfigurationKey];
}
void TestHarness::AddEncodedChromePolicy(NSDictionary* policy) {
NSString* key = @"EncodedChromePolicy";
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary* chromePolicy = [[NSMutableDictionary alloc] init]; NSMutableDictionary* chromePolicy = [[NSMutableDictionary alloc] init];
NSString* previous = [defaults stringForKey:key]; NSDictionary* previous =
[defaults dictionaryForKey:kPolicyLoaderIOSConfigurationKey];
if (previous) { if (previous) {
NSData* data = [[NSData alloc] initWithBase64EncodedString:previous [chromePolicy addEntriesFromDictionary:previous];
options:0];
NSDictionary* properties = [NSPropertyListSerialization
propertyListWithData:data
options:NSPropertyListImmutable
format:NULL
error:NULL];
[chromePolicy addEntriesFromDictionary:properties];
} }
[chromePolicy addEntriesFromDictionary:policy]; [chromePolicy addEntriesFromDictionary:policy];
[[NSUserDefaults standardUserDefaults]
NSData* data = [NSPropertyListSerialization setObject:chromePolicy
dataWithPropertyList:chromePolicy forKey:kPolicyLoaderIOSConfigurationKey];
format:NSPropertyListXMLFormat_v1_0
options:0
error:NULL];
NSString* encoded = [data base64EncodedStringWithOptions:0];
NSDictionary* wrapper = @{
key: encoded
};
[[NSUserDefaults standardUserDefaults] setObject:wrapper
forKey:kConfigurationKey];
} }
} // namespace } // namespace
...@@ -220,54 +182,35 @@ INSTANTIATE_TEST_SUITE_P(PolicyProviderIOSChromePolicyTest, ...@@ -220,54 +182,35 @@ INSTANTIATE_TEST_SUITE_P(PolicyProviderIOSChromePolicyTest,
ConfigurationPolicyProviderTest, ConfigurationPolicyProviderTest,
testing::Values(TestHarness::Create)); testing::Values(TestHarness::Create));
INSTANTIATE_TEST_SUITE_P(PolicyProviderIOSEncodedChromePolicyTest, using PolicyLoaderIOSTest = PlatformTest;
ConfigurationPolicyProviderTest,
testing::Values(TestHarness::CreateWithEncodedKey));
TEST(PolicyProviderIOSTest, ChromePolicyOverEncodedChromePolicy) {
// This test verifies that if the "ChromePolicy" key is present then the
// "EncodedChromePolicy" key is ignored.
// Verifies that policies are not loaded if kPolicyLoaderIOSLoadPolicyKey is not
// present.
TEST_F(PolicyLoaderIOSTest, NoPoliciesLoadedWithoutLoadPolicyKey) {
NSDictionary* policy = @{ NSDictionary* policy = @{
@"shared": @"wrong", @"shared": @"wrong",
@"key1": @"value1", @"key1": @"value1",
}; };
NSData* data = [NSPropertyListSerialization [[NSUserDefaults standardUserDefaults]
dataWithPropertyList:policy setObject:policy
format:NSPropertyListXMLFormat_v1_0 forKey:kPolicyLoaderIOSConfigurationKey];
options:0
error:NULL];
NSString* encodedChromePolicy = [data base64EncodedStringWithOptions:0];
NSDictionary* chromePolicy = @{
@"shared": @"right",
@"key2": @"value2",
};
NSDictionary* wrapper = @{ VerifyNoPoliciesAreLoaded();
@"ChromePolicy": chromePolicy, }
@"EncodedChromePolicy": encodedChromePolicy,
};
[[NSUserDefaults standardUserDefaults] setObject:wrapper
forKey:kConfigurationKey];
PolicyBundle expected; // Verifies that policies are not loaded if kPolicyLoaderIOSLoadPolicyKey is set
PolicyMap& expectedMap = // to false.
expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")); TEST_F(PolicyLoaderIOSTest, NoPoliciesLoadedWhenEnableChromeKeyIsFalse) {
expectedMap.Set("shared", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, NSDictionary* policy = @{
POLICY_SOURCE_PLATFORM, kPolicyLoaderIOSLoadPolicyKey : @NO,
std::make_unique<base::Value>("right"), nullptr); @"shared" : @"wrong",
expectedMap.Set("key2", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, @"key1" : @"value1",
POLICY_SOURCE_PLATFORM, };
std::make_unique<base::Value>("value2"), nullptr); [[NSUserDefaults standardUserDefaults]
setObject:policy
forKey:kPolicyLoaderIOSConfigurationKey];
scoped_refptr<base::TestSimpleTaskRunner> taskRunner = VerifyNoPoliciesAreLoaded();
new base::TestSimpleTaskRunner();
PolicyLoaderIOS loader(taskRunner);
std::unique_ptr<PolicyBundle> bundle = loader.Load();
ASSERT_TRUE(bundle);
EXPECT_TRUE(bundle->Equals(expected));
} }
} // namespace policy } // namespace policy
...@@ -96,12 +96,15 @@ source_set("eg2_tests") { ...@@ -96,12 +96,15 @@ source_set("eg2_tests") {
testonly = true testonly = true
sources = [ sources = [
"policy_app_interface.h",
"policy_app_interface_stub.mm",
"policy_egtest.mm", "policy_egtest.mm",
"policy_egtest_app_interface.h", "policy_platform_provider_egtest.mm",
] ]
deps = [ deps = [
"//base", "//base",
"//components/policy/core/common:common_constants",
"//components/strings", "//components/strings",
"//ios/chrome/browser:pref_names", "//ios/chrome/browser:pref_names",
"//ios/chrome/browser:utils", "//ios/chrome/browser:utils",
...@@ -119,8 +122,8 @@ source_set("eg_app_support+eg2") { ...@@ -119,8 +122,8 @@ source_set("eg_app_support+eg2") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
testonly = true testonly = true
sources = [ sources = [
"policy_egtest_app_interface.h", "policy_app_interface.h",
"policy_egtest_app_interface.mm", "policy_app_interface.mm",
] ]
deps = [ deps = [
":policy", ":policy",
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_POLICY_POLICY_EGTEST_APP_INTERFACE_H_ #ifndef IOS_CHROME_BROWSER_POLICY_POLICY_APP_INTERFACE_H_
#define IOS_CHROME_BROWSER_POLICY_POLICY_EGTEST_APP_INTERFACE_H_ #define IOS_CHROME_BROWSER_POLICY_POLICY_APP_INTERFACE_H_
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface PolicyEGTestAppInterface : NSObject @interface PolicyAppInterface : NSObject
// Returns a JSON-encoded representation of the value for the given |policyKey|. // Returns a JSON-encoded representation of the value for the given |policyKey|.
// Looks for the policy in the platform policy provider under the CHROME policy // Looks for the policy in the platform policy provider under the CHROME policy
...@@ -22,4 +22,4 @@ ...@@ -22,4 +22,4 @@
@end @end
#endif // IOS_CHROME_BROWSER_POLICY_POLICY_EGTEST_APP_INTERFACE_H_ #endif // IOS_CHROME_BROWSER_POLICY_POLICY_APP_INTERFACE_H_
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#import "ios/chrome/browser/policy/policy_egtest_app_interface.h" #import "ios/chrome/browser/policy/policy_app_interface.h"
#include "base/json/json_string_value_serializer.h" #include "base/json/json_string_value_serializer.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
...@@ -42,7 +42,7 @@ NSString* SerializedValue(const base::Value* value) { ...@@ -42,7 +42,7 @@ NSString* SerializedValue(const base::Value* value) {
} }
@implementation PolicyEGTestAppInterface @implementation PolicyAppInterface
+ (NSString*)valueForPlatformPolicy:(NSString*)policyKey { + (NSString*)valueForPlatformPolicy:(NSString*)policyKey {
const std::string key = base::SysNSStringToUTF8(policyKey); const std::string key = base::SysNSStringToUTF8(policyKey);
......
// Copyright 2020 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.
#import "ios/chrome/browser/policy/policy_app_interface.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// TODO(crbug.com/1015113): This macro breaks Xcode indexing unless it is placed
// at the bottom of the file or followed by a semicolon.
GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(PolicyAppInterface)
...@@ -4,39 +4,19 @@ ...@@ -4,39 +4,19 @@
#include "ios/testing/earl_grey/earl_grey_test.h" #include "ios/testing/earl_grey/earl_grey_test.h"
#include <memory>
#include "base/json/json_string_value_serializer.h"
#include "base/strings/sys_string_conversions.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/browser/chrome_switches.h"
#import "ios/chrome/browser/policy/policy_egtest_app_interface.h" #import "ios/chrome/browser/policy/policy_app_interface.h"
#include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/pref_names.h"
#include "ios/chrome/test/earl_grey/chrome_earl_grey.h" #include "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#include "ios/chrome/test/earl_grey/chrome_test_case.h" #include "ios/chrome/test/earl_grey/chrome_test_case.h"
#include "ios/testing/earl_grey/app_launch_configuration.h" #include "ios/testing/earl_grey/app_launch_configuration.h"
#include "ios/testing/earl_grey/app_launch_manager.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
namespace {
// Returns the value of a given policy, looked up in the current platform policy
// provider.
std::unique_ptr<base::Value> GetPlatformPolicy(const std::string& key) {
std::string json_representation =
base::SysNSStringToUTF8([PolicyEGTestAppInterface
valueForPlatformPolicy:base::SysUTF8ToNSString(key)]);
JSONStringValueDeserializer deserializer(json_representation);
return deserializer.Deserialize(/*error_code=*/nullptr,
/*error_message=*/nullptr);
}
} // namespace
// Test case to verify that enterprise policies are set and respected. // Test case to verify that enterprise policies are set and respected.
@interface PolicyTestCase : ChromeTestCase @interface PolicyTestCase : ChromeTestCase
@end @end
...@@ -74,76 +54,14 @@ std::unique_ptr<base::Value> GetPlatformPolicy(const std::string& key) { ...@@ -74,76 +54,14 @@ std::unique_ptr<base::Value> GetPlatformPolicy(const std::string& key) {
@"Unexpected default value"); @"Unexpected default value");
// Force the preference off via policy. // Force the preference off via policy.
[PolicyEGTestAppInterface setSuggestPolicyEnabled:NO]; [PolicyAppInterface setSuggestPolicyEnabled:NO];
GREYAssertFalse([ChromeEarlGrey userBooleanPref:prefs::kSearchSuggestEnabled], GREYAssertFalse([ChromeEarlGrey userBooleanPref:prefs::kSearchSuggestEnabled],
@"Search suggest preference was unexpectedly true"); @"Search suggest preference was unexpectedly true");
// Force the preference on via policy. // Force the preference on via policy.
[PolicyEGTestAppInterface setSuggestPolicyEnabled:YES]; [PolicyAppInterface setSuggestPolicyEnabled:YES];
GREYAssertTrue([ChromeEarlGrey userBooleanPref:prefs::kSearchSuggestEnabled], GREYAssertTrue([ChromeEarlGrey userBooleanPref:prefs::kSearchSuggestEnabled],
@"Search suggest preference was unexpectedly false"); @"Search suggest preference was unexpectedly false");
} }
@end @end
// Test case that uses the production platform policy provider.
@interface PolicyPlatformProviderTestCase : ChromeTestCase
@end
@implementation PolicyPlatformProviderTestCase
- (AppLaunchConfiguration)appConfigurationForTestCase {
AppLaunchConfiguration config;
config.additional_args.push_back(std::string("--") +
switches::kEnableEnterprisePolicy);
// Commandline flags that start with a single "-" are automatically added to
// the NSArgumentDomain in NSUserDefaults. Set fake policy data that can be
// read by the production platform policy provider.
config.additional_args.push_back("-com.apple.configuration.managed");
config.additional_args.push_back("{ChromePolicy={"
"DefaultSearchProviderName=Test;"
"NotARegisteredPolicy=Unknown;"
"};}");
config.relaunch_policy = NoForceRelaunchAndResetState;
return config;
}
// Tests that policies are properly loaded from NSUserDefaults when using the
// production platform policy provider.
// Tests the value of a policy that was explicitly set.
- (void)testProductionPlatformProviderPolicyExplicitlySet {
std::unique_ptr<base::Value> searchValue =
GetPlatformPolicy("DefaultSearchProviderName");
GREYAssertTrue(searchValue && searchValue->is_string(),
@"searchSuggestValue was not of type string");
GREYAssertEqual(searchValue->GetString(), "Test",
@"searchSuggestValue had an unexpected value");
}
// Test the value of a policy that exists in the schema but was not explicitly
// set.
- (void)testProductionPlatformProviderPolicyNotSet {
std::unique_ptr<base::Value> blocklistValue =
GetPlatformPolicy("URLBlacklist");
GREYAssertTrue(blocklistValue && blocklistValue->is_none(),
@"blocklistValue was unexpectedly present");
}
// Test the value of a policy that was set in the configuration but is unknown
// to the policy system.
- (void)testProductionPlatformProviderPolicyUnknown {
std::unique_ptr<base::Value> unknownValue =
GetPlatformPolicy("NotARegisteredPolicy");
GREYAssertTrue(unknownValue && unknownValue->is_string(),
@"unknownValue was not of type string");
GREYAssertEqual(unknownValue->GetString(), "Unknown",
@"unknownValue had an unexpected value");
}
@end
// TODO(crbug.com/1015113): This macro breaks Xcode indexing unless it is placed
// at the bottom of the file or followed by a semicolon.
GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(PolicyEGTestAppInterface)
// Copyright 2020 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 "ios/testing/earl_grey/earl_grey_test.h"
#include <memory>
#include "base/json/json_string_value_serializer.h"
#include "base/strings/sys_string_conversions.h"
#import "components/policy/core/common/policy_loader_ios_constants.h"
#include "ios/chrome/browser/chrome_switches.h"
#import "ios/chrome/browser/policy/policy_app_interface.h"
#include "ios/chrome/browser/pref_names.h"
#include "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#include "ios/chrome/test/earl_grey/chrome_test_case.h"
#include "ios/testing/earl_grey/app_launch_configuration.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Returns the value of a given policy, looked up in the current platform policy
// provider.
std::unique_ptr<base::Value> GetPlatformPolicy(const std::string& key) {
std::string json_representation = base::SysNSStringToUTF8(
[PolicyAppInterface valueForPlatformPolicy:base::SysUTF8ToNSString(key)]);
JSONStringValueDeserializer deserializer(json_representation);
return deserializer.Deserialize(/*error_code=*/nullptr,
/*error_message=*/nullptr);
}
// Returns an AppLaunchConfiguration containing the given policy data.
// |policyData| must be in XML format.
AppLaunchConfiguration GenerateAppLaunchConfiguration(std::string policy_data) {
AppLaunchConfiguration config;
config.additional_args.push_back(std::string("--") +
switches::kEnableEnterprisePolicy);
// Remove whitespace from the policy data, because the XML parser does not
// tolerate newlines.
base::RemoveChars(policy_data, base::kWhitespaceASCII, &policy_data);
// Commandline flags that start with a single "-" are automatically added to
// the NSArgumentDomain in NSUserDefaults. Set fake policy data that can be
// read by the production platform policy provider.
config.additional_args.push_back(
"-" + base::SysNSStringToUTF8(kPolicyLoaderIOSConfigurationKey));
config.additional_args.push_back(policy_data);
config.relaunch_policy = NoForceRelaunchAndResetState;
return config;
}
} // namespace
// Test case that uses the production platform policy provider.
@interface PolicyPlatformProviderTestCase : ChromeTestCase
@end
@implementation PolicyPlatformProviderTestCase
- (AppLaunchConfiguration)appConfigurationForTestCase {
const std::string loadPolicyKey =
base::SysNSStringToUTF8(kPolicyLoaderIOSLoadPolicyKey);
std::string policyData = "<dict>"
" <key>" +
loadPolicyKey +
"</key>"
" <true/>"
" <key>DefaultSearchProviderName</key>"
" <string>Test</string>"
" <key>NotARegisteredPolicy</key>"
" <string>Unknown</string>"
" <key>SearchSuggestEnabled</key>"
" <false/>"
"</dict>";
return GenerateAppLaunchConfiguration(policyData);
}
// Tests the values of policies that were explicitly set.
- (void)testPolicyExplicitlySet {
std::unique_ptr<base::Value> searchValue =
GetPlatformPolicy("DefaultSearchProviderName");
GREYAssertTrue(searchValue && searchValue->is_string(),
@"searchValue was not of type string");
GREYAssertEqual(searchValue->GetString(), "Test",
@"searchValue had an unexpected value");
std::unique_ptr<base::Value> suggestValue =
GetPlatformPolicy("SearchSuggestEnabled");
GREYAssertTrue(suggestValue && suggestValue->is_bool(),
@"suggestValue was not of type bool");
GREYAssertFalse(suggestValue->GetBool(),
@"suggestValue had an unexpected value");
}
// Test the value of a policy that exists in the schema but was not explicitly
// set.
- (void)testPolicyNotSet {
std::unique_ptr<base::Value> blocklistValue =
GetPlatformPolicy("URLBlacklist");
GREYAssertTrue(blocklistValue && blocklistValue->is_none(),
@"blocklistValue was unexpectedly present");
}
// Test the value of a policy that was set in the configuration but is unknown
// to the policy system.
- (void)testPolicyUnknown {
std::unique_ptr<base::Value> unknownValue =
GetPlatformPolicy("NotARegisteredPolicy");
GREYAssertTrue(unknownValue && unknownValue->is_string(),
@"unknownValue was not of type string");
GREYAssertEqual(unknownValue->GetString(), "Unknown",
@"unknownValue had an unexpected value");
}
// Verifies that the kPolicyLoaderIOSLoadPolicyKey field is not loaded, even
// though it is present in the policy data.
- (void)testLoadPolicyKeyIsStripped {
std::unique_ptr<base::Value> loadValue =
GetPlatformPolicy(base::SysNSStringToUTF8(kPolicyLoaderIOSLoadPolicyKey));
GREYAssertTrue(loadValue && loadValue->is_none(),
@"The LoadPolicy key was unexpectedly present in policy data");
}
@end
// Test case that uses the production platform policy provider but does not pass
// the special key that enables policy support.
@interface PolicyNotEnabledTestCase : ChromeTestCase
@end
@implementation PolicyNotEnabledTestCase
- (AppLaunchConfiguration)appConfigurationForTestCase {
std::string policyData = "<dict>"
" <key>DefaultSearchProviderName</key>"
" <string>Test</string>"
"</dict>";
return GenerateAppLaunchConfiguration(policyData);
}
// Tests that policies are not loaded unless kPolicyLoaderIOSLoadPolicyKey is
// set.
- (void)testLoadPolicyKeyNotSet {
std::unique_ptr<base::Value> searchValue =
GetPlatformPolicy("DefaultSearchProviderName");
GREYAssertTrue(searchValue && searchValue->is_none(),
@"searchValue was unexpectedly present");
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment