ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chromeos / login / auth / login_performer.cc
blob5600e377c8bac052c22dbdc3bb94931299f8201b
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 "chromeos/login/auth/login_performer.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h"
11 #include "base/metrics/user_metrics.h"
12 #include "base/metrics/user_metrics_action.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "chromeos/dbus/session_manager_client.h"
18 #include "chromeos/login/user_names.h"
19 #include "chromeos/login_event_recorder.h"
20 #include "chromeos/settings/cros_settings_names.h"
21 #include "google_apis/gaia/gaia_auth_util.h"
22 #include "net/cookies/cookie_monster.h"
23 #include "net/cookies/cookie_store.h"
24 #include "net/url_request/url_request_context.h"
25 #include "net/url_request/url_request_context_getter.h"
27 using base::UserMetricsAction;
29 namespace chromeos {
31 LoginPerformer::LoginPerformer(scoped_refptr<base::TaskRunner> task_runner,
32 Delegate* delegate)
33 : delegate_(delegate),
34 task_runner_(task_runner),
35 online_attempt_host_(this),
36 last_login_failure_(AuthFailure::AuthFailureNone()),
37 password_changed_(false),
38 password_changed_callback_count_(0),
39 auth_mode_(AUTH_MODE_INTERNAL),
40 weak_factory_(this) {
43 LoginPerformer::~LoginPerformer() {
44 DVLOG(1) << "Deleting LoginPerformer";
45 if (authenticator_.get())
46 authenticator_->SetConsumer(NULL);
47 if (extended_authenticator_.get())
48 extended_authenticator_->SetConsumer(NULL);
51 ////////////////////////////////////////////////////////////////////////////////
52 // LoginPerformer, AuthStatusConsumer implementation:
54 void LoginPerformer::OnAuthFailure(const AuthFailure& failure) {
55 DCHECK(task_runner_->RunsTasksOnCurrentThread());
56 base::RecordAction(UserMetricsAction("Login_Failure"));
58 UMA_HISTOGRAM_ENUMERATION("Login.FailureReason",
59 failure.reason(),
60 AuthFailure::NUM_FAILURE_REASONS);
62 DVLOG(1) << "failure.reason " << failure.reason();
63 DVLOG(1) << "failure.error.state " << failure.error().state();
65 last_login_failure_ = failure;
66 if (delegate_) {
67 delegate_->OnAuthFailure(failure);
68 return;
69 } else {
70 // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
71 // happens during offline auth only.
72 NOTREACHED();
76 void LoginPerformer::OnAuthSuccess(const UserContext& user_context) {
77 DCHECK(task_runner_->RunsTasksOnCurrentThread());
78 base::RecordAction(UserMetricsAction("Login_Success"));
79 VLOG(1) << "LoginSuccess hash: " << user_context.GetUserIDHash();
80 DCHECK(delegate_);
81 // After delegate_->OnAuthSuccess(...) is called, delegate_ releases
82 // LoginPerformer ownership. LP now manages it's lifetime on its own.
83 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
84 delegate_->OnAuthSuccess(user_context);
87 void LoginPerformer::OnOffTheRecordAuthSuccess() {
88 DCHECK(task_runner_->RunsTasksOnCurrentThread());
89 base::RecordAction(UserMetricsAction("Login_GuestLoginSuccess"));
91 if (delegate_)
92 delegate_->OnOffTheRecordAuthSuccess();
93 else
94 NOTREACHED();
97 void LoginPerformer::OnPasswordChangeDetected() {
98 password_changed_ = true;
99 password_changed_callback_count_++;
100 if (delegate_) {
101 delegate_->OnPasswordChangeDetected();
102 } else {
103 NOTREACHED();
107 void LoginPerformer::OnChecked(const std::string& user_id, bool success) {
108 if (!delegate_) {
109 // Delegate is reset in case of successful offline login.
110 // See ExistingUserConstoller::OnAuthSuccess().
111 // Case when user has changed password and enters old password
112 // does not block user from sign in yet.
113 return;
115 delegate_->OnOnlineChecked(user_id, success);
118 ////////////////////////////////////////////////////////////////////////////////
119 // LoginPerformer, public:
121 void LoginPerformer::NotifyWhitelistCheckFailure() {
122 if (delegate_)
123 delegate_->WhiteListCheckFailed(user_context_.GetUserID());
124 else
125 NOTREACHED();
128 void LoginPerformer::PerformLogin(const UserContext& user_context,
129 AuthorizationMode auth_mode) {
130 auth_mode_ = auth_mode;
131 user_context_ = user_context;
133 if (RunTrustedCheck(base::Bind(&LoginPerformer::DoPerformLogin,
134 weak_factory_.GetWeakPtr(),
135 user_context_,
136 auth_mode))) {
137 return;
139 DoPerformLogin(user_context_, auth_mode);
142 void LoginPerformer::DoPerformLogin(const UserContext& user_context,
143 AuthorizationMode auth_mode) {
144 std::string email = gaia::CanonicalizeEmail(user_context.GetUserID());
145 bool wildcard_match = false;
146 if (!IsUserWhitelisted(email, &wildcard_match)) {
147 NotifyWhitelistCheckFailure();
148 return;
151 if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_EASY_UNLOCK)
152 SetupEasyUnlockUserFlow(user_context.GetUserID());
154 switch (auth_mode_) {
155 case AUTH_MODE_EXTENSION: {
156 RunOnlineWhitelistCheck(
157 email,
158 wildcard_match,
159 base::Bind(&LoginPerformer::StartLoginCompletion,
160 weak_factory_.GetWeakPtr()),
161 base::Bind(&LoginPerformer::NotifyWhitelistCheckFailure,
162 weak_factory_.GetWeakPtr()));
163 break;
165 case AUTH_MODE_INTERNAL:
166 StartAuthentication();
167 break;
171 void LoginPerformer::LoginAsSupervisedUser(const UserContext& user_context) {
172 DCHECK_EQ(chromeos::login::kSupervisedUserDomain,
173 gaia::ExtractDomainName(user_context.GetUserID()));
175 user_context_ = user_context;
177 if (RunTrustedCheck(base::Bind(&LoginPerformer::TrustedLoginAsSupervisedUser,
178 weak_factory_.GetWeakPtr(),
179 user_context_))) {
180 return;
182 TrustedLoginAsSupervisedUser(user_context_);
185 void LoginPerformer::TrustedLoginAsSupervisedUser(
186 const UserContext& user_context) {
187 if (!AreSupervisedUsersAllowed()) {
188 LOG(ERROR) << "Login attempt of supervised user detected.";
189 delegate_->WhiteListCheckFailed(user_context.GetUserID());
190 return;
193 SetupSupervisedUserFlow(user_context.GetUserID());
194 UserContext user_context_copy = TransformSupervisedKey(user_context);
196 if (UseExtendedAuthenticatorForSupervisedUser(user_context)) {
197 EnsureExtendedAuthenticator();
198 // TODO(antrim) : Replace empty callback with explicit method.
199 // http://crbug.com/351268
200 task_runner_->PostTask(
201 FROM_HERE,
202 base::Bind(&ExtendedAuthenticator::AuthenticateToMount,
203 extended_authenticator_.get(),
204 user_context_copy,
205 ExtendedAuthenticator::ResultCallback()));
207 } else {
208 EnsureAuthenticator();
209 task_runner_->PostTask(FROM_HERE,
210 base::Bind(&Authenticator::LoginAsSupervisedUser,
211 authenticator_.get(),
212 user_context_copy));
216 void LoginPerformer::LoginAsPublicSession(const UserContext& user_context) {
217 if (!CheckPolicyForUser(user_context.GetUserID())) {
218 DCHECK(delegate_);
219 if (delegate_)
220 delegate_->PolicyLoadFailed();
221 return;
224 EnsureAuthenticator();
225 task_runner_->PostTask(FROM_HERE,
226 base::Bind(&Authenticator::LoginAsPublicSession,
227 authenticator_.get(),
228 user_context));
231 void LoginPerformer::LoginOffTheRecord() {
232 EnsureAuthenticator();
233 task_runner_->PostTask(
234 FROM_HERE,
235 base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get()));
238 void LoginPerformer::LoginAsKioskAccount(const std::string& app_user_id,
239 bool use_guest_mount) {
240 EnsureAuthenticator();
241 task_runner_->PostTask(FROM_HERE,
242 base::Bind(&Authenticator::LoginAsKioskAccount,
243 authenticator_.get(),
244 app_user_id,
245 use_guest_mount));
248 void LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
249 task_runner_->PostTask(FROM_HERE,
250 base::Bind(&Authenticator::RecoverEncryptedData,
251 authenticator_.get(),
252 old_password));
255 void LoginPerformer::ResyncEncryptedData() {
256 task_runner_->PostTask(
257 FROM_HERE,
258 base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get()));
261 ////////////////////////////////////////////////////////////////////////////////
262 // LoginPerformer, private:
264 void LoginPerformer::EnsureExtendedAuthenticator() {
265 if (extended_authenticator_.get())
266 extended_authenticator_->SetConsumer(NULL);
267 extended_authenticator_ = ExtendedAuthenticator::Create(this);
270 void LoginPerformer::StartLoginCompletion() {
271 DVLOG(1) << "Login completion started";
272 chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("AuthStarted", false);
273 content::BrowserContext* browser_context = GetSigninContext();
274 EnsureAuthenticator();
275 task_runner_->PostTask(FROM_HERE,
276 base::Bind(&chromeos::Authenticator::CompleteLogin,
277 authenticator_.get(),
278 browser_context,
279 user_context_));
280 user_context_.ClearSecrets();
283 void LoginPerformer::StartAuthentication() {
284 DVLOG(1) << "Auth started";
285 chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("AuthStarted", false);
286 if (delegate_) {
287 EnsureAuthenticator();
288 content::BrowserContext* browser_context = GetSigninContext();
289 task_runner_->PostTask(FROM_HERE,
290 base::Bind(&Authenticator::AuthenticateToLogin,
291 authenticator_.get(),
292 base::Unretained(browser_context),
293 user_context_));
294 // Make unobtrusive online check. It helps to determine password change
295 // state in the case when offline login fails.
296 online_attempt_host_.Check(GetSigninRequestContext(), user_context_);
297 } else {
298 NOTREACHED();
300 user_context_.ClearSecrets();
303 void LoginPerformer::EnsureAuthenticator() {
304 authenticator_ = CreateAuthenticator();
306 } // namespace chromeos