• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/chromeos/login/screens/user_selection_screen.h"
6 
7 #include "ash/shell.h"
8 #include "base/logging.h"
9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
12 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
13 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
14 #include "chrome/browser/signin/screenlock_bridge.h"
15 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
16 #include "chrome/common/pref_names.h"
17 #include "ui/wm/core/user_activity_detector.h"
18 
19 namespace chromeos {
20 
21 namespace {
22 
23 // User dictionary keys.
24 const char kKeyUsername[] = "username";
25 const char kKeyDisplayName[] = "displayName";
26 const char kKeyEmailAddress[] = "emailAddress";
27 const char kKeyEnterpriseDomain[] = "enterpriseDomain";
28 const char kKeyPublicAccount[] = "publicAccount";
29 const char kKeyLocallyManagedUser[] = "locallyManagedUser";
30 const char kKeySignedIn[] = "signedIn";
31 const char kKeyCanRemove[] = "canRemove";
32 const char kKeyIsOwner[] = "isOwner";
33 const char kKeyInitialAuthType[] = "initialAuthType";
34 const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed";
35 const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy";
36 
37 // Max number of users to show.
38 const size_t kMaxUsers = 18;
39 
40 const int kPasswordClearTimeoutSec = 60;
41 
42 }  // namespace
43 
UserSelectionScreen()44 UserSelectionScreen::UserSelectionScreen() : handler_(NULL) {
45 }
46 
~UserSelectionScreen()47 UserSelectionScreen::~UserSelectionScreen() {
48   wm::UserActivityDetector* activity_detector =
49       ash::Shell::GetInstance()->user_activity_detector();
50   if (activity_detector->HasObserver(this))
51     activity_detector->RemoveObserver(this);
52 }
53 
54 // static
FillUserDictionary(User * user,bool is_owner,bool is_signin_to_add,ScreenlockBridge::LockHandler::AuthType auth_type,base::DictionaryValue * user_dict)55 void UserSelectionScreen::FillUserDictionary(
56     User* user,
57     bool is_owner,
58     bool is_signin_to_add,
59     ScreenlockBridge::LockHandler::AuthType auth_type,
60     base::DictionaryValue* user_dict) {
61   const std::string& user_id = user->email();
62   const bool is_public_account =
63       user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
64   const bool is_locally_managed_user =
65       user->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
66 
67   user_dict->SetString(kKeyUsername, user_id);
68   user_dict->SetString(kKeyEmailAddress, user->display_email());
69   user_dict->SetString(kKeyDisplayName, user->GetDisplayName());
70   user_dict->SetBoolean(kKeyPublicAccount, is_public_account);
71   user_dict->SetBoolean(kKeyLocallyManagedUser, is_locally_managed_user);
72   user_dict->SetInteger(kKeyInitialAuthType, auth_type);
73   user_dict->SetBoolean(kKeySignedIn, user->is_logged_in());
74   user_dict->SetBoolean(kKeyIsOwner, is_owner);
75 
76   // Fill in multi-profiles related fields.
77   if (is_signin_to_add) {
78     MultiProfileUserController* multi_profile_user_controller =
79         UserManager::Get()->GetMultiProfileUserController();
80     std::string behavior =
81         multi_profile_user_controller->GetCachedValue(user_id);
82     user_dict->SetBoolean(kKeyMultiProfilesAllowed,
83                           multi_profile_user_controller->IsUserAllowedInSession(
84                               user_id) == MultiProfileUserController::ALLOWED);
85     user_dict->SetString(kKeyMultiProfilesPolicy, behavior);
86   } else {
87     user_dict->SetBoolean(kKeyMultiProfilesAllowed, true);
88   }
89 
90   if (is_public_account) {
91     policy::BrowserPolicyConnectorChromeOS* policy_connector =
92         g_browser_process->platform_part()->browser_policy_connector_chromeos();
93 
94     if (policy_connector->IsEnterpriseManaged()) {
95       user_dict->SetString(kKeyEnterpriseDomain,
96                            policy_connector->GetEnterpriseDomain());
97     }
98   }
99 }
100 
101 // static
ShouldForceOnlineSignIn(const User * user)102 bool UserSelectionScreen::ShouldForceOnlineSignIn(const User* user) {
103   // Public sessions are always allowed to log in offline.
104   // Supervised user are allowed to log in offline if their OAuth token status
105   // is unknown or valid.
106   // For all other users, force online sign in if:
107   // * The flag to force online sign-in is set for the user.
108   // * The user's OAuth token is invalid.
109   // * The user's OAuth token status is unknown (except supervised users,
110   //   see above).
111   if (user->is_logged_in())
112     return false;
113 
114   const User::OAuthTokenStatus token_status = user->oauth_token_status();
115   const bool is_locally_managed_user =
116       user->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
117   const bool is_public_session =
118       user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
119 
120   if (is_locally_managed_user &&
121       token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN) {
122     return false;
123   }
124 
125   if (is_public_session)
126     return false;
127 
128   return user->force_online_signin() ||
129          (token_status == User::OAUTH2_TOKEN_STATUS_INVALID) ||
130          (token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN);
131 }
132 
SetHandler(LoginDisplayWebUIHandler * handler)133 void UserSelectionScreen::SetHandler(LoginDisplayWebUIHandler* handler) {
134   handler_ = handler;
135 }
136 
Init(const UserList & users,bool show_guest)137 void UserSelectionScreen::Init(const UserList& users, bool show_guest) {
138   users_ = users;
139   show_guest_ = show_guest;
140 
141   wm::UserActivityDetector* activity_detector =
142       ash::Shell::GetInstance()->user_activity_detector();
143   if (!activity_detector->HasObserver(this))
144     activity_detector->AddObserver(this);
145 }
146 
OnBeforeUserRemoved(const std::string & username)147 void UserSelectionScreen::OnBeforeUserRemoved(const std::string& username) {
148   for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) {
149     if ((*it)->email() == username) {
150       users_.erase(it);
151       break;
152     }
153   }
154 }
155 
OnUserRemoved(const std::string & username)156 void UserSelectionScreen::OnUserRemoved(const std::string& username) {
157   if (!handler_)
158     return;
159 
160   handler_->OnUserRemoved(username);
161 }
162 
OnUserImageChanged(const User & user)163 void UserSelectionScreen::OnUserImageChanged(const User& user) {
164   if (!handler_)
165     return;
166   handler_->OnUserImageChanged(user);
167   // TODO(antrim) : updateUserImage(user.email())
168 }
169 
GetUsers() const170 const UserList& UserSelectionScreen::GetUsers() const {
171   return users_;
172 }
173 
OnPasswordClearTimerExpired()174 void UserSelectionScreen::OnPasswordClearTimerExpired() {
175   if (handler_)
176     handler_->ClearUserPodPassword();
177 }
178 
OnUserActivity(const ui::Event * event)179 void UserSelectionScreen::OnUserActivity(const ui::Event* event) {
180   if (!password_clear_timer_.IsRunning()) {
181     password_clear_timer_.Start(
182         FROM_HERE,
183         base::TimeDelta::FromSeconds(kPasswordClearTimeoutSec),
184         this,
185         &UserSelectionScreen::OnPasswordClearTimerExpired);
186   }
187   password_clear_timer_.Reset();
188 }
189 
190 // static
PrepareUserListForSending(const UserList & users,std::string owner,bool is_signin_to_add)191 const UserList UserSelectionScreen::PrepareUserListForSending(
192     const UserList& users,
193     std::string owner,
194     bool is_signin_to_add) {
195 
196   UserList users_to_send;
197   bool has_owner = owner.size() > 0;
198   size_t max_non_owner_users = has_owner ? kMaxUsers - 1 : kMaxUsers;
199   size_t non_owner_count = 0;
200 
201   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
202     const std::string& user_id = (*it)->email();
203     bool is_owner = (user_id == owner);
204     bool is_public_account =
205         ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT);
206 
207     if ((is_public_account && !is_signin_to_add) || is_owner ||
208         (!is_public_account && non_owner_count < max_non_owner_users)) {
209 
210       if (!is_owner)
211         ++non_owner_count;
212       if (is_owner && users_to_send.size() > kMaxUsers) {
213         // Owner is always in the list.
214         users_to_send.insert(users_to_send.begin() + (kMaxUsers - 1), *it);
215         while (users_to_send.size() > kMaxUsers)
216           users_to_send.erase(users_to_send.begin() + kMaxUsers);
217       } else if (users_to_send.size() < kMaxUsers) {
218         users_to_send.push_back(*it);
219       }
220     }
221   }
222   return users_to_send;
223 }
224 
SendUserList(bool animated)225 void UserSelectionScreen::SendUserList(bool animated) {
226   base::ListValue users_list;
227   const UserList& users = GetUsers();
228 
229   // TODO(nkostylev): Move to a separate method in UserManager.
230   // http://crbug.com/230852
231   bool single_user = users.size() == 1;
232   bool is_signin_to_add = LoginDisplayHostImpl::default_host() &&
233                           UserManager::Get()->IsUserLoggedIn();
234   std::string owner;
235   chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
236 
237   policy::BrowserPolicyConnectorChromeOS* connector =
238       g_browser_process->platform_part()->browser_policy_connector_chromeos();
239   bool is_enterprise_managed = connector->IsEnterpriseManaged();
240 
241   const UserList users_to_send = PrepareUserListForSending(users,
242                                                            owner,
243                                                            is_signin_to_add);
244 
245   user_auth_type_map_.clear();
246 
247   for (UserList::const_iterator it = users_to_send.begin();
248        it != users_to_send.end();
249        ++it) {
250     const std::string& user_id = (*it)->email();
251     bool is_owner = (user_id == owner);
252     bool is_public_account =
253         ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT);
254     ScreenlockBridge::LockHandler::AuthType initial_auth_type =
255       ShouldForceOnlineSignIn(*it)
256           ? ScreenlockBridge::LockHandler::ONLINE_SIGN_IN
257           : ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
258     user_auth_type_map_[user_id] = initial_auth_type;
259 
260     base::DictionaryValue* user_dict = new base::DictionaryValue();
261     FillUserDictionary(
262         *it, is_owner, is_signin_to_add, initial_auth_type, user_dict);
263     bool signed_in = (*it)->is_logged_in();
264     // Single user check here is necessary because owner info might not be
265     // available when running into login screen on first boot.
266     // See http://crosbug.com/12723
267     bool can_remove_user =
268         ((!single_user || is_enterprise_managed) && !user_id.empty() &&
269          !is_owner && !is_public_account && !signed_in && !is_signin_to_add);
270     user_dict->SetBoolean(kKeyCanRemove, can_remove_user);
271     users_list.Append(user_dict);
272   }
273 
274   handler_->LoadUsers(users_list, animated, show_guest_);
275 }
276 
HandleGetUsers()277 void UserSelectionScreen::HandleGetUsers() {
278   SendUserList(false);
279 }
280 
SetAuthType(const std::string & username,ScreenlockBridge::LockHandler::AuthType auth_type)281 void UserSelectionScreen::SetAuthType(
282     const std::string& username,
283     ScreenlockBridge::LockHandler::AuthType auth_type) {
284   user_auth_type_map_[username] = auth_type;
285 }
286 
GetAuthType(const std::string & username) const287 ScreenlockBridge::LockHandler::AuthType UserSelectionScreen::GetAuthType(
288     const std::string& username) const {
289   if (user_auth_type_map_.find(username) == user_auth_type_map_.end())
290     return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
291   return user_auth_type_map_.find(username)->second;
292 }
293 
294 }  // namespace chromeos
295