Disable polymer-topeka page in key_silk_cases
[chromium-blink-merge.git] / chromeos / login / auth / login_performer.cc
bloba48bb434096c49dcf034fec23414db9591ed2a8c
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 bool disable_client_login)
34 : delegate_(delegate),
35 task_runner_(task_runner),
36 online_attempt_host_(this),
37 last_login_failure_(AuthFailure::AuthFailureNone()),
38 password_changed_(false),
39 password_changed_callback_count_(0),
40 auth_mode_(AUTH_MODE_INTERNAL),
41 disable_client_login_(disable_client_login),
42 weak_factory_(this) {
45 LoginPerformer::~LoginPerformer() {
46 DVLOG(1) << "Deleting LoginPerformer";
47 if (authenticator_.get())
48 authenticator_->SetConsumer(NULL);
49 if (extended_authenticator_.get())
50 extended_authenticator_->SetConsumer(NULL);
53 ////////////////////////////////////////////////////////////////////////////////
54 // LoginPerformer, AuthStatusConsumer implementation:
56 void LoginPerformer::OnAuthFailure(const AuthFailure& failure) {
57 DCHECK(task_runner_->RunsTasksOnCurrentThread());
58 base::RecordAction(UserMetricsAction("Login_Failure"));
60 UMA_HISTOGRAM_ENUMERATION("Login.FailureReason",
61 failure.reason(),
62 AuthFailure::NUM_FAILURE_REASONS);
64 DVLOG(1) << "failure.reason " << failure.reason();
65 DVLOG(1) << "failure.error.state " << failure.error().state();
67 last_login_failure_ = failure;
68 if (delegate_) {
69 delegate_->OnAuthFailure(failure);
70 return;
71 } else {
72 // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
73 // happens during offline auth only.
74 NOTREACHED();
78 void LoginPerformer::OnAuthSuccess(const UserContext& user_context) {
79 DCHECK(task_runner_->RunsTasksOnCurrentThread());
80 base::RecordAction(UserMetricsAction("Login_Success"));
81 VLOG(1) << "LoginSuccess hash: " << user_context.GetUserIDHash();
82 DCHECK(delegate_);
83 // After delegate_->OnAuthSuccess(...) is called, delegate_ releases
84 // LoginPerformer ownership. LP now manages it's lifetime on its own.
85 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
86 delegate_->OnAuthSuccess(user_context);
89 void LoginPerformer::OnOffTheRecordAuthSuccess() {
90 DCHECK(task_runner_->RunsTasksOnCurrentThread());
91 base::RecordAction(UserMetricsAction("Login_GuestLoginSuccess"));
93 if (delegate_)
94 delegate_->OnOffTheRecordAuthSuccess();
95 else
96 NOTREACHED();
99 void LoginPerformer::OnPasswordChangeDetected() {
100 password_changed_ = true;
101 password_changed_callback_count_++;
102 if (delegate_) {
103 delegate_->OnPasswordChangeDetected();
104 } else {
105 NOTREACHED();
109 void LoginPerformer::OnChecked(const std::string& user_id, bool success) {
110 if (!delegate_) {
111 // Delegate is reset in case of successful offline login.
112 // See ExistingUserConstoller::OnAuthSuccess().
113 // Case when user has changed password and enters old password
114 // does not block user from sign in yet.
115 return;
117 delegate_->OnOnlineChecked(user_id, success);
120 ////////////////////////////////////////////////////////////////////////////////
121 // LoginPerformer, public:
123 void LoginPerformer::NotifyWhitelistCheckFailure() {
124 if (delegate_)
125 delegate_->WhiteListCheckFailed(user_context_.GetUserID());
126 else
127 NOTREACHED();
130 void LoginPerformer::PerformLogin(const UserContext& user_context,
131 AuthorizationMode auth_mode) {
132 auth_mode_ = auth_mode;
133 user_context_ = user_context;
135 if (RunTrustedCheck(base::Bind(&LoginPerformer::DoPerformLogin,
136 weak_factory_.GetWeakPtr(),
137 user_context_,
138 auth_mode))) {
139 return;
141 DoPerformLogin(user_context_, auth_mode);
144 void LoginPerformer::DoPerformLogin(const UserContext& user_context,
145 AuthorizationMode auth_mode) {
146 std::string email = gaia::CanonicalizeEmail(user_context.GetUserID());
147 bool wildcard_match = false;
149 if (!IsUserWhitelisted(email, &wildcard_match)) {
150 NotifyWhitelistCheckFailure();
151 return;
154 if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_EASY_UNLOCK)
155 SetupEasyUnlockUserFlow(user_context.GetUserID());
157 switch (auth_mode_) {
158 case AUTH_MODE_EXTENSION: {
159 RunOnlineWhitelistCheck(
160 email, wildcard_match, user_context.GetRefreshToken(),
161 base::Bind(&LoginPerformer::StartLoginCompletion,
162 weak_factory_.GetWeakPtr()),
163 base::Bind(&LoginPerformer::NotifyWhitelistCheckFailure,
164 weak_factory_.GetWeakPtr()));
165 break;
167 case AUTH_MODE_INTERNAL:
168 StartAuthentication();
169 break;
173 void LoginPerformer::LoginAsSupervisedUser(const UserContext& user_context) {
174 DCHECK_EQ(chromeos::login::kSupervisedUserDomain,
175 gaia::ExtractDomainName(user_context.GetUserID()));
177 user_context_ = user_context;
178 user_context_.SetUserType(user_manager::USER_TYPE_SUPERVISED);
180 if (RunTrustedCheck(base::Bind(&LoginPerformer::TrustedLoginAsSupervisedUser,
181 weak_factory_.GetWeakPtr(),
182 user_context_))) {
183 return;
185 TrustedLoginAsSupervisedUser(user_context_);
188 void LoginPerformer::TrustedLoginAsSupervisedUser(
189 const UserContext& user_context) {
190 if (!AreSupervisedUsersAllowed()) {
191 LOG(ERROR) << "Login attempt of supervised user detected.";
192 delegate_->WhiteListCheckFailed(user_context.GetUserID());
193 return;
196 SetupSupervisedUserFlow(user_context.GetUserID());
197 UserContext user_context_copy = TransformSupervisedKey(user_context);
199 if (UseExtendedAuthenticatorForSupervisedUser(user_context)) {
200 EnsureExtendedAuthenticator();
201 // TODO(antrim) : Replace empty callback with explicit method.
202 // http://crbug.com/351268
203 task_runner_->PostTask(
204 FROM_HERE,
205 base::Bind(&ExtendedAuthenticator::AuthenticateToMount,
206 extended_authenticator_.get(),
207 user_context_copy,
208 ExtendedAuthenticator::ResultCallback()));
210 } else {
211 EnsureAuthenticator();
212 task_runner_->PostTask(FROM_HERE,
213 base::Bind(&Authenticator::LoginAsSupervisedUser,
214 authenticator_.get(),
215 user_context_copy));
219 void LoginPerformer::LoginAsPublicSession(const UserContext& user_context) {
220 if (!CheckPolicyForUser(user_context.GetUserID())) {
221 DCHECK(delegate_);
222 if (delegate_)
223 delegate_->PolicyLoadFailed();
224 return;
227 EnsureAuthenticator();
228 task_runner_->PostTask(FROM_HERE,
229 base::Bind(&Authenticator::LoginAsPublicSession,
230 authenticator_.get(),
231 user_context));
234 void LoginPerformer::LoginOffTheRecord() {
235 EnsureAuthenticator();
236 task_runner_->PostTask(
237 FROM_HERE,
238 base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get()));
241 void LoginPerformer::LoginAsKioskAccount(const std::string& app_user_id,
242 bool use_guest_mount) {
243 EnsureAuthenticator();
244 task_runner_->PostTask(FROM_HERE,
245 base::Bind(&Authenticator::LoginAsKioskAccount,
246 authenticator_.get(),
247 app_user_id,
248 use_guest_mount));
251 void LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
252 task_runner_->PostTask(FROM_HERE,
253 base::Bind(&Authenticator::RecoverEncryptedData,
254 authenticator_.get(),
255 old_password));
258 void LoginPerformer::ResyncEncryptedData() {
259 task_runner_->PostTask(
260 FROM_HERE,
261 base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get()));
264 ////////////////////////////////////////////////////////////////////////////////
265 // LoginPerformer, private:
267 void LoginPerformer::EnsureExtendedAuthenticator() {
268 if (extended_authenticator_.get())
269 extended_authenticator_->SetConsumer(NULL);
270 extended_authenticator_ = ExtendedAuthenticator::Create(this);
273 void LoginPerformer::StartLoginCompletion() {
274 DVLOG(1) << "Login completion started";
275 chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("AuthStarted", false);
276 content::BrowserContext* browser_context = GetSigninContext();
277 EnsureAuthenticator();
278 task_runner_->PostTask(FROM_HERE,
279 base::Bind(&chromeos::Authenticator::CompleteLogin,
280 authenticator_.get(),
281 browser_context,
282 user_context_));
283 user_context_.ClearSecrets();
286 void LoginPerformer::StartAuthentication() {
287 DVLOG(1) << "Auth started";
288 chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("AuthStarted", false);
289 if (delegate_) {
290 EnsureAuthenticator();
291 content::BrowserContext* browser_context = GetSigninContext();
292 task_runner_->PostTask(FROM_HERE,
293 base::Bind(&Authenticator::AuthenticateToLogin,
294 authenticator_.get(),
295 base::Unretained(browser_context),
296 user_context_));
297 if (!disable_client_login_) {
298 // Make unobtrusive online check. It helps to determine password change
299 // state in the case when offline login fails.
300 online_attempt_host_.Check(GetSigninRequestContext(), user_context_);
302 } else {
303 NOTREACHED();
305 user_context_.ClearSecrets();
308 void LoginPerformer::EnsureAuthenticator() {
309 authenticator_ = CreateAuthenticator();
311 } // namespace chromeos