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/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_info_cache.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
18 #include "chrome/browser/signin/signin_manager_factory.h"
19 #include "chrome/browser/supervised_user/custodian_profile_downloader_service.h"
20 #include "chrome/browser/supervised_user/custodian_profile_downloader_service_factory.h"
21 #include "chrome/browser/supervised_user/experimental/supervised_user_blacklist_downloader.h"
22 #include "chrome/browser/supervised_user/permission_request_creator_apiary.h"
23 #include "chrome/browser/supervised_user/permission_request_creator_sync.h"
24 #include "chrome/browser/supervised_user/supervised_user_constants.h"
25 #include "chrome/browser/supervised_user/supervised_user_pref_mapping_service.h"
26 #include "chrome/browser/supervised_user/supervised_user_pref_mapping_service_factory.h"
27 #include "chrome/browser/supervised_user/supervised_user_registration_utility.h"
28 #include "chrome/browser/supervised_user/supervised_user_service_observer.h"
29 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
30 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
31 #include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h"
32 #include "chrome/browser/supervised_user/supervised_user_site_list.h"
33 #include "chrome/browser/supervised_user/supervised_user_sync_service.h"
34 #include "chrome/browser/supervised_user/supervised_user_sync_service_factory.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 "google_apis/gaia/google_service_auth_error.h"
49 #include "ui/base/l10n/l10n_util.h"
51 #if defined(OS_CHROMEOS)
52 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
53 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
54 #include "components/user_manager/user_manager.h"
57 #if defined(ENABLE_EXTENSIONS)
58 #include "chrome/browser/extensions/extension_service.h"
59 #include "chrome/common/extensions/api/supervised_user_private/supervised_user_handler.h"
60 #include "extensions/browser/extension_registry.h"
61 #include "extensions/browser/extension_system.h"
62 #include "extensions/common/extension_set.h"
65 #if defined(ENABLE_THEMES)
66 #include "chrome/browser/themes/theme_service.h"
67 #include "chrome/browser/themes/theme_service_factory.h"
70 using base::DictionaryValue;
71 using base::UserMetricsAction;
72 using content::BrowserThread;
74 SupervisedUserService::URLFilterContext::URLFilterContext()
75 : ui_url_filter_(new SupervisedUserURLFilter),
76 io_url_filter_(new SupervisedUserURLFilter) {}
77 SupervisedUserService::URLFilterContext::~URLFilterContext() {}
79 SupervisedUserURLFilter*
80 SupervisedUserService::URLFilterContext::ui_url_filter() const {
81 return ui_url_filter_.get();
84 SupervisedUserURLFilter*
85 SupervisedUserService::URLFilterContext::io_url_filter() const {
86 return io_url_filter_.get();
89 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
90 SupervisedUserURLFilter::FilteringBehavior behavior) {
91 ui_url_filter_->SetDefaultFilteringBehavior(behavior);
92 BrowserThread::PostTask(
95 base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior,
96 io_url_filter_.get(), behavior));
99 void SupervisedUserService::URLFilterContext::LoadWhitelists(
100 ScopedVector<SupervisedUserSiteList> site_lists) {
101 // SupervisedUserURLFilter::LoadWhitelists takes ownership of |site_lists|,
102 // so we make an additional copy of it.
103 /// TODO(bauerb): This is kinda ugly.
104 ScopedVector<SupervisedUserSiteList> site_lists_copy;
105 for (ScopedVector<SupervisedUserSiteList>::iterator it = site_lists.begin();
106 it != site_lists.end(); ++it) {
107 site_lists_copy.push_back((*it)->Clone());
109 ui_url_filter_->LoadWhitelists(site_lists.Pass());
110 BrowserThread::PostTask(
113 base::Bind(&SupervisedUserURLFilter::LoadWhitelists,
114 io_url_filter_, base::Passed(&site_lists_copy)));
117 void SupervisedUserService::URLFilterContext::LoadBlacklist(
118 const base::FilePath& path) {
119 // For now, support loading only once. If we want to support re-load, we'll
120 // have to clear the blacklist pointer in the url filters first.
121 DCHECK_EQ(0u, blacklist_.GetEntryCount());
122 blacklist_.ReadFromFile(
124 base::Bind(&SupervisedUserService::URLFilterContext::OnBlacklistLoaded,
125 base::Unretained(this)));
128 void SupervisedUserService::URLFilterContext::SetManualHosts(
129 scoped_ptr<std::map<std::string, bool> > host_map) {
130 ui_url_filter_->SetManualHosts(host_map.get());
131 BrowserThread::PostTask(
134 base::Bind(&SupervisedUserURLFilter::SetManualHosts,
135 io_url_filter_, base::Owned(host_map.release())));
138 void SupervisedUserService::URLFilterContext::SetManualURLs(
139 scoped_ptr<std::map<GURL, bool> > url_map) {
140 ui_url_filter_->SetManualURLs(url_map.get());
141 BrowserThread::PostTask(
144 base::Bind(&SupervisedUserURLFilter::SetManualURLs,
145 io_url_filter_, base::Owned(url_map.release())));
148 void SupervisedUserService::URLFilterContext::OnBlacklistLoaded() {
149 ui_url_filter_->SetBlacklist(&blacklist_);
150 BrowserThread::PostTask(
153 base::Bind(&SupervisedUserURLFilter::SetBlacklist,
158 SupervisedUserService::SupervisedUserService(Profile* profile)
162 #if defined(ENABLE_EXTENSIONS)
163 extension_registry_observer_(this),
165 waiting_for_sync_initialization_(false),
166 is_profile_active_(false),
167 elevated_for_testing_(false),
169 did_shutdown_(false),
170 weak_ptr_factory_(this) {
173 SupervisedUserService::~SupervisedUserService() {
174 DCHECK(!did_init_ || did_shutdown_);
177 void SupervisedUserService::Shutdown() {
180 DCHECK(!did_shutdown_);
181 did_shutdown_ = true;
182 if (ProfileIsSupervised()) {
183 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
187 ProfileSyncService* sync_service =
188 ProfileSyncServiceFactory::GetForProfile(profile_);
189 // Can be null in tests.
191 sync_service->RemovePreferenceProvider(this);
194 bool SupervisedUserService::ProfileIsSupervised() const {
195 return profile_->IsSupervised();
198 void SupervisedUserService::OnCustodianInfoChanged() {
200 SupervisedUserServiceObserver, observer_list_, OnCustodianInfoChanged());
204 void SupervisedUserService::RegisterProfilePrefs(
205 user_prefs::PrefRegistrySyncable* registry) {
206 registry->RegisterDictionaryPref(
207 prefs::kSupervisedUserManualHosts,
208 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
209 registry->RegisterDictionaryPref(
210 prefs::kSupervisedUserManualURLs,
211 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
212 registry->RegisterIntegerPref(
213 prefs::kDefaultSupervisedUserFilteringBehavior,
214 SupervisedUserURLFilter::ALLOW,
215 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
216 registry->RegisterStringPref(
217 prefs::kSupervisedUserCustodianEmail, std::string(),
218 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
219 registry->RegisterStringPref(
220 prefs::kSupervisedUserCustodianName, std::string(),
221 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
222 registry->RegisterStringPref(
223 prefs::kSupervisedUserCustodianProfileImageURL, std::string(),
224 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
225 registry->RegisterStringPref(
226 prefs::kSupervisedUserCustodianProfileURL, std::string(),
227 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
228 registry->RegisterStringPref(
229 prefs::kSupervisedUserSecondCustodianEmail, std::string(),
230 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
231 registry->RegisterStringPref(
232 prefs::kSupervisedUserSecondCustodianName, std::string(),
233 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
234 registry->RegisterStringPref(
235 prefs::kSupervisedUserSecondCustodianProfileImageURL, std::string(),
236 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
237 registry->RegisterStringPref(
238 prefs::kSupervisedUserSecondCustodianProfileURL, std::string(),
239 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
240 registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true,
241 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
244 void SupervisedUserService::SetDelegate(Delegate* delegate) {
246 // Changing delegates isn't allowed.
249 // If the delegate is removed, deactivate first to give the old delegate a
250 // chance to clean up.
253 delegate_ = delegate;
256 scoped_refptr<const SupervisedUserURLFilter>
257 SupervisedUserService::GetURLFilterForIOThread() {
258 return url_filter_context_.io_url_filter();
261 SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
262 return url_filter_context_.ui_url_filter();
265 // Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js).
266 // Items on a list, but with no category, must return 0 (CATEGORY_OTHER).
267 #define CATEGORY_NOT_ON_LIST -1;
268 #define CATEGORY_OTHER 0;
270 int SupervisedUserService::GetCategory(const GURL& url) {
271 std::vector<SupervisedUserSiteList::Site*> sites;
272 GetURLFilterForUIThread()->GetSites(url, &sites);
274 return CATEGORY_NOT_ON_LIST;
276 return (*sites.begin())->category_id;
280 void SupervisedUserService::GetCategoryNames(CategoryList* list) {
281 SupervisedUserSiteList::GetCategoryNames(list);
284 std::string SupervisedUserService::GetCustodianEmailAddress() const {
285 #if defined(OS_CHROMEOS)
286 return chromeos::ChromeUserManager::Get()
287 ->GetSupervisedUserManager()
288 ->GetManagerDisplayEmail(
289 user_manager::UserManager::Get()->GetActiveUser()->email());
291 return profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianEmail);
295 std::string SupervisedUserService::GetCustodianName() const {
296 #if defined(OS_CHROMEOS)
297 return base::UTF16ToUTF8(
298 chromeos::ChromeUserManager::Get()
299 ->GetSupervisedUserManager()
300 ->GetManagerDisplayName(
301 user_manager::UserManager::Get()->GetActiveUser()->email()));
303 std::string name = profile_->GetPrefs()->GetString(
304 prefs::kSupervisedUserCustodianName);
305 return name.empty() ? GetCustodianEmailAddress() : name;
309 void SupervisedUserService::AddNavigationBlockedCallback(
310 const NavigationBlockedCallback& callback) {
311 navigation_blocked_callbacks_.push_back(callback);
314 void SupervisedUserService::DidBlockNavigation(
315 content::WebContents* web_contents) {
316 for (std::vector<NavigationBlockedCallback>::iterator it =
317 navigation_blocked_callbacks_.begin();
318 it != navigation_blocked_callbacks_.end(); ++it) {
319 it->Run(web_contents);
323 void SupervisedUserService::AddObserver(
324 SupervisedUserServiceObserver* observer) {
325 observer_list_.AddObserver(observer);
328 void SupervisedUserService::RemoveObserver(
329 SupervisedUserServiceObserver* observer) {
330 observer_list_.RemoveObserver(observer);
333 #if defined(ENABLE_EXTENSIONS)
334 std::string SupervisedUserService::GetDebugPolicyProviderName() const {
335 // Save the string space in official builds.
338 return std::string();
340 return "Supervised User Service";
344 bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
345 base::string16* error) const {
346 base::string16 tmp_error;
347 if (ExtensionManagementPolicyImpl(extension, &tmp_error))
350 bool was_installed_by_default = extension->was_installed_by_default();
351 bool was_installed_by_custodian = extension->was_installed_by_custodian();
352 #if defined(OS_CHROMEOS)
353 // On Chrome OS all external sources are controlled by us so it means that
354 // they are "default". Method was_installed_by_default returns false because
355 // extensions creation flags are ignored in case of default extensions with
356 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
357 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
358 // flags are not ignored.
359 was_installed_by_default =
360 extensions::Manifest::IsExternalLocation(extension->location());
362 if (extensions::Manifest::IsComponentLocation(extension->location()) ||
363 was_installed_by_default ||
364 was_installed_by_custodian) {
373 bool SupervisedUserService::UserMayModifySettings(
374 const extensions::Extension* extension,
375 base::string16* error) const {
376 return ExtensionManagementPolicyImpl(extension, error);
379 void SupervisedUserService::OnExtensionLoaded(
380 content::BrowserContext* browser_context,
381 const extensions::Extension* extension) {
382 if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension)
387 void SupervisedUserService::OnExtensionUnloaded(
388 content::BrowserContext* browser_context,
389 const extensions::Extension* extension,
390 extensions::UnloadedExtensionInfo::Reason reason) {
391 if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension)
396 #endif // defined(ENABLE_EXTENSIONS)
398 syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const {
399 if (!ProfileIsSupervised())
400 return syncer::ModelTypeSet();
402 syncer::ModelTypeSet result;
403 result.Put(syncer::SESSIONS);
404 result.Put(syncer::EXTENSIONS);
405 result.Put(syncer::EXTENSION_SETTINGS);
406 result.Put(syncer::APPS);
407 result.Put(syncer::APP_SETTINGS);
408 result.Put(syncer::APP_NOTIFICATIONS);
409 result.Put(syncer::APP_LIST);
413 void SupervisedUserService::OnStateChanged() {
414 ProfileSyncService* service =
415 ProfileSyncServiceFactory::GetForProfile(profile_);
416 if (waiting_for_sync_initialization_ && service->sync_initialized() &&
417 service->backend_mode() == ProfileSyncService::SYNC) {
418 waiting_for_sync_initialization_ = false;
419 service->RemoveObserver(this);
424 DLOG_IF(ERROR, service->GetAuthError().state() ==
425 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
426 << "Credentials rejected";
429 void SupervisedUserService::SetupSync() {
431 FinishSetupSyncWhenReady();
434 void SupervisedUserService::StartSetupSync() {
435 // Tell the sync service that setup is in progress so we don't start syncing
436 // until we've finished configuration.
437 ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true);
440 void SupervisedUserService::FinishSetupSyncWhenReady() {
441 // If we're already waiting for the Sync backend, there's nothing to do here.
442 if (waiting_for_sync_initialization_)
445 // Continue in FinishSetupSync() once the Sync backend has been initialized.
446 ProfileSyncService* service =
447 ProfileSyncServiceFactory::GetForProfile(profile_);
448 if (service->sync_initialized() &&
449 service->backend_mode() == ProfileSyncService::SYNC) {
452 service->AddObserver(this);
453 waiting_for_sync_initialization_ = true;
457 void SupervisedUserService::FinishSetupSync() {
458 ProfileSyncService* service =
459 ProfileSyncServiceFactory::GetForProfile(profile_);
460 DCHECK(service->sync_initialized() &&
461 service->backend_mode() == ProfileSyncService::SYNC);
463 // Sync nothing (except types which are set via GetPreferredDataTypes).
464 bool sync_everything = false;
465 syncer::ModelTypeSet synced_datatypes;
466 service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
468 // Notify ProfileSyncService that we are done with configuration.
469 service->SetSetupInProgress(false);
470 service->SetSyncSetupCompleted();
473 #if defined(ENABLE_EXTENSIONS)
474 bool SupervisedUserService::ExtensionManagementPolicyImpl(
475 const extensions::Extension* extension,
476 base::string16* error) const {
477 // |extension| can be NULL in unit_tests.
478 if (!ProfileIsSupervised() || (extension && extension->is_theme()))
481 if (elevated_for_testing_)
485 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
489 ScopedVector<SupervisedUserSiteList>
490 SupervisedUserService::GetActiveSiteLists() {
491 ScopedVector<SupervisedUserSiteList> site_lists;
492 ExtensionService* extension_service =
493 extensions::ExtensionSystem::Get(profile_)->extension_service();
494 // Can be NULL in unit tests.
495 if (!extension_service)
496 return site_lists.Pass();
498 const extensions::ExtensionSet* extensions = extension_service->extensions();
499 for (extensions::ExtensionSet::const_iterator it = extensions->begin();
500 it != extensions->end(); ++it) {
501 const extensions::Extension* extension = it->get();
502 if (!extension_service->IsExtensionEnabled(extension->id()))
505 extensions::ExtensionResource site_list =
506 extensions::SupervisedUserInfo::GetContentPackSiteList(extension);
507 if (!site_list.empty()) {
508 site_lists.push_back(new SupervisedUserSiteList(extension->id(),
509 site_list.GetFilePath()));
513 return site_lists.Pass();
516 void SupervisedUserService::SetExtensionsActive() {
517 extensions::ExtensionSystem* extension_system =
518 extensions::ExtensionSystem::Get(profile_);
519 extensions::ManagementPolicy* management_policy =
520 extension_system->management_policy();
523 if (management_policy)
524 management_policy->RegisterProvider(this);
526 extension_registry_observer_.Add(
527 extensions::ExtensionRegistry::Get(profile_));
529 if (management_policy)
530 management_policy->UnregisterProvider(this);
532 extension_registry_observer_.RemoveAll();
535 #endif // defined(ENABLE_EXTENSIONS)
537 SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
538 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
541 void SupervisedUserService::OnSupervisedUserIdChanged() {
542 std::string supervised_user_id =
543 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId);
544 SetActive(!supervised_user_id.empty());
547 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
548 DCHECK(ProfileIsSupervised());
550 int behavior_value = profile_->GetPrefs()->GetInteger(
551 prefs::kDefaultSupervisedUserFilteringBehavior);
552 SupervisedUserURLFilter::FilteringBehavior behavior =
553 SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
554 url_filter_context_.SetDefaultFilteringBehavior(behavior);
557 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
560 void SupervisedUserService::UpdateSiteLists() {
561 #if defined(ENABLE_EXTENSIONS)
562 url_filter_context_.LoadWhitelists(GetActiveSiteLists());
565 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
569 void SupervisedUserService::LoadBlacklist(const base::FilePath& path,
571 if (!url.is_valid()) {
572 LoadBlacklistFromFile(path);
576 DCHECK(!blacklist_downloader_.get());
577 blacklist_downloader_.reset(new SupervisedUserBlacklistDownloader(
580 profile_->GetRequestContext(),
581 base::Bind(&SupervisedUserService::OnBlacklistDownloadDone,
582 base::Unretained(this), path)));
585 void SupervisedUserService::LoadBlacklistFromFile(const base::FilePath& path) {
586 url_filter_context_.LoadBlacklist(path);
589 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
592 void SupervisedUserService::OnBlacklistDownloadDone(const base::FilePath& path,
595 LoadBlacklistFromFile(path);
597 LOG(WARNING) << "Blacklist download failed";
599 blacklist_downloader_.reset();
602 bool SupervisedUserService::AccessRequestsEnabled() {
603 ProfileSyncService* service =
604 ProfileSyncServiceFactory::GetForProfile(profile_);
605 GoogleServiceAuthError::State state = service->GetAuthError().state();
606 // We allow requesting access if Sync is working or has a transient error.
607 return (state == GoogleServiceAuthError::NONE ||
608 state == GoogleServiceAuthError::CONNECTION_FAILED ||
609 state == GoogleServiceAuthError::SERVICE_UNAVAILABLE);
612 void SupervisedUserService::OnPermissionRequestIssued() {
613 // TODO(akuegel): Figure out how to show the result of issuing the permission
614 // request in the UI. Currently, we assume the permission request was created
618 void SupervisedUserService::AddAccessRequest(const GURL& url) {
619 permissions_creator_->CreatePermissionRequest(
620 SupervisedUserURLFilter::Normalize(url),
621 base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
622 weak_ptr_factory_.GetWeakPtr()));
625 SupervisedUserService::ManualBehavior
626 SupervisedUserService::GetManualBehaviorForHost(
627 const std::string& hostname) {
628 const base::DictionaryValue* dict =
629 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
631 if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
634 return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
637 SupervisedUserService::ManualBehavior
638 SupervisedUserService::GetManualBehaviorForURL(
640 const base::DictionaryValue* dict =
641 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
642 GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
644 if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
647 return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
650 void SupervisedUserService::GetManualExceptionsForHost(
651 const std::string& host,
652 std::vector<GURL>* urls) {
653 const base::DictionaryValue* dict =
654 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
655 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
657 if (url.host() == host)
658 urls->push_back(url);
662 void SupervisedUserService::InitSync(const std::string& refresh_token) {
665 ProfileOAuth2TokenService* token_service =
666 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
667 token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
670 FinishSetupSyncWhenReady();
673 void SupervisedUserService::Init() {
676 DCHECK(GetSettingsService()->IsReady());
678 pref_change_registrar_.Init(profile_->GetPrefs());
679 pref_change_registrar_.Add(
680 prefs::kSupervisedUserId,
681 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
682 base::Unretained(this)));
684 ProfileSyncService* sync_service =
685 ProfileSyncServiceFactory::GetForProfile(profile_);
686 // Can be null in tests.
688 sync_service->AddPreferenceProvider(this);
690 SetActive(ProfileIsSupervised());
693 void SupervisedUserService::SetActive(bool active) {
694 if (active_ == active)
698 if (!delegate_ || !delegate_->SetActive(active_)) {
700 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
703 CommandLine* command_line = CommandLine::ForCurrentProcess();
704 if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
706 command_line->GetSwitchValueASCII(
707 switches::kSupervisedUserSyncToken));
710 ProfileOAuth2TokenService* token_service =
711 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
712 token_service->LoadCredentials(
713 supervised_users::kSupervisedUserPseudoEmail);
719 // Now activate/deactivate anything not handled by the delegate yet.
721 #if defined(ENABLE_THEMES)
722 // Re-set the default theme to turn the SU theme on/off.
723 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
724 if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme()) {
725 ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme();
729 ProfileSyncService* sync_service =
730 ProfileSyncServiceFactory::GetForProfile(profile_);
731 sync_service->SetEncryptEverythingAllowed(!active_);
733 SupervisedUserSettingsService* settings_service = GetSettingsService();
734 settings_service->SetActive(active_);
736 #if defined(ENABLE_EXTENSIONS)
737 SetExtensionsActive();
741 if (CommandLine::ForCurrentProcess()->HasSwitch(
742 switches::kPermissionRequestApiUrl)) {
743 permissions_creator_ =
744 PermissionRequestCreatorApiary::CreateWithProfile(profile_);
746 PrefService* pref_service = profile_->GetPrefs();
747 permissions_creator_.reset(new PermissionRequestCreatorSync(
749 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
751 GetSupervisedUserName(),
752 pref_service->GetString(prefs::kSupervisedUserId)));
755 pref_change_registrar_.Add(
756 prefs::kDefaultSupervisedUserFilteringBehavior,
757 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
758 base::Unretained(this)));
759 pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
760 base::Bind(&SupervisedUserService::UpdateManualHosts,
761 base::Unretained(this)));
762 pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
763 base::Bind(&SupervisedUserService::UpdateManualURLs,
764 base::Unretained(this)));
765 pref_change_registrar_.Add(prefs::kSupervisedUserCustodianName,
766 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
767 base::Unretained(this)));
768 pref_change_registrar_.Add(prefs::kSupervisedUserCustodianEmail,
769 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
770 base::Unretained(this)));
771 pref_change_registrar_.Add(prefs::kSupervisedUserCustodianProfileImageURL,
772 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
773 base::Unretained(this)));
774 pref_change_registrar_.Add(prefs::kSupervisedUserCustodianProfileURL,
775 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
776 base::Unretained(this)));
777 pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianName,
778 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
779 base::Unretained(this)));
780 pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianEmail,
781 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
782 base::Unretained(this)));
783 pref_change_registrar_.Add(
784 prefs::kSupervisedUserSecondCustodianProfileImageURL,
785 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
786 base::Unretained(this)));
787 pref_change_registrar_.Add(prefs::kSupervisedUserSecondCustodianProfileURL,
788 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
789 base::Unretained(this)));
791 // Initialize the filter.
792 OnDefaultFilteringBehaviorChanged();
797 CommandLine::ForCurrentProcess()->HasSwitch(
798 switches::kEnableSupervisedUserBlacklist);
799 if (delegate_ && use_blacklist) {
800 base::FilePath blacklist_path = delegate_->GetBlacklistPath();
801 if (!blacklist_path.empty())
802 LoadBlacklist(blacklist_path, delegate_->GetBlacklistURL());
805 #if !defined(OS_ANDROID)
806 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
807 // http://crbug.com/313377
808 BrowserList::AddObserver(this);
811 permissions_creator_.reset();
813 pref_change_registrar_.Remove(
814 prefs::kDefaultSupervisedUserFilteringBehavior);
815 pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
816 pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
818 if (waiting_for_sync_initialization_)
819 ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
821 #if !defined(OS_ANDROID)
822 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
823 // http://crbug.com/313377
824 BrowserList::RemoveObserver(this);
829 void SupervisedUserService::RegisterAndInitSync(
830 SupervisedUserRegistrationUtility* registration_utility,
831 Profile* custodian_profile,
832 const std::string& supervised_user_id,
833 const AuthErrorCallback& callback) {
834 DCHECK(ProfileIsSupervised());
835 DCHECK(!custodian_profile->IsSupervised());
837 base::string16 name = base::UTF8ToUTF16(
838 profile_->GetPrefs()->GetString(prefs::kProfileName));
839 int avatar_index = profile_->GetPrefs()->GetInteger(
840 prefs::kProfileAvatarIndex);
841 SupervisedUserRegistrationInfo info(name, avatar_index);
842 registration_utility->Register(
845 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
846 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
848 // Fetch the custodian's profile information, to store the name.
849 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
850 // is ever enabled, take the name from the ProfileInfoCache instead.
851 CustodianProfileDownloaderService* profile_downloader_service =
852 CustodianProfileDownloaderServiceFactory::GetForProfile(
854 profile_downloader_service->DownloadProfile(
855 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
856 weak_ptr_factory_.GetWeakPtr()));
859 void SupervisedUserService::OnCustodianProfileDownloaded(
860 const base::string16& full_name) {
861 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
862 base::UTF16ToUTF8(full_name));
865 void SupervisedUserService::OnSupervisedUserRegistered(
866 const AuthErrorCallback& callback,
867 Profile* custodian_profile,
868 const GoogleServiceAuthError& auth_error,
869 const std::string& token) {
870 if (auth_error.state() == GoogleServiceAuthError::NONE) {
872 SigninManagerBase* signin =
873 SigninManagerFactory::GetForProfile(custodian_profile);
874 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
875 signin->GetAuthenticatedUsername());
877 // The supervised user profile is now ready for use.
878 ProfileManager* profile_manager = g_browser_process->profile_manager();
879 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
880 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
881 cache.SetIsOmittedProfileAtIndex(index, false);
883 DCHECK_EQ(std::string(), token);
886 callback.Run(auth_error);
889 void SupervisedUserService::UpdateManualHosts() {
890 const base::DictionaryValue* dict =
891 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
892 scoped_ptr<std::map<std::string, bool> > host_map(
893 new std::map<std::string, bool>());
894 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
896 bool result = it.value().GetAsBoolean(&allow);
898 (*host_map)[it.key()] = allow;
900 url_filter_context_.SetManualHosts(host_map.Pass());
903 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
906 void SupervisedUserService::UpdateManualURLs() {
907 const base::DictionaryValue* dict =
908 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
909 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
910 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
912 bool result = it.value().GetAsBoolean(&allow);
914 (*url_map)[GURL(it.key())] = allow;
916 url_filter_context_.SetManualURLs(url_map.Pass());
919 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
922 void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
923 bool profile_became_active = profile_->IsSameProfile(browser->profile());
924 if (!is_profile_active_ && profile_became_active)
925 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
926 else if (is_profile_active_ && !profile_became_active)
927 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
929 is_profile_active_ = profile_became_active;
932 std::string SupervisedUserService::GetSupervisedUserName() const {
933 #if defined(OS_CHROMEOS)
934 // The active user can be NULL in unit tests.
935 if (user_manager::UserManager::Get()->GetActiveUser()) {
936 return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
937 user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
939 return std::string();
941 return profile_->GetPrefs()->GetString(prefs::kProfileName);