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/profiles/profile_window.h"
6 
7 #include <stddef.h>
8 
9 #include <string>
10 #include <vector>
11 
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/files/file_path.h"
15 #include "base/location.h"
16 #include "base/macros.h"
17 #include "base/metrics/user_metrics.h"
18 #include "base/single_thread_task_runner.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/threading/thread_task_runner_handle.h"
22 #include "build/build_config.h"
23 #include "chrome/browser/about_flags.h"
24 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/lifetime/application_lifetime.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/profiles/profile_attributes_entry.h"
28 #include "chrome/browser/profiles/profile_attributes_storage.h"
29 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
30 #include "chrome/browser/profiles/profile_manager.h"
31 #include "chrome/browser/signin/account_reconcilor_factory.h"
32 #include "chrome/browser/signin/identity_manager_factory.h"
33 #include "chrome/browser/signin/signin_ui_util.h"
34 #include "chrome/browser/ui/browser.h"
35 #include "chrome/browser/ui/browser_dialogs.h"
36 #include "chrome/browser/ui/profile_chooser_constants.h"
37 #include "chrome/browser/ui/startup/launch_mode_recorder.h"
38 #include "chrome/common/pref_names.h"
39 #include "chrome/common/url_constants.h"
40 #include "components/flags_ui/pref_service_flags_storage.h"
41 #include "components/prefs/pref_service.h"
42 #include "components/signin/public/base/signin_pref_names.h"
43 #include "components/signin/public/identity_manager/account_info.h"
44 #include "components/signin/public/identity_manager/identity_manager.h"
45 #include "content/public/browser/browser_thread.h"
46 #include "extensions/buildflags/buildflags.h"
47 #include "net/base/escape.h"
48 
49 #if BUILDFLAG(ENABLE_EXTENSIONS)
50 #include "chrome/browser/extensions/extension_service.h"
51 #include "extensions/browser/extension_prefs.h"
52 #include "extensions/browser/extension_registry.h"
53 #include "extensions/browser/extension_registry_factory.h"
54 #include "extensions/browser/extension_system.h"
55 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
56 
57 #if !defined(OS_ANDROID)
58 #include "chrome/browser/ui/browser_finder.h"
59 #include "chrome/browser/ui/browser_list.h"
60 #include "chrome/browser/ui/browser_list_observer.h"
61 #include "chrome/browser/ui/browser_window.h"
62 #include "chrome/browser/ui/startup/startup_browser_creator.h"
63 #endif  // !defined (OS_ANDROID)
64 
65 #if !defined(OS_CHROMEOS)
66 #include "chrome/browser/ui/user_manager.h"
67 #endif  // !defined(OS_CHROMEOS)
68 
69 using base::UserMetricsAction;
70 using content::BrowserThread;
71 
72 namespace {
73 
74 #if BUILDFLAG(ENABLE_EXTENSIONS)
BlockExtensions(Profile * profile)75 void BlockExtensions(Profile* profile) {
76   extensions::ExtensionService* extension_service =
77       extensions::ExtensionSystem::Get(profile)->extension_service();
78   extension_service->BlockAllExtensions();
79 }
80 
UnblockExtensions(Profile * profile)81 void UnblockExtensions(Profile* profile) {
82   extensions::ExtensionService* extension_service =
83       extensions::ExtensionSystem::Get(profile)->extension_service();
84   extension_service->UnblockAllExtensions();
85 }
86 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
87 
88 // Called after a |system_profile| is available to be used by the user manager.
89 // Runs |callback|, if it exists. Depending on the value of
90 // |user_manager_action|, executes an action once the user manager displays or
91 // after a profile is opened.
OnUserManagerSystemProfileCreated(const base::FilePath & profile_path_to_focus,profiles::UserManagerAction user_manager_action,base::OnceCallback<void (Profile *,const std::string &)> callback,Profile * system_profile,Profile::CreateStatus status)92 void OnUserManagerSystemProfileCreated(
93     const base::FilePath& profile_path_to_focus,
94     profiles::UserManagerAction user_manager_action,
95     base::OnceCallback<void(Profile*, const std::string&)> callback,
96     Profile* system_profile,
97     Profile::CreateStatus status) {
98   if (status != Profile::CREATE_STATUS_INITIALIZED || callback.is_null())
99     return;
100 
101   // Tell the webui which user should be focused.
102   std::string page = chrome::kChromeUIMdUserManagerUrl;
103 
104   if (!profile_path_to_focus.empty()) {
105     // The file path is processed in the same way as base::CreateFilePathValue
106     // (i.e. convert to std::string with AsUTF8Unsafe()), and then URI encoded.
107     page += "#";
108     page += net::EscapeUrlEncodedData(profile_path_to_focus.AsUTF8Unsafe(),
109                                       false);
110   } else if (user_manager_action ==
111              profiles::USER_MANAGER_OPEN_CREATE_USER_PAGE) {
112     page += profiles::kUserManagerOpenCreateUserPage;
113   } else if (user_manager_action ==
114              profiles::USER_MANAGER_SELECT_PROFILE_TASK_MANAGER) {
115     page += profiles::kUserManagerSelectProfileTaskManager;
116   } else if (user_manager_action ==
117              profiles::USER_MANAGER_SELECT_PROFILE_ABOUT_CHROME) {
118     page += profiles::kUserManagerSelectProfileAboutChrome;
119   } else if (user_manager_action ==
120              profiles::USER_MANAGER_SELECT_PROFILE_CHROME_SETTINGS) {
121     page += profiles::kUserManagerSelectProfileChromeSettings;
122   }
123   std::move(callback).Run(system_profile, page);
124 }
125 
126 // Called in profiles::LoadProfileAsync once profile is loaded. It runs
127 // |callback| if it isn't null.
ProfileLoadedCallback(ProfileManager::CreateCallback callback,Profile * profile,Profile::CreateStatus status)128 void ProfileLoadedCallback(ProfileManager::CreateCallback callback,
129                            Profile* profile,
130                            Profile::CreateStatus status) {
131   DCHECK_CURRENTLY_ON(BrowserThread::UI);
132 
133   if (status != Profile::CREATE_STATUS_INITIALIZED)
134     return;
135 
136   if (!callback.is_null())
137     callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED);
138 }
139 
140 }  // namespace
141 
142 namespace profiles {
143 
144 // User Manager parameters are prefixed with hash.
145 const char kUserManagerOpenCreateUserPage[] = "#create-user";
146 const char kUserManagerSelectProfileTaskManager[] = "#task-manager";
147 const char kUserManagerSelectProfileAboutChrome[] = "#about-chrome";
148 const char kUserManagerSelectProfileChromeSettings[] = "#chrome-settings";
149 
GetPathOfProfileWithEmail(ProfileManager * profile_manager,const std::string & email)150 base::FilePath GetPathOfProfileWithEmail(ProfileManager* profile_manager,
151                                          const std::string& email) {
152   base::string16 profile_email = base::UTF8ToUTF16(email);
153   std::vector<ProfileAttributesEntry*> entries =
154       profile_manager->GetProfileAttributesStorage().GetAllProfilesAttributes();
155   for (ProfileAttributesEntry* entry : entries) {
156     if (entry->GetUserName() == profile_email)
157       return entry->GetPath();
158   }
159   return base::FilePath();
160 }
161 
FindOrCreateNewWindowForProfile(Profile * profile,chrome::startup::IsProcessStartup process_startup,chrome::startup::IsFirstRun is_first_run,bool always_create)162 void FindOrCreateNewWindowForProfile(
163     Profile* profile,
164     chrome::startup::IsProcessStartup process_startup,
165     chrome::startup::IsFirstRun is_first_run,
166     bool always_create) {
167   DCHECK(profile);
168 
169   if (!always_create) {
170     Browser* browser = chrome::FindTabbedBrowser(profile, false);
171     if (browser) {
172       browser->window()->Activate();
173       return;
174     }
175   }
176 
177   base::RecordAction(UserMetricsAction("NewWindow"));
178   base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
179   StartupBrowserCreator browser_creator;
180   // This is not a browser launch from the user; don't record the launch mode.
181   browser_creator.LaunchBrowser(command_line, profile, base::FilePath(),
182                                 process_startup, is_first_run,
183                                 /*launch_mode_recorder=*/nullptr);
184 }
185 
OpenBrowserWindowForProfile(ProfileManager::CreateCallback callback,bool always_create,bool is_new_profile,bool unblock_extensions,Profile * profile,Profile::CreateStatus status)186 void OpenBrowserWindowForProfile(ProfileManager::CreateCallback callback,
187                                  bool always_create,
188                                  bool is_new_profile,
189                                  bool unblock_extensions,
190                                  Profile* profile,
191                                  Profile::CreateStatus status) {
192   DCHECK_CURRENTLY_ON(BrowserThread::UI);
193 
194   if (status != Profile::CREATE_STATUS_INITIALIZED)
195     return;
196 
197   chrome::startup::IsProcessStartup is_process_startup =
198       chrome::startup::IS_NOT_PROCESS_STARTUP;
199   chrome::startup::IsFirstRun is_first_run = chrome::startup::IS_NOT_FIRST_RUN;
200 
201   // If this is a brand new profile, then start a first run window.
202   if (is_new_profile) {
203     is_process_startup = chrome::startup::IS_PROCESS_STARTUP;
204     is_first_run = chrome::startup::IS_FIRST_RUN;
205   }
206 
207 #if !defined(OS_CHROMEOS)
208   if (!profile->IsGuestSession() && !profile->IsEphemeralGuestProfile()) {
209     ProfileAttributesEntry* entry;
210     if (g_browser_process->profile_manager()->GetProfileAttributesStorage().
211             GetProfileAttributesWithPath(profile->GetPath(), &entry) &&
212         entry->IsSigninRequired()) {
213       UserManager::Show(profile->GetPath(),
214                         profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
215       return;
216     }
217   }
218 #endif  // !defined(OS_CHROMEOS)
219 
220 #if BUILDFLAG(ENABLE_EXTENSIONS)
221   if (unblock_extensions)
222     UnblockExtensions(profile);
223 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
224 
225   // If |always_create| is false, and we have a |callback| to run, check
226   // whether a browser already exists so that we can run the callback. We don't
227   // want to rely on the observer listening to OnBrowserSetLastActive in this
228   // case, as you could manually activate an incorrect browser and trigger
229   // a false positive.
230   if (!always_create) {
231     Browser* browser = chrome::FindTabbedBrowser(profile, false);
232     if (browser) {
233       browser->window()->Activate();
234       if (!callback.is_null())
235         callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED);
236       return;
237     }
238   }
239 
240   // If there is a callback, create an observer to make sure it is only
241   // run when the browser has been completely created. This observer will
242   // delete itself once that happens. This should not leak, because we are
243   // passing |always_create| = true to FindOrCreateNewWindow below, which ends
244   // up calling LaunchBrowser and opens a new window. If for whatever reason
245   // that fails, either something has crashed, or the observer will be cleaned
246   // up when a different browser for this profile is opened.
247   if (!callback.is_null())
248     new BrowserAddedForProfileObserver(profile, callback);
249 
250   // We already dealt with the case when |always_create| was false and a browser
251   // existed, which means that here a browser definitely needs to be created.
252   // Passing true for |always_create| means we won't duplicate the code that
253   // tries to find a browser.
254   profiles::FindOrCreateNewWindowForProfile(profile, is_process_startup,
255                                             is_first_run, true);
256 }
257 
258 #if !defined(OS_ANDROID)
259 
LoadProfileAsync(const base::FilePath & path,ProfileManager::CreateCallback callback)260 void LoadProfileAsync(const base::FilePath& path,
261                       ProfileManager::CreateCallback callback) {
262   g_browser_process->profile_manager()->CreateProfileAsync(
263       path, base::BindRepeating(&ProfileLoadedCallback, callback),
264       base::string16(), std::string());
265 }
266 
SwitchToProfile(const base::FilePath & path,bool always_create,ProfileManager::CreateCallback callback)267 void SwitchToProfile(const base::FilePath& path,
268                      bool always_create,
269                      ProfileManager::CreateCallback callback) {
270   g_browser_process->profile_manager()->CreateProfileAsync(
271       path,
272       base::BindRepeating(&profiles::OpenBrowserWindowForProfile, callback,
273                           always_create, false, false),
274       base::string16(), std::string());
275 }
276 
SwitchToGuestProfile(ProfileManager::CreateCallback callback)277 void SwitchToGuestProfile(ProfileManager::CreateCallback callback) {
278   g_browser_process->profile_manager()->CreateProfileAsync(
279       ProfileManager::GetGuestProfilePath(),
280       base::BindRepeating(&profiles::OpenBrowserWindowForProfile, callback,
281                           false, false, false),
282       base::string16(), std::string());
283 }
284 #endif
285 
HasProfileSwitchTargets(Profile * profile)286 bool HasProfileSwitchTargets(Profile* profile) {
287   size_t min_profiles =
288       (profile->IsGuestSession() || profile->IsEphemeralGuestProfile()) ? 1 : 2;
289   size_t number_of_profiles =
290       g_browser_process->profile_manager()->GetNumberOfProfiles();
291   return number_of_profiles >= min_profiles;
292 }
293 
ProfileBrowserCloseSuccess(const base::FilePath & profile_path)294 void ProfileBrowserCloseSuccess(const base::FilePath& profile_path) {
295 #if !defined(OS_CHROMEOS)
296   UserManager::Show(base::FilePath(),
297                     profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
298 #endif  // !defined(OS_CHROMEOS)
299 }
300 
CloseGuestProfileWindows()301 void CloseGuestProfileWindows() {
302   ProfileManager* profile_manager = g_browser_process->profile_manager();
303   Profile* profile = profile_manager->GetProfileByPath(
304       ProfileManager::GetGuestProfilePath());
305 
306   if (profile) {
307     BrowserList::CloseAllBrowsersWithProfile(
308         profile, base::BindRepeating(&ProfileBrowserCloseSuccess),
309         BrowserList::CloseCallback(), false);
310   }
311 }
312 
LockBrowserCloseSuccess(const base::FilePath & profile_path)313 void LockBrowserCloseSuccess(const base::FilePath& profile_path) {
314   ProfileManager* profile_manager = g_browser_process->profile_manager();
315   ProfileAttributesEntry* entry;
316   bool has_entry = profile_manager->GetProfileAttributesStorage().
317                        GetProfileAttributesWithPath(profile_path, &entry);
318   DCHECK(has_entry);
319   entry->SetIsSigninRequired(true);
320 
321 #if BUILDFLAG(ENABLE_EXTENSIONS)
322   // Profile guaranteed to exist for it to have been locked.
323   BlockExtensions(profile_manager->GetProfileByPath(profile_path));
324 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
325 
326   chrome::HideTaskManager();
327 #if !defined(OS_CHROMEOS)
328   UserManager::Show(profile_path,
329                     profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
330 #endif  // !defined(OS_CHROMEOS)
331 }
332 
LockProfile(Profile * profile)333 void LockProfile(Profile* profile) {
334   DCHECK(profile);
335   if (profile) {
336     BrowserList::CloseAllBrowsersWithProfile(
337         profile, base::BindRepeating(&LockBrowserCloseSuccess),
338         BrowserList::CloseCallback(), false);
339   }
340 }
341 
IsLockAvailable(Profile * profile)342 bool IsLockAvailable(Profile* profile) {
343   DCHECK(profile);
344   if (profile->IsGuestSession() || profile->IsSystemProfile() ||
345       profile->IsEphemeralGuestProfile()) {
346     return false;
347   }
348 
349   std::string hosted_domain = profile->GetPrefs()->
350       GetString(prefs::kGoogleServicesHostedDomain);
351   // TODO(mlerman): After one release remove any hosted_domain reference to the
352   // pref, since all users will have this in the AccountTrackerService.
353   if (hosted_domain.empty()) {
354     signin::IdentityManager* identity_manager =
355         IdentityManagerFactory::GetForProfile(profile);
356 
357     base::Optional<AccountInfo> primary_account_info =
358         identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken(
359             identity_manager->GetPrimaryAccountInfo());
360 
361     if (primary_account_info.has_value())
362       hosted_domain = primary_account_info.value().hosted_domain;
363   }
364 
365   // TODO(mlerman): Prohibit only users who authenticate using SAML. Until then,
366   // prohibited users who use hosted domains (aside from google.com).
367   if (hosted_domain != kNoHostedDomainFound && hosted_domain != "google.com") {
368     return false;
369   }
370 
371   // Lock only when there is at least one supervised user on the machine.
372   std::vector<ProfileAttributesEntry*> entries =
373       g_browser_process->profile_manager()->GetProfileAttributesStorage().
374           GetAllProfilesAttributes();
375   for (ProfileAttributesEntry* entry : entries) {
376     if (entry->IsSupervised())
377       return true;
378   }
379   return false;
380 }
381 
CloseProfileWindows(Profile * profile)382 void CloseProfileWindows(Profile* profile) {
383   DCHECK(profile);
384   BrowserList::CloseAllBrowsersWithProfile(
385       profile, base::BindRepeating(&ProfileBrowserCloseSuccess),
386       BrowserList::CloseCallback(), false);
387 }
388 
CreateSystemProfileForUserManager(const base::FilePath & profile_path_to_focus,profiles::UserManagerAction user_manager_action,base::RepeatingCallback<void (Profile *,const std::string &)> callback)389 void CreateSystemProfileForUserManager(
390     const base::FilePath& profile_path_to_focus,
391     profiles::UserManagerAction user_manager_action,
392     base::RepeatingCallback<void(Profile*, const std::string&)> callback) {
393   // Create the system profile, if necessary, and open the User Manager
394   // from the system profile.
395   g_browser_process->profile_manager()->CreateProfileAsync(
396       ProfileManager::GetSystemProfilePath(),
397       base::BindRepeating(&OnUserManagerSystemProfileCreated,
398                           profile_path_to_focus, user_manager_action,
399                           std::move(callback)),
400       base::string16(), std::string());
401 }
402 
BubbleViewModeFromAvatarBubbleMode(BrowserWindow::AvatarBubbleMode mode,Profile * profile,BubbleViewMode * bubble_view_mode)403 void BubbleViewModeFromAvatarBubbleMode(BrowserWindow::AvatarBubbleMode mode,
404                                         Profile* profile,
405                                         BubbleViewMode* bubble_view_mode) {
406   switch (mode) {
407     case BrowserWindow::AVATAR_BUBBLE_MODE_SIGNIN:
408       *bubble_view_mode = BUBBLE_VIEW_MODE_GAIA_SIGNIN;
409       return;
410     case BrowserWindow::AVATAR_BUBBLE_MODE_ADD_ACCOUNT:
411       *bubble_view_mode = BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT;
412       return;
413     case BrowserWindow::AVATAR_BUBBLE_MODE_REAUTH:
414       *bubble_view_mode = BUBBLE_VIEW_MODE_GAIA_REAUTH;
415       return;
416     case BrowserWindow::AVATAR_BUBBLE_MODE_CONFIRM_SIGNIN:
417       *bubble_view_mode = BUBBLE_VIEW_MODE_PROFILE_CHOOSER;
418       return;
419     case BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT:
420       *bubble_view_mode = profile->IsIncognitoProfile()
421                               ? profiles::BUBBLE_VIEW_MODE_INCOGNITO
422                               : profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER;
423   }
424 }
425 
BrowserAddedForProfileObserver(Profile * profile,ProfileManager::CreateCallback callback)426 BrowserAddedForProfileObserver::BrowserAddedForProfileObserver(
427     Profile* profile,
428     ProfileManager::CreateCallback callback)
429     : profile_(profile), callback_(callback) {
430   DCHECK(!callback_.is_null());
431   BrowserList::AddObserver(this);
432 }
433 
~BrowserAddedForProfileObserver()434 BrowserAddedForProfileObserver::~BrowserAddedForProfileObserver() {}
435 
OnBrowserAdded(Browser * browser)436 void BrowserAddedForProfileObserver::OnBrowserAdded(Browser* browser) {
437   if (browser->profile() == profile_) {
438     BrowserList::RemoveObserver(this);
439     // By the time the browser is added a tab (or multiple) are about to be
440     // added. Post the callback to the message loop so it gets executed after
441     // the tabs are created.
442     base::ThreadTaskRunnerHandle::Get()->PostTask(
443         FROM_HERE, base::BindOnce(callback_, profile_,
444                                   Profile::CREATE_STATUS_INITIALIZED));
445     base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
446   }
447 }
448 
449 }  // namespace profiles
450