File: idle_timeout_policy_handler.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (240 lines) | stat: -rw-r--r-- 8,645 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/enterprise/idle/idle_timeout_policy_handler.h"

#include <string>

#include "base/json/values_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/browsing_data/core/browsing_data_policies_utils.h"
#include "components/enterprise/idle/action_type.h"
#include "components/enterprise/idle/idle_pref_names.h"
#include "components/policy/core/browser/configuration_policy_handler.h"
#include "components/policy/core/browser/policy_error_map.h"
#include "components/policy/core/common/policy_logger.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/schema.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_value_map.h"
#include "components/strings/grit/components_strings.h"

namespace enterprise_idle {

namespace {

// If `other_policy_name` is unset, adds an error to `errors` and returns false.
bool CheckOtherPolicySet(const policy::PolicyMap& policies,
                         const std::string& this_policy_name,
                         const std::string& other_policy_name,
                         policy::PolicyErrorMap* errors) {
  if (policies.GetValueUnsafe(other_policy_name)) {
    return true;
  }

  errors->AddError(this_policy_name, IDS_POLICY_DEPENDENCY_ERROR_ANY_VALUE,
                   other_policy_name);
  return false;
}

bool CheckPolicyScopeSupported(const policy::PolicyMap& policies,
                               const std::string& policy_name,
                               policy::PolicyErrorMap* errors) {
// The policies will not be supported as user policies on iOS until we clear
// data on sign out for managed users which requires new UI.
#if BUILDFLAG(IS_IOS)
  bool is_user_policy =
      policies.Get(policy_name)->scope == policy::POLICY_SCOPE_USER;
  if (is_user_policy) {
    errors->AddError(policy_name,
                     IDS_POLICY_NOT_SUPPORTED_AS_USER_POLICY_ON_IOS);
  }
  return !is_user_policy;
#else
  // Return true on all other platforms.
  return true;
#endif  // BUILDFLAG(IS_IOS)
}

}  // namespace

IdleTimeoutPolicyHandler::IdleTimeoutPolicyHandler()
    : policy::IntRangePolicyHandler(policy::key::kIdleTimeout,
                                    prefs::kIdleTimeout,
                                    1,
                                    INT_MAX,
                                    true) {}

IdleTimeoutPolicyHandler::~IdleTimeoutPolicyHandler() = default;

void IdleTimeoutPolicyHandler::ApplyPolicySettings(
    const policy::PolicyMap& policies,
    PrefValueMap* prefs) {
  const base::Value* value =
      policies.GetValue(policy_name(), base::Value::Type::INTEGER);
  DCHECK(value);

  // Apply a minimum of 1.
  base::TimeDelta time_delta = base::Minutes(std::max(value->GetInt(), 1));
  prefs->SetValue(prefs::kIdleTimeout, base::TimeDeltaToValue(time_delta));
}

bool IdleTimeoutPolicyHandler::CheckPolicySettings(
    const policy::PolicyMap& policies,
    policy::PolicyErrorMap* errors) {
  // Nothing to do if unset.
  if (!policies.GetValueUnsafe(policy_name())) {
    return false;
  }

  // Check that it's an integer, and that it's >= 1.
  if (!policy::IntRangePolicyHandler::CheckPolicySettings(policies, errors)) {
    return false;
  }

  // If IdleTimeoutActions is unset, add an error and do nothing.
  if (!CheckOtherPolicySet(policies, policy_name(),
                           policy::key::kIdleTimeoutActions, errors)) {
    return false;
  }

  if (!CheckPolicyScopeSupported(policies, policy_name(), errors)) {
    return false;
  }

  return true;
}

IdleTimeoutActionsPolicyHandler::IdleTimeoutActionsPolicyHandler(
    policy::Schema schema)
    : policy::SchemaValidatingPolicyHandler(
          policy::key::kIdleTimeoutActions,
          schema.GetKnownProperty(policy::key::kIdleTimeoutActions),
          policy::SCHEMA_ALLOW_UNKNOWN_AND_INVALID_LIST_ENTRY) {}

IdleTimeoutActionsPolicyHandler::~IdleTimeoutActionsPolicyHandler() = default;

void IdleTimeoutActionsPolicyHandler::ApplyPolicySettings(
    const policy::PolicyMap& policies,
    PrefValueMap* prefs) {
  const base::Value* policy_value =
      policies.GetValue(policy_name(), base::Value::Type::LIST);
  DCHECK(policy_value);

  // Convert strings to integers (from the ActionType enum).
  base::Value::List converted_actions;
  for (const base::Value& action : policy_value->GetList()) {
    if (!action.is_string()) {
      continue;
    }
    if (std::optional<ActionType> action_type =
            NameToActionType(action.GetString())) {
      converted_actions.Append(static_cast<int>(action_type.value()));
    }
  }
  prefs->SetValue(prefs::kIdleTimeoutActions,
                  base::Value(std::move(converted_actions)));

  std::string log_message = browsing_data::DisableSyncTypes(
      forced_disabled_sync_types_, prefs, policy_name());
  if (!log_message.empty()) {
    LOG_POLICY(INFO, POLICY_PROCESSING) << log_message;
  }

#if BUILDFLAG(IS_IOS)
  // Set the `kIdleTimeoutPolicyAppliesToUserOnly`pref if the policy is set as a
  // user policy. This will determine whether data should be cleared for
  // `TimePeriod::ALL_TIME` or only for the time the user was signed in.
  bool user_policy =
      policies.Get(policy_name())->scope == policy::POLICY_SCOPE_USER;
  prefs->SetBoolean(prefs::kIdleTimeoutPolicyAppliesToUserOnly, user_policy);
#endif  // BUILDFLAG(IS_IOS)
}

bool IdleTimeoutActionsPolicyHandler::CheckPolicySettings(
    const policy::PolicyMap& policies,
    policy::PolicyErrorMap* errors) {
  // Nothing to do if unset.
  if (!policies.GetValueUnsafe(policy_name())) {
    return false;
  }

  // Check that it's a list of strings, and that they're supported enum values.
  // Unsupported enum values are dropped, with a warning on chrome://policy.
  if (!policy::SchemaValidatingPolicyHandler::CheckPolicySettings(policies,
                                                                  errors)) {
    return false;
  }

  // If IdleTimeout is unset, add an error and do nothing.
  if (!CheckOtherPolicySet(policies, policy_name(), policy::key::kIdleTimeout,
                           errors)) {
    return false;
  }

  if (!CheckPolicyScopeSupported(policies, policy_name(), errors)) {
    return false;
  }

#if !BUILDFLAG(IS_ANDROID)
  const base::Value* sync_disabled =
      policies.GetValue(policy::key::kSyncDisabled, base::Value::Type::BOOLEAN);
  if (sync_disabled && sync_disabled->GetBool()) {
    return true;
  }
#endif  //! BUILDFLAG(IS_ANDROID)

// BrowserSignin policy is not available on ChromeOS.
#if !BUILDFLAG(IS_CHROMEOS)
  const auto* browser_signin_disabled = policies.GetValue(
      policy::key::kBrowserSignin, base::Value::Type::INTEGER);
  if (browser_signin_disabled && browser_signin_disabled->GetInt() == 0) {
    return true;
  }
#endif

  // Automatically disable sync for the required data types.
  const base::Value* value =
      policies.GetValue(this->policy_name(), base::Value::Type::LIST);
  DCHECK(value);
  base::Value::List clear_data_actions;
  for (const base::Value& action : value->GetList()) {
    if (!action.is_string()) {
      continue;
    }
    std::string clear_data_action =
        GetActionBrowsingDataTypeName(action.GetString());
    if (!clear_data_action.empty()) {
      clear_data_actions.Append(clear_data_action);
    }
  }
  forced_disabled_sync_types_ = browsing_data::GetSyncTypesForClearBrowsingData(
      base::Value(std::move(clear_data_actions)));

  return true;
}

// TODO(esalma): Move this logic to `ApplyPolicySettings()` after fixing
// crbug.com/1435069.
void IdleTimeoutActionsPolicyHandler::PrepareForDisplaying(
    policy::PolicyMap* policies) const {
  policy::PolicyMap::Entry* entry = policies->GetMutable(policy_name());
  if (!entry || forced_disabled_sync_types_.empty()) {
    return;
  }
  // `PolicyConversionsClient::GetPolicyValue()` doesn't support
  // MessageType::kInfo in the PolicyErrorMap, so add the message to the policy
  // when it is prepared to be displayed on chrome://policy.
  entry->AddMessage(policy::PolicyMap::MessageType::kInfo,
                    IDS_POLICY_BROWSING_DATA_DEPENDENCY_APPLIED_INFO,
                    {base::UTF8ToUTF16(UserSelectableTypeSetToString(
                        forced_disabled_sync_types_))});
}

}  // namespace enterprise_idle