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