Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: chrome/browser/policy/cloud_policy_client.cc

Issue 6312121: Add initial device policy infrastructure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanup/compile fixes. Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/policy/cloud_policy_client.h"
6
7 #include "base/message_loop.h"
8 #include "base/rand_util.h"
9 #include "base/string_util.h"
10 #include "chrome/browser/policy/cloud_policy_cache.h"
11 #include "chrome/browser/policy/cloud_policy_context.h"
12 #include "chrome/browser/policy/device_management_backend.h"
13 #include "chrome/browser/policy/proto/device_management_constants.h"
14
15 // Domain names that are known not to be managed.
16 // We don't register the device when such a user logs in.
17 static const char* kNonManagedDomains[] = {
18 "@googlemail.com",
19 "@gmail.com"
20 };
21
22 // Checks the domain part of the given username against the list of known
23 // non-managed domain names. Returns false if |username| is empty or its
danno 2011/02/04 16:01:33 s/its/it's/
Jakob Kummerow 2011/02/14 13:50:34 Done.
24 // in a domain known not to be managed.
25 static bool CanBeInManagedDomain(const std::string& username) {
26 if (username.empty()) {
27 // This means incognito user in case of ChromiumOS and
28 // no logged-in user in case of Chromium (SigninService).
29 return false;
30 }
31 for (size_t i = 0; i < arraysize(kNonManagedDomains); i++) {
32 if (EndsWith(username, kNonManagedDomains[i], true)) {
33 return false;
34 }
35 }
36 return true;
37 }
38
39 namespace policy {
40
41 namespace em = enterprise_management;
42
43 // The maximum ratio in percent of the policy refresh rate we use for adjusting
44 // the policy refresh time instant. The rationale is to avoid load spikes from
45 // many devices that were set up in sync for some reason.
46 const int kPolicyRefreshDeviationFactorPercent = 10;
47 // Maximum deviation we are willing to accept.
48 const int64 kPolicyRefreshDeviationMaxInMilliseconds = 30 * 60 * 1000;
49
50 // These are the base values for delays before retrying after an error. They
51 // will be doubled each time they are used.
52 const int64 kPolicyRefreshErrorDelayInMilliseconds = 3 * 1000; // 3 seconds
53
54 CloudPolicyClient::CloudPolicyClient(CloudPolicyCache* cache,
55 DeviceManagementBackend* backend,
56 DeviceTokenFetcher* token_fetcher,
57 CloudPolicyController* controller)
58 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
59 Initialize(cache,
60 backend,
61 token_fetcher,
62 controller,
63 CloudPolicyContext::kDefaultPolicyRefreshRateInMilliseconds,
64 kPolicyRefreshDeviationFactorPercent,
65 kPolicyRefreshDeviationMaxInMilliseconds,
66 kPolicyRefreshErrorDelayInMilliseconds);
67 }
68
69 CloudPolicyClient::~CloudPolicyClient() {
70 token_fetcher_->RemoveObserver(this);
71 controller_->RemoveObserver(this);
72 CancelDelayedWork();
73 }
74
75 void CloudPolicyClient::SetRefreshRate(int64 refresh_rate_milliseconds) {
76 policy_refresh_rate_ms_ = refresh_rate_milliseconds;
77
78 // Reschedule the refresh task if necessary.
79 if (state_ == STATE_POLICY_VALID)
80 SetState(STATE_POLICY_VALID);
81 }
82
83 void CloudPolicyClient::HandlePolicyResponse(
84 const em::DevicePolicyResponse& response) {
85 if (state_ == STATE_TOKEN_UNAVAILABLE)
86 return;
87
88 cache_->SetPolicy(response);
89 SetState(STATE_POLICY_VALID);
90 }
91
92 void CloudPolicyClient::OnError(DeviceManagementBackend::ErrorCode code) {
93 if (state_ == STATE_TOKEN_UNAVAILABLE)
94 return;
95
96 if (code == DeviceManagementBackend::kErrorServiceDeviceNotFound ||
97 code == DeviceManagementBackend::kErrorServiceManagementTokenInvalid) {
98 LOG(WARNING) << "The device token was either invalid or unknown to the "
99 << "device manager, re-registering device.";
100 SetState(STATE_TOKEN_UNAVAILABLE);
101 } else if (code ==
102 DeviceManagementBackend::kErrorServiceManagementNotSupported) {
103 VLOG(1) << "The device is no longer managed, resetting device token.";
104 SetState(STATE_TOKEN_UNAVAILABLE);
105 } else {
106 LOG(WARNING) << "Could not provide policy from the device manager (error = "
107 << code << "), will retry in "
108 << (effective_policy_refresh_error_delay_ms_ / 1000)
109 << " seconds.";
110 SetState(STATE_POLICY_ERROR);
111 }
112 }
113
114 void CloudPolicyClient::OnTokenAvailable() {
115 controller_->OnTokenAvailable(token_fetcher_->GetDeviceToken());
116 }
117
118 void CloudPolicyClient::OnTokenChanged() {
119 if (controller_->GetDeviceToken().empty())
120 SetState(STATE_TOKEN_UNAVAILABLE);
121 else
122 SetState(STATE_TOKEN_VALID);
123 }
124
125 void CloudPolicyClient::OnCredentialsChanged() {
126 SetState(STATE_TOKEN_UNAVAILABLE);
127 }
128
129 CloudPolicyClient::CloudPolicyClient(
130 CloudPolicyCache* cache,
131 DeviceManagementBackend* backend,
132 DeviceTokenFetcher* token_fetcher,
133 CloudPolicyController* controller,
134 int64 policy_refresh_rate_ms,
135 int policy_refresh_deviation_factor_percent,
136 int64 policy_refresh_deviation_max_ms,
137 int64 policy_refresh_error_delay_ms)
138 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
139 Initialize(cache,
140 backend,
141 token_fetcher,
142 controller,
143 policy_refresh_rate_ms,
144 policy_refresh_deviation_factor_percent,
145 policy_refresh_deviation_max_ms,
146 policy_refresh_error_delay_ms);
147 }
148
149 void CloudPolicyClient::Initialize(
150 CloudPolicyCache* cache,
151 DeviceManagementBackend* backend,
152 DeviceTokenFetcher* token_fetcher,
153 CloudPolicyController* controller,
154 int64 policy_refresh_rate_ms,
155 int policy_refresh_deviation_factor_percent,
156 int64 policy_refresh_deviation_max_ms,
157 int64 policy_refresh_error_delay_ms) {
158 DCHECK(cache);
159
160 cache_ = cache;
161 backend_.reset(backend);
162 token_fetcher_ = token_fetcher;
163 controller_ = controller;
164 state_ = STATE_TOKEN_UNAVAILABLE;
165 delayed_work_task_ = NULL;
166 policy_refresh_rate_ms_ = policy_refresh_rate_ms;
167 policy_refresh_deviation_factor_percent_ =
168 policy_refresh_deviation_factor_percent;
169 policy_refresh_deviation_max_ms_ = policy_refresh_deviation_max_ms;
170 policy_refresh_error_delay_ms_ = policy_refresh_error_delay_ms;
171 effective_policy_refresh_error_delay_ms_ = policy_refresh_error_delay_ms;
172
173 token_fetcher_->AddObserver(this);
174 controller_->AddObserver(this);
175 if (!controller_->GetDeviceToken().empty())
176 SetState(STATE_TOKEN_VALID);
177 else
178 SetState(STATE_TOKEN_UNAVAILABLE);
179 }
180
181 void CloudPolicyClient::FetchToken() {
182 token_fetcher_->Reset();
183
184 std::string username;
185 std::string auth_token;
186 std::string device_id = controller_->GetDeviceID();
187 if (controller_->GetCredentials(&username, &auth_token) &&
188 CanBeInManagedDomain(username))
189 token_fetcher_->FetchToken(auth_token, device_id);
190 }
191
192 void CloudPolicyClient::SendPolicyRequest() {
193 DCHECK(!controller_->GetDeviceToken().empty());
194 em::DevicePolicyRequest policy_request;
195 policy_request.set_policy_scope(kChromePolicyScope);
196 em::DevicePolicySettingRequest* setting =
197 policy_request.add_setting_request();
198 setting->set_key(kChromeDevicePolicySettingKey);
199 setting->set_watermark("");
200 backend_->ProcessPolicyRequest(controller_->GetDeviceToken(),
201 controller_->GetDeviceID(),
202 policy_request, this);
203 }
204
205 void CloudPolicyClient::DoDelayedWork() {
206 DCHECK(delayed_work_task_);
207 delayed_work_task_ = NULL;
208
209 switch (state_) {
210 case STATE_TOKEN_UNAVAILABLE:
211 FetchToken();
212 return;
213 case STATE_TOKEN_VALID:
214 case STATE_POLICY_VALID:
215 case STATE_POLICY_ERROR:
216 SendPolicyRequest();
217 return;
218 }
219
220 NOTREACHED() << "Unhandled state" << state_;
221 }
222
223 void CloudPolicyClient::CancelDelayedWork() {
224 if (delayed_work_task_) {
225 delayed_work_task_->Cancel();
226 delayed_work_task_ = NULL;
227 }
228 }
229
230 void CloudPolicyClient::SetState(CloudPolicyClient::ClientState new_state) {
231 state_ = new_state;
232
233 base::Time now(base::Time::NowFromSystemTime());
234 base::Time refresh_at;
235 base::Time last_refresh(cache_->last_policy_refresh_time());
236 if (last_refresh.is_null())
237 last_refresh = now;
238
239 // Determine when to take the next step.
240 switch (state_) {
241 case STATE_TOKEN_UNAVAILABLE:
242 case STATE_TOKEN_VALID:
243 refresh_at = now;
244 break;
245 case STATE_POLICY_VALID:
246 effective_policy_refresh_error_delay_ms_ = policy_refresh_error_delay_ms_;
247 refresh_at =
248 last_refresh + base::TimeDelta::FromMilliseconds(GetRefreshDelay());
249 break;
250 case STATE_POLICY_ERROR:
251 refresh_at = now + base::TimeDelta::FromMilliseconds(
252 effective_policy_refresh_error_delay_ms_);
253 effective_policy_refresh_error_delay_ms_ *= 2;
254 if (effective_policy_refresh_error_delay_ms_ > policy_refresh_rate_ms_)
255 effective_policy_refresh_error_delay_ms_ = policy_refresh_rate_ms_;
256 break;
257 }
258
259 // Update the delayed work task.
260 CancelDelayedWork();
261 if (!refresh_at.is_null()) {
262 int64 delay = std::max<int64>((refresh_at - now).InMilliseconds(), 0);
263 delayed_work_task_ =
264 method_factory_.NewRunnableMethod(&CloudPolicyClient::DoDelayedWork);
265 MessageLoop::current()->PostDelayedTask(FROM_HERE, delayed_work_task_,
266 delay);
267 }
268 }
269
270 int64 CloudPolicyClient::GetRefreshDelay() {
271 int64 deviation = (policy_refresh_deviation_factor_percent_ *
272 policy_refresh_rate_ms_) / 100;
273 deviation = std::min(deviation, policy_refresh_deviation_max_ms_);
274 return policy_refresh_rate_ms_ - base::RandGenerator(deviation + 1);
275 }
276
277 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698