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.
6 #include "base/message_loop/message_loop.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.h"
9 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
10 #include "chrome/grit/generated_resources.h"
11 #include "chromeos/dbus/dbus_thread_manager.h"
12 #include "chromeos/dbus/session_manager_client.h"
13 #include "chromeos/login/auth/auth_status_consumer.h"
14 #include "chromeos/login/auth/user_context.h"
15 #include "components/proximity_auth/screenlock_bridge.h"
16 #include "content/public/browser/notification_details.h"
17 #include "content/public/browser/notification_observer.h"
18 #include "content/public/browser/notification_registrar.h"
19 #include "content/public/browser/notification_service.h"
20 #include "ui/base/l10n/l10n_util.h"
26 void EndReauthAttempt();
28 // Performs the actual reauth flow and returns the user context it obtains.
29 class ReauthHandler
: public content::NotificationObserver
,
30 public chromeos::AuthStatusConsumer
{
32 explicit ReauthHandler(EasyUnlockReauth::UserContextCallback callback
)
33 : callback_(callback
) {}
35 ~ReauthHandler() override
{}
38 ScreenLocker
* screen_locker
= ScreenLocker::default_screen_locker();
39 if (screen_locker
&& screen_locker
->locked()) {
44 user_manager::UserManager
* user_manager
= user_manager::UserManager::Get();
45 if (user_manager
->GetPrimaryUser() != user_manager
->GetActiveUser() ||
46 user_manager
->GetUnlockUsers().size() != 1) {
47 LOG(WARNING
) << "Only primary users in non-multiprofile sessions are "
48 << "currently supported for reauth.";
52 notification_registrar_
.Add(this,
53 chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED
,
54 content::NotificationService::AllSources());
56 SessionManagerClient
* session_manager
=
57 chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
58 session_manager
->RequestLockScreen();
62 // content::NotificationObserver
63 void Observe(int type
,
64 const content::NotificationSource
& source
,
65 const content::NotificationDetails
& details
) override
{
66 CHECK(type
== chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED
);
67 bool is_screen_locked
= *content::Details
<bool>(details
).ptr();
68 DCHECK(is_screen_locked
);
69 notification_registrar_
.RemoveAll();
71 // TODO(tengs): Add an explicit reauth state to the locker and account
72 // picker, so we can customize the UI.
73 ScreenLocker
* screen_locker
= ScreenLocker::default_screen_locker();
74 screen_locker
->SetLoginStatusConsumer(this);
76 // Show tooltip explaining reauth.
77 proximity_auth::ScreenlockBridge::UserPodCustomIconOptions icon_options
;
79 proximity_auth::ScreenlockBridge::USER_POD_CUSTOM_ICON_NONE
);
80 icon_options
.SetTooltip(
81 l10n_util::GetStringUTF16(
82 IDS_SMART_LOCK_SCREENLOCK_TOOLTIP_HARDLOCK_REAUTH_USER
),
85 const user_manager::UserList
& lock_users
= screen_locker
->users();
86 DCHECK(lock_users
.size() == 1);
87 proximity_auth::ScreenlockBridge::Get()
89 ->ShowUserPodCustomIcon(lock_users
[0]->email(), icon_options
);
92 // chromeos::AuthStatusConsumer:
93 void OnAuthSuccess(const chromeos::UserContext
& user_context
) override
{
94 callback_
.Run(user_context
);
96 base::MessageLoopForUI::current()->PostTask(FROM_HERE
,
97 base::Bind(&EndReauthAttempt
));
100 void OnAuthFailure(const chromeos::AuthFailure
& error
) override
{}
103 content::NotificationRegistrar notification_registrar_
;
104 EasyUnlockReauth::UserContextCallback callback_
;
106 DISALLOW_COPY_AND_ASSIGN(ReauthHandler
);
109 ReauthHandler
* g_reauth_handler
= NULL
;
111 void EndReauthAttempt() {
112 DCHECK(base::MessageLoopForUI::IsCurrent());
113 DCHECK(g_reauth_handler
);
114 delete g_reauth_handler
;
115 g_reauth_handler
= NULL
;
121 bool EasyUnlockReauth::ReauthForUserContext(
122 base::Callback
<void(const UserContext
&)> callback
) {
123 DCHECK(base::MessageLoopForUI::IsCurrent());
124 if (g_reauth_handler
)
127 g_reauth_handler
= new ReauthHandler(callback
);
128 return g_reauth_handler
->Start();
131 } // namespace chromeos