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