blob: ba82b0f8ba7787fe94e8f2cd20c3d038d4c11bf3 [file] [log] [blame]
[email protected]cce15bb2014-06-17 13:43:511// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]0850e842013-01-19 03:44:312// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]cce15bb2014-06-17 13:43:515#include "chrome/browser/supervised_user/supervised_user_service.h"
[email protected]0850e842013-01-19 03:44:316
dchenge73d8520c2015-12-27 01:19:097#include <utility>
8
[email protected]a19df3e2013-05-21 00:03:039#include "base/command_line.h"
treibdaece84f2014-09-05 12:58:1510#include "base/files/file_path.h"
treib2fd187392015-04-16 17:19:3811#include "base/files/file_util.h"
[email protected]0850e842013-01-19 03:44:3112#include "base/memory/ref_counted.h"
treibd3f8b7a2015-04-10 11:41:3313#include "base/path_service.h"
treib40d3ad92015-10-20 18:15:4214#include "base/strings/stringprintf.h"
[email protected]112158af2013-06-07 23:46:1815#include "base/strings/utf_string_conversions.h"
treib2fd187392015-04-16 17:19:3816#include "base/task_runner_util.h"
treibf832a992015-03-24 18:09:2417#include "base/version.h"
avi664c07b2015-12-26 02:18:3118#include "build/build_config.h"
[email protected]5ddfade2014-02-03 10:24:5319#include "chrome/browser/browser_process.h"
bauerb4da36132014-12-26 19:53:1320#include "chrome/browser/component_updater/supervised_user_whitelist_installer.h"
[email protected]0850e842013-01-19 03:44:3121#include "chrome/browser/profiles/profile.h"
lwchkg7f133c72016-03-01 16:48:5322#include "chrome/browser/profiles/profile_attributes_entry.h"
23#include "chrome/browser/profiles/profile_attributes_storage.h"
[email protected]5ddfade2014-02-03 10:24:5324#include "chrome/browser/profiles/profile_manager.h"
[email protected]aab946912013-11-06 22:18:5125#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
[email protected]f252df2e2013-06-06 23:47:1926#include "chrome/browser/signin/signin_manager_factory.h"
treibe2082a0e2015-04-08 10:15:3027#include "chrome/browser/supervised_user/experimental/supervised_user_filtering_switches.h"
bauerb5f8cda92015-10-07 15:36:4428#include "chrome/browser/supervised_user/permission_request_creator.h"
[email protected]cce15bb2014-06-17 13:43:5129#include "chrome/browser/supervised_user/supervised_user_constants.h"
treibab0a39e2014-09-24 14:48:2830#include "chrome/browser/supervised_user/supervised_user_service_observer.h"
[email protected]cce15bb2014-06-17 13:43:5131#include "chrome/browser/supervised_user/supervised_user_settings_service.h"
32#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
[email protected]cce15bb2014-06-17 13:43:5133#include "chrome/browser/supervised_user/supervised_user_site_list.h"
bauerb4da36132014-12-26 19:53:1334#include "chrome/browser/supervised_user/supervised_user_whitelist_service.h"
[email protected]a19df3e2013-05-21 00:03:0335#include "chrome/browser/sync/profile_sync_service_factory.h"
[email protected]509ad1a92013-03-19 21:41:0636#include "chrome/browser/ui/browser.h"
[email protected]dfddd022013-07-10 17:29:4837#include "chrome/browser/ui/browser_list.h"
treibd3f8b7a2015-04-10 11:41:3338#include "chrome/common/chrome_paths.h"
[email protected]a19df3e2013-05-21 00:03:0339#include "chrome/common/chrome_switches.h"
[email protected]0850e842013-01-19 03:44:3140#include "chrome/common/pref_names.h"
[email protected]af39f002014-08-22 10:18:1841#include "chrome/grit/generated_resources.h"
blundell7282b512015-11-09 07:21:1142#include "components/browser_sync/browser/profile_sync_service.h"
[email protected]f0c8c4992014-05-15 17:37:2643#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0844#include "components/prefs/pref_service.h"
[email protected]7274ef02014-03-24 22:43:4045#include "components/signin/core/browser/profile_oauth2_token_service.h"
[email protected]7fbd3b12014-04-01 11:19:1646#include "components/signin/core/browser/signin_manager.h"
[email protected]63c7f0c2014-03-25 21:12:5947#include "components/signin/core/browser/signin_manager_base.h"
brettwf1958912015-10-07 19:43:1248#include "components/signin/core/common/signin_switches.h"
[email protected]0850e842013-01-19 03:44:3149#include "content/public/browser/browser_thread.h"
[email protected]2056c3b2014-04-07 18:08:5050#include "content/public/browser/user_metrics.h"
[email protected]0850e842013-01-19 03:44:3151#include "ui/base/l10n/l10n_util.h"
52
jam1c5a91492016-02-24 20:47:5353#if !defined(OS_ANDROID)
bauerb5f8cda92015-10-07 15:36:4454#include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service.h"
55#include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service_factory.h"
56#include "chrome/browser/supervised_user/legacy/permission_request_creator_sync.h"
57#include "chrome/browser/supervised_user/legacy/supervised_user_pref_mapping_service.h"
58#include "chrome/browser/supervised_user/legacy/supervised_user_pref_mapping_service_factory.h"
thestig1b76f1a2015-09-30 22:52:3859#include "chrome/browser/supervised_user/legacy/supervised_user_registration_utility.h"
bauerb5f8cda92015-10-07 15:36:4460#include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_factory.h"
thestig1b76f1a2015-09-30 22:52:3861#endif
62
[email protected]3aacc9c2013-08-08 11:19:3163#if defined(OS_CHROMEOS)
[email protected]4d390782014-08-15 09:22:5864#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
[email protected]83d82d42014-05-16 02:04:4265#include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
[email protected]4d390782014-08-15 09:22:5866#include "components/user_manager/user_manager.h"
[email protected]3aacc9c2013-08-08 11:19:3167#endif
68
[email protected]c14a6802014-07-11 21:51:1269#if defined(ENABLE_EXTENSIONS)
treib9e30e302015-04-15 08:12:1670#include "chrome/browser/extensions/extension_service.h"
[email protected]c14a6802014-07-11 21:51:1271#include "extensions/browser/extension_system.h"
[email protected]c14a6802014-07-11 21:51:1272#endif
73
[email protected]f085fdd52014-06-11 18:09:2074#if defined(ENABLE_THEMES)
75#include "chrome/browser/themes/theme_service.h"
76#include "chrome/browser/themes/theme_service_factory.h"
77#endif
78
[email protected]a581ea22013-05-06 12:34:1979using base::DictionaryValue;
[email protected]2056c3b2014-04-07 18:08:5080using base::UserMetricsAction;
[email protected]0850e842013-01-19 03:44:3181using content::BrowserThread;
82
treib22c3a042015-01-15 21:30:1383namespace {
84
treibd3f8b7a2015-04-10 11:41:3385// The URL from which to download a host blacklist if no local one exists yet.
86const char kBlacklistURL[] =
87 "https://www.gstatic.com/chrome/supervised_user/blacklist-20141001-1k.bin";
88// The filename under which we'll store the blacklist (in the user data dir).
89const char kBlacklistFilename[] = "su-blacklist.bin";
90
treib22c3a042015-01-15 21:30:1391const char* const kCustodianInfoPrefs[] = {
92 prefs::kSupervisedUserCustodianName,
93 prefs::kSupervisedUserCustodianEmail,
94 prefs::kSupervisedUserCustodianProfileImageURL,
95 prefs::kSupervisedUserCustodianProfileURL,
96 prefs::kSupervisedUserSecondCustodianName,
97 prefs::kSupervisedUserSecondCustodianEmail,
98 prefs::kSupervisedUserSecondCustodianProfileImageURL,
99 prefs::kSupervisedUserSecondCustodianProfileURL,
100};
101
treib8ecc1eb52015-03-04 18:29:06102void CreateURLAccessRequest(
103 const GURL& url,
104 PermissionRequestCreator* creator,
105 const SupervisedUserService::SuccessCallback& callback) {
106 creator->CreateURLAccessRequest(url, callback);
107}
108
109void CreateExtensionUpdateRequest(
treibf832a992015-03-24 18:09:24110 const std::string& id,
treib8ecc1eb52015-03-04 18:29:06111 PermissionRequestCreator* creator,
112 const SupervisedUserService::SuccessCallback& callback) {
treibf832a992015-03-24 18:09:24113 creator->CreateExtensionUpdateRequest(id, callback);
treib8ecc1eb52015-03-04 18:29:06114}
115
treib40d3ad92015-10-20 18:15:42116// Default callback for AddExtensionUpdateRequest.
117void ExtensionUpdateRequestSent(const std::string& id, bool success) {
118 VLOG_IF(1, !success) << "Failed sending update request for " << id;
119}
120
treibd3f8b7a2015-04-10 11:41:33121base::FilePath GetBlacklistPath() {
122 base::FilePath blacklist_dir;
123 PathService::Get(chrome::DIR_USER_DATA, &blacklist_dir);
124 return blacklist_dir.AppendASCII(kBlacklistFilename);
125}
126
treibbb9a1962015-02-25 13:40:59127#if defined(ENABLE_EXTENSIONS)
128enum ExtensionState {
129 EXTENSION_FORCED,
130 EXTENSION_BLOCKED,
131 EXTENSION_ALLOWED
132};
133
134ExtensionState GetExtensionState(const extensions::Extension* extension) {
treibbb9a1962015-02-25 13:40:59135 bool was_installed_by_default = extension->was_installed_by_default();
treibbb9a1962015-02-25 13:40:59136#if defined(OS_CHROMEOS)
137 // On Chrome OS all external sources are controlled by us so it means that
138 // they are "default". Method was_installed_by_default returns false because
139 // extensions creation flags are ignored in case of default extensions with
140 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
141 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
142 // flags are not ignored.
143 was_installed_by_default =
144 extensions::Manifest::IsExternalLocation(extension->location());
145#endif
treib2fc09342015-04-09 15:53:58146 // Note: Component extensions are protected from modification/uninstallation
147 // anyway, so there's no need to enforce them again for supervised users.
treib7d8925f2015-12-16 14:11:04148 // Also, leave policy-installed extensions alone - they have their own
149 // management; in particular we don't want to override the force-install list.
treibbb9a1962015-02-25 13:40:59150 if (extensions::Manifest::IsComponentLocation(extension->location()) ||
treib7d8925f2015-12-16 14:11:04151 extensions::Manifest::IsPolicyLocation(extension->location()) ||
treib2fc09342015-04-09 15:53:58152 extension->is_theme() ||
benwellsf4f10382015-05-22 10:17:59153 extension->from_bookmark() ||
treib7d8925f2015-12-16 14:11:04154 extension->is_shared_module() ||
treib2fc09342015-04-09 15:53:58155 was_installed_by_default) {
156 return EXTENSION_ALLOWED;
treibbb9a1962015-02-25 13:40:59157 }
158
treib2fc09342015-04-09 15:53:58159 if (extension->was_installed_by_custodian())
160 return EXTENSION_FORCED;
161
treibbb9a1962015-02-25 13:40:59162 return EXTENSION_BLOCKED;
163}
164#endif
165
treib22c3a042015-01-15 21:30:13166} // namespace
167
bauerb5f8cda92015-10-07 15:36:44168SupervisedUserService::~SupervisedUserService() {
169 DCHECK(!did_init_ || did_shutdown_);
170 url_filter_context_.ui_url_filter()->RemoveObserver(this);
171}
172
173// static
174void SupervisedUserService::RegisterProfilePrefs(
175 user_prefs::PrefRegistrySyncable* registry) {
176 registry->RegisterDictionaryPref(prefs::kSupervisedUserManualHosts);
177 registry->RegisterDictionaryPref(prefs::kSupervisedUserManualURLs);
178 registry->RegisterIntegerPref(prefs::kDefaultSupervisedUserFilteringBehavior,
179 SupervisedUserURLFilter::ALLOW);
180 registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true);
181 registry->RegisterBooleanPref(prefs::kSupervisedUserSafeSites, true);
182 for (const char* pref : kCustodianInfoPrefs) {
183 registry->RegisterStringPref(pref, std::string());
184 }
185}
186
187void SupervisedUserService::Init() {
188 DCHECK(!did_init_);
189 did_init_ = true;
190 DCHECK(GetSettingsService()->IsReady());
191
192 pref_change_registrar_.Init(profile_->GetPrefs());
193 pref_change_registrar_.Add(
194 prefs::kSupervisedUserId,
195 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
196 base::Unretained(this)));
197 pref_change_registrar_.Add(
198 prefs::kRecordHistory,
199 base::Bind(&SupervisedUserService::OnHistoryRecordingStateChanged,
200 base::Unretained(this)));
201
202 ProfileSyncService* sync_service =
203 ProfileSyncServiceFactory::GetForProfile(profile_);
204 // Can be null in tests.
205 if (sync_service)
206 sync_service->AddPreferenceProvider(this);
207
208 std::string client_id = component_updater::SupervisedUserWhitelistInstaller::
209 ClientIdForProfilePath(profile_->GetPath());
210 whitelist_service_.reset(new SupervisedUserWhitelistService(
211 profile_->GetPrefs(),
212 g_browser_process->supervised_user_whitelist_installer(), client_id));
213 whitelist_service_->AddSiteListsChangedCallback(
214 base::Bind(&SupervisedUserService::OnSiteListsChanged,
215 weak_ptr_factory_.GetWeakPtr()));
216
217 SetActive(ProfileIsSupervised());
218}
219
220void SupervisedUserService::SetDelegate(Delegate* delegate) {
221 if (delegate) {
222 // Changing delegates isn't allowed.
223 DCHECK(!delegate_);
224 } else {
225 // If the delegate is removed, deactivate first to give the old delegate a
226 // chance to clean up.
227 SetActive(false);
228 }
229 delegate_ = delegate;
230}
231
232scoped_refptr<const SupervisedUserURLFilter>
233SupervisedUserService::GetURLFilterForIOThread() {
234 return url_filter_context_.io_url_filter();
235}
236
237SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
238 return url_filter_context_.ui_url_filter();
239}
240
241SupervisedUserWhitelistService* SupervisedUserService::GetWhitelistService() {
242 return whitelist_service_.get();
243}
244
245bool SupervisedUserService::AccessRequestsEnabled() {
246 return FindEnabledPermissionRequestCreator(0) < permissions_creators_.size();
247}
248
249void SupervisedUserService::AddURLAccessRequest(
250 const GURL& url,
251 const SuccessCallback& callback) {
252 AddPermissionRequestInternal(
253 base::Bind(CreateURLAccessRequest,
254 SupervisedUserURLFilter::Normalize(url)),
255 callback, 0);
256}
257
atanasovaac676032016-04-05 16:31:05258void SupervisedUserService::ReportURL(const GURL& url,
259 const SuccessCallback& callback) {
260 if (url_reporter_)
261 url_reporter_->ReportUrl(url, callback);
262 else
263 callback.Run(false);
264}
265
bauerb5f8cda92015-10-07 15:36:44266void SupervisedUserService::AddExtensionUpdateRequest(
267 const std::string& extension_id,
268 const base::Version& version,
269 const SuccessCallback& callback) {
treib40d3ad92015-10-20 18:15:42270 std::string id = GetExtensionUpdateRequestId(extension_id, version);
bauerb5f8cda92015-10-07 15:36:44271 AddPermissionRequestInternal(
treib40d3ad92015-10-20 18:15:42272 base::Bind(CreateExtensionUpdateRequest, id), callback, 0);
273}
274
275void SupervisedUserService::AddExtensionUpdateRequest(
276 const std::string& extension_id,
277 const base::Version& version) {
278 std::string id = GetExtensionUpdateRequestId(extension_id, version);
279 AddExtensionUpdateRequest(extension_id, version,
280 base::Bind(ExtensionUpdateRequestSent, id));
281}
282
283// static
284std::string SupervisedUserService::GetExtensionUpdateRequestId(
285 const std::string& extension_id,
286 const base::Version& version) {
287 return base::StringPrintf("%s:%s", extension_id.c_str(),
288 version.GetString().c_str());
bauerb5f8cda92015-10-07 15:36:44289}
290
291std::string SupervisedUserService::GetCustodianEmailAddress() const {
treib2170ea02015-10-13 14:55:12292 std::string email = profile_->GetPrefs()->GetString(
bauerb5f8cda92015-10-07 15:36:44293 prefs::kSupervisedUserCustodianEmail);
294#if defined(OS_CHROMEOS)
treib2170ea02015-10-13 14:55:12295 // |GetActiveUser()| can return null in unit tests.
296 if (email.empty() && !!user_manager::UserManager::Get()->GetActiveUser()) {
297 email = chromeos::ChromeUserManager::Get()
bauerb5f8cda92015-10-07 15:36:44298 ->GetSupervisedUserManager()
299 ->GetManagerDisplayEmail(
300 user_manager::UserManager::Get()->GetActiveUser()->email());
301 }
302#endif
treib2170ea02015-10-13 14:55:12303 return email;
bauerb5f8cda92015-10-07 15:36:44304}
305
306std::string SupervisedUserService::GetCustodianName() const {
307 std::string name = profile_->GetPrefs()->GetString(
308 prefs::kSupervisedUserCustodianName);
309#if defined(OS_CHROMEOS)
treib2170ea02015-10-13 14:55:12310 // |GetActiveUser()| can return null in unit tests.
311 if (name.empty() && !!user_manager::UserManager::Get()->GetActiveUser()) {
bauerb5f8cda92015-10-07 15:36:44312 name = base::UTF16ToUTF8(chromeos::ChromeUserManager::Get()
313 ->GetSupervisedUserManager()
314 ->GetManagerDisplayName(
315 user_manager::UserManager::Get()->GetActiveUser()->email()));
316 }
317#endif
318 return name.empty() ? GetCustodianEmailAddress() : name;
319}
320
321std::string SupervisedUserService::GetSecondCustodianEmailAddress() const {
322 return profile_->GetPrefs()->GetString(
323 prefs::kSupervisedUserSecondCustodianEmail);
324}
325
326std::string SupervisedUserService::GetSecondCustodianName() const {
327 std::string name = profile_->GetPrefs()->GetString(
328 prefs::kSupervisedUserSecondCustodianName);
329 return name.empty() ? GetSecondCustodianEmailAddress() : name;
330}
331
treib2170ea02015-10-13 14:55:12332base::string16 SupervisedUserService::GetExtensionsLockedMessage() const {
333 return l10n_util::GetStringFUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER,
334 base::UTF8ToUTF16(GetCustodianName()));
335}
336
jam1c5a91492016-02-24 20:47:53337#if !defined(OS_ANDROID)
bauerb5f8cda92015-10-07 15:36:44338void SupervisedUserService::InitSync(const std::string& refresh_token) {
339 StartSetupSync();
340
341 ProfileOAuth2TokenService* token_service =
342 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
343 token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
344 refresh_token);
345
346 FinishSetupSyncWhenReady();
347}
348
349void SupervisedUserService::RegisterAndInitSync(
350 SupervisedUserRegistrationUtility* registration_utility,
351 Profile* custodian_profile,
352 const std::string& supervised_user_id,
353 const AuthErrorCallback& callback) {
354 DCHECK(ProfileIsSupervised());
355 DCHECK(!custodian_profile->IsSupervised());
356
357 base::string16 name = base::UTF8ToUTF16(
358 profile_->GetPrefs()->GetString(prefs::kProfileName));
359 int avatar_index = profile_->GetPrefs()->GetInteger(
360 prefs::kProfileAvatarIndex);
361 SupervisedUserRegistrationInfo info(name, avatar_index);
362 registration_utility->Register(
363 supervised_user_id,
364 info,
365 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
366 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
367
368 // Fetch the custodian's profile information, to store the name.
369 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
lwchkg7f133c72016-03-01 16:48:53370 // is ever enabled, take the name from the ProfileAttributesStorage instead.
bauerb5f8cda92015-10-07 15:36:44371 CustodianProfileDownloaderService* profile_downloader_service =
372 CustodianProfileDownloaderServiceFactory::GetForProfile(
373 custodian_profile);
374 profile_downloader_service->DownloadProfile(
375 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
376 weak_ptr_factory_.GetWeakPtr()));
377}
jam1c5a91492016-02-24 20:47:53378#endif // !defined(OS_ANDROID)
bauerb5f8cda92015-10-07 15:36:44379
380void SupervisedUserService::AddNavigationBlockedCallback(
381 const NavigationBlockedCallback& callback) {
382 navigation_blocked_callbacks_.push_back(callback);
383}
384
385void SupervisedUserService::DidBlockNavigation(
386 content::WebContents* web_contents) {
387 for (const auto& callback : navigation_blocked_callbacks_)
388 callback.Run(web_contents);
389}
390
391void SupervisedUserService::AddObserver(
392 SupervisedUserServiceObserver* observer) {
393 observer_list_.AddObserver(observer);
394}
395
396void SupervisedUserService::RemoveObserver(
397 SupervisedUserServiceObserver* observer) {
398 observer_list_.RemoveObserver(observer);
399}
400
401void SupervisedUserService::AddPermissionRequestCreator(
dchengf624e472016-04-12 08:33:17402 std::unique_ptr<PermissionRequestCreator> creator) {
bauerb5f8cda92015-10-07 15:36:44403 permissions_creators_.push_back(creator.release());
404}
405
atanasovaac676032016-04-05 16:31:05406void SupervisedUserService::SetSafeSearchURLReporter(
dchengf624e472016-04-12 08:33:17407 std::unique_ptr<SafeSearchURLReporter> reporter) {
atanasovaac676032016-04-05 16:31:05408 url_reporter_ = std::move(reporter);
409}
410
[email protected]cce15bb2014-06-17 13:43:51411SupervisedUserService::URLFilterContext::URLFilterContext()
412 : ui_url_filter_(new SupervisedUserURLFilter),
413 io_url_filter_(new SupervisedUserURLFilter) {}
414SupervisedUserService::URLFilterContext::~URLFilterContext() {}
[email protected]0850e842013-01-19 03:44:31415
[email protected]cce15bb2014-06-17 13:43:51416SupervisedUserURLFilter*
417SupervisedUserService::URLFilterContext::ui_url_filter() const {
[email protected]0850e842013-01-19 03:44:31418 return ui_url_filter_.get();
419}
420
[email protected]cce15bb2014-06-17 13:43:51421SupervisedUserURLFilter*
422SupervisedUserService::URLFilterContext::io_url_filter() const {
[email protected]0850e842013-01-19 03:44:31423 return io_url_filter_.get();
424}
425
[email protected]cce15bb2014-06-17 13:43:51426void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
427 SupervisedUserURLFilter::FilteringBehavior behavior) {
[email protected]0850e842013-01-19 03:44:31428 ui_url_filter_->SetDefaultFilteringBehavior(behavior);
429 BrowserThread::PostTask(
430 BrowserThread::IO,
431 FROM_HERE,
[email protected]cce15bb2014-06-17 13:43:51432 base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
[email protected]5e022292013-02-06 16:42:17433 io_url_filter_.get(), behavior));
[email protected]0850e842013-01-19 03:44:31434}
435
[email protected]cce15bb2014-06-17 13:43:51436void SupervisedUserService::URLFilterContext::LoadWhitelists(
bauerb95a50682015-01-07 17:04:15437 const std::vector<scoped_refptr<SupervisedUserSiteList> >& site_lists) {
438 ui_url_filter_->LoadWhitelists(site_lists);
439 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
440 base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
441 io_url_filter_, site_lists));
[email protected]0850e842013-01-19 03:44:31442}
443
treib9cc1b112016-01-08 10:08:01444void SupervisedUserService::URLFilterContext::SetBlacklist(
445 const SupervisedUserBlacklist* blacklist) {
446 ui_url_filter_->SetBlacklist(blacklist);
447 BrowserThread::PostTask(
448 BrowserThread::IO,
449 FROM_HERE,
450 base::Bind(&SupervisedUserURLFilter::SetBlacklist,
451 io_url_filter_,
452 blacklist));
453}
454
455bool SupervisedUserService::URLFilterContext::HasBlacklist() const {
456 return ui_url_filter_->HasBlacklist();
treib4edbded2014-09-05 08:43:55457}
458
[email protected]cce15bb2014-06-17 13:43:51459void SupervisedUserService::URLFilterContext::SetManualHosts(
dchengf624e472016-04-12 08:33:17460 std::unique_ptr<std::map<std::string, bool>> host_map) {
[email protected]5e022292013-02-06 16:42:17461 ui_url_filter_->SetManualHosts(host_map.get());
[email protected]0850e842013-01-19 03:44:31462 BrowserThread::PostTask(
463 BrowserThread::IO,
464 FROM_HERE,
[email protected]cce15bb2014-06-17 13:43:51465 base::Bind(&SupervisedUserURLFilter::SetManualHosts,
[email protected]5e022292013-02-06 16:42:17466 io_url_filter_, base::Owned(host_map.release())));
[email protected]0850e842013-01-19 03:44:31467}
468
[email protected]cce15bb2014-06-17 13:43:51469void SupervisedUserService::URLFilterContext::SetManualURLs(
dchengf624e472016-04-12 08:33:17470 std::unique_ptr<std::map<GURL, bool>> url_map) {
[email protected]5e022292013-02-06 16:42:17471 ui_url_filter_->SetManualURLs(url_map.get());
[email protected]0850e842013-01-19 03:44:31472 BrowserThread::PostTask(
473 BrowserThread::IO,
474 FROM_HERE,
[email protected]cce15bb2014-06-17 13:43:51475 base::Bind(&SupervisedUserURLFilter::SetManualURLs,
[email protected]5e022292013-02-06 16:42:17476 io_url_filter_, base::Owned(url_map.release())));
[email protected]0850e842013-01-19 03:44:31477}
478
treib22c3a042015-01-15 21:30:13479void SupervisedUserService::URLFilterContext::Clear() {
480 ui_url_filter_->Clear();
481 BrowserThread::PostTask(
482 BrowserThread::IO,
483 FROM_HERE,
484 base::Bind(&SupervisedUserURLFilter::Clear,
485 io_url_filter_));
486}
487
bauerb5f8cda92015-10-07 15:36:44488void SupervisedUserService::URLFilterContext::InitAsyncURLChecker(
489 const scoped_refptr<net::URLRequestContextGetter>& context) {
490 ui_url_filter_->InitAsyncURLChecker(context.get());
491 BrowserThread::PostTask(
vmpstra34d11322016-03-21 20:28:47492 BrowserThread::IO, FROM_HERE,
493 base::Bind(&SupervisedUserURLFilter::InitAsyncURLChecker, io_url_filter_,
494 base::RetainedRef(context)));
bauerb5f8cda92015-10-07 15:36:44495}
496
treib9cc1b112016-01-08 10:08:01497bool SupervisedUserService::URLFilterContext::HasAsyncURLChecker() const {
498 return ui_url_filter_->HasAsyncURLChecker();
499}
500
501void SupervisedUserService::URLFilterContext::ClearAsyncURLChecker() {
502 ui_url_filter_->ClearAsyncURLChecker();
treib4edbded2014-09-05 08:43:55503 BrowserThread::PostTask(
504 BrowserThread::IO,
505 FROM_HERE,
treib9cc1b112016-01-08 10:08:01506 base::Bind(&SupervisedUserURLFilter::ClearAsyncURLChecker,
507 io_url_filter_));
treib4edbded2014-09-05 08:43:55508}
509
[email protected]cce15bb2014-06-17 13:43:51510SupervisedUserService::SupervisedUserService(Profile* profile)
fhorschig1f351f02014-09-30 12:30:22511 : includes_sync_sessions_type_(true),
512 profile_(profile),
[email protected]f085fdd52014-06-11 18:09:20513 active_(false),
514 delegate_(NULL),
[email protected]a243d644c2013-06-20 18:37:55515 waiting_for_sync_initialization_(false),
[email protected]dfddd022013-07-10 17:29:48516 is_profile_active_(false),
[email protected]3a276ff2014-08-12 14:22:09517 did_init_(false),
[email protected]8052b242013-11-15 16:40:55518 did_shutdown_(false),
treib9cc1b112016-01-08 10:08:01519 blacklist_state_(BlacklistLoadState::NOT_LOADED),
[email protected]8052b242013-11-15 16:40:55520 weak_ptr_factory_(this) {
bauerbce9a1a82014-12-18 13:34:24521 url_filter_context_.ui_url_filter()->AddObserver(this);
[email protected]a243d644c2013-06-20 18:37:55522}
[email protected]0850e842013-01-19 03:44:31523
[email protected]cce15bb2014-06-17 13:43:51524void SupervisedUserService::SetActive(bool active) {
[email protected]f085fdd52014-06-11 18:09:20525 if (active_ == active)
[email protected]0850e842013-01-19 03:44:31526 return;
[email protected]f085fdd52014-06-11 18:09:20527 active_ = active;
528
529 if (!delegate_ || !delegate_->SetActive(active_)) {
530 if (active_) {
jam1c5a91492016-02-24 20:47:53531#if !defined(OS_ANDROID)
[email protected]f085fdd52014-06-11 18:09:20532 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
533 ->Init();
534
avi556c05022014-12-22 23:31:43535 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]d20d0432014-06-12 17:14:05536 if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
[email protected]f085fdd52014-06-11 18:09:20537 InitSync(
[email protected]d20d0432014-06-12 17:14:05538 command_line->GetSwitchValueASCII(
539 switches::kSupervisedUserSyncToken));
[email protected]f085fdd52014-06-11 18:09:20540 }
541
542 ProfileOAuth2TokenService* token_service =
543 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
[email protected]cce15bb2014-06-17 13:43:51544 token_service->LoadCredentials(
545 supervised_users::kSupervisedUserPseudoEmail);
[email protected]6e08b9a62014-07-08 00:32:48546
treib531fc7312014-12-09 12:49:20547 permissions_creators_.push_back(new PermissionRequestCreatorSync(
548 GetSettingsService(),
549 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
550 profile_),
551 ProfileSyncServiceFactory::GetForProfile(profile_),
552 GetSupervisedUserName(),
553 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId)));
554
[email protected]6e08b9a62014-07-08 00:32:48555 SetupSync();
bauerb7f3b8542015-06-29 19:56:19556#else
557 NOTREACHED();
558#endif
[email protected]f085fdd52014-06-11 18:09:20559 }
[email protected]e861bba2013-06-17 15:20:54560 }
[email protected]0850e842013-01-19 03:44:31561
[email protected]f085fdd52014-06-11 18:09:20562 // Now activate/deactivate anything not handled by the delegate yet.
[email protected]e1480482013-09-11 11:49:58563
[email protected]f085fdd52014-06-11 18:09:20564#if defined(ENABLE_THEMES)
565 // Re-set the default theme to turn the SU theme on/off.
566 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
treib9e30e302015-04-15 08:12:16567 if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme())
568 theme_service->UseDefaultTheme();
[email protected]f085fdd52014-06-11 18:09:20569#endif
[email protected]a19df3e2013-05-21 00:03:03570
bauerbf03588b92014-10-27 13:40:15571 ProfileSyncService* sync_service =
572 ProfileSyncServiceFactory::GetForProfile(profile_);
573 sync_service->SetEncryptEverythingAllowed(!active_);
574
bauerbd3a36cc42014-10-01 13:05:49575 GetSettingsService()->SetActive(active_);
[email protected]a243d644c2013-06-20 18:37:55576
[email protected]c14a6802014-07-11 21:51:12577#if defined(ENABLE_EXTENSIONS)
578 SetExtensionsActive();
579#endif
[email protected]0850e842013-01-19 03:44:31580
[email protected]f085fdd52014-06-11 18:09:20581 if (active_) {
[email protected]f085fdd52014-06-11 18:09:20582 pref_change_registrar_.Add(
[email protected]d20d0432014-06-12 17:14:05583 prefs::kDefaultSupervisedUserFilteringBehavior,
[email protected]cce15bb2014-06-17 13:43:51584 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
[email protected]f085fdd52014-06-11 18:09:20585 base::Unretained(this)));
treib9cc1b112016-01-08 10:08:01586 pref_change_registrar_.Add(prefs::kSupervisedUserSafeSites,
587 base::Bind(&SupervisedUserService::OnSafeSitesSettingChanged,
588 base::Unretained(this)));
[email protected]d20d0432014-06-12 17:14:05589 pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
[email protected]cce15bb2014-06-17 13:43:51590 base::Bind(&SupervisedUserService::UpdateManualHosts,
[email protected]f085fdd52014-06-11 18:09:20591 base::Unretained(this)));
[email protected]d20d0432014-06-12 17:14:05592 pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
[email protected]cce15bb2014-06-17 13:43:51593 base::Bind(&SupervisedUserService::UpdateManualURLs,
[email protected]f085fdd52014-06-11 18:09:20594 base::Unretained(this)));
treib22c3a042015-01-15 21:30:13595 for (const char* pref : kCustodianInfoPrefs) {
596 pref_change_registrar_.Add(pref,
597 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
598 base::Unretained(this)));
599 }
[email protected]f085fdd52014-06-11 18:09:20600
601 // Initialize the filter.
602 OnDefaultFilteringBehaviorChanged();
treib9cc1b112016-01-08 10:08:01603 OnSafeSitesSettingChanged();
bauerb4da36132014-12-26 19:53:13604 whitelist_service_->Init();
[email protected]f085fdd52014-06-11 18:09:20605 UpdateManualHosts();
606 UpdateManualURLs();
[email protected]0850e842013-01-19 03:44:31607
jam1c5a91492016-02-24 20:47:53608#if !defined(OS_ANDROID)
[email protected]f085fdd52014-06-11 18:09:20609 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
610 // http://crbug.com/313377
611 BrowserList::AddObserver(this);
[email protected]975677d2013-11-14 16:15:34612#endif
[email protected]f085fdd52014-06-11 18:09:20613 } else {
bauerbd3a36cc42014-10-01 13:05:49614 permissions_creators_.clear();
atanasovaac676032016-04-05 16:31:05615 url_reporter_.reset();
[email protected]dfddd022013-07-10 17:29:48616
[email protected]d20d0432014-06-12 17:14:05617 pref_change_registrar_.Remove(
618 prefs::kDefaultSupervisedUserFilteringBehavior);
619 pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
620 pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
treib22c3a042015-01-15 21:30:13621 for (const char* pref : kCustodianInfoPrefs) {
622 pref_change_registrar_.Remove(pref);
623 }
624
625 url_filter_context_.Clear();
626 FOR_EACH_OBSERVER(
627 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
[email protected]f085fdd52014-06-11 18:09:20628
jam1c5a91492016-02-24 20:47:53629#if !defined(OS_ANDROID)
[email protected]3a276ff2014-08-12 14:22:09630 if (waiting_for_sync_initialization_)
631 ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
[email protected]f085fdd52014-06-11 18:09:20632
[email protected]f085fdd52014-06-11 18:09:20633 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
634 // http://crbug.com/313377
635 BrowserList::RemoveObserver(this);
636#endif
637 }
[email protected]0850e842013-01-19 03:44:31638}
639
jam1c5a91492016-02-24 20:47:53640#if !defined(OS_ANDROID)
[email protected]cce15bb2014-06-17 13:43:51641void SupervisedUserService::OnCustodianProfileDownloaded(
[email protected]0085863a2013-12-06 21:19:03642 const base::string16& full_name) {
[email protected]d20d0432014-06-12 17:14:05643 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
[email protected]6778fed2013-12-24 20:09:37644 base::UTF16ToUTF8(full_name));
[email protected]acfcfbb2013-05-13 18:01:27645}
646
[email protected]cce15bb2014-06-17 13:43:51647void SupervisedUserService::OnSupervisedUserRegistered(
[email protected]514fcf22013-08-13 06:37:24648 const AuthErrorCallback& callback,
[email protected]f252df2e2013-06-06 23:47:19649 Profile* custodian_profile,
[email protected]acfcfbb2013-05-13 18:01:27650 const GoogleServiceAuthError& auth_error,
651 const std::string& token) {
[email protected]514fcf22013-08-13 06:37:24652 if (auth_error.state() == GoogleServiceAuthError::NONE) {
653 InitSync(token);
654 SigninManagerBase* signin =
655 SigninManagerFactory::GetForProfile(custodian_profile);
bzanotti1b5be292015-08-31 12:10:05656 profile_->GetPrefs()->SetString(
657 prefs::kSupervisedUserCustodianEmail,
658 signin->GetAuthenticatedAccountInfo().email);
[email protected]5ddfade2014-02-03 10:24:53659
[email protected]cce15bb2014-06-17 13:43:51660 // The supervised user profile is now ready for use.
lwchkg7f133c72016-03-01 16:48:53661 ProfileAttributesEntry* entry = nullptr;
662 bool has_entry =
663 g_browser_process->profile_manager()->GetProfileAttributesStorage().
664 GetProfileAttributesWithPath(profile_->GetPath(), &entry);
665 DCHECK(has_entry);
666 entry->SetIsOmitted(false);
[email protected]514fcf22013-08-13 06:37:24667 } else {
[email protected]acfcfbb2013-05-13 18:01:27668 DCHECK_EQ(std::string(), token);
[email protected]acfcfbb2013-05-13 18:01:27669 }
670
[email protected]514fcf22013-08-13 06:37:24671 callback.Run(auth_error);
[email protected]acfcfbb2013-05-13 18:01:27672}
bauerb5f8cda92015-10-07 15:36:44673void SupervisedUserService::SetupSync() {
674 StartSetupSync();
675 FinishSetupSyncWhenReady();
676}
677
678void SupervisedUserService::StartSetupSync() {
679 // Tell the sync service that setup is in progress so we don't start syncing
680 // until we've finished configuration.
681 ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true);
682}
683
684void SupervisedUserService::FinishSetupSyncWhenReady() {
685 // If we're already waiting for the Sync backend, there's nothing to do here.
686 if (waiting_for_sync_initialization_)
687 return;
688
689 // Continue in FinishSetupSync() once the Sync backend has been initialized.
690 ProfileSyncService* service =
691 ProfileSyncServiceFactory::GetForProfile(profile_);
zea32a7684cf2016-02-24 20:41:48692 if (service->IsBackendInitialized()) {
bauerb5f8cda92015-10-07 15:36:44693 FinishSetupSync();
694 } else {
695 service->AddObserver(this);
696 waiting_for_sync_initialization_ = true;
697 }
698}
699
700void SupervisedUserService::FinishSetupSync() {
701 ProfileSyncService* service =
702 ProfileSyncServiceFactory::GetForProfile(profile_);
703 DCHECK(service->IsBackendInitialized());
bauerb5f8cda92015-10-07 15:36:44704
705 // Sync nothing (except types which are set via GetPreferredDataTypes).
706 bool sync_everything = false;
707 syncer::ModelTypeSet synced_datatypes;
708 service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
709
710 // Notify ProfileSyncService that we are done with configuration.
711 service->SetSetupInProgress(false);
maxboguefe00952a2016-01-19 19:02:01712 service->SetFirstSetupComplete();
bauerb5f8cda92015-10-07 15:36:44713}
714#endif
715
716bool SupervisedUserService::ProfileIsSupervised() const {
717 return profile_->IsSupervised();
718}
719
720void SupervisedUserService::OnCustodianInfoChanged() {
721 FOR_EACH_OBSERVER(
722 SupervisedUserServiceObserver, observer_list_, OnCustodianInfoChanged());
723}
724
725SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
726 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
727}
728
729size_t SupervisedUserService::FindEnabledPermissionRequestCreator(
730 size_t start) {
731 for (size_t i = start; i < permissions_creators_.size(); ++i) {
732 if (permissions_creators_[i]->IsEnabled())
733 return i;
734 }
735 return permissions_creators_.size();
736}
737
738void SupervisedUserService::AddPermissionRequestInternal(
739 const CreatePermissionRequestCallback& create_request,
740 const SuccessCallback& callback,
741 size_t index) {
742 // Find a permission request creator that is enabled.
743 size_t next_index = FindEnabledPermissionRequestCreator(index);
744 if (next_index >= permissions_creators_.size()) {
745 callback.Run(false);
746 return;
747 }
748
749 create_request.Run(
750 permissions_creators_[next_index],
751 base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
752 weak_ptr_factory_.GetWeakPtr(), create_request,
753 callback, next_index));
754}
755
756void SupervisedUserService::OnPermissionRequestIssued(
757 const CreatePermissionRequestCallback& create_request,
758 const SuccessCallback& callback,
759 size_t index,
760 bool success) {
761 if (success) {
762 callback.Run(true);
763 return;
764 }
765
766 AddPermissionRequestInternal(create_request, callback, index + 1);
767}
768
769void SupervisedUserService::OnSupervisedUserIdChanged() {
770 SetActive(ProfileIsSupervised());
771}
772
773void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
774 int behavior_value = profile_->GetPrefs()->GetInteger(
775 prefs::kDefaultSupervisedUserFilteringBehavior);
776 SupervisedUserURLFilter::FilteringBehavior behavior =
777 SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
778 url_filter_context_.SetDefaultFilteringBehavior(behavior);
779
780 FOR_EACH_OBSERVER(
781 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
782}
783
treib9cc1b112016-01-08 10:08:01784void SupervisedUserService::OnSafeSitesSettingChanged() {
785 bool use_blacklist = supervised_users::IsSafeSitesBlacklistEnabled(profile_);
786 if (use_blacklist != url_filter_context_.HasBlacklist()) {
787 if (use_blacklist && blacklist_state_ == BlacklistLoadState::NOT_LOADED) {
788 LoadBlacklist(GetBlacklistPath(), GURL(kBlacklistURL));
789 } else if (!use_blacklist ||
790 blacklist_state_ == BlacklistLoadState::LOADED) {
791 // Either the blacklist was turned off, or it was turned on but has
792 // already been loaded previously. Just update the setting.
793 UpdateBlacklist();
794 }
795 // Else: The blacklist was enabled, but the load is already in progress.
796 // Do nothing - we'll check the setting again when the load finishes.
797 }
798
799 bool use_online_check =
800 supervised_users::IsSafeSitesOnlineCheckEnabled(profile_);
treibe821d6542016-01-21 01:10:19801 if (use_online_check != url_filter_context_.HasAsyncURLChecker()) {
treib9cc1b112016-01-08 10:08:01802 if (use_online_check)
803 url_filter_context_.InitAsyncURLChecker(profile_->GetRequestContext());
804 else
805 url_filter_context_.ClearAsyncURLChecker();
806 }
807}
808
bauerb5f8cda92015-10-07 15:36:44809void SupervisedUserService::OnSiteListsChanged(
810 const std::vector<scoped_refptr<SupervisedUserSiteList> >& site_lists) {
atanasova9572aaf2016-02-26 18:08:26811 whitelists_ = site_lists;
bauerb5f8cda92015-10-07 15:36:44812 url_filter_context_.LoadWhitelists(site_lists);
813}
814
815void SupervisedUserService::LoadBlacklist(const base::FilePath& path,
816 const GURL& url) {
treib9cc1b112016-01-08 10:08:01817 DCHECK(blacklist_state_ == BlacklistLoadState::NOT_LOADED);
818 blacklist_state_ = BlacklistLoadState::LOAD_STARTED;
bauerb5f8cda92015-10-07 15:36:44819 base::PostTaskAndReplyWithResult(
820 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
821 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN).get(),
822 FROM_HERE,
823 base::Bind(&base::PathExists, path),
824 base::Bind(&SupervisedUserService::OnBlacklistFileChecked,
825 weak_ptr_factory_.GetWeakPtr(), path, url));
826}
827
828void SupervisedUserService::OnBlacklistFileChecked(const base::FilePath& path,
829 const GURL& url,
830 bool file_exists) {
treib9cc1b112016-01-08 10:08:01831 DCHECK(blacklist_state_ == BlacklistLoadState::LOAD_STARTED);
bauerb5f8cda92015-10-07 15:36:44832 if (file_exists) {
833 LoadBlacklistFromFile(path);
834 return;
835 }
836
837 DCHECK(!blacklist_downloader_);
838 blacklist_downloader_.reset(new FileDownloader(
839 url,
840 path,
841 false,
842 profile_->GetRequestContext(),
843 base::Bind(&SupervisedUserService::OnBlacklistDownloadDone,
844 base::Unretained(this), path)));
845}
846
847void SupervisedUserService::LoadBlacklistFromFile(const base::FilePath& path) {
treib9cc1b112016-01-08 10:08:01848 DCHECK(blacklist_state_ == BlacklistLoadState::LOAD_STARTED);
849 blacklist_.ReadFromFile(
850 path,
851 base::Bind(&SupervisedUserService::OnBlacklistLoaded,
852 base::Unretained(this)));
bauerb5f8cda92015-10-07 15:36:44853}
854
treibf38cc252016-04-07 14:44:11855void SupervisedUserService::OnBlacklistDownloadDone(
856 const base::FilePath& path,
857 FileDownloader::Result result) {
treib9cc1b112016-01-08 10:08:01858 DCHECK(blacklist_state_ == BlacklistLoadState::LOAD_STARTED);
treibf38cc252016-04-07 14:44:11859 if (FileDownloader::IsSuccess(result)) {
bauerb5f8cda92015-10-07 15:36:44860 LoadBlacklistFromFile(path);
861 } else {
862 LOG(WARNING) << "Blacklist download failed";
treib9cc1b112016-01-08 10:08:01863 // TODO(treib): Retry downloading after some time?
bauerb5f8cda92015-10-07 15:36:44864 }
865 blacklist_downloader_.reset();
866}
867
868void SupervisedUserService::OnBlacklistLoaded() {
treib9cc1b112016-01-08 10:08:01869 DCHECK(blacklist_state_ == BlacklistLoadState::LOAD_STARTED);
870 blacklist_state_ = BlacklistLoadState::LOADED;
871 UpdateBlacklist();
872}
873
874void SupervisedUserService::UpdateBlacklist() {
875 bool use_blacklist = supervised_users::IsSafeSitesBlacklistEnabled(profile_);
876 url_filter_context_.SetBlacklist(use_blacklist ? &blacklist_ : nullptr);
bauerb5f8cda92015-10-07 15:36:44877 FOR_EACH_OBSERVER(
878 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
879}
[email protected]acfcfbb2013-05-13 18:01:27880
[email protected]cce15bb2014-06-17 13:43:51881void SupervisedUserService::UpdateManualHosts() {
[email protected]cb1078de2013-12-23 20:04:22882 const base::DictionaryValue* dict =
[email protected]d20d0432014-06-12 17:14:05883 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
dchengf624e472016-04-12 08:33:17884 std::unique_ptr<std::map<std::string, bool>> host_map(
[email protected]5e022292013-02-06 16:42:17885 new std::map<std::string, bool>());
[email protected]cb1078de2013-12-23 20:04:22886 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
[email protected]5e022292013-02-06 16:42:17887 bool allow = false;
888 bool result = it.value().GetAsBoolean(&allow);
889 DCHECK(result);
890 (*host_map)[it.key()] = allow;
891 }
dchenge73d8520c2015-12-27 01:19:09892 url_filter_context_.SetManualHosts(std::move(host_map));
treibab0a39e2014-09-24 14:48:28893
894 FOR_EACH_OBSERVER(
895 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
[email protected]0850e842013-01-19 03:44:31896}
897
[email protected]cce15bb2014-06-17 13:43:51898void SupervisedUserService::UpdateManualURLs() {
[email protected]cb1078de2013-12-23 20:04:22899 const base::DictionaryValue* dict =
[email protected]d20d0432014-06-12 17:14:05900 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
dchengf624e472016-04-12 08:33:17901 std::unique_ptr<std::map<GURL, bool>> url_map(new std::map<GURL, bool>());
[email protected]cb1078de2013-12-23 20:04:22902 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
[email protected]5e022292013-02-06 16:42:17903 bool allow = false;
904 bool result = it.value().GetAsBoolean(&allow);
905 DCHECK(result);
906 (*url_map)[GURL(it.key())] = allow;
907 }
dchenge73d8520c2015-12-27 01:19:09908 url_filter_context_.SetManualURLs(std::move(url_map));
treibab0a39e2014-09-24 14:48:28909
910 FOR_EACH_OBSERVER(
911 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
[email protected]0850e842013-01-19 03:44:31912}
[email protected]dfddd022013-07-10 17:29:48913
[email protected]0b4c6b22014-08-04 09:46:31914std::string SupervisedUserService::GetSupervisedUserName() const {
915#if defined(OS_CHROMEOS)
916 // The active user can be NULL in unit tests.
[email protected]4d390782014-08-15 09:22:58917 if (user_manager::UserManager::Get()->GetActiveUser()) {
918 return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
alemate3ffbde6f2015-11-03 02:02:55919 user_manager::UserManager::Get()->GetActiveUser()->GetAccountId()));
[email protected]0b4c6b22014-08-04 09:46:31920 }
921 return std::string();
922#else
923 return profile_->GetPrefs()->GetString(prefs::kProfileName);
924#endif
925}
bauerb5f8cda92015-10-07 15:36:44926
927void SupervisedUserService::OnHistoryRecordingStateChanged() {
928 bool record_history =
929 profile_->GetPrefs()->GetBoolean(prefs::kRecordHistory);
930 includes_sync_sessions_type_ = record_history;
931 ProfileSyncServiceFactory::GetForProfile(profile_)
932 ->ReconfigureDatatypeManager();
933}
934
935bool SupervisedUserService::IncludesSyncSessionsType() const {
936 return includes_sync_sessions_type_;
937}
938
939void SupervisedUserService::Shutdown() {
940 if (!did_init_)
941 return;
942 DCHECK(!did_shutdown_);
943 did_shutdown_ = true;
944 if (ProfileIsSupervised()) {
945 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
946 }
947 SetActive(false);
948
949 ProfileSyncService* sync_service =
950 ProfileSyncServiceFactory::GetForProfile(profile_);
951
952 // Can be null in tests.
953 if (sync_service)
954 sync_service->RemovePreferenceProvider(this);
955}
956
957#if defined(ENABLE_EXTENSIONS)
958std::string SupervisedUserService::GetDebugPolicyProviderName() const {
959 // Save the string space in official builds.
960#ifdef NDEBUG
961 NOTREACHED();
962 return std::string();
963#else
964 return "Supervised User Service";
965#endif
966}
967
968bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
969 base::string16* error) const {
970 DCHECK(ProfileIsSupervised());
971 ExtensionState result = GetExtensionState(extension);
972 bool may_load = (result != EXTENSION_BLOCKED);
973 if (!may_load && error)
treib2170ea02015-10-13 14:55:12974 *error = GetExtensionsLockedMessage();
bauerb5f8cda92015-10-07 15:36:44975 return may_load;
976}
977
978bool SupervisedUserService::UserMayModifySettings(
979 const extensions::Extension* extension,
980 base::string16* error) const {
981 DCHECK(ProfileIsSupervised());
982 ExtensionState result = GetExtensionState(extension);
983 bool may_modify = (result == EXTENSION_ALLOWED);
984 if (!may_modify && error)
treib2170ea02015-10-13 14:55:12985 *error = GetExtensionsLockedMessage();
bauerb5f8cda92015-10-07 15:36:44986 return may_modify;
987}
988
989// Note: Having MustRemainInstalled always say "true" for custodian-installed
990// extensions does NOT prevent remote uninstalls (which is a bit unexpected, but
991// exactly what we want).
992bool SupervisedUserService::MustRemainInstalled(
993 const extensions::Extension* extension,
994 base::string16* error) const {
995 DCHECK(ProfileIsSupervised());
996 ExtensionState result = GetExtensionState(extension);
997 bool may_not_uninstall = (result == EXTENSION_FORCED);
998 if (may_not_uninstall && error)
treib2170ea02015-10-13 14:55:12999 *error = GetExtensionsLockedMessage();
bauerb5f8cda92015-10-07 15:36:441000 return may_not_uninstall;
1001}
1002
1003void SupervisedUserService::SetExtensionsActive() {
1004 extensions::ExtensionSystem* extension_system =
1005 extensions::ExtensionSystem::Get(profile_);
1006 extensions::ManagementPolicy* management_policy =
1007 extension_system->management_policy();
1008
1009 if (management_policy) {
1010 if (active_)
1011 management_policy->RegisterProvider(this);
1012 else
1013 management_policy->UnregisterProvider(this);
1014
1015 // Re-check the policy to make sure any new settings get applied.
1016 extension_system->extension_service()->CheckManagementPolicy();
1017 }
1018}
1019#endif // defined(ENABLE_EXTENSIONS)
1020
1021syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const {
1022 if (!ProfileIsSupervised())
1023 return syncer::ModelTypeSet();
1024
1025 syncer::ModelTypeSet result;
1026 if (IncludesSyncSessionsType())
1027 result.Put(syncer::SESSIONS);
1028 result.Put(syncer::EXTENSIONS);
1029 result.Put(syncer::EXTENSION_SETTINGS);
1030 result.Put(syncer::APPS);
1031 result.Put(syncer::APP_SETTINGS);
1032 result.Put(syncer::APP_NOTIFICATIONS);
1033 result.Put(syncer::APP_LIST);
1034 return result;
1035}
1036
jam1c5a91492016-02-24 20:47:531037#if !defined(OS_ANDROID)
bauerb5f8cda92015-10-07 15:36:441038void SupervisedUserService::OnStateChanged() {
1039 ProfileSyncService* service =
1040 ProfileSyncServiceFactory::GetForProfile(profile_);
zea32a7684cf2016-02-24 20:41:481041 if (waiting_for_sync_initialization_ && service->IsBackendInitialized()) {
bauerb5f8cda92015-10-07 15:36:441042 waiting_for_sync_initialization_ = false;
1043 service->RemoveObserver(this);
1044 FinishSetupSync();
1045 return;
1046 }
1047
1048 DLOG_IF(ERROR, service->GetAuthError().state() ==
1049 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
1050 << "Credentials rejected";
1051}
1052
1053void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
1054 bool profile_became_active = profile_->IsSameProfile(browser->profile());
1055 if (!is_profile_active_ && profile_became_active)
1056 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
1057 else if (is_profile_active_ && !profile_became_active)
1058 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
1059
1060 is_profile_active_ = profile_became_active;
1061}
jam1c5a91492016-02-24 20:47:531062#endif // !defined(OS_ANDROID)
bauerb5f8cda92015-10-07 15:36:441063
1064void SupervisedUserService::OnSiteListUpdated() {
1065 FOR_EACH_OBSERVER(
1066 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
1067}