Add ProfileInfoCache::ProfileIsChild/IsLegacySupervisedAtIndex.
[chromium-blink-merge.git] / chrome / browser / supervised_user / child_accounts / child_account_service.cc
blob0bae4e32ed1db1adc44cc42f6af20771ed48e9d1
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.
5 #include "chrome/browser/supervised_user/child_accounts/child_account_service.h"
7 #include "base/callback.h"
8 #include "base/command_line.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/path_service.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/time/time.h"
15 #include "base/values.h"
16 #include "chrome/browser/profiles/profile.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_service.h"
21 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
22 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
23 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
24 #include "chrome/browser/sync/profile_sync_service.h"
25 #include "chrome/browser/sync/profile_sync_service_factory.h"
26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h"
29 #include "components/signin/core/browser/profile_oauth2_token_service.h"
30 #include "components/signin/core/browser/signin_manager.h"
32 #if defined(OS_CHROMEOS)
33 #include "chrome/browser/chromeos/profiles/profile_helper.h"
34 #include "components/user_manager/user_manager.h"
35 #endif
37 const char kIsChildAccountServiceFlagName[] = "uca";
39 ChildAccountService::ChildAccountService(Profile* profile)
40 : profile_(profile), active_(false), weak_ptr_factory_(this) {}
42 ChildAccountService::~ChildAccountService() {}
44 void ChildAccountService::Init() {
45 SigninManagerFactory::GetForProfile(profile_)->AddObserver(this);
46 SupervisedUserServiceFactory::GetForProfile(profile_)->SetDelegate(this);
48 PropagateChildStatusToUser(IsChildAccount());
50 // If we're already signed in, fetch the flag again just to be sure.
51 // (Previously, the browser might have been closed before we got the flag.
52 // This also handles the graduation use case in a basic way.)
53 std::string account_id = SigninManagerFactory::GetForProfile(profile_)
54 ->GetAuthenticatedAccountId();
55 if (!account_id.empty())
56 StartFetchingServiceFlags(account_id);
59 void ChildAccountService::Shutdown() {
60 CancelFetchingServiceFlags();
61 SupervisedUserService* service =
62 SupervisedUserServiceFactory::GetForProfile(profile_);
63 service->SetDelegate(NULL);
64 DCHECK(!active_);
65 SigninManagerFactory::GetForProfile(profile_)->RemoveObserver(this);
68 bool ChildAccountService::IsChildAccount() const {
69 return profile_->GetPrefs()->GetString(prefs::kSupervisedUserId) ==
70 supervised_users::kChildAccountSUID;
73 bool ChildAccountService::SetActive(bool active) {
74 if (!IsChildAccount() && !active_)
75 return false;
76 if (active_ == active)
77 return true;
78 active_ = active;
80 if (active_) {
81 // In contrast to local SUs, child account SUs must sign in.
82 scoped_ptr<base::Value> allow_signin(new base::FundamentalValue(true));
83 SupervisedUserSettingsService* settings_service =
84 SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
85 settings_service->SetLocalSetting(supervised_users::kSigninAllowed,
86 allow_signin.Pass());
87 #if !defined(OS_CHROMEOS)
88 // This is also used by user policies (UserPolicySigninService), but since
89 // child accounts can not also be Dasher accounts, there shouldn't be any
90 // problems.
91 SigninManagerFactory::GetForProfile(profile_)->ProhibitSignout(true);
92 #endif
94 // TODO(treib): Maybe only fetch the parents on the first start, and then
95 // refresh occasionally (like once every 24h)? That's what
96 // GAIAInfoUpdateService does.
97 family_fetcher_.reset(new FamilyInfoFetcher(
98 this,
99 SigninManagerFactory::GetForProfile(profile_)
100 ->GetAuthenticatedAccountId(),
101 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_),
102 profile_->GetRequestContext()));
103 family_fetcher_->StartGetFamilyMembers();
105 // Set the permission request API URL and scope, unless they have been
106 // explicitly specified on the command line.
107 CommandLine* command_line = CommandLine::ForCurrentProcess();
108 if (!command_line->HasSwitch(switches::kPermissionRequestApiUrl)) {
109 command_line->AppendSwitchASCII(
110 switches::kPermissionRequestApiUrl,
111 "https://www.googleapis.com/"
112 "kidsmanagement/v1/people/me/permissionRequests");
114 if (!command_line->HasSwitch(switches::kPermissionRequestApiScope)) {
115 command_line->AppendSwitchASCII(
116 switches::kPermissionRequestApiScope,
117 "https://www.googleapis.com/auth/kid.permission");
119 } else {
120 SupervisedUserSettingsService* settings_service =
121 SupervisedUserSettingsServiceFactory::GetForProfile(profile_);
122 settings_service->SetLocalSetting(supervised_users::kSigninAllowed,
123 scoped_ptr<base::Value>());
124 #if !defined(OS_CHROMEOS)
125 SigninManagerFactory::GetForProfile(profile_)->ProhibitSignout(false);
126 #endif
128 profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserCustodianName);
129 profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserCustodianEmail);
132 // Trigger a sync reconfig to enable/disable the right SU data types.
133 // The logic to do this lives in the SupervisedUserSyncDataTypeController.
134 ProfileSyncService* sync_service =
135 ProfileSyncServiceFactory::GetForProfile(profile_);
136 if (sync_service->HasSyncSetupCompleted())
137 sync_service->ReconfigureDatatypeManager();
139 return true;
142 base::FilePath ChildAccountService::GetBlacklistPath() const {
143 if (!active_)
144 return base::FilePath();
145 base::FilePath blacklist_path;
146 PathService::Get(chrome::DIR_USER_DATA, &blacklist_path);
147 blacklist_path = blacklist_path.AppendASCII("su-blacklist.bin");
148 return blacklist_path;
151 GURL ChildAccountService::GetBlacklistURL() const {
152 if (!active_)
153 return GURL();
154 return GURL("https://www.gstatic.com/chrome/supervised_user/"
155 "blacklist-20141001-1k.bin");
158 std::string ChildAccountService::GetSafeSitesCx() const {
159 if (!active_)
160 return std::string();
161 return "017993620680222980993%3A1wdumejvx5i";
164 void ChildAccountService::GoogleSigninSucceeded(const std::string& account_id,
165 const std::string& username,
166 const std::string& password) {
167 DCHECK(!account_id.empty());
169 StartFetchingServiceFlags(account_id);
172 void ChildAccountService::GoogleSignedOut(const std::string& account_id,
173 const std::string& username) {
174 DCHECK(!IsChildAccount());
175 CancelFetchingServiceFlags();
178 void ChildAccountService::OnGetFamilyMembersSuccess(
179 const std::vector<FamilyInfoFetcher::FamilyMember>& members) {
180 bool hoh_found = false;
181 bool parent_found = false;
182 for (const FamilyInfoFetcher::FamilyMember& member : members) {
183 if (member.role == FamilyInfoFetcher::HEAD_OF_HOUSEHOLD) {
184 hoh_found = true;
185 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianName,
186 member.display_name);
187 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianEmail,
188 member.email);
189 profile_->GetPrefs()->SetString(prefs::kSupervisedUserCustodianProfileURL,
190 member.profile_url);
191 profile_->GetPrefs()->SetString(
192 prefs::kSupervisedUserCustodianProfileImageURL,
193 member.profile_image_url);
194 } else if (member.role == FamilyInfoFetcher::PARENT) {
195 parent_found = true;
196 profile_->GetPrefs()->SetString(prefs::kSupervisedUserSecondCustodianName,
197 member.display_name);
198 profile_->GetPrefs()->SetString(
199 prefs::kSupervisedUserSecondCustodianEmail,
200 member.email);
201 profile_->GetPrefs()->SetString(
202 prefs::kSupervisedUserSecondCustodianProfileURL,
203 member.profile_url);
204 profile_->GetPrefs()->SetString(
205 prefs::kSupervisedUserSecondCustodianProfileImageURL,
206 member.profile_image_url);
208 if (hoh_found && parent_found)
209 break;
211 if (!hoh_found) {
212 DLOG(WARNING) << "GetFamilyMembers didn't return a HOH?!";
213 profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserCustodianName);
214 profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserCustodianEmail);
215 profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserCustodianProfileURL);
216 profile_->GetPrefs()->ClearPref(
217 prefs::kSupervisedUserCustodianProfileImageURL);
219 if (!parent_found) {
220 profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserSecondCustodianName);
221 profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserSecondCustodianEmail);
222 profile_->GetPrefs()->ClearPref(
223 prefs::kSupervisedUserSecondCustodianProfileURL);
224 profile_->GetPrefs()->ClearPref(
225 prefs::kSupervisedUserSecondCustodianProfileImageURL);
229 void ChildAccountService::OnFailure(FamilyInfoFetcher::ErrorCode error) {
230 DLOG(WARNING) << "GetFamilyMembers failed with code " << error;
231 // TODO(treib): Retry after a while?
234 void ChildAccountService::StartFetchingServiceFlags(
235 const std::string& account_id) {
236 account_id_ = account_id;
237 flag_fetcher_.reset(new AccountServiceFlagFetcher(
238 account_id_,
239 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_),
240 profile_->GetRequestContext(),
241 base::Bind(&ChildAccountService::OnFlagsFetched,
242 weak_ptr_factory_.GetWeakPtr())));
245 void ChildAccountService::CancelFetchingServiceFlags() {
246 flag_fetcher_.reset();
247 account_id_.clear();
250 void ChildAccountService::OnFlagsFetched(
251 AccountServiceFlagFetcher::ResultCode result,
252 const std::vector<std::string>& flags) {
253 // If we've been signed out again (or signed in to a different account),
254 // ignore the fetched flags.
255 const std::string& new_account_id =
256 SigninManagerFactory::GetForProfile(profile_)
257 ->GetAuthenticatedAccountId();
258 if (account_id_.empty() || account_id_ != new_account_id)
259 return;
261 // In case of an error, retry after a while.
262 if (result != AccountServiceFlagFetcher::SUCCESS) {
263 DLOG(WARNING) << "AccountServiceFlagFetcher returned error code " << result;
264 base::MessageLoop::current()->PostDelayedTask(
265 FROM_HERE,
266 base::Bind(&ChildAccountService::StartFetchingServiceFlags,
267 weak_ptr_factory_.GetWeakPtr(),
268 account_id_),
269 base::TimeDelta::FromSeconds(10));
270 return;
273 account_id_.clear();
275 bool is_child_account =
276 std::find(flags.begin(), flags.end(),
277 kIsChildAccountServiceFlagName) != flags.end();
278 SetIsChildAccount(is_child_account);
281 void ChildAccountService::SetIsChildAccount(bool is_child_account) {
282 if (IsChildAccount() == is_child_account)
283 return;
285 if (is_child_account) {
286 profile_->GetPrefs()->SetString(prefs::kSupervisedUserId,
287 supervised_users::kChildAccountSUID);
288 } else {
289 profile_->GetPrefs()->ClearPref(prefs::kSupervisedUserId);
291 PropagateChildStatusToUser(is_child_account);
294 void ChildAccountService::PropagateChildStatusToUser(bool is_child) {
295 #if defined(OS_CHROMEOS)
296 // TODO(merkulova,treib): Figure out why this causes tests to fail.
297 // user_manager::User* user =
298 // chromeos::ProfileHelper::Get()->GetUserByProfile(profile_);
299 // if (user) {
300 // user_manager::UserManager::Get()->ChangeUserSupervisedStatus(
301 // user, is_child);
302 // } else {
303 // LOG(WARNING) <<
304 // "User instance wasn't found while setting child account flag.";
305 // }
306 #endif