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