Supervised user SafeSites: Add a field trial to turn on/off.
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_service.cc
blob20c3f5a3f9708ff3c6f4840c20008f087fafbfab
1 // Copyright 2014 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.
5 #include "chrome/browser/supervised_user/supervised_user_service.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/version.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/component_updater/supervised_user_whitelist_installer.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/profiles/profile_info_cache.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
19 #include "chrome/browser/signin/signin_manager_factory.h"
20 #include "chrome/browser/supervised_user/experimental/supervised_user_blacklist_downloader.h"
21 #include "chrome/browser/supervised_user/experimental/supervised_user_filtering_switches.h"
22 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service.h"
23 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service_factory.h"
24 #include "chrome/browser/supervised_user/legacy/permission_request_creator_sync.h"
25 #include "chrome/browser/supervised_user/legacy/supervised_user_pref_mapping_service.h"
26 #include "chrome/browser/supervised_user/legacy/supervised_user_pref_mapping_service_factory.h"
27 #include "chrome/browser/supervised_user/legacy/supervised_user_registration_utility.h"
28 #include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_factory.h"
29 #include "chrome/browser/supervised_user/supervised_user_constants.h"
30 #include "chrome/browser/supervised_user/supervised_user_service_observer.h"
31 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
32 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
33 #include "chrome/browser/supervised_user/supervised_user_site_list.h"
34 #include "chrome/browser/supervised_user/supervised_user_whitelist_service.h"
35 #include "chrome/browser/sync/profile_sync_service.h"
36 #include "chrome/browser/sync/profile_sync_service_factory.h"
37 #include "chrome/browser/ui/browser.h"
38 #include "chrome/browser/ui/browser_list.h"
39 #include "chrome/common/chrome_switches.h"
40 #include "chrome/common/pref_names.h"
41 #include "chrome/grit/generated_resources.h"
42 #include "components/pref_registry/pref_registry_syncable.h"
43 #include "components/signin/core/browser/profile_oauth2_token_service.h"
44 #include "components/signin/core/browser/signin_manager.h"
45 #include "components/signin/core/browser/signin_manager_base.h"
46 #include "content/public/browser/browser_thread.h"
47 #include "content/public/browser/user_metrics.h"
48 #include "ui/base/l10n/l10n_util.h"
50 #if defined(OS_CHROMEOS)
51 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
52 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
53 #include "components/user_manager/user_manager.h"
54 #endif
56 #if defined(ENABLE_EXTENSIONS)
57 #include "extensions/browser/extension_registry.h"
58 #include "extensions/browser/extension_system.h"
59 #endif
61 #if defined(ENABLE_THEMES)
62 #include "chrome/browser/themes/theme_service.h"
63 #include "chrome/browser/themes/theme_service_factory.h"
64 #endif
66 using base::DictionaryValue;
67 using base::UserMetricsAction;
68 using content::BrowserThread;
70 namespace {
72 const char* const kCustodianInfoPrefs[] = {
73 prefs::kSupervisedUserCustodianName,
74 prefs::kSupervisedUserCustodianEmail,
75 prefs::kSupervisedUserCustodianProfileImageURL,
76 prefs::kSupervisedUserCustodianProfileURL,
77 prefs::kSupervisedUserSecondCustodianName,
78 prefs::kSupervisedUserSecondCustodianEmail,
79 prefs::kSupervisedUserSecondCustodianProfileImageURL,
80 prefs::kSupervisedUserSecondCustodianProfileURL,
83 void CreateURLAccessRequest(
84 const GURL& url,
85 PermissionRequestCreator* creator,
86 const SupervisedUserService::SuccessCallback& callback) {
87 creator->CreateURLAccessRequest(url, callback);
90 void CreateExtensionUpdateRequest(
91 const std::string& id,
92 PermissionRequestCreator* creator,
93 const SupervisedUserService::SuccessCallback& callback) {
94 creator->CreateExtensionUpdateRequest(id, callback);
97 #if defined(ENABLE_EXTENSIONS)
98 enum ExtensionState {
99 EXTENSION_FORCED,
100 EXTENSION_BLOCKED,
101 EXTENSION_ALLOWED
104 ExtensionState GetExtensionState(const extensions::Extension* extension) {
105 if (extension->is_theme())
106 return EXTENSION_ALLOWED;
108 bool was_installed_by_default = extension->was_installed_by_default();
109 bool was_installed_by_custodian = extension->was_installed_by_custodian();
110 #if defined(OS_CHROMEOS)
111 // On Chrome OS all external sources are controlled by us so it means that
112 // they are "default". Method was_installed_by_default returns false because
113 // extensions creation flags are ignored in case of default extensions with
114 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
115 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
116 // flags are not ignored.
117 was_installed_by_default =
118 extensions::Manifest::IsExternalLocation(extension->location());
119 #endif
120 if (extensions::Manifest::IsComponentLocation(extension->location()) ||
121 was_installed_by_default ||
122 was_installed_by_custodian) {
123 // Enforce default extensions as well as custodian-installed extensions
124 // (if we'd allow the supervised user to uninstall them, there'd be no way
125 // to get them back).
126 return EXTENSION_FORCED;
129 return EXTENSION_BLOCKED;
131 #endif
133 } // namespace
135 base::FilePath SupervisedUserService::Delegate::GetBlacklistPath() const {
136 return base::FilePath();
139 GURL SupervisedUserService::Delegate::GetBlacklistURL() const {
140 return GURL();
143 std::string SupervisedUserService::Delegate::GetSafeSitesCx() const {
144 return std::string();
147 SupervisedUserService::URLFilterContext::URLFilterContext()
148 : ui_url_filter_(new SupervisedUserURLFilter),
149 io_url_filter_(new SupervisedUserURLFilter) {}
150 SupervisedUserService::URLFilterContext::~URLFilterContext() {}
152 SupervisedUserURLFilter*
153 SupervisedUserService::URLFilterContext::ui_url_filter() const {
154 return ui_url_filter_.get();
157 SupervisedUserURLFilter*
158 SupervisedUserService::URLFilterContext::io_url_filter() const {
159 return io_url_filter_.get();
162 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
163 SupervisedUserURLFilter::FilteringBehavior behavior) {
164 ui_url_filter_->SetDefaultFilteringBehavior(behavior);
165 BrowserThread::PostTask(
166 BrowserThread::IO,
167 FROM_HERE,
168 base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
169 io_url_filter_.get(), behavior));
172 void SupervisedUserService::URLFilterContext::LoadWhitelists(
173 const std::vector<scoped_refptr<SupervisedUserSiteList> >& site_lists) {
174 ui_url_filter_->LoadWhitelists(site_lists);
175 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
176 base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
177 io_url_filter_, site_lists));
180 void SupervisedUserService::URLFilterContext::LoadBlacklist(
181 const base::FilePath& path,
182 const base::Closure& callback) {
183 // For now, support loading only once. If we want to support re-load, we'll
184 // have to clear the blacklist pointer in the url filters first.
185 DCHECK_EQ(0u, blacklist_.GetEntryCount());
186 blacklist_.ReadFromFile(
187 path,
188 base::Bind(&SupervisedUserService::URLFilterContext::OnBlacklistLoaded,
189 base::Unretained(this), callback));
192 void SupervisedUserService::URLFilterContext::SetManualHosts(
193 scoped_ptr<std::map<std::string, bool> > host_map) {
194 ui_url_filter_->SetManualHosts(host_map.get());
195 BrowserThread::PostTask(
196 BrowserThread::IO,
197 FROM_HERE,
198 base::Bind(&SupervisedUserURLFilter::SetManualHosts,
199 io_url_filter_, base::Owned(host_map.release())));
202 void SupervisedUserService::URLFilterContext::SetManualURLs(
203 scoped_ptr<std::map<GURL, bool> > url_map) {
204 ui_url_filter_->SetManualURLs(url_map.get());
205 BrowserThread::PostTask(
206 BrowserThread::IO,
207 FROM_HERE,
208 base::Bind(&SupervisedUserURLFilter::SetManualURLs,
209 io_url_filter_, base::Owned(url_map.release())));
212 void SupervisedUserService::URLFilterContext::Clear() {
213 ui_url_filter_->Clear();
214 BrowserThread::PostTask(
215 BrowserThread::IO,
216 FROM_HERE,
217 base::Bind(&SupervisedUserURLFilter::Clear,
218 io_url_filter_));
221 void SupervisedUserService::URLFilterContext::OnBlacklistLoaded(
222 const base::Closure& callback) {
223 ui_url_filter_->SetBlacklist(&blacklist_);
224 BrowserThread::PostTask(
225 BrowserThread::IO,
226 FROM_HERE,
227 base::Bind(&SupervisedUserURLFilter::SetBlacklist,
228 io_url_filter_,
229 &blacklist_));
230 callback.Run();
233 void SupervisedUserService::URLFilterContext::InitAsyncURLChecker(
234 const scoped_refptr<net::URLRequestContextGetter>& context,
235 const std::string& cx) {
236 ui_url_filter_->InitAsyncURLChecker(context.get(), cx);
237 BrowserThread::PostTask(
238 BrowserThread::IO,
239 FROM_HERE,
240 base::Bind(&SupervisedUserURLFilter::InitAsyncURLChecker,
241 io_url_filter_, context, cx));
244 SupervisedUserService::SupervisedUserService(Profile* profile)
245 : includes_sync_sessions_type_(true),
246 profile_(profile),
247 active_(false),
248 delegate_(NULL),
249 waiting_for_sync_initialization_(false),
250 is_profile_active_(false),
251 did_init_(false),
252 did_shutdown_(false),
253 weak_ptr_factory_(this) {
254 url_filter_context_.ui_url_filter()->AddObserver(this);
257 SupervisedUserService::~SupervisedUserService() {
258 DCHECK(!did_init_ || did_shutdown_);
259 url_filter_context_.ui_url_filter()->RemoveObserver(this);
262 void SupervisedUserService::Shutdown() {
263 if (!did_init_)
264 return;
265 DCHECK(!did_shutdown_);
266 did_shutdown_ = true;
267 if (ProfileIsSupervised()) {
268 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
270 SetActive(false);
272 ProfileSyncService* sync_service =
273 ProfileSyncServiceFactory::GetForProfile(profile_);
274 // Can be null in tests.
275 if (sync_service)
276 sync_service->RemovePreferenceProvider(this);
279 bool SupervisedUserService::ProfileIsSupervised() const {
280 return profile_->IsSupervised();
283 void SupervisedUserService::OnCustodianInfoChanged() {
284 FOR_EACH_OBSERVER(
285 SupervisedUserServiceObserver, observer_list_, OnCustodianInfoChanged());
288 // static
289 void SupervisedUserService::RegisterProfilePrefs(
290 user_prefs::PrefRegistrySyncable* registry) {
291 registry->RegisterDictionaryPref(
292 prefs::kSupervisedUserManualHosts,
293 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
294 registry->RegisterDictionaryPref(
295 prefs::kSupervisedUserManualURLs,
296 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
297 registry->RegisterIntegerPref(
298 prefs::kDefaultSupervisedUserFilteringBehavior,
299 SupervisedUserURLFilter::ALLOW,
300 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
301 registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true,
302 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
303 for (const char* pref : kCustodianInfoPrefs) {
304 registry->RegisterStringPref(pref, std::string(),
305 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
309 void SupervisedUserService::SetDelegate(Delegate* delegate) {
310 if (delegate) {
311 // Changing delegates isn't allowed.
312 DCHECK(!delegate_);
313 } else {
314 // If the delegate is removed, deactivate first to give the old delegate a
315 // chance to clean up.
316 SetActive(false);
318 delegate_ = delegate;
321 scoped_refptr<const SupervisedUserURLFilter>
322 SupervisedUserService::GetURLFilterForIOThread() {
323 return url_filter_context_.io_url_filter();
326 SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
327 return url_filter_context_.ui_url_filter();
330 SupervisedUserWhitelistService* SupervisedUserService::GetWhitelistService() {
331 return whitelist_service_.get();
334 std::string SupervisedUserService::GetCustodianEmailAddress() const {
335 std::string custodian_email = profile_->GetPrefs()->GetString(
336 prefs::kSupervisedUserCustodianEmail);
337 #if defined(OS_CHROMEOS)
338 if (custodian_email.empty()) {
339 custodian_email = chromeos::ChromeUserManager::Get()
340 ->GetSupervisedUserManager()
341 ->GetManagerDisplayEmail(
342 user_manager::UserManager::Get()->GetActiveUser()->email());
344 #endif
345 return custodian_email;
348 std::string SupervisedUserService::GetCustodianName() const {
349 std::string name = profile_->GetPrefs()->GetString(
350 prefs::kSupervisedUserCustodianName);
351 #if defined(OS_CHROMEOS)
352 if (name.empty()) {
353 name = base::UTF16ToUTF8(chromeos::ChromeUserManager::Get()
354 ->GetSupervisedUserManager()
355 ->GetManagerDisplayName(
356 user_manager::UserManager::Get()->GetActiveUser()->email()));
358 #endif
359 return name.empty() ? GetCustodianEmailAddress() : name;
362 std::string SupervisedUserService::GetSecondCustodianEmailAddress() const {
363 return profile_->GetPrefs()->GetString(
364 prefs::kSupervisedUserSecondCustodianEmail);
367 std::string SupervisedUserService::GetSecondCustodianName() const {
368 std::string name = profile_->GetPrefs()->GetString(
369 prefs::kSupervisedUserSecondCustodianName);
370 return name.empty() ? GetSecondCustodianEmailAddress() : name;
373 void SupervisedUserService::AddNavigationBlockedCallback(
374 const NavigationBlockedCallback& callback) {
375 navigation_blocked_callbacks_.push_back(callback);
378 void SupervisedUserService::DidBlockNavigation(
379 content::WebContents* web_contents) {
380 for (const auto& callback : navigation_blocked_callbacks_)
381 callback.Run(web_contents);
384 void SupervisedUserService::AddObserver(
385 SupervisedUserServiceObserver* observer) {
386 observer_list_.AddObserver(observer);
389 void SupervisedUserService::RemoveObserver(
390 SupervisedUserServiceObserver* observer) {
391 observer_list_.RemoveObserver(observer);
394 void SupervisedUserService::AddPermissionRequestCreator(
395 scoped_ptr<PermissionRequestCreator> creator) {
396 permissions_creators_.push_back(creator.release());
399 syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const {
400 if (!ProfileIsSupervised())
401 return syncer::ModelTypeSet();
403 syncer::ModelTypeSet result;
404 if (IncludesSyncSessionsType())
405 result.Put(syncer::SESSIONS);
406 result.Put(syncer::EXTENSIONS);
407 result.Put(syncer::EXTENSION_SETTINGS);
408 result.Put(syncer::APPS);
409 result.Put(syncer::APP_SETTINGS);
410 result.Put(syncer::APP_NOTIFICATIONS);
411 result.Put(syncer::APP_LIST);
412 return result;
415 void SupervisedUserService::OnHistoryRecordingStateChanged() {
416 bool record_history =
417 profile_->GetPrefs()->GetBoolean(prefs::kRecordHistory);
418 includes_sync_sessions_type_ = record_history;
419 ProfileSyncServiceFactory::GetForProfile(profile_)
420 ->ReconfigureDatatypeManager();
423 bool SupervisedUserService::IncludesSyncSessionsType() const {
424 return includes_sync_sessions_type_;
427 void SupervisedUserService::OnStateChanged() {
428 ProfileSyncService* service =
429 ProfileSyncServiceFactory::GetForProfile(profile_);
430 if (waiting_for_sync_initialization_ && service->backend_initialized() &&
431 service->backend_mode() == ProfileSyncService::SYNC) {
432 waiting_for_sync_initialization_ = false;
433 service->RemoveObserver(this);
434 FinishSetupSync();
435 return;
438 DLOG_IF(ERROR, service->GetAuthError().state() ==
439 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
440 << "Credentials rejected";
443 void SupervisedUserService::SetupSync() {
444 StartSetupSync();
445 FinishSetupSyncWhenReady();
448 void SupervisedUserService::StartSetupSync() {
449 // Tell the sync service that setup is in progress so we don't start syncing
450 // until we've finished configuration.
451 ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true);
454 void SupervisedUserService::FinishSetupSyncWhenReady() {
455 // If we're already waiting for the Sync backend, there's nothing to do here.
456 if (waiting_for_sync_initialization_)
457 return;
459 // Continue in FinishSetupSync() once the Sync backend has been initialized.
460 ProfileSyncService* service =
461 ProfileSyncServiceFactory::GetForProfile(profile_);
462 if (service->backend_initialized() &&
463 service->backend_mode() == ProfileSyncService::SYNC) {
464 FinishSetupSync();
465 } else {
466 service->AddObserver(this);
467 waiting_for_sync_initialization_ = true;
471 void SupervisedUserService::FinishSetupSync() {
472 ProfileSyncService* service =
473 ProfileSyncServiceFactory::GetForProfile(profile_);
474 DCHECK(service->backend_initialized());
475 DCHECK(service->backend_mode() == ProfileSyncService::SYNC);
477 // Sync nothing (except types which are set via GetPreferredDataTypes).
478 bool sync_everything = false;
479 syncer::ModelTypeSet synced_datatypes;
480 service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
482 // Notify ProfileSyncService that we are done with configuration.
483 service->SetSetupInProgress(false);
484 service->SetSyncSetupCompleted();
487 #if defined(ENABLE_EXTENSIONS)
488 std::string SupervisedUserService::GetDebugPolicyProviderName() const {
489 // Save the string space in official builds.
490 #ifdef NDEBUG
491 NOTREACHED();
492 return std::string();
493 #else
494 return "Supervised User Service";
495 #endif
498 bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
499 base::string16* error) const {
500 DCHECK(ProfileIsSupervised());
501 ExtensionState result = GetExtensionState(extension);
502 bool may_load = (result != EXTENSION_BLOCKED);
503 if (!may_load && error)
504 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
505 return may_load;
508 bool SupervisedUserService::UserMayModifySettings(
509 const extensions::Extension* extension,
510 base::string16* error) const {
511 DCHECK(ProfileIsSupervised());
512 ExtensionState result = GetExtensionState(extension);
513 bool may_modify = (result == EXTENSION_ALLOWED);
514 if (!may_modify && error)
515 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
516 return may_modify;
519 // Note: Having MustRemainInstalled always say "true" for custodian-installed
520 // extensions does NOT prevent remote uninstalls (which is a bit unexpected, but
521 // exactly what we want).
522 bool SupervisedUserService::MustRemainInstalled(
523 const extensions::Extension* extension,
524 base::string16* error) const {
525 DCHECK(ProfileIsSupervised());
526 ExtensionState result = GetExtensionState(extension);
527 bool may_not_uninstall = (result == EXTENSION_FORCED);
528 if (may_not_uninstall && error)
529 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
530 return may_not_uninstall;
533 void SupervisedUserService::SetExtensionsActive() {
534 extensions::ExtensionSystem* extension_system =
535 extensions::ExtensionSystem::Get(profile_);
536 extensions::ManagementPolicy* management_policy =
537 extension_system->management_policy();
539 if (management_policy) {
540 if (active_)
541 management_policy->RegisterProvider(this);
542 else
543 management_policy->UnregisterProvider(this);
546 #endif // defined(ENABLE_EXTENSIONS)
548 SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
549 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
552 size_t SupervisedUserService::FindEnabledPermissionRequestCreator(
553 size_t start) {
554 for (size_t i = start; i < permissions_creators_.size(); ++i) {
555 if (permissions_creators_[i]->IsEnabled())
556 return i;
558 return permissions_creators_.size();
561 void SupervisedUserService::AddPermissionRequestInternal(
562 const CreatePermissionRequestCallback& create_request,
563 const SuccessCallback& callback,
564 size_t index) {
565 // Find a permission request creator that is enabled.
566 size_t next_index = FindEnabledPermissionRequestCreator(index);
567 if (next_index >= permissions_creators_.size()) {
568 callback.Run(false);
569 return;
572 create_request.Run(
573 permissions_creators_[next_index],
574 base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
575 weak_ptr_factory_.GetWeakPtr(), create_request,
576 callback, next_index));
579 void SupervisedUserService::OnPermissionRequestIssued(
580 const CreatePermissionRequestCallback& create_request,
581 const SuccessCallback& callback,
582 size_t index,
583 bool success) {
584 if (success) {
585 callback.Run(true);
586 return;
589 AddPermissionRequestInternal(create_request, callback, index + 1);
592 void SupervisedUserService::OnSupervisedUserIdChanged() {
593 SetActive(ProfileIsSupervised());
596 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
597 DCHECK(ProfileIsSupervised());
599 int behavior_value = profile_->GetPrefs()->GetInteger(
600 prefs::kDefaultSupervisedUserFilteringBehavior);
601 SupervisedUserURLFilter::FilteringBehavior behavior =
602 SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
603 url_filter_context_.SetDefaultFilteringBehavior(behavior);
605 FOR_EACH_OBSERVER(
606 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
609 void SupervisedUserService::OnSiteListsChanged(
610 const std::vector<scoped_refptr<SupervisedUserSiteList> >& site_lists) {
611 url_filter_context_.LoadWhitelists(site_lists);
614 void SupervisedUserService::OnSiteListUpdated() {
615 FOR_EACH_OBSERVER(
616 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
619 void SupervisedUserService::LoadBlacklist(const base::FilePath& path,
620 const GURL& url) {
621 if (!url.is_valid()) {
622 LoadBlacklistFromFile(path);
623 return;
626 DCHECK(!blacklist_downloader_);
627 blacklist_downloader_.reset(new SupervisedUserBlacklistDownloader(
628 url,
629 path,
630 profile_->GetRequestContext(),
631 base::Bind(&SupervisedUserService::OnBlacklistDownloadDone,
632 base::Unretained(this), path)));
635 void SupervisedUserService::LoadBlacklistFromFile(const base::FilePath& path) {
636 // This object is guaranteed to outlive the URLFilterContext, so we can bind a
637 // raw pointer to it in the callback.
638 url_filter_context_.LoadBlacklist(
639 path, base::Bind(&SupervisedUserService::OnBlacklistLoaded,
640 base::Unretained(this)));
643 void SupervisedUserService::OnBlacklistDownloadDone(const base::FilePath& path,
644 bool success) {
645 if (success) {
646 LoadBlacklistFromFile(path);
647 } else {
648 LOG(WARNING) << "Blacklist download failed";
650 blacklist_downloader_.reset();
653 void SupervisedUserService::OnBlacklistLoaded() {
654 FOR_EACH_OBSERVER(
655 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
658 bool SupervisedUserService::AccessRequestsEnabled() {
659 return FindEnabledPermissionRequestCreator(0) < permissions_creators_.size();
662 void SupervisedUserService::AddURLAccessRequest(
663 const GURL& url,
664 const SuccessCallback& callback) {
665 AddPermissionRequestInternal(
666 base::Bind(CreateURLAccessRequest,
667 SupervisedUserURLFilter::Normalize(url)),
668 callback, 0);
671 void SupervisedUserService::AddExtensionUpdateRequest(
672 const std::string& extension_id,
673 const base::Version& version,
674 const SuccessCallback& callback) {
675 std::string id = extension_id + ":" + version.GetString();
676 AddPermissionRequestInternal(
677 base::Bind(CreateExtensionUpdateRequest, id),
678 callback, 0);
681 void SupervisedUserService::InitSync(const std::string& refresh_token) {
682 StartSetupSync();
684 ProfileOAuth2TokenService* token_service =
685 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
686 token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
687 refresh_token);
689 FinishSetupSyncWhenReady();
692 void SupervisedUserService::Init() {
693 DCHECK(!did_init_);
694 did_init_ = true;
695 DCHECK(GetSettingsService()->IsReady());
697 pref_change_registrar_.Init(profile_->GetPrefs());
698 pref_change_registrar_.Add(
699 prefs::kSupervisedUserId,
700 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
701 base::Unretained(this)));
702 pref_change_registrar_.Add(
703 prefs::kRecordHistory,
704 base::Bind(&SupervisedUserService::OnHistoryRecordingStateChanged,
705 base::Unretained(this)));
707 ProfileSyncService* sync_service =
708 ProfileSyncServiceFactory::GetForProfile(profile_);
709 // Can be null in tests.
710 if (sync_service)
711 sync_service->AddPreferenceProvider(this);
713 std::string client_id = component_updater::SupervisedUserWhitelistInstaller::
714 ClientIdForProfilePath(profile_->GetPath());
715 whitelist_service_.reset(new SupervisedUserWhitelistService(
716 profile_->GetPrefs(),
717 g_browser_process->supervised_user_whitelist_installer(), client_id));
718 whitelist_service_->AddSiteListsChangedCallback(
719 base::Bind(&SupervisedUserService::OnSiteListsChanged,
720 weak_ptr_factory_.GetWeakPtr()));
722 SetActive(ProfileIsSupervised());
725 void SupervisedUserService::SetActive(bool active) {
726 if (active_ == active)
727 return;
728 active_ = active;
730 if (!delegate_ || !delegate_->SetActive(active_)) {
731 if (active_) {
732 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
733 ->Init();
735 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
736 if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
737 InitSync(
738 command_line->GetSwitchValueASCII(
739 switches::kSupervisedUserSyncToken));
742 ProfileOAuth2TokenService* token_service =
743 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
744 token_service->LoadCredentials(
745 supervised_users::kSupervisedUserPseudoEmail);
747 permissions_creators_.push_back(new PermissionRequestCreatorSync(
748 GetSettingsService(),
749 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
750 profile_),
751 ProfileSyncServiceFactory::GetForProfile(profile_),
752 GetSupervisedUserName(),
753 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId)));
755 SetupSync();
759 // Now activate/deactivate anything not handled by the delegate yet.
761 #if defined(ENABLE_THEMES)
762 // Re-set the default theme to turn the SU theme on/off.
763 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
764 if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme()) {
765 ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme();
767 #endif
769 ProfileSyncService* sync_service =
770 ProfileSyncServiceFactory::GetForProfile(profile_);
771 sync_service->SetEncryptEverythingAllowed(!active_);
773 GetSettingsService()->SetActive(active_);
775 #if defined(ENABLE_EXTENSIONS)
776 SetExtensionsActive();
777 #endif
779 if (active_) {
780 pref_change_registrar_.Add(
781 prefs::kDefaultSupervisedUserFilteringBehavior,
782 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
783 base::Unretained(this)));
784 pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
785 base::Bind(&SupervisedUserService::UpdateManualHosts,
786 base::Unretained(this)));
787 pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
788 base::Bind(&SupervisedUserService::UpdateManualURLs,
789 base::Unretained(this)));
790 for (const char* pref : kCustodianInfoPrefs) {
791 pref_change_registrar_.Add(pref,
792 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
793 base::Unretained(this)));
796 // Initialize the filter.
797 OnDefaultFilteringBehaviorChanged();
798 whitelist_service_->Init();
799 UpdateManualHosts();
800 UpdateManualURLs();
801 if (profile_->IsChild() &&
802 supervised_users::IsSafeSitesBlacklistEnabled()) {
803 base::FilePath blacklist_path = delegate_->GetBlacklistPath();
804 if (!blacklist_path.empty())
805 LoadBlacklist(blacklist_path, delegate_->GetBlacklistURL());
807 if (profile_->IsChild() &&
808 supervised_users::IsSafeSitesOnlineCheckEnabled()) {
809 const std::string& cx = delegate_->GetSafeSitesCx();
810 if (!cx.empty()) {
811 url_filter_context_.InitAsyncURLChecker(
812 profile_->GetRequestContext(), cx);
816 #if !defined(OS_ANDROID)
817 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
818 // http://crbug.com/313377
819 BrowserList::AddObserver(this);
820 #endif
821 } else {
822 permissions_creators_.clear();
824 pref_change_registrar_.Remove(
825 prefs::kDefaultSupervisedUserFilteringBehavior);
826 pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
827 pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
828 for (const char* pref : kCustodianInfoPrefs) {
829 pref_change_registrar_.Remove(pref);
832 url_filter_context_.Clear();
833 FOR_EACH_OBSERVER(
834 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
836 if (waiting_for_sync_initialization_)
837 ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
839 #if !defined(OS_ANDROID)
840 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
841 // http://crbug.com/313377
842 BrowserList::RemoveObserver(this);
843 #endif
847 void SupervisedUserService::RegisterAndInitSync(
848 SupervisedUserRegistrationUtility* registration_utility,
849 Profile* custodian_profile,
850 const std::string& supervised_user_id,
851 const AuthErrorCallback& callback) {
852 DCHECK(ProfileIsSupervised());
853 DCHECK(!custodian_profile->IsSupervised());
855 base::string16 name = base::UTF8ToUTF16(
856 profile_->GetPrefs()->GetString(prefs::kProfileName));
857 int avatar_index = profile_->GetPrefs()->GetInteger(
858 prefs::kProfileAvatarIndex);
859 SupervisedUserRegistrationInfo info(name, avatar_index);
860 registration_utility->Register(
861 supervised_user_id,
862 info,
863 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
864 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
866 // Fetch the custodian's profile information, to store the name.
867 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
868 // is ever enabled, take the name from the ProfileInfoCache instead.
869 CustodianProfileDownloaderService* profile_downloader_service =
870 CustodianProfileDownloaderServiceFactory::GetForProfile(
871 custodian_profile);
872 profile_downloader_service->DownloadProfile(
873 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
874 weak_ptr_factory_.GetWeakPtr()));
877 void SupervisedUserService::OnCustodianProfileDownloaded(
878 const base::string16& full_name) {
879 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
880 base::UTF16ToUTF8(full_name));
883 void SupervisedUserService::OnSupervisedUserRegistered(
884 const AuthErrorCallback& callback,
885 Profile* custodian_profile,
886 const GoogleServiceAuthError& auth_error,
887 const std::string& token) {
888 if (auth_error.state() == GoogleServiceAuthError::NONE) {
889 InitSync(token);
890 SigninManagerBase* signin =
891 SigninManagerFactory::GetForProfile(custodian_profile);
892 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
893 signin->GetAuthenticatedUsername());
895 // The supervised user profile is now ready for use.
896 ProfileManager* profile_manager = g_browser_process->profile_manager();
897 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
898 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
899 cache.SetIsOmittedProfileAtIndex(index, false);
900 } else {
901 DCHECK_EQ(std::string(), token);
904 callback.Run(auth_error);
907 void SupervisedUserService::UpdateManualHosts() {
908 const base::DictionaryValue* dict =
909 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
910 scoped_ptr<std::map<std::string, bool> > host_map(
911 new std::map<std::string, bool>());
912 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
913 bool allow = false;
914 bool result = it.value().GetAsBoolean(&allow);
915 DCHECK(result);
916 (*host_map)[it.key()] = allow;
918 url_filter_context_.SetManualHosts(host_map.Pass());
920 FOR_EACH_OBSERVER(
921 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
924 void SupervisedUserService::UpdateManualURLs() {
925 const base::DictionaryValue* dict =
926 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
927 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
928 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
929 bool allow = false;
930 bool result = it.value().GetAsBoolean(&allow);
931 DCHECK(result);
932 (*url_map)[GURL(it.key())] = allow;
934 url_filter_context_.SetManualURLs(url_map.Pass());
936 FOR_EACH_OBSERVER(
937 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
940 void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
941 bool profile_became_active = profile_->IsSameProfile(browser->profile());
942 if (!is_profile_active_ && profile_became_active)
943 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
944 else if (is_profile_active_ && !profile_became_active)
945 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
947 is_profile_active_ = profile_became_active;
950 std::string SupervisedUserService::GetSupervisedUserName() const {
951 #if defined(OS_CHROMEOS)
952 // The active user can be NULL in unit tests.
953 if (user_manager::UserManager::Get()->GetActiveUser()) {
954 return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
955 user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
957 return std::string();
958 #else
959 return profile_->GetPrefs()->GetString(prefs::kProfileName);
960 #endif