Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_service.cc
blobcdf63678eede1c35217ae4bb6d9ea8a5d5c56e28
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/net/file_downloader.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/profiles/profile_info_cache.h"
21 #include "chrome/browser/profiles/profile_manager.h"
22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
23 #include "chrome/browser/signin/signin_manager_factory.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"
58 #endif
60 #if defined(ENABLE_EXTENSIONS)
61 #include "chrome/browser/extensions/extension_service.h"
62 #include "extensions/browser/extension_system.h"
63 #endif
65 #if defined(ENABLE_THEMES)
66 #include "chrome/browser/themes/theme_service.h"
67 #include "chrome/browser/themes/theme_service_factory.h"
68 #endif
70 using base::DictionaryValue;
71 using base::UserMetricsAction;
72 using content::BrowserThread;
74 namespace {
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(
94 const GURL& url,
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 {
115 EXTENSION_FORCED,
116 EXTENSION_BLOCKED,
117 EXTENSION_ALLOWED
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());
131 #endif
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;
146 #endif
148 } // namespace
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(
169 BrowserThread::IO,
170 FROM_HERE,
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(
190 path,
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(
199 BrowserThread::IO,
200 FROM_HERE,
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(
209 BrowserThread::IO,
210 FROM_HERE,
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(
218 BrowserThread::IO,
219 FROM_HERE,
220 base::Bind(&SupervisedUserURLFilter::Clear,
221 io_url_filter_));
224 void SupervisedUserService::URLFilterContext::OnBlacklistLoaded(
225 const base::Closure& callback) {
226 ui_url_filter_->SetBlacklist(&blacklist_);
227 BrowserThread::PostTask(
228 BrowserThread::IO,
229 FROM_HERE,
230 base::Bind(&SupervisedUserURLFilter::SetBlacklist,
231 io_url_filter_,
232 &blacklist_));
233 callback.Run();
236 void SupervisedUserService::URLFilterContext::InitAsyncURLChecker(
237 const scoped_refptr<net::URLRequestContextGetter>& context) {
238 ui_url_filter_->InitAsyncURLChecker(context.get());
239 BrowserThread::PostTask(
240 BrowserThread::IO,
241 FROM_HERE,
242 base::Bind(&SupervisedUserURLFilter::InitAsyncURLChecker,
243 io_url_filter_, context));
246 SupervisedUserService::SupervisedUserService(Profile* profile)
247 : includes_sync_sessions_type_(true),
248 profile_(profile),
249 active_(false),
250 delegate_(NULL),
251 waiting_for_sync_initialization_(false),
252 is_profile_active_(false),
253 did_init_(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() {
265 if (!did_init_)
266 return;
267 DCHECK(!did_shutdown_);
268 did_shutdown_ = true;
269 if (ProfileIsSupervised()) {
270 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
272 SetActive(false);
274 ProfileSyncService* sync_service =
275 ProfileSyncServiceFactory::GetForProfile(profile_);
276 // Can be null in tests.
277 if (sync_service)
278 sync_service->RemovePreferenceProvider(this);
281 bool SupervisedUserService::ProfileIsSupervised() const {
282 return profile_->IsSupervised();
285 void SupervisedUserService::OnCustodianInfoChanged() {
286 FOR_EACH_OBSERVER(
287 SupervisedUserServiceObserver, observer_list_, OnCustodianInfoChanged());
290 // static
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 registry->RegisterBooleanPref(prefs::kSupervisedUserSafeSites, true);
299 for (const char* pref : kCustodianInfoPrefs) {
300 registry->RegisterStringPref(pref, std::string());
304 void SupervisedUserService::SetDelegate(Delegate* delegate) {
305 if (delegate) {
306 // Changing delegates isn't allowed.
307 DCHECK(!delegate_);
308 } else {
309 // If the delegate is removed, deactivate first to give the old delegate a
310 // chance to clean up.
311 SetActive(false);
313 delegate_ = delegate;
316 scoped_refptr<const SupervisedUserURLFilter>
317 SupervisedUserService::GetURLFilterForIOThread() {
318 return url_filter_context_.io_url_filter();
321 SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() {
322 return url_filter_context_.ui_url_filter();
325 SupervisedUserWhitelistService* SupervisedUserService::GetWhitelistService() {
326 return whitelist_service_.get();
329 std::string SupervisedUserService::GetCustodianEmailAddress() const {
330 std::string custodian_email = profile_->GetPrefs()->GetString(
331 prefs::kSupervisedUserCustodianEmail);
332 #if defined(OS_CHROMEOS)
333 if (custodian_email.empty()) {
334 custodian_email = chromeos::ChromeUserManager::Get()
335 ->GetSupervisedUserManager()
336 ->GetManagerDisplayEmail(
337 user_manager::UserManager::Get()->GetActiveUser()->email());
339 #endif
340 return custodian_email;
343 std::string SupervisedUserService::GetCustodianName() const {
344 std::string name = profile_->GetPrefs()->GetString(
345 prefs::kSupervisedUserCustodianName);
346 #if defined(OS_CHROMEOS)
347 if (name.empty()) {
348 name = base::UTF16ToUTF8(chromeos::ChromeUserManager::Get()
349 ->GetSupervisedUserManager()
350 ->GetManagerDisplayName(
351 user_manager::UserManager::Get()->GetActiveUser()->email()));
353 #endif
354 return name.empty() ? GetCustodianEmailAddress() : name;
357 std::string SupervisedUserService::GetSecondCustodianEmailAddress() const {
358 return profile_->GetPrefs()->GetString(
359 prefs::kSupervisedUserSecondCustodianEmail);
362 std::string SupervisedUserService::GetSecondCustodianName() const {
363 std::string name = profile_->GetPrefs()->GetString(
364 prefs::kSupervisedUserSecondCustodianName);
365 return name.empty() ? GetSecondCustodianEmailAddress() : name;
368 void SupervisedUserService::AddNavigationBlockedCallback(
369 const NavigationBlockedCallback& callback) {
370 navigation_blocked_callbacks_.push_back(callback);
373 void SupervisedUserService::DidBlockNavigation(
374 content::WebContents* web_contents) {
375 for (const auto& callback : navigation_blocked_callbacks_)
376 callback.Run(web_contents);
379 void SupervisedUserService::AddObserver(
380 SupervisedUserServiceObserver* observer) {
381 observer_list_.AddObserver(observer);
384 void SupervisedUserService::RemoveObserver(
385 SupervisedUserServiceObserver* observer) {
386 observer_list_.RemoveObserver(observer);
389 void SupervisedUserService::AddPermissionRequestCreator(
390 scoped_ptr<PermissionRequestCreator> creator) {
391 permissions_creators_.push_back(creator.release());
394 syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const {
395 if (!ProfileIsSupervised())
396 return syncer::ModelTypeSet();
398 syncer::ModelTypeSet result;
399 if (IncludesSyncSessionsType())
400 result.Put(syncer::SESSIONS);
401 result.Put(syncer::EXTENSIONS);
402 result.Put(syncer::EXTENSION_SETTINGS);
403 result.Put(syncer::APPS);
404 result.Put(syncer::APP_SETTINGS);
405 result.Put(syncer::APP_NOTIFICATIONS);
406 result.Put(syncer::APP_LIST);
407 return result;
410 void SupervisedUserService::OnHistoryRecordingStateChanged() {
411 bool record_history =
412 profile_->GetPrefs()->GetBoolean(prefs::kRecordHistory);
413 includes_sync_sessions_type_ = record_history;
414 ProfileSyncServiceFactory::GetForProfile(profile_)
415 ->ReconfigureDatatypeManager();
418 bool SupervisedUserService::IncludesSyncSessionsType() const {
419 return includes_sync_sessions_type_;
422 void SupervisedUserService::OnStateChanged() {
423 ProfileSyncService* service =
424 ProfileSyncServiceFactory::GetForProfile(profile_);
425 if (waiting_for_sync_initialization_ && service->IsBackendInitialized() &&
426 service->backend_mode() == ProfileSyncService::SYNC) {
427 waiting_for_sync_initialization_ = false;
428 service->RemoveObserver(this);
429 FinishSetupSync();
430 return;
433 DLOG_IF(ERROR, service->GetAuthError().state() ==
434 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
435 << "Credentials rejected";
438 void SupervisedUserService::SetupSync() {
439 StartSetupSync();
440 FinishSetupSyncWhenReady();
443 void SupervisedUserService::StartSetupSync() {
444 // Tell the sync service that setup is in progress so we don't start syncing
445 // until we've finished configuration.
446 ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true);
449 void SupervisedUserService::FinishSetupSyncWhenReady() {
450 // If we're already waiting for the Sync backend, there's nothing to do here.
451 if (waiting_for_sync_initialization_)
452 return;
454 // Continue in FinishSetupSync() once the Sync backend has been initialized.
455 ProfileSyncService* service =
456 ProfileSyncServiceFactory::GetForProfile(profile_);
457 if (service->IsBackendInitialized() &&
458 service->backend_mode() == ProfileSyncService::SYNC) {
459 FinishSetupSync();
460 } else {
461 service->AddObserver(this);
462 waiting_for_sync_initialization_ = true;
466 void SupervisedUserService::FinishSetupSync() {
467 ProfileSyncService* service =
468 ProfileSyncServiceFactory::GetForProfile(profile_);
469 DCHECK(service->IsBackendInitialized());
470 DCHECK(service->backend_mode() == ProfileSyncService::SYNC);
472 // Sync nothing (except types which are set via GetPreferredDataTypes).
473 bool sync_everything = false;
474 syncer::ModelTypeSet synced_datatypes;
475 service->OnUserChoseDatatypes(sync_everything, synced_datatypes);
477 // Notify ProfileSyncService that we are done with configuration.
478 service->SetSetupInProgress(false);
479 service->SetSyncSetupCompleted();
482 #if defined(ENABLE_EXTENSIONS)
483 std::string SupervisedUserService::GetDebugPolicyProviderName() const {
484 // Save the string space in official builds.
485 #ifdef NDEBUG
486 NOTREACHED();
487 return std::string();
488 #else
489 return "Supervised User Service";
490 #endif
493 bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension,
494 base::string16* error) const {
495 DCHECK(ProfileIsSupervised());
496 ExtensionState result = GetExtensionState(extension);
497 bool may_load = (result != EXTENSION_BLOCKED);
498 if (!may_load && error)
499 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
500 return may_load;
503 bool SupervisedUserService::UserMayModifySettings(
504 const extensions::Extension* extension,
505 base::string16* error) const {
506 DCHECK(ProfileIsSupervised());
507 ExtensionState result = GetExtensionState(extension);
508 bool may_modify = (result == EXTENSION_ALLOWED);
509 if (!may_modify && error)
510 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
511 return may_modify;
514 // Note: Having MustRemainInstalled always say "true" for custodian-installed
515 // extensions does NOT prevent remote uninstalls (which is a bit unexpected, but
516 // exactly what we want).
517 bool SupervisedUserService::MustRemainInstalled(
518 const extensions::Extension* extension,
519 base::string16* error) const {
520 DCHECK(ProfileIsSupervised());
521 ExtensionState result = GetExtensionState(extension);
522 bool may_not_uninstall = (result == EXTENSION_FORCED);
523 if (may_not_uninstall && error)
524 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER);
525 return may_not_uninstall;
528 void SupervisedUserService::SetExtensionsActive() {
529 extensions::ExtensionSystem* extension_system =
530 extensions::ExtensionSystem::Get(profile_);
531 extensions::ManagementPolicy* management_policy =
532 extension_system->management_policy();
534 if (management_policy) {
535 if (active_)
536 management_policy->RegisterProvider(this);
537 else
538 management_policy->UnregisterProvider(this);
540 // Re-check the policy to make sure any new settings get applied.
541 extension_system->extension_service()->CheckManagementPolicy();
544 #endif // defined(ENABLE_EXTENSIONS)
546 SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() {
547 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
550 size_t SupervisedUserService::FindEnabledPermissionRequestCreator(
551 size_t start) {
552 for (size_t i = start; i < permissions_creators_.size(); ++i) {
553 if (permissions_creators_[i]->IsEnabled())
554 return i;
556 return permissions_creators_.size();
559 void SupervisedUserService::AddPermissionRequestInternal(
560 const CreatePermissionRequestCallback& create_request,
561 const SuccessCallback& callback,
562 size_t index) {
563 // Find a permission request creator that is enabled.
564 size_t next_index = FindEnabledPermissionRequestCreator(index);
565 if (next_index >= permissions_creators_.size()) {
566 callback.Run(false);
567 return;
570 create_request.Run(
571 permissions_creators_[next_index],
572 base::Bind(&SupervisedUserService::OnPermissionRequestIssued,
573 weak_ptr_factory_.GetWeakPtr(), create_request,
574 callback, next_index));
577 void SupervisedUserService::OnPermissionRequestIssued(
578 const CreatePermissionRequestCallback& create_request,
579 const SuccessCallback& callback,
580 size_t index,
581 bool success) {
582 if (success) {
583 callback.Run(true);
584 return;
587 AddPermissionRequestInternal(create_request, callback, index + 1);
590 void SupervisedUserService::OnSupervisedUserIdChanged() {
591 SetActive(ProfileIsSupervised());
594 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
595 int behavior_value = profile_->GetPrefs()->GetInteger(
596 prefs::kDefaultSupervisedUserFilteringBehavior);
597 SupervisedUserURLFilter::FilteringBehavior behavior =
598 SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
599 url_filter_context_.SetDefaultFilteringBehavior(behavior);
601 FOR_EACH_OBSERVER(
602 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
605 void SupervisedUserService::OnSiteListsChanged(
606 const std::vector<scoped_refptr<SupervisedUserSiteList> >& site_lists) {
607 url_filter_context_.LoadWhitelists(site_lists);
610 void SupervisedUserService::OnSiteListUpdated() {
611 FOR_EACH_OBSERVER(
612 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
615 void SupervisedUserService::LoadBlacklist(const base::FilePath& path,
616 const GURL& url) {
617 base::PostTaskAndReplyWithResult(
618 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
619 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN).get(),
620 FROM_HERE,
621 base::Bind(&base::PathExists, path),
622 base::Bind(&SupervisedUserService::OnBlacklistFileChecked,
623 weak_ptr_factory_.GetWeakPtr(), path, url));
626 void SupervisedUserService::OnBlacklistFileChecked(const base::FilePath& path,
627 const GURL& url,
628 bool file_exists) {
629 if (file_exists) {
630 LoadBlacklistFromFile(path);
631 return;
634 DCHECK(!blacklist_downloader_);
635 blacklist_downloader_.reset(new FileDownloader(
636 url,
637 path,
638 profile_->GetRequestContext(),
639 base::Bind(&SupervisedUserService::OnBlacklistDownloadDone,
640 base::Unretained(this), path)));
643 void SupervisedUserService::LoadBlacklistFromFile(const base::FilePath& path) {
644 // This object is guaranteed to outlive the URLFilterContext, so we can bind a
645 // raw pointer to it in the callback.
646 url_filter_context_.LoadBlacklist(
647 path, base::Bind(&SupervisedUserService::OnBlacklistLoaded,
648 base::Unretained(this)));
651 void SupervisedUserService::OnBlacklistDownloadDone(const base::FilePath& path,
652 bool success) {
653 if (success) {
654 LoadBlacklistFromFile(path);
655 } else {
656 LOG(WARNING) << "Blacklist download failed";
658 blacklist_downloader_.reset();
661 void SupervisedUserService::OnBlacklistLoaded() {
662 FOR_EACH_OBSERVER(
663 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
666 bool SupervisedUserService::AccessRequestsEnabled() {
667 return FindEnabledPermissionRequestCreator(0) < permissions_creators_.size();
670 void SupervisedUserService::AddURLAccessRequest(
671 const GURL& url,
672 const SuccessCallback& callback) {
673 AddPermissionRequestInternal(
674 base::Bind(CreateURLAccessRequest,
675 SupervisedUserURLFilter::Normalize(url)),
676 callback, 0);
679 void SupervisedUserService::AddExtensionUpdateRequest(
680 const std::string& extension_id,
681 const base::Version& version,
682 const SuccessCallback& callback) {
683 std::string id = extension_id + ":" + version.GetString();
684 AddPermissionRequestInternal(
685 base::Bind(CreateExtensionUpdateRequest, id),
686 callback, 0);
689 void SupervisedUserService::InitSync(const std::string& refresh_token) {
690 StartSetupSync();
692 ProfileOAuth2TokenService* token_service =
693 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
694 token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail,
695 refresh_token);
697 FinishSetupSyncWhenReady();
700 void SupervisedUserService::Init() {
701 DCHECK(!did_init_);
702 did_init_ = true;
703 DCHECK(GetSettingsService()->IsReady());
705 pref_change_registrar_.Init(profile_->GetPrefs());
706 pref_change_registrar_.Add(
707 prefs::kSupervisedUserId,
708 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged,
709 base::Unretained(this)));
710 pref_change_registrar_.Add(
711 prefs::kRecordHistory,
712 base::Bind(&SupervisedUserService::OnHistoryRecordingStateChanged,
713 base::Unretained(this)));
715 ProfileSyncService* sync_service =
716 ProfileSyncServiceFactory::GetForProfile(profile_);
717 // Can be null in tests.
718 if (sync_service)
719 sync_service->AddPreferenceProvider(this);
721 std::string client_id = component_updater::SupervisedUserWhitelistInstaller::
722 ClientIdForProfilePath(profile_->GetPath());
723 whitelist_service_.reset(new SupervisedUserWhitelistService(
724 profile_->GetPrefs(),
725 g_browser_process->supervised_user_whitelist_installer(), client_id));
726 whitelist_service_->AddSiteListsChangedCallback(
727 base::Bind(&SupervisedUserService::OnSiteListsChanged,
728 weak_ptr_factory_.GetWeakPtr()));
730 SetActive(ProfileIsSupervised());
733 void SupervisedUserService::SetActive(bool active) {
734 if (active_ == active)
735 return;
736 active_ = active;
738 if (!delegate_ || !delegate_->SetActive(active_)) {
739 if (active_) {
740 #if !defined(OS_ANDROID) && !defined(OS_IOS)
741 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_)
742 ->Init();
744 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
745 if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) {
746 InitSync(
747 command_line->GetSwitchValueASCII(
748 switches::kSupervisedUserSyncToken));
751 ProfileOAuth2TokenService* token_service =
752 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
753 token_service->LoadCredentials(
754 supervised_users::kSupervisedUserPseudoEmail);
756 permissions_creators_.push_back(new PermissionRequestCreatorSync(
757 GetSettingsService(),
758 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
759 profile_),
760 ProfileSyncServiceFactory::GetForProfile(profile_),
761 GetSupervisedUserName(),
762 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId)));
764 SetupSync();
765 #else
766 NOTREACHED();
767 #endif
771 // Now activate/deactivate anything not handled by the delegate yet.
773 #if defined(ENABLE_THEMES)
774 // Re-set the default theme to turn the SU theme on/off.
775 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
776 if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme())
777 theme_service->UseDefaultTheme();
778 #endif
780 ProfileSyncService* sync_service =
781 ProfileSyncServiceFactory::GetForProfile(profile_);
782 sync_service->SetEncryptEverythingAllowed(!active_);
784 GetSettingsService()->SetActive(active_);
786 #if defined(ENABLE_EXTENSIONS)
787 SetExtensionsActive();
788 #endif
790 if (active_) {
791 pref_change_registrar_.Add(
792 prefs::kDefaultSupervisedUserFilteringBehavior,
793 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged,
794 base::Unretained(this)));
795 pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts,
796 base::Bind(&SupervisedUserService::UpdateManualHosts,
797 base::Unretained(this)));
798 pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs,
799 base::Bind(&SupervisedUserService::UpdateManualURLs,
800 base::Unretained(this)));
801 for (const char* pref : kCustodianInfoPrefs) {
802 pref_change_registrar_.Add(pref,
803 base::Bind(&SupervisedUserService::OnCustodianInfoChanged,
804 base::Unretained(this)));
807 // Initialize the filter.
808 OnDefaultFilteringBehaviorChanged();
809 whitelist_service_->Init();
810 UpdateManualHosts();
811 UpdateManualURLs();
812 if (supervised_users::IsSafeSitesBlacklistEnabled(profile_))
813 LoadBlacklist(GetBlacklistPath(), GURL(kBlacklistURL));
814 if (supervised_users::IsSafeSitesOnlineCheckEnabled(profile_))
815 url_filter_context_.InitAsyncURLChecker(profile_->GetRequestContext());
817 #if !defined(OS_ANDROID)
818 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
819 // http://crbug.com/313377
820 BrowserList::AddObserver(this);
821 #endif
822 } else {
823 permissions_creators_.clear();
825 pref_change_registrar_.Remove(
826 prefs::kDefaultSupervisedUserFilteringBehavior);
827 pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts);
828 pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs);
829 for (const char* pref : kCustodianInfoPrefs) {
830 pref_change_registrar_.Remove(pref);
833 url_filter_context_.Clear();
834 FOR_EACH_OBSERVER(
835 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
837 if (waiting_for_sync_initialization_)
838 ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
840 #if !defined(OS_ANDROID)
841 // TODO(bauerb): Get rid of the platform-specific #ifdef here.
842 // http://crbug.com/313377
843 BrowserList::RemoveObserver(this);
844 #endif
848 void SupervisedUserService::RegisterAndInitSync(
849 SupervisedUserRegistrationUtility* registration_utility,
850 Profile* custodian_profile,
851 const std::string& supervised_user_id,
852 const AuthErrorCallback& callback) {
853 DCHECK(ProfileIsSupervised());
854 DCHECK(!custodian_profile->IsSupervised());
856 base::string16 name = base::UTF8ToUTF16(
857 profile_->GetPrefs()->GetString(prefs::kProfileName));
858 int avatar_index = profile_->GetPrefs()->GetInteger(
859 prefs::kProfileAvatarIndex);
860 SupervisedUserRegistrationInfo info(name, avatar_index);
861 registration_utility->Register(
862 supervised_user_id,
863 info,
864 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered,
865 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile));
867 // Fetch the custodian's profile information, to store the name.
868 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo)
869 // is ever enabled, take the name from the ProfileInfoCache instead.
870 CustodianProfileDownloaderService* profile_downloader_service =
871 CustodianProfileDownloaderServiceFactory::GetForProfile(
872 custodian_profile);
873 profile_downloader_service->DownloadProfile(
874 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded,
875 weak_ptr_factory_.GetWeakPtr()));
878 void SupervisedUserService::OnCustodianProfileDownloaded(
879 const base::string16& full_name) {
880 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
881 base::UTF16ToUTF8(full_name));
884 void SupervisedUserService::OnSupervisedUserRegistered(
885 const AuthErrorCallback& callback,
886 Profile* custodian_profile,
887 const GoogleServiceAuthError& auth_error,
888 const std::string& token) {
889 if (auth_error.state() == GoogleServiceAuthError::NONE) {
890 InitSync(token);
891 SigninManagerBase* signin =
892 SigninManagerFactory::GetForProfile(custodian_profile);
893 profile_->GetPrefs()->SetString(
894 prefs::kSupervisedUserCustodianEmail,
895 signin->GetAuthenticatedAccountInfo().email);
897 // The supervised user profile is now ready for use.
898 ProfileManager* profile_manager = g_browser_process->profile_manager();
899 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
900 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
901 cache.SetIsOmittedProfileAtIndex(index, false);
902 } else {
903 DCHECK_EQ(std::string(), token);
906 callback.Run(auth_error);
909 void SupervisedUserService::UpdateManualHosts() {
910 const base::DictionaryValue* dict =
911 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
912 scoped_ptr<std::map<std::string, bool> > host_map(
913 new std::map<std::string, bool>());
914 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
915 bool allow = false;
916 bool result = it.value().GetAsBoolean(&allow);
917 DCHECK(result);
918 (*host_map)[it.key()] = allow;
920 url_filter_context_.SetManualHosts(host_map.Pass());
922 FOR_EACH_OBSERVER(
923 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
926 void SupervisedUserService::UpdateManualURLs() {
927 const base::DictionaryValue* dict =
928 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
929 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>());
930 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
931 bool allow = false;
932 bool result = it.value().GetAsBoolean(&allow);
933 DCHECK(result);
934 (*url_map)[GURL(it.key())] = allow;
936 url_filter_context_.SetManualURLs(url_map.Pass());
938 FOR_EACH_OBSERVER(
939 SupervisedUserServiceObserver, observer_list_, OnURLFilterChanged());
942 void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) {
943 bool profile_became_active = profile_->IsSameProfile(browser->profile());
944 if (!is_profile_active_ && profile_became_active)
945 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile"));
946 else if (is_profile_active_ && !profile_became_active)
947 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile"));
949 is_profile_active_ = profile_became_active;
952 std::string SupervisedUserService::GetSupervisedUserName() const {
953 #if defined(OS_CHROMEOS)
954 // The active user can be NULL in unit tests.
955 if (user_manager::UserManager::Get()->GetActiveUser()) {
956 return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName(
957 user_manager::UserManager::Get()->GetActiveUser()->GetUserID()));
959 return std::string();
960 #else
961 return profile_->GetPrefs()->GetString(prefs::kProfileName);
962 #endif