Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(719)

Side by Side Diff: chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api.cc

Issue 1968083004: Implement the private API for quick unlock. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Migrate browser tests to unit tests Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/extensions/quick_unlock_private/quick_unlock_p rivate_api.h"
6
7 #include "chrome/browser/chromeos/login/quick_unlock/pin_storage.h"
8 #include "chrome/browser/chromeos/login/quick_unlock/pin_storage_factory.h"
9 #include "chrome/browser/chromeos/profiles/profile_helper.h"
10 #include "chromeos/login/auth/extended_authenticator.h"
11 #include "chromeos/login/auth/user_context.h"
12 #include "extensions/browser/event_router.h"
13
14 namespace quick_unlock_private = extensions::api::quick_unlock_private;
15 namespace SetModes = quick_unlock_private::SetModes;
16 namespace GetActiveModes = quick_unlock_private::GetActiveModes;
17 namespace GetAvailableModes = quick_unlock_private::GetAvailableModes;
18 namespace OnActiveModesChanged = quick_unlock_private::OnActiveModesChanged;
19 using QuickUnlockMode = quick_unlock_private::QuickUnlockMode;
20 using ModeList = std::vector<QuickUnlockMode>;
21
22 namespace extensions {
23
24 namespace {
25 const char kModesAndCredentialsLengthMismatch[] =
26 "|modes| and |credentials| must have the same number of elements";
27 const char kMultipleModesNotSupported[] =
28 "Currently at most one quick unlock mode can be active.";
29
30 QuickUnlockPrivateSetModesFunction::CreateAuthenticator create_authenticator_ =
31 nullptr;
32 QuickUnlockPrivateSetModesFunction::ModesChangedEventHandler
33 modes_changed_handler_ = nullptr;
34
35 // Triggers a QuickUnlockMode change event.
36 void FireEvent(Profile* profile, const ModeList& modes) {
37 // Allow unit tests to override how events are raised/handled.
38 if (modes_changed_handler_) {
39 modes_changed_handler_(modes);
40 return;
41 }
42
43 std::unique_ptr<base::ListValue> args = OnActiveModesChanged::Create(modes);
44 std::unique_ptr<extensions::Event> event(new extensions::Event(
45 extensions::events::QUICK_UNLOCK_PRIVATE_ON_ACTIVE_MODES_CHANGED,
Devlin 2016/06/06 16:35:01 nit: no extensions:: prefix (applies to this whole
jdufault 2016/06/08 18:39:09 Done.
46 OnActiveModesChanged::kEventName, std::move(args)));
47 extensions::EventRouter::Get(profile)->BroadcastEvent(std::move(event));
48 }
49
50 // Returns the active set of quick unlock modes.
51 ModeList GetActiveModes(Profile* profile) {
52 ModeList modes;
53
54 chromeos::PinStorage* pin_storage =
55 chromeos::PinStorageFactory::GetForProfile(profile);
56 if (pin_storage->IsPinSet())
57 modes.push_back(quick_unlock_private::QUICK_UNLOCK_MODE_PIN);
58
59 return modes;
60 }
61
62 // Returns true if |a| and |b| contain the same elements. The elements do not
63 // need to be in the same order.
64 bool AreModesEqual(const ModeList& a, const ModeList& b) {
65 if (a.size() != b.size())
66 return false;
67
68 for (size_t i = 0; i < a.size(); ++i) {
Devlin 2016/06/06 16:35:01 nitty nit: might be worth a comment: // This is a
jdufault 2016/06/08 18:39:09 Done.
69 if (std::find(b.begin(), b.end(), a[i]) == b.end())
70 return false;
71 }
72
73 return true;
74 }
75
76 } // namespace
77
78 //////////// quickUnlockPrivate.getAvailableModes
79
80 QuickUnlockPrivateGetAvailableModesFunction::
81 QuickUnlockPrivateGetAvailableModesFunction()
82 : chrome_details_(this) {}
83
84 QuickUnlockPrivateGetAvailableModesFunction::
85 ~QuickUnlockPrivateGetAvailableModesFunction() {}
86
87 ExtensionFunction::ResponseAction
88 QuickUnlockPrivateGetAvailableModesFunction::Run() {
89 // TODO(jdufault): Check for policy and do not return PIN if policy makes it
90 // unavailable. See crbug.com/612271.
91 const ModeList modes = {quick_unlock_private::QUICK_UNLOCK_MODE_PIN};
92
93 return RespondNow(ArgumentList(GetAvailableModes::Results::Create(modes)));
94 }
95
96 //////////// quickUnlockPrivate.getActiveModes
97
98 QuickUnlockPrivateGetActiveModesFunction::
99 QuickUnlockPrivateGetActiveModesFunction()
100 : chrome_details_(this) {}
101
102 QuickUnlockPrivateGetActiveModesFunction::
103 ~QuickUnlockPrivateGetActiveModesFunction() {}
104
105 ExtensionFunction::ResponseAction
106 QuickUnlockPrivateGetActiveModesFunction::Run() {
107 const ModeList modes = GetActiveModes(chrome_details_.GetProfile());
108 return RespondNow(ArgumentList(GetActiveModes::Results::Create(modes)));
109 }
110
111 //////////// quickUnlockPrivate.setModes
112
113 // static
114 void QuickUnlockPrivateSetModesFunction::SetCreateAuthenticatorForTesting(
115 QuickUnlockPrivateSetModesFunction::CreateAuthenticator allocator) {
116 create_authenticator_ = allocator;
117 }
118
119 // static
120 void QuickUnlockPrivateSetModesFunction::SetModesChangedEventHandlerForTesting(
121 ModesChangedEventHandler handler) {
122 modes_changed_handler_ = handler;
123 }
124
125 QuickUnlockPrivateSetModesFunction::QuickUnlockPrivateSetModesFunction()
126 : chrome_details_(this) {
127 // Setup a fake authenticator if we are testing.
128 if (create_authenticator_)
129 extended_authenticator_ = create_authenticator_(this);
130 else
131 extended_authenticator_ = chromeos::ExtendedAuthenticator::Create(this);
132 }
133
134 QuickUnlockPrivateSetModesFunction::~QuickUnlockPrivateSetModesFunction() {}
135
136 ExtensionFunction::ResponseAction QuickUnlockPrivateSetModesFunction::Run() {
137 // The params are also parsed/used inside of ApplyModeChange, so they need to
138 // always be validated here.
139 std::unique_ptr<SetModes::Params> params(SetModes::Params::Create(*args_));
140 EXTENSION_FUNCTION_VALIDATE(params.get());
141
142 if (params->modes.size() != params->credentials.size())
143 return RespondNow(Error(kModesAndCredentialsLengthMismatch));
144
145 if (params->modes.size() > 1)
146 return RespondNow(Error(kMultipleModesNotSupported));
147
148 user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(
149 chrome_details_.GetProfile());
150 chromeos::UserContext user_context(user->GetAccountId());
151 user_context.SetKey(chromeos::Key(params->account_password));
152
153 // The extension function needs to stay alive while the authenticator is
154 // running the password check. Add a ref before the authenticator starts, and
155 // remove the ref after it invokes one of the OnAuth* callbacks.
156 AddRef();
157
158 content::BrowserThread::PostTask(
159 content::BrowserThread::UI, FROM_HERE,
160 base::Bind(&chromeos::ExtendedAuthenticator::AuthenticateToCheck,
161 extended_authenticator_.get(), user_context, base::Closure()));
162
163 return RespondLater();
164 }
165
166 void QuickUnlockPrivateSetModesFunction::OnAuthFailure(
167 const chromeos::AuthFailure& error) {
168 Respond(ArgumentList(SetModes::Results::Create(false)));
169 Release(); // Balanced in Run().
170 }
171
172 void QuickUnlockPrivateSetModesFunction::OnAuthSuccess(
173 const chromeos::UserContext& user_context) {
174 const ModeList initial_modes = GetActiveModes(chrome_details_.GetProfile());
175 ApplyModeChange();
176 const ModeList updated_modes = GetActiveModes(chrome_details_.GetProfile());
177
178 if (!AreModesEqual(initial_modes, updated_modes))
179 FireEvent(chrome_details_.GetProfile(), updated_modes);
180
181 Respond(ArgumentList(SetModes::Results::Create(true)));
182 Release(); // Balanced in Run().
183 }
184
185 void QuickUnlockPrivateSetModesFunction::ApplyModeChange() {
186 // NOTE: params has already been validated inside of Run().
187 std::unique_ptr<SetModes::Params> params(SetModes::Params::Create(*args_));
Devlin 2016/06/06 16:35:01 We should store params as a member so we don't hav
jdufault 2016/06/08 18:39:09 Done.
188
189 // This function is setup so it is easy to add another quick unlock mode while
190 // following all of the invariants, which are:
191 //
192 // 1: If an unlock type is not specified, it should be deactivated.
193 // 2: If a credential for an unlock type is empty, it should not be touched.
194 // 3: Otherwise, the credential should be set to the new value.
195
196 bool update_pin = true;
197 std::string pin_credential;
198
199 // Compute needed changes.
200 for (size_t i = 0; i < params->modes.size(); ++i) {
201 const QuickUnlockMode mode = params->modes[i];
202 const std::string& credential = params->credentials[i];
203
204 if (mode == quick_unlock_private::QUICK_UNLOCK_MODE_PIN) {
205 update_pin = !credential.empty();
206 pin_credential = credential;
207 }
208 }
209
210 // Apply changes.
211 if (update_pin) {
212 Profile* profile = chrome_details_.GetProfile();
213 chromeos::PinStorage* pin_storage =
214 chromeos::PinStorageFactory::GetForProfile(profile);
215
216 if (pin_credential.empty())
217 pin_storage->RemovePin();
218 else
219 pin_storage->SetPin(pin_credential);
220 }
221 }
222
223 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698