• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
URLFilterContext()65 ManagedUserService::URLFilterContext::URLFilterContext()
66     : ui_url_filter_(new ManagedModeURLFilter),
67       io_url_filter_(new ManagedModeURLFilter) {}
~URLFilterContext()68 ManagedUserService::URLFilterContext::~URLFilterContext() {}
69 
70 ManagedModeURLFilter*
ui_url_filter() const71 ManagedUserService::URLFilterContext::ui_url_filter() const {
72   return ui_url_filter_.get();
73 }
74 
75 ManagedModeURLFilter*
io_url_filter() const76 ManagedUserService::URLFilterContext::io_url_filter() const {
77   return io_url_filter_.get();
78 }
79 
SetDefaultFilteringBehavior(ManagedModeURLFilter::FilteringBehavior behavior)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 
LoadWhitelists(ScopedVector<ManagedModeSiteList> site_lists)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 
SetManualHosts(scoped_ptr<std::map<std::string,bool>> host_map)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 
SetManualURLs(scoped_ptr<std::map<GURL,bool>> url_map)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 
ManagedUserService(Profile * profile)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 
~ManagedUserService()137 ManagedUserService::~ManagedUserService() {
138   DCHECK(did_shutdown_);
139 }
140 
Shutdown()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 
ProfileIsManaged() const160 bool ManagedUserService::ProfileIsManaged() const {
161   return profile_->IsManaged();
162 }
163 
164 // static
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)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
MigrateUserPrefs(PrefService * prefs)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>
GetURLFilterForIOThread()205 ManagedUserService::GetURLFilterForIOThread() {
206   return url_filter_context_.io_url_filter();
207 }
208 
GetURLFilterForUIThread()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 
GetCategory(const GURL & url)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
GetCategoryNames(CategoryList * list)228 void ManagedUserService::GetCategoryNames(CategoryList* list) {
229   ManagedModeSiteList::GetCategoryNames(list);
230 }
231 
GetCustodianEmailAddress() const232 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 
GetCustodianName() const242 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 
AddNavigationBlockedCallback(const NavigationBlockedCallback & callback)254 void ManagedUserService::AddNavigationBlockedCallback(
255     const NavigationBlockedCallback& callback) {
256   navigation_blocked_callbacks_.push_back(callback);
257 }
258 
DidBlockNavigation(content::WebContents * web_contents)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 
GetDebugPolicyProviderName() const268 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 
UserMayLoad(const extensions::Extension * extension,base::string16 * error) const278 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 
UserMayModifySettings(const extensions::Extension * extension,base::string16 * error) const315 bool ManagedUserService::UserMayModifySettings(
316     const extensions::Extension* extension,
317     base::string16* error) const {
318   return ExtensionManagementPolicyImpl(extension, error);
319 }
320 
OnStateChanged()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 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)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 
SetupSync()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 
ExtensionManagementPolicyImpl(const extensions::Extension * extension,base::string16 * error) const378 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 
GetActiveSiteLists()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 
GetSettingsService()419 ManagedUserSettingsService* ManagedUserService::GetSettingsService() {
420   return ManagedUserSettingsServiceFactory::GetForProfile(profile_);
421 }
422 
OnDefaultFilteringBehaviorChanged()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 
UpdateSiteLists()433 void ManagedUserService::UpdateSiteLists() {
434   url_filter_context_.LoadWhitelists(GetActiveSiteLists());
435 }
436 
AccessRequestsEnabled()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 
AddAccessRequest(const GURL & url)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 
GetManualBehaviorForHost(const std::string & hostname)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 
GetManualBehaviorForURL(const GURL & url)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 
GetManualExceptionsForHost(const std::string & host,std::vector<GURL> * urls)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 
InitSync(const std::string & refresh_token)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 
Init()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 
RegisterAndInitSync(ManagedUserRegistrationUtility * registration_utility,Profile * custodian_profile,const std::string & managed_user_id,const AuthErrorCallback & callback)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 
OnCustodianProfileDownloaded(const base::string16 & full_name)611 void ManagedUserService::OnCustodianProfileDownloaded(
612     const base::string16& full_name) {
613   profile_->GetPrefs()->SetString(prefs::kManagedUserCustodianName,
614                                   UTF16ToUTF8(full_name));
615 }
616 
OnManagedUserRegistered(const AuthErrorCallback & callback,Profile * custodian_profile,const GoogleServiceAuthError & auth_error,const std::string & token)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 
UpdateManualHosts()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 
UpdateManualURLs()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 
OnBrowserSetLastActive(Browser * browser)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 
RecordProfileAndBrowserEventsHelper(const char * key_prefix)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