1// Copyright 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/ui/webui/options/managed_user_import_handler.h" 6 7#include <set> 8 9#include "base/bind.h" 10#include "base/prefs/pref_service.h" 11#include "base/values.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/profiles/profile.h" 14#include "chrome/browser/profiles/profile_avatar_icon_util.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/supervised_user_constants.h" 20#include "chrome/browser/supervised_user/supervised_user_shared_settings_service.h" 21#include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h" 22#include "chrome/browser/supervised_user/supervised_user_sync_service.h" 23#include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h" 24#include "chrome/common/pref_names.h" 25#include "chrome/common/url_constants.h" 26#include "components/signin/core/browser/profile_oauth2_token_service.h" 27#include "components/signin/core/browser/signin_error_controller.h" 28#include "components/signin/core/browser/signin_manager.h" 29#include "content/public/browser/web_ui.h" 30#include "grit/generated_resources.h" 31#include "grit/theme_resources.h" 32#include "ui/base/l10n/l10n_util.h" 33 34namespace { 35 36scoped_ptr<base::ListValue> GetAvatarIcons() { 37 scoped_ptr<base::ListValue> avatar_icons(new base::ListValue); 38 for (size_t i = 0; i < profiles::GetDefaultAvatarIconCount(); ++i) { 39 std::string avatar_url = profiles::GetDefaultAvatarIconUrl(i); 40 avatar_icons->Append(new base::StringValue(avatar_url)); 41 } 42 43 return avatar_icons.Pass(); 44} 45 46} // namespace 47 48namespace options { 49 50ManagedUserImportHandler::ManagedUserImportHandler() 51 : observer_(this), 52 weak_ptr_factory_(this) {} 53 54ManagedUserImportHandler::~ManagedUserImportHandler() { 55 Profile* profile = Profile::FromWebUI(web_ui()); 56 if (!profile->IsSupervised()) { 57 SupervisedUserSyncService* service = 58 SupervisedUserSyncServiceFactory::GetForProfile(profile); 59 if (service) 60 service->RemoveObserver(this); 61 subscription_.reset(); 62 } 63} 64 65void ManagedUserImportHandler::GetLocalizedValues( 66 base::DictionaryValue* localized_strings) { 67 DCHECK(localized_strings); 68 69 static OptionsStringResource resources[] = { 70 { "managedUserImportTitle", IDS_IMPORT_EXISTING_MANAGED_USER_TITLE }, 71 { "managedUserImportText", IDS_IMPORT_EXISTING_MANAGED_USER_TEXT }, 72 { "createNewUserLink", IDS_CREATE_NEW_USER_LINK }, 73 { "managedUserImportOk", IDS_IMPORT_EXISTING_MANAGED_USER_OK }, 74 { "managedUserImportSigninError", IDS_MANAGED_USER_IMPORT_SIGN_IN_ERROR }, 75 { "managedUserAlreadyOnThisDevice", 76 IDS_MANAGED_USER_ALREADY_ON_THIS_DEVICE }, 77 { "noExistingManagedUsers", IDS_MANAGED_USER_NO_EXISTING_ERROR }, 78 { "managedUserSelectAvatarTitle", IDS_MANAGED_USER_SELECT_AVATAR_TITLE }, 79 { "managedUserSelectAvatarText", IDS_MANAGED_USER_SELECT_AVATAR_TEXT }, 80 { "managedUserSelectAvatarOk", IDS_MANAGED_USER_SELECT_AVATAR_OK }, 81 }; 82 83 RegisterStrings(localized_strings, resources, arraysize(resources)); 84 localized_strings->Set("avatarIcons", GetAvatarIcons().release()); 85} 86 87void ManagedUserImportHandler::InitializeHandler() { 88 Profile* profile = Profile::FromWebUI(web_ui()); 89 if (!profile->IsSupervised()) { 90 SupervisedUserSyncService* sync_service = 91 SupervisedUserSyncServiceFactory::GetForProfile(profile); 92 if (sync_service) { 93 sync_service->AddObserver(this); 94 observer_.Add(ProfileOAuth2TokenServiceFactory::GetForProfile(profile)-> 95 signin_error_controller()); 96 SupervisedUserSharedSettingsService* settings_service = 97 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext( 98 profile); 99 subscription_ = settings_service->Subscribe( 100 base::Bind(&ManagedUserImportHandler::OnSharedSettingChanged, 101 weak_ptr_factory_.GetWeakPtr())); 102 } else { 103 DCHECK(!SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext( 104 profile)); 105 DCHECK(!ProfileOAuth2TokenServiceFactory::GetForProfile(profile)); 106 } 107 } 108} 109 110void ManagedUserImportHandler::RegisterMessages() { 111 web_ui()->RegisterMessageCallback("requestManagedUserImportUpdate", 112 base::Bind(&ManagedUserImportHandler::RequestManagedUserImportUpdate, 113 base::Unretained(this))); 114} 115 116void ManagedUserImportHandler::OnSupervisedUsersChanged() { 117 FetchManagedUsers(); 118} 119 120void ManagedUserImportHandler::FetchManagedUsers() { 121 web_ui()->CallJavascriptFunction("options.ManagedUserListData.resetPromise"); 122 RequestManagedUserImportUpdate(NULL); 123} 124 125void ManagedUserImportHandler::RequestManagedUserImportUpdate( 126 const base::ListValue* /* args */) { 127 if (Profile::FromWebUI(web_ui())->IsSupervised()) 128 return; 129 130 if (!IsAccountConnected() || HasAuthError()) { 131 ClearManagedUsersAndShowError(); 132 } else { 133 SupervisedUserSyncService* supervised_user_sync_service = 134 SupervisedUserSyncServiceFactory::GetForProfile( 135 Profile::FromWebUI(web_ui())); 136 if (supervised_user_sync_service) { 137 supervised_user_sync_service->GetSupervisedUsersAsync( 138 base::Bind(&ManagedUserImportHandler::SendExistingManagedUsers, 139 weak_ptr_factory_.GetWeakPtr())); 140 } 141 } 142} 143 144void ManagedUserImportHandler::SendExistingManagedUsers( 145 const base::DictionaryValue* dict) { 146 DCHECK(dict); 147 const ProfileInfoCache& cache = 148 g_browser_process->profile_manager()->GetProfileInfoCache(); 149 150 // Collect the ids of local supervised user profiles. 151 std::set<std::string> supervised_user_ids; 152 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { 153 if (cache.ProfileIsSupervisedAtIndex(i)) 154 supervised_user_ids.insert(cache.GetSupervisedUserIdOfProfileAtIndex(i)); 155 } 156 157 base::ListValue supervised_users; 158 Profile* profile = Profile::FromWebUI(web_ui()); 159 SupervisedUserSharedSettingsService* service = 160 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(profile); 161 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { 162 const base::DictionaryValue* value = NULL; 163 bool success = it.value().GetAsDictionary(&value); 164 DCHECK(success); 165 std::string name; 166 value->GetString(SupervisedUserSyncService::kName, &name); 167 168 base::DictionaryValue* supervised_user = new base::DictionaryValue; 169 supervised_user->SetString("id", it.key()); 170 supervised_user->SetString("name", name); 171 172 int avatar_index = SupervisedUserSyncService::kNoAvatar; 173 const base::Value* avatar_index_value = 174 service->GetValue(it.key(), supervised_users::kChromeAvatarIndex); 175 if (avatar_index_value) { 176 success = avatar_index_value->GetAsInteger(&avatar_index); 177 } else { 178 // Check if there is a legacy avatar index stored. 179 std::string avatar_str; 180 value->GetString(SupervisedUserSyncService::kChromeAvatar, &avatar_str); 181 success = 182 SupervisedUserSyncService::GetAvatarIndex(avatar_str, &avatar_index); 183 } 184 DCHECK(success); 185 supervised_user->SetBoolean( 186 "needAvatar", 187 avatar_index == SupervisedUserSyncService::kNoAvatar); 188 189 std::string supervised_user_icon = 190 std::string(chrome::kChromeUIThemeURL) + 191 "IDR_SUPERVISED_USER_PLACEHOLDER"; 192 std::string avatar_url = 193 avatar_index == SupervisedUserSyncService::kNoAvatar ? 194 supervised_user_icon : 195 profiles::GetDefaultAvatarIconUrl(avatar_index); 196 supervised_user->SetString("iconURL", avatar_url); 197 bool on_current_device = 198 supervised_user_ids.find(it.key()) != supervised_user_ids.end(); 199 supervised_user->SetBoolean("onCurrentDevice", on_current_device); 200 201 supervised_users.Append(supervised_user); 202 } 203 204 web_ui()->CallJavascriptFunction( 205 "options.ManagedUserListData.receiveExistingManagedUsers", 206 supervised_users); 207} 208 209void ManagedUserImportHandler::ClearManagedUsersAndShowError() { 210 web_ui()->CallJavascriptFunction("options.ManagedUserListData.onSigninError"); 211} 212 213bool ManagedUserImportHandler::IsAccountConnected() const { 214 Profile* profile = Profile::FromWebUI(web_ui()); 215 SigninManagerBase* signin_manager = 216 SigninManagerFactory::GetForProfile(profile); 217 return signin_manager && !signin_manager->GetAuthenticatedUsername().empty(); 218} 219 220bool ManagedUserImportHandler::HasAuthError() const { 221 Profile* profile = Profile::FromWebUI(web_ui()); 222 ProfileOAuth2TokenService* token_service = 223 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); 224 if (!token_service) 225 return true; 226 227 SigninErrorController* error_controller = 228 token_service->signin_error_controller(); 229 230 GoogleServiceAuthError::State state = error_controller->auth_error().state(); 231 232 return state == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || 233 state == GoogleServiceAuthError::USER_NOT_SIGNED_UP || 234 state == GoogleServiceAuthError::ACCOUNT_DELETED || 235 state == GoogleServiceAuthError::ACCOUNT_DISABLED; 236} 237 238void ManagedUserImportHandler::OnSharedSettingChanged( 239 const std::string& supervised_user_id, 240 const std::string& key) { 241 if (key == supervised_users::kChromeAvatarIndex) 242 FetchManagedUsers(); 243} 244 245void ManagedUserImportHandler::OnErrorChanged() { 246 FetchManagedUsers(); 247} 248 249} // namespace options 250