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

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: Misc fixes 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;
stevenjb 2016/06/22 21:35:21 nit: Unnecessary if you put all of this inside nam
jdufault 2016/06/23 00:14:20 Done.
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;
stevenjb 2016/06/22 21:35:20 nit: FWIW, I generally find using the full name mo
jdufault 2016/06/23 00:14:19 Keeping existing approach as discussed offline.
20 using ModeList = std::vector<QuickUnlockMode>;
stevenjb 2016/06/22 21:35:21 nit: for those of us unfamiliar with the code, Uqi
jdufault 2016/06/23 00:14:20 Done.
21
22 namespace extensions {
23
24 namespace {
25
26 const char kModesAndCredentialsLengthMismatch[] =
27 "|modes| and |credentials| must have the same number of elements";
28 const char kMultipleModesNotSupported[] =
29 "Currently at most one quick unlock mode can be active.";
stevenjb 2016/06/22 21:35:21 nit: Remove "Currently"
jdufault 2016/06/23 00:14:19 Done.
30
31 // Returns the active set of quick unlock modes.
32 ModeList GetActiveModes(Profile* profile) {
33 ModeList modes;
34
35 chromeos::PinStorage* pin_storage =
36 chromeos::PinStorageFactory::GetForProfile(profile);
37 if (pin_storage->IsPinSet())
38 modes.push_back(quick_unlock_private::QUICK_UNLOCK_MODE_PIN);
39
40 return modes;
41 }
42
43 // Returns true if |a| and |b| contain the same elements. The elements do not
44 // need to be in the same order.
45 bool AreModesEqual(const ModeList& a, const ModeList& b) {
46 if (a.size() != b.size())
47 return false;
48
49 // This is a slow comparison algorithm, but the number of entries in |a| and
50 // |b| will always be very low (0-3 items) so it doesn't matter.
51 for (size_t i = 0; i < a.size(); ++i) {
52 if (std::find(b.begin(), b.end(), a[i]) == b.end())
53 return false;
54 }
55
56 return true;
57 }
58
59 } // namespace
60
61 //////////// quickUnlockPrivate.getAvailableModes
stevenjb 2016/06/22 21:35:20 nit: Just '// quickUnlockPrivate.getAvailableModes
jdufault 2016/06/23 00:14:20 Done.
62
63 QuickUnlockPrivateGetAvailableModesFunction::
64 QuickUnlockPrivateGetAvailableModesFunction()
65 : chrome_details_(this) {}
66
67 QuickUnlockPrivateGetAvailableModesFunction::
68 ~QuickUnlockPrivateGetAvailableModesFunction() {}
69
70 ExtensionFunction::ResponseAction
71 QuickUnlockPrivateGetAvailableModesFunction::Run() {
72 // TODO(jdufault): Check for policy and do not return PIN if policy makes it
73 // unavailable. See crbug.com/612271.
74 const ModeList modes = {quick_unlock_private::QUICK_UNLOCK_MODE_PIN};
75
76 return RespondNow(ArgumentList(GetAvailableModes::Results::Create(modes)));
77 }
78
79 //////////// quickUnlockPrivate.getActiveModes
80
81 QuickUnlockPrivateGetActiveModesFunction::
82 QuickUnlockPrivateGetActiveModesFunction()
83 : chrome_details_(this) {}
84
85 QuickUnlockPrivateGetActiveModesFunction::
86 ~QuickUnlockPrivateGetActiveModesFunction() {}
87
88 ExtensionFunction::ResponseAction
89 QuickUnlockPrivateGetActiveModesFunction::Run() {
90 const ModeList modes = GetActiveModes(chrome_details_.GetProfile());
91 return RespondNow(ArgumentList(GetActiveModes::Results::Create(modes)));
92 }
93
94 //////////// quickUnlockPrivate.setModes
95
96 QuickUnlockPrivateSetModesFunction::QuickUnlockPrivateSetModesFunction()
97 : chrome_details_(this) {}
98
99 QuickUnlockPrivateSetModesFunction::~QuickUnlockPrivateSetModesFunction() {}
100
101 void QuickUnlockPrivateSetModesFunction::SetAuthenticatorAllocatorForTesting(
102 const QuickUnlockPrivateSetModesFunction::AuthenticatorAllocator&
103 allocator) {
104 authenticator_allocator_ = allocator;
105 }
106
107 void QuickUnlockPrivateSetModesFunction::SetModesChangedEventHandlerForTesting(
108 const ModesChangedEventHandler& handler) {
109 modes_changed_handler_ = handler;
110 }
111
112 ExtensionFunction::ResponseAction QuickUnlockPrivateSetModesFunction::Run() {
113 params_ = SetModes::Params::Create(*args_);
114 EXTENSION_FUNCTION_VALIDATE(params_.get());
115
116 if (params_->modes.size() != params_->credentials.size())
117 return RespondNow(Error(kModesAndCredentialsLengthMismatch));
118
119 if (params_->modes.size() > 1)
120 return RespondNow(Error(kMultipleModesNotSupported));
121
122 user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(
123 chrome_details_.GetProfile());
124 chromeos::UserContext user_context(user->GetAccountId());
125 user_context.SetKey(chromeos::Key(params_->account_password));
126
127 // The extension function needs to stay alive while the authenticator is
128 // running the password check. Add a ref before the authenticator starts, and
129 // remove the ref after it invokes one of the OnAuth* callbacks.
130 AddRef();
stevenjb 2016/06/22 21:35:21 Why not make this an AsyncExtensionFunction and us
Devlin 2016/06/22 21:47:04 NoNoNo. AsyncExtensionFunction uber deprecated an
stevenjb 2016/06/22 22:02:19 I see. Thanks for correcting me. I find the explic
131
132 // Lazily allocate the authenticator. We do this here, instead of in the ctor,
133 // so that tests can install a fake.
134 if (authenticator_allocator_.is_null())
135 extended_authenticator_ = chromeos::ExtendedAuthenticator::Create(this);
136 else
137 extended_authenticator_ = authenticator_allocator_.Run(this);
138
139 content::BrowserThread::PostTask(
140 content::BrowserThread::UI, FROM_HERE,
141 base::Bind(&chromeos::ExtendedAuthenticator::AuthenticateToCheck,
142 extended_authenticator_.get(), user_context, base::Closure()));
143
144 return RespondLater();
145 }
146
147 void QuickUnlockPrivateSetModesFunction::OnAuthFailure(
148 const chromeos::AuthFailure& error) {
149 Respond(ArgumentList(SetModes::Results::Create(false)));
150 Release(); // Balanced in Run().
151 }
152
153 void QuickUnlockPrivateSetModesFunction::OnAuthSuccess(
154 const chromeos::UserContext& user_context) {
155 const ModeList initial_modes = GetActiveModes(chrome_details_.GetProfile());
156 ApplyModeChange();
157 const ModeList updated_modes = GetActiveModes(chrome_details_.GetProfile());
158
159 if (!AreModesEqual(initial_modes, updated_modes))
160 FireEvent(updated_modes);
161
162 Respond(ArgumentList(SetModes::Results::Create(true)));
163 Release(); // Balanced in Run().
164 }
165
166 void QuickUnlockPrivateSetModesFunction::ApplyModeChange() {
167 // This function is setup so it is easy to add another quick unlock mode while
168 // following all of the invariants, which are:
169 //
170 // 1: If an unlock type is not specified, it should be deactivated.
171 // 2: If a credential for an unlock type is empty, it should not be touched.
172 // 3: Otherwise, the credential should be set to the new value.
173
174 bool update_pin = true;
175 std::string pin_credential;
176
177 // Compute needed changes.
178 for (size_t i = 0; i < params_->modes.size(); ++i) {
179 const QuickUnlockMode mode = params_->modes[i];
180 const std::string& credential = params_->credentials[i];
181
182 if (mode == quick_unlock_private::QUICK_UNLOCK_MODE_PIN) {
183 update_pin = !credential.empty();
184 pin_credential = credential;
185 }
186 }
187
188 // Apply changes.
189 if (update_pin) {
190 Profile* profile = chrome_details_.GetProfile();
191 chromeos::PinStorage* pin_storage =
192 chromeos::PinStorageFactory::GetForProfile(profile);
193
194 if (pin_credential.empty())
195 pin_storage->RemovePin();
196 else
197 pin_storage->SetPin(pin_credential);
198 }
199 }
200
201 // Triggers a QuickUnlockMode change event.
202 void QuickUnlockPrivateSetModesFunction::FireEvent(const ModeList& modes) {
203 // Allow unit tests to override how events are raised/handled.
204 if (!modes_changed_handler_.is_null()) {
205 modes_changed_handler_.Run(modes);
206 return;
207 }
208
209 std::unique_ptr<base::ListValue> args = OnActiveModesChanged::Create(modes);
210 std::unique_ptr<Event> event(
211 new Event(events::QUICK_UNLOCK_PRIVATE_ON_ACTIVE_MODES_CHANGED,
212 OnActiveModesChanged::kEventName, std::move(args)));
213 EventRouter::Get(browser_context())->BroadcastEvent(std::move(event));
214 }
215
216 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698