1 // Copyright (c) 2013 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/managed_mode/managed_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/chrome_notification_types.h" 13 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_system.h" 15 #include "chrome/browser/managed_mode/custodian_profile_downloader_service.h" 16 #include "chrome/browser/managed_mode/custodian_profile_downloader_service_factory.h" 17 #include "chrome/browser/managed_mode/managed_mode_site_list.h" 18 #include "chrome/browser/managed_mode/managed_user_constants.h" 19 #include "chrome/browser/managed_mode/managed_user_registration_utility.h" 20 #include "chrome/browser/managed_mode/managed_user_settings_service.h" 21 #include "chrome/browser/managed_mode/managed_user_settings_service_factory.h" 22 #include "chrome/browser/managed_mode/managed_user_sync_service.h" 23 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h" 24 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/signin/profile_oauth2_token_service.h" 26 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 27 #include "chrome/browser/signin/signin_manager.h" 28 #include "chrome/browser/signin/signin_manager_base.h" 29 #include "chrome/browser/signin/signin_manager_factory.h" 30 #include "chrome/browser/sync/profile_sync_service.h" 31 #include "chrome/browser/sync/profile_sync_service_factory.h" 32 #include "chrome/browser/ui/browser.h" 33 #include "chrome/browser/ui/browser_list.h" 34 #include "chrome/common/chrome_switches.h" 35 #include "chrome/common/extensions/api/managed_mode_private/managed_mode_handler.h" 36 #include "chrome/common/extensions/extension_set.h" 37 #include "chrome/common/pref_names.h" 38 #include "components/user_prefs/pref_registry_syncable.h" 39 #include "content/public/browser/browser_thread.h" 40 #include "content/public/browser/notification_details.h" 41 #include "content/public/browser/notification_source.h" 42 #include "google_apis/gaia/google_service_auth_error.h" 43 #include "grit/generated_resources.h" 44 #include "net/base/escape.h" 45 #include "ui/base/l10n/l10n_util.h" 46 47 #if defined(OS_CHROMEOS) 48 #include "chrome/browser/chromeos/login/supervised_user_manager.h" 49 #include "chrome/browser/chromeos/login/user_manager.h" 50 #endif 51 52 using base::DictionaryValue; 53 using content::BrowserThread; 54 55 const char kManagedUserAccessRequestKeyPrefix[] = 56 "X-ManagedUser-AccessRequests"; 57 const char kManagedUserAccessRequestTime[] = "timestamp"; 58 const char kManagedUserName[] = "name"; 59 const char kOpenManagedProfileKeyPrefix[] = "X-ManagedUser-Events-OpenProfile"; 60 const char kQuitBrowserKeyPrefix[] = "X-ManagedUser-Events-QuitBrowser"; 61 const char kSwitchFromManagedProfileKeyPrefix[] = 62 "X-ManagedUser-Events-SwitchProfile"; 63 const char kEventTimestamp[] = "timestamp"; 64 65 ManagedUserService::URLFilterContext::URLFilterContext() 66 : ui_url_filter_(new ManagedModeURLFilter), 67 io_url_filter_(new ManagedModeURLFilter) {} 68 ManagedUserService::URLFilterContext::~URLFilterContext() {} 69 70 ManagedModeURLFilter* 71 ManagedUserService::URLFilterContext::ui_url_filter() const { 72 return ui_url_filter_.get(); 73 } 74 75 ManagedModeURLFilter* 76 ManagedUserService::URLFilterContext::io_url_filter() const { 77 return io_url_filter_.get(); 78 } 79 80 void ManagedUserService::URLFilterContext::SetDefaultFilteringBehavior( 81 ManagedModeURLFilter::FilteringBehavior behavior) { 82 ui_url_filter_->SetDefaultFilteringBehavior(behavior); 83 BrowserThread::PostTask( 84 BrowserThread::IO, 85 FROM_HERE, 86 base::Bind(&ManagedModeURLFilter::SetDefaultFilteringBehavior, 87 io_url_filter_.get(), behavior)); 88 } 89 90 void ManagedUserService::URLFilterContext::LoadWhitelists( 91 ScopedVector<ManagedModeSiteList> site_lists) { 92 // ManagedModeURLFilter::LoadWhitelists takes ownership of |site_lists|, 93 // so we make an additional copy of it. 94 /// TODO(bauerb): This is kinda ugly. 95 ScopedVector<ManagedModeSiteList> site_lists_copy; 96 for (ScopedVector<ManagedModeSiteList>::iterator it = site_lists.begin(); 97 it != site_lists.end(); ++it) { 98 site_lists_copy.push_back((*it)->Clone()); 99 } 100 ui_url_filter_->LoadWhitelists(site_lists.Pass()); 101 BrowserThread::PostTask( 102 BrowserThread::IO, 103 FROM_HERE, 104 base::Bind(&ManagedModeURLFilter::LoadWhitelists, 105 io_url_filter_, base::Passed(&site_lists_copy))); 106 } 107 108 void ManagedUserService::URLFilterContext::SetManualHosts( 109 scoped_ptr<std::map<std::string, bool> > host_map) { 110 ui_url_filter_->SetManualHosts(host_map.get()); 111 BrowserThread::PostTask( 112 BrowserThread::IO, 113 FROM_HERE, 114 base::Bind(&ManagedModeURLFilter::SetManualHosts, 115 io_url_filter_, base::Owned(host_map.release()))); 116 } 117 118 void ManagedUserService::URLFilterContext::SetManualURLs( 119 scoped_ptr<std::map<GURL, bool> > url_map) { 120 ui_url_filter_->SetManualURLs(url_map.get()); 121 BrowserThread::PostTask( 122 BrowserThread::IO, 123 FROM_HERE, 124 base::Bind(&ManagedModeURLFilter::SetManualURLs, 125 io_url_filter_, base::Owned(url_map.release()))); 126 } 127 128 ManagedUserService::ManagedUserService(Profile* profile) 129 : profile_(profile), 130 waiting_for_sync_initialization_(false), 131 is_profile_active_(false), 132 elevated_for_testing_(false), 133 did_shutdown_(false), 134 weak_ptr_factory_(this) { 135 } 136 137 ManagedUserService::~ManagedUserService() { 138 DCHECK(did_shutdown_); 139 } 140 141 void ManagedUserService::Shutdown() { 142 did_shutdown_ = true; 143 if (ProfileIsManaged()) { 144 RecordProfileAndBrowserEventsHelper(kQuitBrowserKeyPrefix); 145 #if !defined(OS_ANDROID) 146 // TODO(bauerb): Get rid of the platform-specific #ifdef here. 147 // http://crbug.com/313377 148 BrowserList::RemoveObserver(this); 149 #endif 150 } 151 152 if (!waiting_for_sync_initialization_) 153 return; 154 155 ProfileSyncService* sync_service = 156 ProfileSyncServiceFactory::GetForProfile(profile_); 157 sync_service->RemoveObserver(this); 158 } 159 160 bool ManagedUserService::ProfileIsManaged() const { 161 return profile_->IsManaged(); 162 } 163 164 // static 165 void ManagedUserService::RegisterProfilePrefs( 166 user_prefs::PrefRegistrySyncable* registry) { 167 registry->RegisterDictionaryPref( 168 prefs::kManagedModeManualHosts, 169 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 170 registry->RegisterDictionaryPref( 171 prefs::kManagedModeManualURLs, 172 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 173 registry->RegisterIntegerPref( 174 prefs::kDefaultManagedModeFilteringBehavior, ManagedModeURLFilter::ALLOW, 175 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 176 registry->RegisterStringPref( 177 prefs::kManagedUserCustodianEmail, std::string(), 178 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 179 registry->RegisterStringPref( 180 prefs::kManagedUserCustodianName, std::string(), 181 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 182 registry->RegisterBooleanPref(prefs::kManagedUserCreationAllowed, true, 183 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 184 } 185 186 // static 187 void ManagedUserService::MigrateUserPrefs(PrefService* prefs) { 188 if (!prefs->HasPrefPath(prefs::kProfileIsManaged)) 189 return; 190 191 bool is_managed = prefs->GetBoolean(prefs::kProfileIsManaged); 192 prefs->ClearPref(prefs::kProfileIsManaged); 193 194 if (!is_managed) 195 return; 196 197 std::string managed_user_id = prefs->GetString(prefs::kManagedUserId); 198 if (!managed_user_id.empty()) 199 return; 200 201 prefs->SetString(prefs::kManagedUserId, "Dummy ID"); 202 } 203 204 scoped_refptr<const ManagedModeURLFilter> 205 ManagedUserService::GetURLFilterForIOThread() { 206 return url_filter_context_.io_url_filter(); 207 } 208 209 ManagedModeURLFilter* ManagedUserService::GetURLFilterForUIThread() { 210 return url_filter_context_.ui_url_filter(); 211 } 212 213 // Items not on any list must return -1 (CATEGORY_NOT_ON_LIST in history.js). 214 // Items on a list, but with no category, must return 0 (CATEGORY_OTHER). 215 #define CATEGORY_NOT_ON_LIST -1; 216 #define CATEGORY_OTHER 0; 217 218 int ManagedUserService::GetCategory(const GURL& url) { 219 std::vector<ManagedModeSiteList::Site*> sites; 220 GetURLFilterForUIThread()->GetSites(url, &sites); 221 if (sites.empty()) 222 return CATEGORY_NOT_ON_LIST; 223 224 return (*sites.begin())->category_id; 225 } 226 227 // static 228 void ManagedUserService::GetCategoryNames(CategoryList* list) { 229 ManagedModeSiteList::GetCategoryNames(list); 230 } 231 232 std::string ManagedUserService::GetCustodianEmailAddress() const { 233 #if defined(OS_CHROMEOS) 234 return chromeos::UserManager::Get()->GetSupervisedUserManager()-> 235 GetManagerDisplayEmail( 236 chromeos::UserManager::Get()->GetActiveUser()->email()); 237 #else 238 return profile_->GetPrefs()->GetString(prefs::kManagedUserCustodianEmail); 239 #endif 240 } 241 242 std::string ManagedUserService::GetCustodianName() const { 243 #if defined(OS_CHROMEOS) 244 return UTF16ToUTF8(chromeos::UserManager::Get()->GetSupervisedUserManager()-> 245 GetManagerDisplayName( 246 chromeos::UserManager::Get()->GetActiveUser()->email())); 247 #else 248 std::string name = profile_->GetPrefs()->GetString( 249 prefs::kManagedUserCustodianName); 250 return name.empty() ? GetCustodianEmailAddress() : name; 251 #endif 252 } 253 254 void ManagedUserService::AddNavigationBlockedCallback( 255 const NavigationBlockedCallback& callback) { 256 navigation_blocked_callbacks_.push_back(callback); 257 } 258 259 void ManagedUserService::DidBlockNavigation( 260 content::WebContents* web_contents) { 261 for (std::vector<NavigationBlockedCallback>::iterator it = 262 navigation_blocked_callbacks_.begin(); 263 it != navigation_blocked_callbacks_.end(); ++it) { 264 it->Run(web_contents); 265 } 266 } 267 268 std::string ManagedUserService::GetDebugPolicyProviderName() const { 269 // Save the string space in official builds. 270 #ifdef NDEBUG 271 NOTREACHED(); 272 return std::string(); 273 #else 274 return "Managed User Service"; 275 #endif 276 } 277 278 bool ManagedUserService::UserMayLoad(const extensions::Extension* extension, 279 base::string16* error) const { 280 base::string16 tmp_error; 281 if (ExtensionManagementPolicyImpl(extension, &tmp_error)) 282 return true; 283 284 // If the extension is already loaded, we allow it, otherwise we'd unload 285 // all existing extensions. 286 ExtensionService* extension_service = 287 extensions::ExtensionSystem::Get(profile_)->extension_service(); 288 289 // |extension_service| can be NULL in a unit test. 290 if (extension_service && 291 extension_service->GetInstalledExtension(extension->id())) 292 return true; 293 294 bool was_installed_by_default = extension->was_installed_by_default(); 295 #if defined(OS_CHROMEOS) 296 // On Chrome OS all external sources are controlled by us so it means that 297 // they are "default". Method was_installed_by_default returns false because 298 // extensions creation flags are ignored in case of default extensions with 299 // update URL(the flags aren't passed to OnExternalExtensionUpdateUrlFound). 300 // TODO(dpolukhin): remove this Chrome OS specific code as soon as creation 301 // flags are not ignored. 302 was_installed_by_default = 303 extensions::Manifest::IsExternalLocation(extension->location()); 304 #endif 305 if (extension->location() == extensions::Manifest::COMPONENT || 306 was_installed_by_default) { 307 return true; 308 } 309 310 if (error) 311 *error = tmp_error; 312 return false; 313 } 314 315 bool ManagedUserService::UserMayModifySettings( 316 const extensions::Extension* extension, 317 base::string16* error) const { 318 return ExtensionManagementPolicyImpl(extension, error); 319 } 320 321 void ManagedUserService::OnStateChanged() { 322 ProfileSyncService* service = 323 ProfileSyncServiceFactory::GetForProfile(profile_); 324 if (waiting_for_sync_initialization_ && service->sync_initialized()) { 325 waiting_for_sync_initialization_ = false; 326 service->RemoveObserver(this); 327 SetupSync(); 328 return; 329 } 330 331 DLOG_IF(ERROR, service->GetAuthError().state() == 332 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) 333 << "Credentials rejected"; 334 } 335 336 void ManagedUserService::Observe(int type, 337 const content::NotificationSource& source, 338 const content::NotificationDetails& details) { 339 switch (type) { 340 case chrome::NOTIFICATION_EXTENSION_LOADED: { 341 const extensions::Extension* extension = 342 content::Details<extensions::Extension>(details).ptr(); 343 if (!extensions::ManagedModeInfo::GetContentPackSiteList( 344 extension).empty()) { 345 UpdateSiteLists(); 346 } 347 break; 348 } 349 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 350 const extensions::UnloadedExtensionInfo* extension_info = 351 content::Details<extensions::UnloadedExtensionInfo>(details).ptr(); 352 if (!extensions::ManagedModeInfo::GetContentPackSiteList( 353 extension_info->extension).empty()) { 354 UpdateSiteLists(); 355 } 356 break; 357 } 358 default: 359 NOTREACHED(); 360 } 361 } 362 363 void ManagedUserService::SetupSync() { 364 ProfileSyncService* service = 365 ProfileSyncServiceFactory::GetForProfile(profile_); 366 DCHECK(service->sync_initialized()); 367 368 bool sync_everything = false; 369 syncer::ModelTypeSet synced_datatypes; 370 synced_datatypes.Put(syncer::MANAGED_USER_SETTINGS); 371 service->OnUserChoseDatatypes(sync_everything, synced_datatypes); 372 373 // Notify ProfileSyncService that we are done with configuration. 374 service->SetSetupInProgress(false); 375 service->SetSyncSetupCompleted(); 376 } 377 378 bool ManagedUserService::ExtensionManagementPolicyImpl( 379 const extensions::Extension* extension, 380 base::string16* error) const { 381 // |extension| can be NULL in unit_tests. 382 if (!ProfileIsManaged() || (extension && extension->is_theme())) 383 return true; 384 385 if (elevated_for_testing_) 386 return true; 387 388 if (error) 389 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_USER); 390 return false; 391 } 392 393 ScopedVector<ManagedModeSiteList> ManagedUserService::GetActiveSiteLists() { 394 ScopedVector<ManagedModeSiteList> site_lists; 395 ExtensionService* extension_service = 396 extensions::ExtensionSystem::Get(profile_)->extension_service(); 397 // Can be NULL in unit tests. 398 if (!extension_service) 399 return site_lists.Pass(); 400 401 const ExtensionSet* extensions = extension_service->extensions(); 402 for (ExtensionSet::const_iterator it = extensions->begin(); 403 it != extensions->end(); ++it) { 404 const extensions::Extension* extension = it->get(); 405 if (!extension_service->IsExtensionEnabled(extension->id())) 406 continue; 407 408 extensions::ExtensionResource site_list = 409 extensions::ManagedModeInfo::GetContentPackSiteList(extension); 410 if (!site_list.empty()) { 411 site_lists.push_back(new ManagedModeSiteList(extension->id(), 412 site_list.GetFilePath())); 413 } 414 } 415 416 return site_lists.Pass(); 417 } 418 419 ManagedUserSettingsService* ManagedUserService::GetSettingsService() { 420 return ManagedUserSettingsServiceFactory::GetForProfile(profile_); 421 } 422 423 void ManagedUserService::OnDefaultFilteringBehaviorChanged() { 424 DCHECK(ProfileIsManaged()); 425 426 int behavior_value = profile_->GetPrefs()->GetInteger( 427 prefs::kDefaultManagedModeFilteringBehavior); 428 ManagedModeURLFilter::FilteringBehavior behavior = 429 ManagedModeURLFilter::BehaviorFromInt(behavior_value); 430 url_filter_context_.SetDefaultFilteringBehavior(behavior); 431 } 432 433 void ManagedUserService::UpdateSiteLists() { 434 url_filter_context_.LoadWhitelists(GetActiveSiteLists()); 435 } 436 437 bool ManagedUserService::AccessRequestsEnabled() { 438 ProfileSyncService* service = 439 ProfileSyncServiceFactory::GetForProfile(profile_); 440 GoogleServiceAuthError::State state = service->GetAuthError().state(); 441 // We allow requesting access if Sync is working or has a transient error. 442 return (state == GoogleServiceAuthError::NONE || 443 state == GoogleServiceAuthError::CONNECTION_FAILED || 444 state == GoogleServiceAuthError::SERVICE_UNAVAILABLE); 445 } 446 447 void ManagedUserService::AddAccessRequest(const GURL& url) { 448 // Normalize the URL. 449 GURL normalized_url = ManagedModeURLFilter::Normalize(url); 450 451 // Escape the URL. 452 std::string output(net::EscapeQueryParamValue(normalized_url.spec(), true)); 453 454 // Add the prefix. 455 std::string key = ManagedUserSettingsService::MakeSplitSettingKey( 456 kManagedUserAccessRequestKeyPrefix, output); 457 458 scoped_ptr<DictionaryValue> dict(new DictionaryValue); 459 460 // TODO(sergiu): Use sane time here when it's ready. 461 dict->SetDouble(kManagedUserAccessRequestTime, base::Time::Now().ToJsTime()); 462 463 dict->SetString(kManagedUserName, profile_->GetProfileName()); 464 465 GetSettingsService()->UploadItem(key, dict.PassAs<Value>()); 466 } 467 468 ManagedUserService::ManualBehavior ManagedUserService::GetManualBehaviorForHost( 469 const std::string& hostname) { 470 const DictionaryValue* dict = 471 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualHosts); 472 bool allow = false; 473 if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow)) 474 return MANUAL_NONE; 475 476 return allow ? MANUAL_ALLOW : MANUAL_BLOCK; 477 } 478 479 ManagedUserService::ManualBehavior ManagedUserService::GetManualBehaviorForURL( 480 const GURL& url) { 481 const DictionaryValue* dict = 482 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs); 483 GURL normalized_url = ManagedModeURLFilter::Normalize(url); 484 bool allow = false; 485 if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow)) 486 return MANUAL_NONE; 487 488 return allow ? MANUAL_ALLOW : MANUAL_BLOCK; 489 } 490 491 void ManagedUserService::GetManualExceptionsForHost(const std::string& host, 492 std::vector<GURL>* urls) { 493 const DictionaryValue* dict = 494 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs); 495 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { 496 GURL url(it.key()); 497 if (url.host() == host) 498 urls->push_back(url); 499 } 500 } 501 502 void ManagedUserService::InitSync(const std::string& refresh_token) { 503 ProfileSyncService* service = 504 ProfileSyncServiceFactory::GetForProfile(profile_); 505 // Tell the sync service that setup is in progress so we don't start syncing 506 // until we've finished configuration. 507 service->SetSetupInProgress(true); 508 509 ProfileOAuth2TokenService* token_service = 510 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); 511 token_service->UpdateCredentials(managed_users::kManagedUserPseudoEmail, 512 refresh_token); 513 514 // Continue in SetupSync() once the Sync backend has been initialized. 515 if (service->sync_initialized()) { 516 SetupSync(); 517 } else { 518 ProfileSyncServiceFactory::GetForProfile(profile_)->AddObserver(this); 519 waiting_for_sync_initialization_ = true; 520 } 521 } 522 523 void ManagedUserService::Init() { 524 ManagedUserSettingsService* settings_service = GetSettingsService(); 525 DCHECK(settings_service->IsReady()); 526 if (!ProfileIsManaged()) { 527 settings_service->Clear(); 528 return; 529 } 530 531 settings_service->Activate(); 532 533 CommandLine* command_line = CommandLine::ForCurrentProcess(); 534 if (command_line->HasSwitch(switches::kManagedUserSyncToken)) { 535 InitSync( 536 command_line->GetSwitchValueASCII(switches::kManagedUserSyncToken)); 537 } 538 539 // TODO(rogerta): Remove this once PO2TS has replaced TokenService. 540 ProfileOAuth2TokenService* token_service = 541 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); 542 token_service->LoadCredentials(); 543 544 extensions::ExtensionSystem* extension_system = 545 extensions::ExtensionSystem::Get(profile_); 546 extensions::ManagementPolicy* management_policy = 547 extension_system->management_policy(); 548 if (management_policy) 549 extension_system->management_policy()->RegisterProvider(this); 550 551 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, 552 content::Source<Profile>(profile_)); 553 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 554 content::Source<Profile>(profile_)); 555 556 pref_change_registrar_.Init(profile_->GetPrefs()); 557 pref_change_registrar_.Add( 558 prefs::kDefaultManagedModeFilteringBehavior, 559 base::Bind(&ManagedUserService::OnDefaultFilteringBehaviorChanged, 560 base::Unretained(this))); 561 pref_change_registrar_.Add(prefs::kManagedModeManualHosts, 562 base::Bind(&ManagedUserService::UpdateManualHosts, 563 base::Unretained(this))); 564 pref_change_registrar_.Add(prefs::kManagedModeManualURLs, 565 base::Bind(&ManagedUserService::UpdateManualURLs, 566 base::Unretained(this))); 567 568 #if !defined(OS_ANDROID) 569 // TODO(bauerb): Get rid of the platform-specific #ifdef here. 570 // http://crbug.com/313377 571 BrowserList::AddObserver(this); 572 #endif 573 574 // Initialize the filter. 575 OnDefaultFilteringBehaviorChanged(); 576 UpdateSiteLists(); 577 UpdateManualHosts(); 578 UpdateManualURLs(); 579 } 580 581 void ManagedUserService::RegisterAndInitSync( 582 ManagedUserRegistrationUtility* registration_utility, 583 Profile* custodian_profile, 584 const std::string& managed_user_id, 585 const AuthErrorCallback& callback) { 586 DCHECK(ProfileIsManaged()); 587 DCHECK(!custodian_profile->IsManaged()); 588 589 base::string16 name = UTF8ToUTF16( 590 profile_->GetPrefs()->GetString(prefs::kProfileName)); 591 int avatar_index = profile_->GetPrefs()->GetInteger( 592 prefs::kProfileAvatarIndex); 593 ManagedUserRegistrationInfo info(name, avatar_index); 594 registration_utility->Register( 595 managed_user_id, 596 info, 597 base::Bind(&ManagedUserService::OnManagedUserRegistered, 598 weak_ptr_factory_.GetWeakPtr(), callback, custodian_profile)); 599 600 // Fetch the custodian's profile information, to store the name. 601 // TODO(pamg): If --google-profile-info (flag: switches::kGoogleProfileInfo) 602 // is ever enabled, take the name from the ProfileInfoCache instead. 603 CustodianProfileDownloaderService* profile_downloader_service = 604 CustodianProfileDownloaderServiceFactory::GetForProfile( 605 custodian_profile); 606 profile_downloader_service->DownloadProfile( 607 base::Bind(&ManagedUserService::OnCustodianProfileDownloaded, 608 weak_ptr_factory_.GetWeakPtr())); 609 } 610 611 void ManagedUserService::OnCustodianProfileDownloaded( 612 const base::string16& full_name) { 613 profile_->GetPrefs()->SetString(prefs::kManagedUserCustodianName, 614 UTF16ToUTF8(full_name)); 615 } 616 617 void ManagedUserService::OnManagedUserRegistered( 618 const AuthErrorCallback& callback, 619 Profile* custodian_profile, 620 const GoogleServiceAuthError& auth_error, 621 const std::string& token) { 622 if (auth_error.state() == GoogleServiceAuthError::NONE) { 623 InitSync(token); 624 SigninManagerBase* signin = 625 SigninManagerFactory::GetForProfile(custodian_profile); 626 profile_->GetPrefs()->SetString(prefs::kManagedUserCustodianEmail, 627 signin->GetAuthenticatedUsername()); 628 } else { 629 DCHECK_EQ(std::string(), token); 630 } 631 632 callback.Run(auth_error); 633 } 634 635 void ManagedUserService::UpdateManualHosts() { 636 const DictionaryValue* dict = 637 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualHosts); 638 scoped_ptr<std::map<std::string, bool> > host_map( 639 new std::map<std::string, bool>()); 640 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { 641 bool allow = false; 642 bool result = it.value().GetAsBoolean(&allow); 643 DCHECK(result); 644 (*host_map)[it.key()] = allow; 645 } 646 url_filter_context_.SetManualHosts(host_map.Pass()); 647 } 648 649 void ManagedUserService::UpdateManualURLs() { 650 const DictionaryValue* dict = 651 profile_->GetPrefs()->GetDictionary(prefs::kManagedModeManualURLs); 652 scoped_ptr<std::map<GURL, bool> > url_map(new std::map<GURL, bool>()); 653 for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { 654 bool allow = false; 655 bool result = it.value().GetAsBoolean(&allow); 656 DCHECK(result); 657 (*url_map)[GURL(it.key())] = allow; 658 } 659 url_filter_context_.SetManualURLs(url_map.Pass()); 660 } 661 662 void ManagedUserService::OnBrowserSetLastActive(Browser* browser) { 663 bool profile_became_active = profile_->IsSameProfile(browser->profile()); 664 if (!is_profile_active_ && profile_became_active) 665 RecordProfileAndBrowserEventsHelper(kOpenManagedProfileKeyPrefix); 666 else if (is_profile_active_ && !profile_became_active) 667 RecordProfileAndBrowserEventsHelper(kSwitchFromManagedProfileKeyPrefix); 668 669 is_profile_active_ = profile_became_active; 670 } 671 672 void ManagedUserService::RecordProfileAndBrowserEventsHelper( 673 const char* key_prefix) { 674 std::string key = ManagedUserSettingsService::MakeSplitSettingKey( 675 key_prefix, 676 base::Int64ToString(base::TimeTicks::Now().ToInternalValue())); 677 678 scoped_ptr<DictionaryValue> dict(new DictionaryValue); 679 680 // TODO(bauerb): Use sane time when ready. 681 dict->SetDouble(kEventTimestamp, base::Time::Now().ToJsTime()); 682 683 GetSettingsService()->UploadItem(key, dict.PassAs<Value>()); 684 } 685