supervised_user_service.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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. 4 5#include "chrome/browser/supervised_user/supervised_user_service.h" 6 7#include "base/command_line.h" 8#include "base/memory/ref_counted.h" 9#include "base/prefs/pref_service.h" 10#include "base/strings/string_number_conversions.h" 11#include "base/strings/utf_string_conversions.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/profiles/profile.h" 14#include "chrome/browser/profiles/profile_info_cache.h" 15#include "chrome/browser/profiles/profile_manager.h" 16#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 17#include "chrome/browser/signin/signin_manager_factory.h" 18#include "chrome/browser/supervised_user/custodian_profile_downloader_service.h" 19#include "chrome/browser/supervised_user/custodian_profile_downloader_service_factory.h" 20#include "chrome/browser/supervised_user/permission_request_creator_apiary.h" 21#include "chrome/browser/supervised_user/permission_request_creator_sync.h" 22#include "chrome/browser/supervised_user/supervised_user_constants.h" 23#include "chrome/browser/supervised_user/supervised_user_pref_mapping_service.h" 24#include "chrome/browser/supervised_user/supervised_user_pref_mapping_service_factory.h" 25#include "chrome/browser/supervised_user/supervised_user_registration_utility.h" 26#include "chrome/browser/supervised_user/supervised_user_settings_service.h" 27#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" 28#include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h" 29#include "chrome/browser/supervised_user/supervised_user_site_list.h" 30#include "chrome/browser/supervised_user/supervised_user_sync_service.h" 31#include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h" 32#include "chrome/browser/sync/profile_sync_service.h" 33#include "chrome/browser/sync/profile_sync_service_factory.h" 34#include "chrome/browser/ui/browser.h" 35#include "chrome/browser/ui/browser_list.h" 36#include "chrome/common/chrome_switches.h" 37#include "chrome/common/pref_names.h" 38#include "components/pref_registry/pref_registry_syncable.h" 39#include "components/signin/core/browser/profile_oauth2_token_service.h" 40#include "components/signin/core/browser/signin_manager.h" 41#include "components/signin/core/browser/signin_manager_base.h" 42#include "content/public/browser/browser_thread.h" 43#include "content/public/browser/user_metrics.h" 44#include "google_apis/gaia/google_service_auth_error.h" 45#include "grit/generated_resources.h" 46#include "net/base/escape.h" 47#include "ui/base/l10n/l10n_util.h" 48 49#if defined(OS_CHROMEOS) 50#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" 51#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 52#include "components/user_manager/user_manager.h" 53#endif 54 55#if defined(ENABLE_EXTENSIONS) 56#include "chrome/browser/extensions/extension_service.h" 57#include "chrome/common/extensions/api/supervised_user_private/supervised_user_handler.h" 58#include "extensions/browser/extension_registry.h" 59#include "extensions/browser/extension_system.h" 60#include "extensions/common/extension_set.h" 61#endif 62 63#if defined(ENABLE_THEMES) 64#include "chrome/browser/themes/theme_service.h" 65#include "chrome/browser/themes/theme_service_factory.h" 66#endif 67 68using base::DictionaryValue; 69using base::UserMetricsAction; 70using content::BrowserThread; 71 72SupervisedUserService::URLFilterContext::URLFilterContext() 73 : ui_url_filter_(new SupervisedUserURLFilter), 74 io_url_filter_(new SupervisedUserURLFilter) {} 75SupervisedUserService::URLFilterContext::~URLFilterContext() {} 76 77SupervisedUserURLFilter* 78SupervisedUserService::URLFilterContext::ui_url_filter() const { 79 return ui_url_filter_.get(); 80} 81 82SupervisedUserURLFilter* 83SupervisedUserService::URLFilterContext::io_url_filter() const { 84 return io_url_filter_.get(); 85} 86 87void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior( 88 SupervisedUserURLFilter::FilteringBehavior behavior) { 89 ui_url_filter_->SetDefaultFilteringBehavior(behavior); 90 BrowserThread::PostTask( 91 BrowserThread::IO, 92 FROM_HERE, 93 base::Bind(&SupervisedUserURLFilter::SetDefaultFilteringBehavior, 94 io_url_filter_.get(), behavior)); 95} 96 97void SupervisedUserService::URLFilterContext::LoadWhitelists( 98 ScopedVector<SupervisedUserSiteList> site_lists) { 99 // SupervisedUserURLFilter::LoadWhitelists takes ownership of |site_lists|, 100 // so we make an additional copy of it. 101 /// TODO(bauerb): This is kinda ugly. 102 ScopedVector<SupervisedUserSiteList> site_lists_copy; 103 for (ScopedVector<SupervisedUserSiteList>::iterator it = site_lists.begin(); 104 it != site_lists.end(); ++it) { 105 site_lists_copy.push_back((*it)->Clone()); 106 } 107 ui_url_filter_->LoadWhitelists(site_lists.Pass()); 108 BrowserThread::PostTask( 109 BrowserThread::IO, 110 FROM_HERE, 111 base::Bind(&SupervisedUserURLFilter::LoadWhitelists, 112 io_url_filter_, base::Passed(&site_lists_copy))); 113} 114 115void SupervisedUserService::URLFilterContext::SetManualHosts( 116 scoped_ptr<std::map<std::string, bool> > host_map) { 117 ui_url_filter_->SetManualHosts(host_map.get()); 118 BrowserThread::PostTask( 119 BrowserThread::IO, 120 FROM_HERE, 121 base::Bind(&SupervisedUserURLFilter::SetManualHosts, 122 io_url_filter_, base::Owned(host_map.release()))); 123} 124 125void SupervisedUserService::URLFilterContext::SetManualURLs( 126 scoped_ptr<std::map<GURL, bool> > url_map) { 127 ui_url_filter_->SetManualURLs(url_map.get()); 128 BrowserThread::PostTask( 129 BrowserThread::IO, 130 FROM_HERE, 131 base::Bind(&SupervisedUserURLFilter::SetManualURLs, 132 io_url_filter_, base::Owned(url_map.release()))); 133} 134 135SupervisedUserService::SupervisedUserService(Profile* profile) 136 : profile_(profile), 137 active_(false), 138 delegate_(NULL), 139#if defined(ENABLE_EXTENSIONS) 140 extension_registry_observer_(this), 141#endif 142 waiting_for_sync_initialization_(false), 143 is_profile_active_(false), 144 elevated_for_testing_(false), 145 did_init_(false), 146 did_shutdown_(false), 147 waiting_for_permissions_(false), 148 weak_ptr_factory_(this) { 149} 150 151SupervisedUserService::~SupervisedUserService() { 152 DCHECK(!did_init_ || did_shutdown_); 153} 154 155void SupervisedUserService::Shutdown() { 156 if (!did_init_) 157 return; 158 DCHECK(!did_shutdown_); 159 did_shutdown_ = true; 160 if (ProfileIsSupervised()) { 161 content::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser")); 162 } 163 SetActive(false); 164 165 ProfileSyncService* sync_service = 166 ProfileSyncServiceFactory::GetForProfile(profile_); 167 // Can be null in tests. 168 if (sync_service) 169 sync_service->RemovePreferenceProvider(this); 170} 171 172bool SupervisedUserService::ProfileIsSupervised() const { 173 return profile_->IsSupervised(); 174} 175 176// static 177void SupervisedUserService::RegisterProfilePrefs( 178 user_prefs::PrefRegistrySyncable* registry) { 179 registry->RegisterDictionaryPref( 180 prefs::kSupervisedUserManualHosts, 181 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 182 registry->RegisterDictionaryPref( 183 prefs::kSupervisedUserManualURLs, 184 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 185 registry->RegisterIntegerPref( 186 prefs::kDefaultSupervisedUserFilteringBehavior, 187 SupervisedUserURLFilter::ALLOW, 188 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 189 registry->RegisterStringPref( 190 prefs::kSupervisedUserCustodianEmail, std::string(), 191 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 192 registry->RegisterStringPref( 193 prefs::kSupervisedUserCustodianName, std::string(), 194 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 195 registry->RegisterStringPref( 196 prefs::kSupervisedUserCustodianProfileImageURL, std::string(), 197 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 198 registry->RegisterStringPref( 199 prefs::kSupervisedUserCustodianProfileURL, std::string(), 200 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 201 registry->RegisterStringPref( 202 prefs::kSupervisedUserSecondCustodianEmail, std::string(), 203 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 204 registry->RegisterStringPref( 205 prefs::kSupervisedUserSecondCustodianName, std::string(), 206 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 207 registry->RegisterStringPref( 208 prefs::kSupervisedUserSecondCustodianProfileImageURL, std::string(), 209 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 210 registry->RegisterStringPref( 211 prefs::kSupervisedUserSecondCustodianProfileURL, std::string(), 212 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 213 registry->RegisterBooleanPref(prefs::kSupervisedUserCreationAllowed, true, 214 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 215} 216 217void SupervisedUserService::SetDelegate(Delegate* delegate) { 218 if (delegate) { 219 // Changing delegates isn't allowed. 220 DCHECK(!delegate_); 221 } else { 222 // If the delegate is removed, deactivate first to give the old delegate a 223 // chance to clean up. 224 SetActive(false); 225 } 226 delegate_ = delegate; 227} 228 229scoped_refptr<const SupervisedUserURLFilter> 230SupervisedUserService::GetURLFilterForIOThread() { 231 return url_filter_context_.io_url_filter(); 232} 233 234SupervisedUserURLFilter* SupervisedUserService::GetURLFilterForUIThread() { 235 return url_filter_context_.ui_url_filter(); 236} 237 238// Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js). 239// Items on a list, but with no category, must return 0 (CATEGORY_OTHER). 240#define CATEGORY_NOT_ON_LIST -1; 241#define CATEGORY_OTHER 0; 242 243int SupervisedUserService::GetCategory(const GURL& url) { 244 std::vector<SupervisedUserSiteList::Site*> sites; 245 GetURLFilterForUIThread()->GetSites(url, &sites); 246 if (sites.empty()) 247 return CATEGORY_NOT_ON_LIST; 248 249 return (*sites.begin())->category_id; 250} 251 252// static 253void SupervisedUserService::GetCategoryNames(CategoryList* list) { 254 SupervisedUserSiteList::GetCategoryNames(list); 255} 256 257std::string SupervisedUserService::GetCustodianEmailAddress() const { 258#if defined(OS_CHROMEOS) 259 return chromeos::ChromeUserManager::Get() 260 ->GetSupervisedUserManager() 261 ->GetManagerDisplayEmail( 262 user_manager::UserManager::Get()->GetActiveUser()->email()); 263#else 264 return profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianEmail); 265#endif 266} 267 268std::string SupervisedUserService::GetCustodianName() const { 269#if defined(OS_CHROMEOS) 270 return base::UTF16ToUTF8( 271 chromeos::ChromeUserManager::Get() 272 ->GetSupervisedUserManager() 273 ->GetManagerDisplayName( 274 user_manager::UserManager::Get()->GetActiveUser()->email())); 275#else 276 std::string name = profile_->GetPrefs()->GetString( 277 prefs::kSupervisedUserCustodianName); 278 return name.empty() ? GetCustodianEmailAddress() : name; 279#endif 280} 281 282void SupervisedUserService::AddNavigationBlockedCallback( 283 const NavigationBlockedCallback& callback) { 284 navigation_blocked_callbacks_.push_back(callback); 285} 286 287void SupervisedUserService::DidBlockNavigation( 288 content::WebContents* web_contents) { 289 for (std::vector<NavigationBlockedCallback>::iterator it = 290 navigation_blocked_callbacks_.begin(); 291 it != navigation_blocked_callbacks_.end(); ++it) { 292 it->Run(web_contents); 293 } 294} 295 296#if defined(ENABLE_EXTENSIONS) 297std::string SupervisedUserService::GetDebugPolicyProviderName() const { 298 // Save the string space in official builds. 299#ifdef NDEBUG 300 NOTREACHED(); 301 return std::string(); 302#else 303 return "Supervised User Service"; 304#endif 305} 306 307bool SupervisedUserService::UserMayLoad(const extensions::Extension* extension, 308 base::string16* error) const { 309 base::string16 tmp_error; 310 if (ExtensionManagementPolicyImpl(extension, &tmp_error)) 311 return true; 312 313 bool was_installed_by_default = extension->was_installed_by_default(); 314 bool was_installed_by_custodian = extension->was_installed_by_custodian(); 315#if defined(OS_CHROMEOS) 316 // On Chrome OS all external sources are controlled by us so it means that 317 // they are "default". Method was_installed_by_default returns false because 318 // extensions creation flags are ignored in case of default extensions with 319 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound). 320 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation 321 // flags are not ignored. 322 was_installed_by_default = 323 extensions::Manifest::IsExternalLocation(extension->location()); 324#endif 325 if (extensions::Manifest::IsComponentLocation(extension->location()) || 326 was_installed_by_default || 327 was_installed_by_custodian) { 328 return true; 329 } 330 331 if (error) 332 *error = tmp_error; 333 return false; 334} 335 336bool SupervisedUserService::UserMayModifySettings( 337 const extensions::Extension* extension, 338 base::string16* error) const { 339 return ExtensionManagementPolicyImpl(extension, error); 340} 341 342void SupervisedUserService::OnExtensionLoaded( 343 content::BrowserContext* browser_context, 344 const extensions::Extension* extension) { 345 if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension) 346 .empty()) { 347 UpdateSiteLists(); 348 } 349} 350void SupervisedUserService::OnExtensionUnloaded( 351 content::BrowserContext* browser_context, 352 const extensions::Extension* extension, 353 extensions::UnloadedExtensionInfo::Reason reason) { 354 if (!extensions::SupervisedUserInfo::GetContentPackSiteList(extension) 355 .empty()) { 356 UpdateSiteLists(); 357 } 358} 359#endif // defined(ENABLE_EXTENSIONS) 360 361syncer::ModelTypeSet SupervisedUserService::GetPreferredDataTypes() const { 362 if (!ProfileIsSupervised()) 363 return syncer::ModelTypeSet(); 364 365 syncer::ModelTypeSet result; 366 result.Put(syncer::SESSIONS); 367 result.Put(syncer::EXTENSIONS); 368 result.Put(syncer::EXTENSION_SETTINGS); 369 result.Put(syncer::APPS); 370 result.Put(syncer::APP_SETTINGS); 371 result.Put(syncer::APP_NOTIFICATIONS); 372 result.Put(syncer::APP_LIST); 373 return result; 374} 375 376void SupervisedUserService::OnStateChanged() { 377 ProfileSyncService* service = 378 ProfileSyncServiceFactory::GetForProfile(profile_); 379 if (waiting_for_sync_initialization_ && service->sync_initialized()) { 380 waiting_for_sync_initialization_ = false; 381 service->RemoveObserver(this); 382 FinishSetupSync(); 383 return; 384 } 385 386 DLOG_IF(ERROR, service->GetAuthError().state() == 387 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) 388 << "Credentials rejected"; 389} 390 391void SupervisedUserService::SetupSync() { 392 StartSetupSync(); 393 FinishSetupSyncWhenReady(); 394} 395 396void SupervisedUserService::StartSetupSync() { 397 // Tell the sync service that setup is in progress so we don't start syncing 398 // until we've finished configuration. 399 ProfileSyncServiceFactory::GetForProfile(profile_)->SetSetupInProgress(true); 400} 401 402void SupervisedUserService::FinishSetupSyncWhenReady() { 403 // If we're already waiting for the Sync backend, there's nothing to do here. 404 if (waiting_for_sync_initialization_) 405 return; 406 407 // Continue in FinishSetupSync() once the Sync backend has been initialized. 408 ProfileSyncService* service = 409 ProfileSyncServiceFactory::GetForProfile(profile_); 410 if (service->sync_initialized()) { 411 FinishSetupSync(); 412 } else { 413 service->AddObserver(this); 414 waiting_for_sync_initialization_ = true; 415 } 416} 417 418void SupervisedUserService::FinishSetupSync() { 419 ProfileSyncService* service = 420 ProfileSyncServiceFactory::GetForProfile(profile_); 421 DCHECK(service->sync_initialized()); 422 423 // Sync nothing (except types which are set via GetPreferredDataTypes). 424 bool sync_everything = false; 425 syncer::ModelTypeSet synced_datatypes; 426 service->OnUserChoseDatatypes(sync_everything, synced_datatypes); 427 428 // Notify ProfileSyncService that we are done with configuration. 429 service->SetSetupInProgress(false); 430 service->SetSyncSetupCompleted(); 431} 432 433#if defined(ENABLE_EXTENSIONS) 434bool SupervisedUserService::ExtensionManagementPolicyImpl( 435 const extensions::Extension* extension, 436 base::string16* error) const { 437 // |extension| can be NULL in unit_tests. 438 if (!ProfileIsSupervised() || (extension && extension->is_theme())) 439 return true; 440 441 if (elevated_for_testing_) 442 return true; 443 444 if (error) 445 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER); 446 return false; 447} 448 449ScopedVector<SupervisedUserSiteList> 450SupervisedUserService::GetActiveSiteLists() { 451 ScopedVector<SupervisedUserSiteList> site_lists; 452 ExtensionService* extension_service = 453 extensions::ExtensionSystem::Get(profile_)->extension_service(); 454 // Can be NULL in unit tests. 455 if (!extension_service) 456 return site_lists.Pass(); 457 458 const extensions::ExtensionSet* extensions = extension_service->extensions(); 459 for (extensions::ExtensionSet::const_iterator it = extensions->begin(); 460 it != extensions->end(); ++it) { 461 const extensions::Extension* extension = it->get(); 462 if (!extension_service->IsExtensionEnabled(extension->id())) 463 continue; 464 465 extensions::ExtensionResource site_list = 466 extensions::SupervisedUserInfo::GetContentPackSiteList(extension); 467 if (!site_list.empty()) { 468 site_lists.push_back(new SupervisedUserSiteList(extension->id(), 469 site_list.GetFilePath())); 470 } 471 } 472 473 return site_lists.Pass(); 474} 475 476void SupervisedUserService::SetExtensionsActive() { 477 extensions::ExtensionSystem* extension_system = 478 extensions::ExtensionSystem::Get(profile_); 479 extensions::ManagementPolicy* management_policy = 480 extension_system->management_policy(); 481 482 if (active_) { 483 if (management_policy) 484 management_policy->RegisterProvider(this); 485 486 extension_registry_observer_.Add( 487 extensions::ExtensionRegistry::Get(profile_)); 488 } else { 489 if (management_policy) 490 management_policy->UnregisterProvider(this); 491 492 extension_registry_observer_.RemoveAll(); 493 } 494} 495#endif // defined(ENABLE_EXTENSIONS) 496 497SupervisedUserSettingsService* SupervisedUserService::GetSettingsService() { 498 return SupervisedUserSettingsServiceFactory::GetForProfile(profile_); 499} 500 501void SupervisedUserService::OnSupervisedUserIdChanged() { 502 std::string supervised_user_id = 503 profile_->GetPrefs()->GetString(prefs::kSupervisedUserId); 504 SetActive(!supervised_user_id.empty()); 505} 506 507void SupervisedUserService::OnDefaultFilteringBehaviorChanged() { 508 DCHECK(ProfileIsSupervised()); 509 510 int behavior_value = profile_->GetPrefs()->GetInteger( 511 prefs::kDefaultSupervisedUserFilteringBehavior); 512 SupervisedUserURLFilter::FilteringBehavior behavior = 513 SupervisedUserURLFilter::BehaviorFromInt(behavior_value); 514 url_filter_context_.SetDefaultFilteringBehavior(behavior); 515} 516 517void SupervisedUserService::UpdateSiteLists() { 518#if defined(ENABLE_EXTENSIONS) 519 url_filter_context_.LoadWhitelists(GetActiveSiteLists()); 520#endif 521} 522 523bool SupervisedUserService::AccessRequestsEnabled() { 524 if (waiting_for_permissions_) 525 return false; 526 527 ProfileSyncService* service = 528 ProfileSyncServiceFactory::GetForProfile(profile_); 529 GoogleServiceAuthError::State state = service->GetAuthError().state(); 530 // We allow requesting access if Sync is working or has a transient error. 531 return (state == GoogleServiceAuthError::NONE || 532 state == GoogleServiceAuthError::CONNECTION_FAILED || 533 state == GoogleServiceAuthError::SERVICE_UNAVAILABLE); 534} 535 536void SupervisedUserService::OnPermissionRequestIssued() { 537 waiting_for_permissions_ = false; 538 // TODO(akuegel): Figure out how to show the result of issuing the permission 539 // request in the UI. Currently, we assume the permission request was created 540 // successfully. 541} 542 543void SupervisedUserService::AddAccessRequest(const GURL& url) { 544 // Normalize the URL. 545 GURL normalized_url = SupervisedUserURLFilter::Normalize(url); 546 547 // Escape the URL. 548 std::string output(net::EscapeQueryParamValue(normalized_url.spec(), true)); 549 550 waiting_for_permissions_ = true; 551 permissions_creator_->CreatePermissionRequest( 552 output, 553 base::Bind(&SupervisedUserService::OnPermissionRequestIssued, 554 weak_ptr_factory_.GetWeakPtr())); 555} 556 557SupervisedUserService::ManualBehavior 558SupervisedUserService::GetManualBehaviorForHost( 559 const std::string& hostname) { 560 const base::DictionaryValue* dict = 561 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts); 562 bool allow = false; 563 if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow)) 564 return MANUAL_NONE; 565 566 return allow ? MANUAL_ALLOW : MANUAL_BLOCK; 567} 568 569SupervisedUserService::ManualBehavior 570SupervisedUserService::GetManualBehaviorForURL( 571 const GURL& url) { 572 const base::DictionaryValue* dict = 573 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs); 574 GURL normalized_url = SupervisedUserURLFilter::Normalize(url); 575 bool allow = false; 576 if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow)) 577 return MANUAL_NONE; 578 579 return allow ? MANUAL_ALLOW : MANUAL_BLOCK; 580} 581 582void SupervisedUserService::GetManualExceptionsForHost( 583 const std::string& host, 584 std::vector<GURL>* urls) { 585 const base::DictionaryValue* dict = 586 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs); 587 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { 588 GURL url(it.key()); 589 if (url.host() == host) 590 urls->push_back(url); 591 } 592} 593 594void SupervisedUserService::InitSync(const std::string& refresh_token) { 595 StartSetupSync(); 596 597 ProfileOAuth2TokenService* token_service = 598 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); 599 token_service->UpdateCredentials(supervised_users::kSupervisedUserPseudoEmail, 600 refresh_token); 601 602 FinishSetupSyncWhenReady(); 603} 604 605void SupervisedUserService::Init() { 606 DCHECK(!did_init_); 607 did_init_ = true; 608 DCHECK(GetSettingsService()->IsReady()); 609 610 pref_change_registrar_.Init(profile_->GetPrefs()); 611 pref_change_registrar_.Add( 612 prefs::kSupervisedUserId, 613 base::Bind(&SupervisedUserService::OnSupervisedUserIdChanged, 614 base::Unretained(this))); 615 616 ProfileSyncService* sync_service = 617 ProfileSyncServiceFactory::GetForProfile(profile_); 618 // Can be null in tests. 619 if (sync_service) 620 sync_service->AddPreferenceProvider(this); 621 622 SetActive(ProfileIsSupervised()); 623} 624 625void SupervisedUserService::SetActive(bool active) { 626 if (active_ == active) 627 return; 628 active_ = active; 629 630 if (!delegate_ || !delegate_->SetActive(active_)) { 631 if (active_) { 632 SupervisedUserPrefMappingServiceFactory::GetForBrowserContext(profile_) 633 ->Init(); 634 635 CommandLine* command_line = CommandLine::ForCurrentProcess(); 636 if (command_line->HasSwitch(switches::kSupervisedUserSyncToken)) { 637 InitSync( 638 command_line->GetSwitchValueASCII( 639 switches::kSupervisedUserSyncToken)); 640 } 641 642 ProfileOAuth2TokenService* token_service = 643 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); 644 token_service->LoadCredentials( 645 supervised_users::kSupervisedUserPseudoEmail); 646 647 SetupSync(); 648 } 649 } 650 651 // Now activate/deactivate anything not handled by the delegate yet. 652 653#if defined(ENABLE_THEMES) 654 // Re-set the default theme to turn the SU theme on/off. 655 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_); 656 if (theme_service->UsingDefaultTheme() || theme_service->UsingSystemTheme()) { 657 ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme(); 658 } 659#endif 660 661 SupervisedUserSettingsService* settings_service = GetSettingsService(); 662 settings_service->SetActive(active_); 663 664#if defined(ENABLE_EXTENSIONS) 665 SetExtensionsActive(); 666#endif 667 668 if (active_) { 669 if (CommandLine::ForCurrentProcess()->HasSwitch( 670 switches::kPermissionRequestApiUrl)) { 671 permissions_creator_ = 672 PermissionRequestCreatorApiary::CreateWithProfile(profile_); 673 } else { 674 PrefService* pref_service = profile_->GetPrefs(); 675 permissions_creator_.reset(new PermissionRequestCreatorSync( 676 settings_service, 677 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext( 678 profile_), 679 GetSupervisedUserName(), 680 pref_service->GetString(prefs::kSupervisedUserId))); 681 } 682 683 pref_change_registrar_.Add( 684 prefs::kDefaultSupervisedUserFilteringBehavior, 685 base::Bind(&SupervisedUserService::OnDefaultFilteringBehaviorChanged, 686 base::Unretained(this))); 687 pref_change_registrar_.Add(prefs::kSupervisedUserManualHosts, 688 base::Bind(&SupervisedUserService::UpdateManualHosts, 689 base::Unretained(this))); 690 pref_change_registrar_.Add(prefs::kSupervisedUserManualURLs, 691 base::Bind(&SupervisedUserService::UpdateManualURLs, 692 base::Unretained(this))); 693 694 // Initialize the filter. 695 OnDefaultFilteringBehaviorChanged(); 696 UpdateSiteLists(); 697 UpdateManualHosts(); 698 UpdateManualURLs(); 699 700#if !defined(OS_ANDROID) 701 // TODO(bauerb): Get rid of the platform-specific #ifdef here. 702 // http://crbug.com/313377 703 BrowserList::AddObserver(this); 704#endif 705 } else { 706 permissions_creator_.reset(); 707 708 pref_change_registrar_.Remove( 709 prefs::kDefaultSupervisedUserFilteringBehavior); 710 pref_change_registrar_.Remove(prefs::kSupervisedUserManualHosts); 711 pref_change_registrar_.Remove(prefs::kSupervisedUserManualURLs); 712 713 if (waiting_for_sync_initialization_) 714 ProfileSyncServiceFactory::GetForProfile(profile_)->RemoveObserver(this); 715 716#if !defined(OS_ANDROID) 717 // TODO(bauerb): Get rid of the platform-specific #ifdef here. 718 // http://crbug.com/313377 719 BrowserList::RemoveObserver(this); 720#endif 721 } 722} 723 724void SupervisedUserService::RegisterAndInitSync( 725 SupervisedUserRegistrationUtility* registration_utility, 726 Profile* custodian_profile, 727 const std::string& supervised_user_id, 728 const AuthErrorCallback& callback) { 729 DCHECK(ProfileIsSupervised()); 730 DCHECK(!custodian_profile->IsSupervised()); 731 732 base::string16 name = base::UTF8ToUTF16( 733 profile_->GetPrefs()->GetString(prefs::kProfileName)); 734 int avatar_index = profile_->GetPrefs()->GetInteger( 735 prefs::kProfileAvatarIndex); 736 SupervisedUserRegistrationInfo info(name, avatar_index); 737 registration_utility->Register( 738 supervised_user_id, 739 info, 740 base::Bind(&SupervisedUserService::OnSupervisedUserRegistered, 741 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile)); 742 743 // Fetch the custodian's profile information, to store the name. 744 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo) 745 // is ever enabled, take the name from the ProfileInfoCache instead. 746 CustodianProfileDownloaderService* profile_downloader_service = 747 CustodianProfileDownloaderServiceFactory::GetForProfile( 748 custodian_profile); 749 profile_downloader_service->DownloadProfile( 750 base::Bind(&SupervisedUserService::OnCustodianProfileDownloaded, 751 weak_ptr_factory_.GetWeakPtr())); 752} 753 754void SupervisedUserService::OnCustodianProfileDownloaded( 755 const base::string16& full_name) { 756 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName, 757 base::UTF16ToUTF8(full_name)); 758} 759 760void SupervisedUserService::OnSupervisedUserRegistered( 761 const AuthErrorCallback& callback, 762 Profile* custodian_profile, 763 const GoogleServiceAuthError& auth_error, 764 const std::string& token) { 765 if (auth_error.state() == GoogleServiceAuthError::NONE) { 766 InitSync(token); 767 SigninManagerBase* signin = 768 SigninManagerFactory::GetForProfile(custodian_profile); 769 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail, 770 signin->GetAuthenticatedUsername()); 771 772 // The supervised user profile is now ready for use. 773 ProfileManager* profile_manager = g_browser_process->profile_manager(); 774 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache(); 775 size_t index = cache.GetIndexOfProfileWithPath(profile_->GetPath()); 776 cache.SetIsOmittedProfileAtIndex(index, false); 777 } else { 778 DCHECK_EQ(std::string(), token); 779 } 780 781 callback.Run(auth_error); 782} 783 784void SupervisedUserService::UpdateManualHosts() { 785 const base::DictionaryValue* dict = 786 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts); 787 scoped_ptr<std::map<std::string, bool> > host_map( 788 new std::map<std::string, bool>()); 789 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { 790 bool allow = false; 791 bool result = it.value().GetAsBoolean(&allow); 792 DCHECK(result); 793 (*host_map)[it.key()] = allow; 794 } 795 url_filter_context_.SetManualHosts(host_map.Pass()); 796} 797 798void SupervisedUserService::UpdateManualURLs() { 799 const base::DictionaryValue* dict = 800 profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs); 801 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>()); 802 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { 803 bool allow = false; 804 bool result = it.value().GetAsBoolean(&allow); 805 DCHECK(result); 806 (*url_map)[GURL(it.key())] = allow; 807 } 808 url_filter_context_.SetManualURLs(url_map.Pass()); 809} 810 811void SupervisedUserService::OnBrowserSetLastActive(Browser* browser) { 812 bool profile_became_active = profile_->IsSameProfile(browser->profile()); 813 if (!is_profile_active_ && profile_became_active) 814 content::RecordAction(UserMetricsAction("ManagedUsers_OpenProfile")); 815 else if (is_profile_active_ && !profile_became_active) 816 content::RecordAction(UserMetricsAction("ManagedUsers_SwitchProfile")); 817 818 is_profile_active_ = profile_became_active; 819} 820 821std::string SupervisedUserService::GetSupervisedUserName() const { 822#if defined(OS_CHROMEOS) 823 // The active user can be NULL in unit tests. 824 if (user_manager::UserManager::Get()->GetActiveUser()) { 825 return UTF16ToUTF8(user_manager::UserManager::Get()->GetUserDisplayName( 826 user_manager::UserManager::Get()->GetActiveUser()->GetUserID())); 827 } 828 return std::string(); 829#else 830 return profile_->GetPrefs()->GetString(prefs::kProfileName); 831#endif 832} 833