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/files/file_util.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/path_service.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/task_runner_util.h"
15 #include "base/version.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/component_updater/supervised_user_whitelist_installer.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/profiles/profile_info_cache.h"
20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
22 #include "chrome/browser/signin/signin_manager_factory.h"
23 #include "chrome/browser/supervised_user/experimental/supervised_user_blacklist_downloader.h"
24 #include "chrome/browser/supervised_user/experimental/supervised_user_filtering_switches.h"
25 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service.h"
26 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service_factory.h"
27 #include "chrome/browser/supervised_user/legacy/permission_request_creator_sync.h"
28 #include "chrome/browser/supervised_user/legacy/supervised_user_pref_mapping_service.h"
29 #include "chrome/browser/supervised_user/legacy/supervised_user_pref_mapping_service_factory.h"
30 #include "chrome/browser/supervised_user/legacy/supervised_user_registration_utility.h"
31 #include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_factory.h"
32 #include "chrome/browser/supervised_user/supervised_user_constants.h"
33 #include "chrome/browser/supervised_user/supervised_user_service_observer.h"
34 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
35 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
36 #include "chrome/browser/supervised_user/supervised_user_site_list.h"
37 #include "chrome/browser/supervised_user/supervised_user_whitelist_service.h"
38 #include "chrome/browser/sync/profile_sync_service.h"
39 #include "chrome/browser/sync/profile_sync_service_factory.h"
40 #include "chrome/browser/ui/browser.h"
41 #include "chrome/browser/ui/browser_list.h"
42 #include "chrome/common/chrome_paths.h"
43 #include "chrome/common/chrome_switches.h"
44 #include "chrome/common/pref_names.h"
45 #include "chrome/grit/generated_resources.h"
46 #include "components/pref_registry/pref_registry_syncable.h"
47 #include "components/signin/core/browser/profile_oauth2_token_service.h"
48 #include "components/signin/core/browser/signin_manager.h"
49 #include "components/signin/core/browser/signin_manager_base.h"
50 #include "content/public/browser/browser_thread.h"
51 #include "content/public/browser/user_metrics.h"
52 #include "ui/base/l10n/l10n_util.h"
54 #if defined(OS_CHROMEOS)
55 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
56 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
57 #include "components/user_manager/user_manager.h"
60 #if defined(ENABLE_EXTENSIONS)
61 #include "chrome/browser/extensions/extension_service.h"
62 #include "extensions/browser/extension_system.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
;
76 // The URL from which to download a host blacklist if no local one exists yet.
77 const char kBlacklistURL
[] =
78 "https://www.gstatic.com/chrome/supervised_user/blacklist-20141001-1k.bin";
79 // The filename under which we'll store the blacklist (in the user data dir).
80 const char kBlacklistFilename
[] = "su-blacklist.bin";
82 const char* const kCustodianInfoPrefs
[] = {
83 prefs::kSupervisedUserCustodianName
,
84 prefs::kSupervisedUserCustodianEmail
,
85 prefs::kSupervisedUserCustodianProfileImageURL
,
86 prefs::kSupervisedUserCustodianProfileURL
,
87 prefs::kSupervisedUserSecondCustodianName
,
88 prefs::kSupervisedUserSecondCustodianEmail
,
89 prefs::kSupervisedUserSecondCustodianProfileImageURL
,
90 prefs::kSupervisedUserSecondCustodianProfileURL
,
93 void CreateURLAccessRequest(
95 PermissionRequestCreator
* creator
,
96 const SupervisedUserService::SuccessCallback
& callback
) {
97 creator
->CreateURLAccessRequest(url
, callback
);
100 void CreateExtensionUpdateRequest(
101 const std::string
& id
,
102 PermissionRequestCreator
* creator
,
103 const SupervisedUserService::SuccessCallback
& callback
) {
104 creator
->CreateExtensionUpdateRequest(id
, callback
);
107 base::FilePath
GetBlacklistPath() {
108 base::FilePath blacklist_dir
;
109 PathService::Get(chrome::DIR_USER_DATA
, &blacklist_dir
);
110 return blacklist_dir
.AppendASCII(kBlacklistFilename
);
113 #if defined(ENABLE_EXTENSIONS)
114 enum ExtensionState
{
120 ExtensionState
GetExtensionState(const extensions::Extension
* extension
) {
121 bool was_installed_by_default
= extension
->was_installed_by_default();
122 #if defined(OS_CHROMEOS)
123 // On Chrome OS all external sources are controlled by us so it means that
124 // they are "default". Method was_installed_by_default returns false because
125 // extensions creation flags are ignored in case of default extensions with
126 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound).
127 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation
128 // flags are not ignored.
129 was_installed_by_default
=
130 extensions::Manifest::IsExternalLocation(extension
->location());
132 // Note: Component extensions are protected from modification/uninstallation
133 // anyway, so there's no need to enforce them again for supervised users.
134 if (extensions::Manifest::IsComponentLocation(extension
->location()) ||
135 extension
->is_theme() ||
136 extension
->from_bookmark() ||
137 was_installed_by_default
) {
138 return EXTENSION_ALLOWED
;
141 if (extension
->was_installed_by_custodian())
142 return EXTENSION_FORCED
;
144 return EXTENSION_BLOCKED
;
150 SupervisedUserService::URLFilterContext::URLFilterContext()
151 : ui_url_filter_(new SupervisedUserURLFilter
),
152 io_url_filter_(new SupervisedUserURLFilter
) {}
153 SupervisedUserService::URLFilterContext::~URLFilterContext() {}
155 SupervisedUserURLFilter
*
156 SupervisedUserService::URLFilterContext::ui_url_filter() const {
157 return ui_url_filter_
.get();
160 SupervisedUserURLFilter
*
161 SupervisedUserService::URLFilterContext::io_url_filter() const {
162 return io_url_filter_
.get();
165 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
166 SupervisedUserURLFilter::FilteringBehavior behavior
) {
167 ui_url_filter_
->SetDefaultFilteringBehavior(behavior
);
168 BrowserThread::PostTask(
171 base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior
,
172 io_url_filter_
.get(), behavior
));
175 void SupervisedUserService::URLFilterContext::LoadWhitelists(
176 const std::vector
<scoped_refptr
<SupervisedUserSiteList
> >& site_lists
) {
177 ui_url_filter_
->LoadWhitelists(site_lists
);
178 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
179 base::Bind(&SupervisedUserURLFilter::LoadWhitelists
,
180 io_url_filter_
, site_lists
));
183 void SupervisedUserService::URLFilterContext::LoadBlacklist(
184 const base::FilePath
& path
,
185 const base::Closure
& callback
) {
186 // For now, support loading only once. If we want to support re-load, we'll
187 // have to clear the blacklist pointer in the url filters first.
188 DCHECK_EQ(0u, blacklist_
.GetEntryCount());
189 blacklist_
.ReadFromFile(
191 base::Bind(&SupervisedUserService::URLFilterContext::OnBlacklistLoaded
,
192 base::Unretained(this), callback
));
195 void SupervisedUserService::URLFilterContext::SetManualHosts(
196 scoped_ptr
<std::map
<std::string
, bool> > host_map
) {
197 ui_url_filter_
->SetManualHosts(host_map
.get());
198 BrowserThread::PostTask(
201 base::Bind(&SupervisedUserURLFilter::SetManualHosts
,
202 io_url_filter_
, base::Owned(host_map
.release())));
205 void SupervisedUserService::URLFilterContext::SetManualURLs(
206 scoped_ptr
<std::map
<GURL
, bool> > url_map
) {
207 ui_url_filter_
->SetManualURLs(url_map
.get());
208 BrowserThread::PostTask(
211 base::Bind(&SupervisedUserURLFilter::SetManualURLs
,
212 io_url_filter_
, base::Owned(url_map
.release())));
215 void SupervisedUserService::URLFilterContext::Clear() {
216 ui_url_filter_
->Clear();
217 BrowserThread::PostTask(
220 base::Bind(&SupervisedUserURLFilter::Clear
,
224 void SupervisedUserService::URLFilterContext::OnBlacklistLoaded(
225 const base::Closure
& callback
) {
226 ui_url_filter_
->SetBlacklist(&blacklist_
);
227 BrowserThread::PostTask(
230 base::Bind(&SupervisedUserURLFilter::SetBlacklist
,
236 void SupervisedUserService::URLFilterContext::InitAsyncURLChecker(
237 const scoped_refptr
<net::URLRequestContextGetter
>& context
) {
238 ui_url_filter_
->InitAsyncURLChecker(context
.get());
239 BrowserThread::PostTask(
242 base::Bind(&SupervisedUserURLFilter::InitAsyncURLChecker
,
243 io_url_filter_
, context
));
246 SupervisedUserService::SupervisedUserService(Profile
* profile
)
247 : includes_sync_sessions_type_(true),
251 waiting_for_sync_initialization_(false),
252 is_profile_active_(false),
254 did_shutdown_(false),
255 weak_ptr_factory_(this) {
256 url_filter_context_
.ui_url_filter()->AddObserver(this);
259 SupervisedUserService::~SupervisedUserService() {
260 DCHECK(!did_init_
|| did_shutdown_
);
261 url_filter_context_
.ui_url_filter()->RemoveObserver(this);
264 void SupervisedUserService::Shutdown() {
267 DCHECK(!did_shutdown_
);
268 did_shutdown_
= true;
269 if (ProfileIsSupervised()) {
270 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
274 ProfileSyncService
* sync_service
=
275 ProfileSyncServiceFactory::GetForProfile(profile_
);
276 // Can be null in tests.
278 sync_service
->RemovePreferenceProvider(this);
281 bool SupervisedUserService::ProfileIsSupervised() const {
282 return profile_
->IsSupervised();
285 void SupervisedUserService::OnCustodianInfoChanged() {
287 SupervisedUserServiceObserver
, observer_list_
, OnCustodianInfoChanged());
291 void SupervisedUserService::RegisterProfilePrefs(
292 user_prefs::PrefRegistrySyncable
* registry
) {
293 registry
->RegisterDictionaryPref(prefs::kSupervisedUserManualHosts
);
294 registry
->RegisterDictionaryPref(prefs::kSupervisedUserManualURLs
);
295 registry
->RegisterIntegerPref(prefs::kDefaultSupervisedUserFilteringBehavior
,
296 SupervisedUserURLFilter::ALLOW
);
297 registry
->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed
, true);
298 for (const char* pref
: kCustodianInfoPrefs
) {
299 registry
->RegisterStringPref(pref
, std::string());
303 void SupervisedUserService::SetDelegate(Delegate
* delegate
) {
305 // Changing delegates isn't allowed.
308 // If the delegate is removed, deactivate first to give the old delegate a
309 // chance to clean up.
312 delegate_
= delegate
;
315 scoped_refptr
<const SupervisedUserURLFilter
>
316 SupervisedUserService::GetURLFilterForIOThread() {
317 return url_filter_context_
.io_url_filter();
320 SupervisedUserURLFilter
* SupervisedUserService::GetURLFilterForUIThread() {
321 return url_filter_context_
.ui_url_filter();
324 SupervisedUserWhitelistService
* SupervisedUserService::GetWhitelistService() {
325 return whitelist_service_
.get();
328 std::string
SupervisedUserService::GetCustodianEmailAddress() const {
329 std::string custodian_email
= profile_
->GetPrefs()->GetString(
330 prefs::kSupervisedUserCustodianEmail
);
331 #if defined(OS_CHROMEOS)
332 if (custodian_email
.empty()) {
333 custodian_email
= chromeos::ChromeUserManager::Get()
334 ->GetSupervisedUserManager()
335 ->GetManagerDisplayEmail(
336 user_manager::UserManager::Get()->GetActiveUser()->email());
339 return custodian_email
;
342 std::string
SupervisedUserService::GetCustodianName() const {
343 std::string name
= profile_
->GetPrefs()->GetString(
344 prefs::kSupervisedUserCustodianName
);
345 #if defined(OS_CHROMEOS)
347 name
= base::UTF16ToUTF8(chromeos::ChromeUserManager::Get()
348 ->GetSupervisedUserManager()
349 ->GetManagerDisplayName(
350 user_manager::UserManager::Get()->GetActiveUser()->email()));
353 return name
.empty() ? GetCustodianEmailAddress() : name
;
356 std::string
SupervisedUserService::GetSecondCustodianEmailAddress() const {
357 return profile_
->GetPrefs()->GetString(
358 prefs::kSupervisedUserSecondCustodianEmail
);
361 std::string
SupervisedUserService::GetSecondCustodianName() const {
362 std::string name
= profile_
->GetPrefs()->GetString(
363 prefs::kSupervisedUserSecondCustodianName
);
364 return name
.empty() ? GetSecondCustodianEmailAddress() : name
;
367 void SupervisedUserService::AddNavigationBlockedCallback(
368 const NavigationBlockedCallback
& callback
) {
369 navigation_blocked_callbacks_
.push_back(callback
);
372 void SupervisedUserService::DidBlockNavigation(
373 content::WebContents
* web_contents
) {
374 for (const auto& callback
: navigation_blocked_callbacks_
)
375 callback
.Run(web_contents
);
378 void SupervisedUserService::AddObserver(
379 SupervisedUserServiceObserver
* observer
) {
380 observer_list_
.AddObserver(observer
);
383 void SupervisedUserService::RemoveObserver(
384 SupervisedUserServiceObserver
* observer
) {
385 observer_list_
.RemoveObserver(observer
);
388 void SupervisedUserService::AddPermissionRequestCreator(
389 scoped_ptr
<PermissionRequestCreator
> creator
) {
390 permissions_creators_
.push_back(creator
.release());
393 syncer::ModelTypeSet
SupervisedUserService::GetPreferredDataTypes() const {
394 if (!ProfileIsSupervised())
395 return syncer::ModelTypeSet();
397 syncer::ModelTypeSet result
;
398 if (IncludesSyncSessionsType())
399 result
.Put(syncer::SESSIONS
);
400 result
.Put(syncer::EXTENSIONS
);
401 result
.Put(syncer::EXTENSION_SETTINGS
);
402 result
.Put(syncer::APPS
);
403 result
.Put(syncer::APP_SETTINGS
);
404 result
.Put(syncer::APP_NOTIFICATIONS
);
405 result
.Put(syncer::APP_LIST
);
409 void SupervisedUserService::OnHistoryRecordingStateChanged() {
410 bool record_history
=
411 profile_
->GetPrefs()->GetBoolean(prefs::kRecordHistory
);
412 includes_sync_sessions_type_
= record_history
;
413 ProfileSyncServiceFactory::GetForProfile(profile_
)
414 ->ReconfigureDatatypeManager();
417 bool SupervisedUserService::IncludesSyncSessionsType() const {
418 return includes_sync_sessions_type_
;
421 void SupervisedUserService::OnStateChanged() {
422 ProfileSyncService
* service
=
423 ProfileSyncServiceFactory::GetForProfile(profile_
);
424 if (waiting_for_sync_initialization_
&& service
->backend_initialized() &&
425 service
->backend_mode() == ProfileSyncService::SYNC
) {
426 waiting_for_sync_initialization_
= false;
427 service
->RemoveObserver(this);
432 DLOG_IF(ERROR
, service
->GetAuthError().state() ==
433 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
)
434 << "Credentials rejected";
437 void SupervisedUserService::SetupSync() {
439 FinishSetupSyncWhenReady();
442 void SupervisedUserService::StartSetupSync() {
443 // Tell the sync service that setup is in progress so we don't start syncing
444 // until we've finished configuration.
445 ProfileSyncServiceFactory::GetForProfile(profile_
)->SetSetupInProgress(true);
448 void SupervisedUserService::FinishSetupSyncWhenReady() {
449 // If we're already waiting for the Sync backend, there's nothing to do here.
450 if (waiting_for_sync_initialization_
)
453 // Continue in FinishSetupSync() once the Sync backend has been initialized.
454 ProfileSyncService
* service
=
455 ProfileSyncServiceFactory::GetForProfile(profile_
);
456 if (service
->backend_initialized() &&
457 service
->backend_mode() == ProfileSyncService::SYNC
) {
460 service
->AddObserver(this);
461 waiting_for_sync_initialization_
= true;
465 void SupervisedUserService::FinishSetupSync() {
466 ProfileSyncService
* service
=
467 ProfileSyncServiceFactory::GetForProfile(profile_
);
468 DCHECK(service
->backend_initialized());
469 DCHECK(service
->backend_mode() == ProfileSyncService::SYNC
);
471 // Sync nothing (except types which are set via GetPreferredDataTypes).
472 bool sync_everything
= false;
473 syncer::ModelTypeSet synced_datatypes
;
474 service
->OnUserChoseDatatypes(sync_everything
, synced_datatypes
);
476 // Notify ProfileSyncService that we are done with configuration.
477 service
->SetSetupInProgress(false);
478 service
->SetSyncSetupCompleted();
481 #if defined(ENABLE_EXTENSIONS)
482 std::string
SupervisedUserService::GetDebugPolicyProviderName() const {
483 // Save the string space in official builds.
486 return std::string();
488 return "Supervised User Service";
492 bool SupervisedUserService::UserMayLoad(const extensions::Extension
* extension
,
493 base::string16
* error
) const {
494 DCHECK(ProfileIsSupervised());
495 ExtensionState result
= GetExtensionState(extension
);
496 bool may_load
= (result
!= EXTENSION_BLOCKED
);
497 if (!may_load
&& error
)
498 *error
= l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER
);
502 bool SupervisedUserService::UserMayModifySettings(
503 const extensions::Extension
* extension
,
504 base::string16
* error
) const {
505 DCHECK(ProfileIsSupervised());
506 ExtensionState result
= GetExtensionState(extension
);
507 bool may_modify
= (result
== EXTENSION_ALLOWED
);
508 if (!may_modify
&& error
)
509 *error
= l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER
);
513 // Note: Having MustRemainInstalled always say "true" for custodian-installed
514 // extensions does NOT prevent remote uninstalls (which is a bit unexpected, but
515 // exactly what we want).
516 bool SupervisedUserService::MustRemainInstalled(
517 const extensions::Extension
* extension
,
518 base::string16
* error
) const {
519 DCHECK(ProfileIsSupervised());
520 ExtensionState result
= GetExtensionState(extension
);
521 bool may_not_uninstall
= (result
== EXTENSION_FORCED
);
522 if (may_not_uninstall
&& error
)
523 *error
= l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER
);
524 return may_not_uninstall
;
527 void SupervisedUserService::SetExtensionsActive() {
528 extensions::ExtensionSystem
* extension_system
=
529 extensions::ExtensionSystem::Get(profile_
);
530 extensions::ManagementPolicy
* management_policy
=
531 extension_system
->management_policy();
533 if (management_policy
) {
535 management_policy
->RegisterProvider(this);
537 management_policy
->UnregisterProvider(this);
539 // Re-check the policy to make sure any new settings get applied.
540 extension_system
->extension_service()->CheckManagementPolicy();
543 #endif // defined(ENABLE_EXTENSIONS)
545 SupervisedUserSettingsService
* SupervisedUserService::GetSettingsService() {
546 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_
);
549 size_t SupervisedUserService::FindEnabledPermissionRequestCreator(
551 for (size_t i
= start
; i
< permissions_creators_
.size(); ++i
) {
552 if (permissions_creators_
[i
]->IsEnabled())
555 return permissions_creators_
.size();
558 void SupervisedUserService::AddPermissionRequestInternal(
559 const CreatePermissionRequestCallback
& create_request
,
560 const SuccessCallback
& callback
,
562 // Find a permission request creator that is enabled.
563 size_t next_index
= FindEnabledPermissionRequestCreator(index
);
564 if (next_index
>= permissions_creators_
.size()) {
570 permissions_creators_
[next_index
],
571 base::Bind(&SupervisedUserService::OnPermissionRequestIssued
,
572 weak_ptr_factory_
.GetWeakPtr(), create_request
,
573 callback
, next_index
));
576 void SupervisedUserService::OnPermissionRequestIssued(
577 const CreatePermissionRequestCallback
& create_request
,
578 const SuccessCallback
& callback
,
586 AddPermissionRequestInternal(create_request
, callback
, index
+ 1);
589 void SupervisedUserService::OnSupervisedUserIdChanged() {
590 SetActive(ProfileIsSupervised());
593 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
594 int behavior_value
= profile_
->GetPrefs()->GetInteger(
595 prefs::kDefaultSupervisedUserFilteringBehavior
);
596 SupervisedUserURLFilter::FilteringBehavior behavior
=
597 SupervisedUserURLFilter::BehaviorFromInt(behavior_value
);
598 url_filter_context_
.SetDefaultFilteringBehavior(behavior
);
601 SupervisedUserServiceObserver
, observer_list_
, OnURLFilterChanged());
604 void SupervisedUserService::OnSiteListsChanged(
605 const std::vector
<scoped_refptr
<SupervisedUserSiteList
> >& site_lists
) {
606 url_filter_context_
.LoadWhitelists(site_lists
);
609 void SupervisedUserService::OnSiteListUpdated() {
611 SupervisedUserServiceObserver
, observer_list_
, OnURLFilterChanged());
614 void SupervisedUserService::LoadBlacklist(const base::FilePath
& path
,
616 base::PostTaskAndReplyWithResult(
617 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
618 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
).get(),
620 base::Bind(&base::PathExists
, path
),
621 base::Bind(&SupervisedUserService::OnBlacklistFileChecked
,
622 weak_ptr_factory_
.GetWeakPtr(), path
, url
));
625 void SupervisedUserService::OnBlacklistFileChecked(const base::FilePath
& path
,
629 LoadBlacklistFromFile(path
);
633 DCHECK(!blacklist_downloader_
);
634 blacklist_downloader_
.reset(new SupervisedUserBlacklistDownloader(
637 profile_
->GetRequestContext(),
638 base::Bind(&SupervisedUserService::OnBlacklistDownloadDone
,
639 base::Unretained(this), path
)));
642 void SupervisedUserService::LoadBlacklistFromFile(const base::FilePath
& path
) {
643 // This object is guaranteed to outlive the URLFilterContext, so we can bind a
644 // raw pointer to it in the callback.
645 url_filter_context_
.LoadBlacklist(
646 path
, base::Bind(&SupervisedUserService::OnBlacklistLoaded
,
647 base::Unretained(this)));
650 void SupervisedUserService::OnBlacklistDownloadDone(const base::FilePath
& path
,
653 LoadBlacklistFromFile(path
);
655 LOG(WARNING
) << "Blacklist download failed";
657 blacklist_downloader_
.reset();
660 void SupervisedUserService::OnBlacklistLoaded() {
662 SupervisedUserServiceObserver
, observer_list_
, OnURLFilterChanged());
665 bool SupervisedUserService::AccessRequestsEnabled() {
666 return FindEnabledPermissionRequestCreator(0) < permissions_creators_
.size();
669 void SupervisedUserService::AddURLAccessRequest(
671 const SuccessCallback
& callback
) {
672 AddPermissionRequestInternal(
673 base::Bind(CreateURLAccessRequest
,
674 SupervisedUserURLFilter::Normalize(url
)),
678 void SupervisedUserService::AddExtensionUpdateRequest(
679 const std::string
& extension_id
,
680 const base::Version
& version
,
681 const SuccessCallback
& callback
) {
682 std::string id
= extension_id
+ ":" + version
.GetString();
683 AddPermissionRequestInternal(
684 base::Bind(CreateExtensionUpdateRequest
, id
),
688 void SupervisedUserService::InitSync(const std::string
& refresh_token
) {
691 ProfileOAuth2TokenService
* token_service
=
692 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
);
693 token_service
->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail
,
696 FinishSetupSyncWhenReady();
699 void SupervisedUserService::Init() {
702 DCHECK(GetSettingsService()->IsReady());
704 pref_change_registrar_
.Init(profile_
->GetPrefs());
705 pref_change_registrar_
.Add(
706 prefs::kSupervisedUserId
,
707 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged
,
708 base::Unretained(this)));
709 pref_change_registrar_
.Add(
710 prefs::kRecordHistory
,
711 base::Bind(&SupervisedUserService::OnHistoryRecordingStateChanged
,
712 base::Unretained(this)));
714 ProfileSyncService
* sync_service
=
715 ProfileSyncServiceFactory::GetForProfile(profile_
);
716 // Can be null in tests.
718 sync_service
->AddPreferenceProvider(this);
720 std::string client_id
= component_updater::SupervisedUserWhitelistInstaller::
721 ClientIdForProfilePath(profile_
->GetPath());
722 whitelist_service_
.reset(new SupervisedUserWhitelistService(
723 profile_
->GetPrefs(),
724 g_browser_process
->supervised_user_whitelist_installer(), client_id
));
725 whitelist_service_
->AddSiteListsChangedCallback(
726 base::Bind(&SupervisedUserService::OnSiteListsChanged
,
727 weak_ptr_factory_
.GetWeakPtr()));
729 SetActive(ProfileIsSupervised());
732 void SupervisedUserService::SetActive(bool active
) {
733 if (active_
== active
)
737 if (!delegate_
|| !delegate_
->SetActive(active_
)) {
739 #if !defined(OS_ANDROID) && !defined(OS_IOS)
740 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_
)
743 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
744 if (command_line
->HasSwitch(switches::kSupervisedUserSyncToken
)) {
746 command_line
->GetSwitchValueASCII(
747 switches::kSupervisedUserSyncToken
));
750 ProfileOAuth2TokenService
* token_service
=
751 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
);
752 token_service
->LoadCredentials(
753 supervised_users::kSupervisedUserPseudoEmail
);
755 permissions_creators_
.push_back(new PermissionRequestCreatorSync(
756 GetSettingsService(),
757 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
759 ProfileSyncServiceFactory::GetForProfile(profile_
),
760 GetSupervisedUserName(),
761 profile_
->GetPrefs()->GetString(prefs::kSupervisedUserId
)));
770 // Now activate/deactivate anything not handled by the delegate yet.
772 #if defined(ENABLE_THEMES)
773 // Re-set the default theme to turn the SU theme on/off.
774 ThemeService
* theme_service
= ThemeServiceFactory::GetForProfile(profile_
);
775 if (theme_service
->UsingDefaultTheme() || theme_service
->UsingSystemTheme())
776 theme_service
->UseDefaultTheme();
779 ProfileSyncService
* sync_service
=
780 ProfileSyncServiceFactory::GetForProfile(profile_
);
781 sync_service
->SetEncryptEverythingAllowed(!active_
);
783 GetSettingsService()->SetActive(active_
);
785 #if defined(ENABLE_EXTENSIONS)
786 SetExtensionsActive();
790 pref_change_registrar_
.Add(
791 prefs::kDefaultSupervisedUserFilteringBehavior
,
792 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged
,
793 base::Unretained(this)));
794 pref_change_registrar_
.Add(prefs::kSupervisedUserManualHosts
,
795 base::Bind(&SupervisedUserService::UpdateManualHosts
,
796 base::Unretained(this)));
797 pref_change_registrar_
.Add(prefs::kSupervisedUserManualURLs
,
798 base::Bind(&SupervisedUserService::UpdateManualURLs
,
799 base::Unretained(this)));
800 for (const char* pref
: kCustodianInfoPrefs
) {
801 pref_change_registrar_
.Add(pref
,
802 base::Bind(&SupervisedUserService::OnCustodianInfoChanged
,
803 base::Unretained(this)));
806 // Initialize the filter.
807 OnDefaultFilteringBehaviorChanged();
808 whitelist_service_
->Init();
811 if (profile_
->IsChild() && delegate_
&&
812 supervised_users::IsSafeSitesBlacklistEnabled()) {
813 LoadBlacklist(GetBlacklistPath(), GURL(kBlacklistURL
));
815 if (profile_
->IsChild() && delegate_
&&
816 supervised_users::IsSafeSitesOnlineCheckEnabled()) {
817 url_filter_context_
.InitAsyncURLChecker(profile_
->GetRequestContext());
820 #if !defined(OS_ANDROID)
821 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
822 // http://crbug.com/313377
823 BrowserList::AddObserver(this);
826 permissions_creators_
.clear();
828 pref_change_registrar_
.Remove(
829 prefs::kDefaultSupervisedUserFilteringBehavior
);
830 pref_change_registrar_
.Remove(prefs::kSupervisedUserManualHosts
);
831 pref_change_registrar_
.Remove(prefs::kSupervisedUserManualURLs
);
832 for (const char* pref
: kCustodianInfoPrefs
) {
833 pref_change_registrar_
.Remove(pref
);
836 url_filter_context_
.Clear();
838 SupervisedUserServiceObserver
, observer_list_
, OnURLFilterChanged());
840 if (waiting_for_sync_initialization_
)
841 ProfileSyncServiceFactory::GetForProfile(profile_
)->RemoveObserver(this);
843 #if !defined(OS_ANDROID)
844 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
845 // http://crbug.com/313377
846 BrowserList::RemoveObserver(this);
851 void SupervisedUserService::RegisterAndInitSync(
852 SupervisedUserRegistrationUtility
* registration_utility
,
853 Profile
* custodian_profile
,
854 const std::string
& supervised_user_id
,
855 const AuthErrorCallback
& callback
) {
856 DCHECK(ProfileIsSupervised());
857 DCHECK(!custodian_profile
->IsSupervised());
859 base::string16 name
= base::UTF8ToUTF16(
860 profile_
->GetPrefs()->GetString(prefs::kProfileName
));
861 int avatar_index
= profile_
->GetPrefs()->GetInteger(
862 prefs::kProfileAvatarIndex
);
863 SupervisedUserRegistrationInfo
info(name
, avatar_index
);
864 registration_utility
->Register(
867 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered
,
868 weak_ptr_factory_
.GetWeakPtr(), callback
, custodian_profile
));
870 // Fetch the custodian's profile information, to store the name.
871 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
872 // is ever enabled, take the name from the ProfileInfoCache instead.
873 CustodianProfileDownloaderService
* profile_downloader_service
=
874 CustodianProfileDownloaderServiceFactory::GetForProfile(
876 profile_downloader_service
->DownloadProfile(
877 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded
,
878 weak_ptr_factory_
.GetWeakPtr()));
881 void SupervisedUserService::OnCustodianProfileDownloaded(
882 const base::string16
& full_name
) {
883 profile_
->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName
,
884 base::UTF16ToUTF8(full_name
));
887 void SupervisedUserService::OnSupervisedUserRegistered(
888 const AuthErrorCallback
& callback
,
889 Profile
* custodian_profile
,
890 const GoogleServiceAuthError
& auth_error
,
891 const std::string
& token
) {
892 if (auth_error
.state() == GoogleServiceAuthError::NONE
) {
894 SigninManagerBase
* signin
=
895 SigninManagerFactory::GetForProfile(custodian_profile
);
896 profile_
->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail
,
897 signin
->GetAuthenticatedUsername());
899 // The supervised user profile is now ready for use.
900 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
901 ProfileInfoCache
& cache
= profile_manager
->GetProfileInfoCache();
902 size_t index
= cache
.GetIndexOfProfileWithPath(profile_
->GetPath());
903 cache
.SetIsOmittedProfileAtIndex(index
, false);
905 DCHECK_EQ(std::string(), token
);
908 callback
.Run(auth_error
);
911 void SupervisedUserService::UpdateManualHosts() {
912 const base::DictionaryValue
* dict
=
913 profile_
->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts
);
914 scoped_ptr
<std::map
<std::string
, bool> > host_map(
915 new std::map
<std::string
, bool>());
916 for (base::DictionaryValue::Iterator
it(*dict
); !it
.IsAtEnd(); it
.Advance()) {
918 bool result
= it
.value().GetAsBoolean(&allow
);
920 (*host_map
)[it
.key()] = allow
;
922 url_filter_context_
.SetManualHosts(host_map
.Pass());
925 SupervisedUserServiceObserver
, observer_list_
, OnURLFilterChanged());
928 void SupervisedUserService::UpdateManualURLs() {
929 const base::DictionaryValue
* dict
=
930 profile_
->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs
);
931 scoped_ptr
<std::map
<GURL
, bool> > url_map(new std::map
<GURL
, bool>());
932 for (base::DictionaryValue::Iterator
it(*dict
); !it
.IsAtEnd(); it
.Advance()) {
934 bool result
= it
.value().GetAsBoolean(&allow
);
936 (*url_map
)[GURL(it
.key())] = allow
;
938 url_filter_context_
.SetManualURLs(url_map
.Pass());
941 SupervisedUserServiceObserver
, observer_list_
, OnURLFilterChanged());
944 void SupervisedUserService::OnBrowserSetLastActive(Browser
* browser
) {
945 bool profile_became_active
= profile_
->IsSameProfile(browser
->profile());
946 if (!is_profile_active_
&& profile_became_active
)
947 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
948 else if (is_profile_active_
&& !profile_became_active
)
949 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
951 is_profile_active_
= profile_became_active
;
954 std::string
SupervisedUserService::GetSupervisedUserName() const {
955 #if defined(OS_CHROMEOS)
956 // The active user can be NULL in unit tests.
957 if (user_manager::UserManager::Get()->GetActiveUser()) {
958 return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
959 user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
961 return std::string();
963 return profile_
->GetPrefs()->GetString(prefs::kProfileName
);