aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdolfo Victoria <adokar@google.com>2018-06-12 16:28:36 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-07-18 18:15:27 -0700
commit2d3967d969318f3041c766f377eed2ef88a613af (patch)
treee219722c6223e9d2e9e4e65f961af58ff1da25a8
parent4f500daeeff106af163421a2c13f7f33fe627393 (diff)
downloadplatform_external_libbrillo-2d3967d969318f3041c766f377eed2ef88a613af.tar.gz
platform_external_libbrillo-2d3967d969318f3041c766f377eed2ef88a613af.tar.bz2
platform_external_libbrillo-2d3967d969318f3041c766f377eed2ef88a613af.zip
libbrillo: policy: Add new update time restrictions policy
Add a new device policy from chrome_device_policy.proto: DeviceAutoUpdateTimeRestrictions BUG=chromium:852860 TEST=libpolicy unit tests CQ-DEPEND=CL:1136538 Change-Id: Iaef8791f683af00668dcd4041282758cc26b8fbf Reviewed-on: https://chromium-review.googlesource.com/1101707 Commit-Ready: Adolfo Higueros <adokar@google.com> Tested-by: Adolfo Higueros <adokar@google.com> Reviewed-by: Dan Erat <derat@chromium.org>
-rw-r--r--policy/device_policy.h24
-rw-r--r--policy/device_policy_impl.cc106
-rw-r--r--policy/device_policy_impl.h2
-rw-r--r--policy/mock_device_policy.h3
-rw-r--r--policy/tests/libpolicy_unittest.cc17
-rw-r--r--policy/tests/whitelist/policy_allbin938 -> 1203 bytes
6 files changed, 151 insertions, 1 deletions
diff --git a/policy/device_policy.h b/policy/device_policy.h
index b71d9de..52e73d5 100644
--- a/policy/device_policy.h
+++ b/policy/device_policy.h
@@ -12,6 +12,7 @@
#include <vector>
#include <base/macros.h>
+#include <base/time/time.h>
#pragma GCC visibility push(default)
@@ -35,6 +36,22 @@ class DevicePolicy {
uint16_t product_id;
};
+ // Time interval represented by two |day_of_week| and |time| pairs. The start
+ // of the interval is inclusive and the end is exclusive. The time represented
+ // by those pairs will be interpreted to be in the local timezone. Because of
+ // this, there exists the possibility of intervals being repeated or skipped
+ // in a day with daylight savings transitions, this is expected behavior.
+ struct WeeklyTimeInterval {
+ // Value is from 1 to 7 (1 = Monday, 2 = Tuesday, etc.). All values outside
+ // this range are invalid and will be discarded.
+ int start_day_of_week;
+ // Time since the start of the day. This value will be interpreted to be in
+ // the system's current timezone when used for range checking.
+ base::TimeDelta start_time;
+ int end_day_of_week;
+ base::TimeDelta end_time;
+ };
+
DevicePolicy();
virtual ~DevicePolicy();
@@ -178,6 +195,13 @@ class DevicePolicy {
// U2F or U2F_EXTENDED). Returns true on success.
virtual bool GetSecondFactorAuthenticationMode(int* mode_out) const = 0;
+ // Writes the valid time intervals to |intervals_out|. These
+ // intervals are taken from the disallowed time intervals field in the
+ // AutoUpdateSettingsProto. Returns true if the intervals in the proto are
+ // valid.
+ virtual bool GetDisallowedTimeIntervals(
+ std::vector<WeeklyTimeInterval>* intervals_out) const = 0;
+
private:
// Verifies that the policy signature is correct.
virtual bool VerifyPolicySignature() = 0;
diff --git a/policy/device_policy_impl.cc b/policy/device_policy_impl.cc
index 6189ca7..4d506ba 100644
--- a/policy/device_policy_impl.cc
+++ b/policy/device_policy_impl.cc
@@ -8,9 +8,12 @@
#include <base/containers/adapters.h>
#include <base/files/file_util.h>
+#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ptr_util.h>
+#include <base/time/time.h>
+#include <base/values.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
@@ -98,6 +101,50 @@ std::string DecodeConnectionType(int type) {
return kConnectionTypes[type];
}
+// TODO(adokar): change type to base::Optional<int> when available.
+int ConvertDayOfWeekStringToInt(const std::string& day_of_week_str) {
+ if (day_of_week_str == "Sunday") return 0;
+ if (day_of_week_str == "Monday") return 1;
+ if (day_of_week_str == "Tuesday") return 2;
+ if (day_of_week_str == "Wednesday") return 3;
+ if (day_of_week_str == "Thursday") return 4;
+ if (day_of_week_str == "Friday") return 5;
+ if (day_of_week_str == "Saturday") return 6;
+ return -1;
+}
+
+bool DecodeWeeklyTimeFromValue(const base::DictionaryValue& dict_value,
+ int* day_of_week_out,
+ base::TimeDelta* time_out) {
+ std::string day_of_week_str;
+ if (!dict_value.GetString("day_of_week", &day_of_week_str)) {
+ LOG(ERROR) << "Day of the week is absent.";
+ return false;
+ }
+ *day_of_week_out = ConvertDayOfWeekStringToInt(day_of_week_str);
+ if (*day_of_week_out == -1) {
+ LOG(ERROR) << "Undefined day of the week: " << day_of_week_str;
+ return false;
+ }
+
+ int hours;
+ if (!dict_value.GetInteger("hours", &hours) || hours < 0 || hours > 23) {
+ LOG(ERROR) << "Hours are absent or are outside of the range [0, 24).";
+ return false;
+ }
+
+ int minutes;
+ if (!dict_value.GetInteger("minutes", &minutes) || minutes < 0 ||
+ minutes > 59) {
+ LOG(ERROR) << "Minutes are absent or are outside the range [0, 60)";
+ return false;
+ }
+
+ *time_out =
+ base::TimeDelta::FromMinutes(minutes) + base::TimeDelta::FromHours(hours);
+ return true;
+}
+
} // namespace
DevicePolicyImpl::DevicePolicyImpl()
@@ -510,6 +557,65 @@ bool DevicePolicyImpl::GetSecondFactorAuthenticationMode(int* mode_out) const {
return true;
}
+bool DevicePolicyImpl::GetDisallowedTimeIntervals(
+ std::vector<WeeklyTimeInterval>* intervals_out) const {
+ if (!device_policy_.has_auto_update_settings()) {
+ return false;
+ }
+
+ const em::AutoUpdateSettingsProto& proto =
+ device_policy_.auto_update_settings();
+
+ if (!proto.has_disallowed_time_intervals()) {
+ return false;
+ }
+
+ // Decode the JSON string
+ std::string error;
+ std::unique_ptr<base::Value> decoded_json =
+ base::JSONReader::ReadAndReturnError(proto.disallowed_time_intervals(),
+ base::JSON_ALLOW_TRAILING_COMMAS,
+ NULL, &error);
+ if (!decoded_json) {
+ LOG(ERROR) << "Invalid JSON string " << error;
+ return false;
+ }
+
+ std::unique_ptr<base::ListValue> list_val =
+ base::ListValue::From(std::move(decoded_json));
+ if (!list_val) {
+ LOG(ERROR) << "JSON string is not a list";
+ return false;
+ }
+
+ intervals_out->clear();
+
+ for (const auto& interval_value : *list_val) {
+ base::DictionaryValue* interval_dict;
+ if (!interval_value->GetAsDictionary(&interval_dict)) {
+ LOG(ERROR) << "Invalid JSON string given. Interval is not a dict.";
+ return false;
+ }
+ base::DictionaryValue* start;
+ base::DictionaryValue* end;
+ if (!interval_dict->GetDictionary("start", &start) ||
+ !interval_dict->GetDictionary("end", &end)) {
+ LOG(ERROR) << "Interval is missing start/end.";
+ return false;
+ }
+ WeeklyTimeInterval weekly_interval;
+ if (!DecodeWeeklyTimeFromValue(*start, &weekly_interval.start_day_of_week,
+ &weekly_interval.start_time) ||
+ !DecodeWeeklyTimeFromValue(*end, &weekly_interval.end_day_of_week,
+ &weekly_interval.end_time)) {
+ return false;
+ }
+
+ intervals_out->push_back(weekly_interval);
+ }
+ return true;
+}
+
bool DevicePolicyImpl::VerifyPolicyFile(const base::FilePath& policy_path) {
if (!verify_root_ownership_) {
return true;
diff --git a/policy/device_policy_impl.h b/policy/device_policy_impl.h
index 9ec39ac..ee00f0f 100644
--- a/policy/device_policy_impl.h
+++ b/policy/device_policy_impl.h
@@ -78,6 +78,8 @@ class DevicePolicyImpl : public DevicePolicy {
bool GetAutoLaunchedKioskAppId(std::string* app_id_out) const override;
bool IsEnterpriseManaged() const override;
bool GetSecondFactorAuthenticationMode(int* mode_out) const override;
+ bool GetDisallowedTimeIntervals(
+ std::vector<WeeklyTimeInterval>* intervals_out) const override;
// Methods that can be used only for testing.
void set_policy_data_for_testing(
diff --git a/policy/mock_device_policy.h b/policy/mock_device_policy.h
index eba80f4..2999a18 100644
--- a/policy/mock_device_policy.h
+++ b/policy/mock_device_policy.h
@@ -101,7 +101,8 @@ class MockDevicePolicy : public DevicePolicy {
MOCK_CONST_METHOD1(GetAutoLaunchedKioskAppId, bool(std::string*));
MOCK_CONST_METHOD0(IsEnterpriseManaged, bool());
MOCK_CONST_METHOD1(GetSecondFactorAuthenticationMode, bool(int*));
-
+ MOCK_CONST_METHOD1(GetDisallowedTimeIntervals,
+ bool(std::vector<WeeklyTimeInterval>*));
MOCK_METHOD0(VerifyPolicyFiles, bool(void));
MOCK_METHOD0(VerifyPolicySignature, bool(void));
};
diff --git a/policy/tests/libpolicy_unittest.cc b/policy/tests/libpolicy_unittest.cc
index 384bd69..6fc7258 100644
--- a/policy/tests/libpolicy_unittest.cc
+++ b/policy/tests/libpolicy_unittest.cc
@@ -178,6 +178,21 @@ TEST(PolicyTest, DevicePolicyAllSetTest) {
ASSERT_TRUE(policy.GetSecondFactorAuthenticationMode(&int_value));
EXPECT_EQ(2, int_value);
+ std::vector<DevicePolicy::WeeklyTimeInterval> intervals;
+ ASSERT_TRUE(policy.GetDisallowedTimeIntervals(&intervals));
+ ASSERT_EQ(2, intervals.size());
+ EXPECT_EQ(4, intervals[0].start_day_of_week);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(30) + base::TimeDelta::FromHours(12),
+ intervals[0].start_time);
+ EXPECT_EQ(6, intervals[0].end_day_of_week);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(15) + base::TimeDelta::FromHours(3),
+ intervals[0].end_time);
+ EXPECT_EQ(1, intervals[1].start_day_of_week);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(10) + base::TimeDelta::FromHours(20),
+ intervals[1].start_time);
+ EXPECT_EQ(3, intervals[1].end_day_of_week);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(20), intervals[1].end_time);
+
// Reloading the protobuf should succeed.
EXPECT_TRUE(provider.Reload());
}
@@ -207,6 +222,7 @@ TEST(PolicyTest, DevicePolicyNoneSetTest) {
bool bool_value;
std::string string_value;
std::vector<DevicePolicy::UsbDeviceId> list_device;
+ std::vector<DevicePolicy::WeeklyTimeInterval> intervals;
EXPECT_FALSE(policy.GetPolicyRefreshRate(&int_value));
EXPECT_FALSE(policy.GetUserWhitelist(&list_value));
@@ -235,6 +251,7 @@ TEST(PolicyTest, DevicePolicyNoneSetTest) {
EXPECT_FALSE(policy.GetAllowKioskAppControlChromeVersion(&bool_value));
EXPECT_FALSE(policy.GetUsbDetachableWhitelist(&list_device));
EXPECT_FALSE(policy.GetSecondFactorAuthenticationMode(&int_value));
+ EXPECT_FALSE(policy.GetDisallowedTimeIntervals(&intervals));
}
// Verify that the library will correctly recognize and signal missing files.
diff --git a/policy/tests/whitelist/policy_all b/policy/tests/whitelist/policy_all
index 07999f6..c0dfaaf 100644
--- a/policy/tests/whitelist/policy_all
+++ b/policy/tests/whitelist/policy_all
Binary files differ