1 // Copyright 2018 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/chromeos/system/user_removal_manager.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/no_destructor.h"
13 #include "base/task_runner.h"
14 #include "base/threading/sequenced_task_runner_handle.h"
15 #include "base/time/time.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/lifetime/application_lifetime.h"
18 #include "chrome/common/pref_names.h"
19 #include "components/prefs/persistent_pref_store.h"
20 #include "components/prefs/pref_service.h"
21 #include "components/user_manager/user.h"
22 #include "components/user_manager/user_manager.h"
23 
24 namespace chromeos {
25 namespace user_removal_manager {
26 
27 namespace {
28 
29 // The time that InitiateUserRemoval waits on the passed callback to do a log
30 // out, otherwise it does the log out itself.
31 constexpr base::TimeDelta kFailsafeTimerTimeout =
32     base::TimeDelta::FromSeconds(60);
33 
34 // Override for the LogOut function inside of tests.
GetLogOutOverrideCallbackForTest()35 base::OnceClosure& GetLogOutOverrideCallbackForTest() {
36   static base::NoDestructor<base::OnceClosure> callback;
37   return *callback;
38 }
39 
40 }  // namespace
41 
RemoveUsersIfNeeded()42 bool RemoveUsersIfNeeded() {
43   PrefService* local_state = g_browser_process->local_state();
44   const bool should_remove_users =
45       local_state->GetBoolean(prefs::kRemoveUsersRemoteCommand);
46   if (!should_remove_users)
47     return false;
48 
49   local_state->SetBoolean(prefs::kRemoveUsersRemoteCommand, false);
50 
51   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
52   // Make a copy of the list since we'll be removing users (and the list would
53   // change underneath us if we used a reference).
54   const user_manager::UserList user_list = user_manager->GetUsers();
55 
56   for (user_manager::User* user : user_list)
57     user_manager->RemoveUser(user->GetAccountId(), nullptr);
58 
59   return true;
60 }
61 
LogOut()62 void LogOut() {
63   auto& log_out_override_callback = GetLogOutOverrideCallbackForTest();
64   if (log_out_override_callback) {
65     std::move(log_out_override_callback).Run();
66     return;
67   }
68   chrome::AttemptUserExit();
69 }
70 
OverrideLogOutForTesting(base::OnceClosure callback)71 void OverrideLogOutForTesting(base::OnceClosure callback) {
72   auto& log_out_override_callback = GetLogOutOverrideCallbackForTest();
73   log_out_override_callback = std::move(callback);
74 }
75 
InitiateUserRemoval(base::OnceClosure on_pref_persisted_callback)76 void InitiateUserRemoval(base::OnceClosure on_pref_persisted_callback) {
77   PrefService* local_state = g_browser_process->local_state();
78   local_state->SetBoolean(prefs::kRemoveUsersRemoteCommand, true);
79 
80   local_state->CommitPendingWrite(base::BindOnce(
81       [](base::OnceClosure on_pref_persisted_callback) {
82         // Start the failsafe timer.
83         base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
84             FROM_HERE, base::BindOnce(&LogOut), kFailsafeTimerTimeout);
85 
86         if (on_pref_persisted_callback)
87           std::move(on_pref_persisted_callback).Run();
88       },
89       std::move(on_pref_persisted_callback)));
90 }
91 
92 }  // namespace user_removal_manager
93 }  // namespace chromeos
94