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

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: Fix compile Created 4 years, 5 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 extensions {
15
16 namespace quick_unlock_private = api::quick_unlock_private;
17 namespace SetModes = quick_unlock_private::SetModes;
18 namespace GetActiveModes = quick_unlock_private::GetActiveModes;
19 namespace GetAvailableModes = quick_unlock_private::GetAvailableModes;
20 namespace OnActiveModesChanged = quick_unlock_private::OnActiveModesChanged;
21 using QuickUnlockMode = quick_unlock_private::QuickUnlockMode;
22 using QuickUnlockModeList = std::vector<QuickUnlockMode>;
23
24 namespace {
25
26 const char kModesAndCredentialsLengthMismatch[] =
27 "|modes| and |credentials| must have the same number of elements";
28 const char kMultipleModesNotSupported[] =
29 "At most one quick unlock mode can be active.";
30
31 // Returns the active set of quick unlock modes.
32 QuickUnlockModeList ComputeActiveModes(Profile* profile) {
33 QuickUnlockModeList 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 QuickUnlockModeList& a, const QuickUnlockModeList& 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
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 QuickUnlockModeList modes = {
75 quick_unlock_private::QUICK_UNLOCK_MODE_PIN};
76
77 return RespondNow(ArgumentList(GetAvailableModes::Results::Create(modes)));
78 }
79
80 // quickUnlockPrivate.getActiveModes
81
82 QuickUnlockPrivateGetActiveModesFunction::
83 QuickUnlockPrivateGetActiveModesFunction()
84 : chrome_details_(this) {}
85
86 QuickUnlockPrivateGetActiveModesFunction::
87 ~QuickUnlockPrivateGetActiveModesFunction() {}
88
89 ExtensionFunction::ResponseAction
90 QuickUnlockPrivateGetActiveModesFunction::Run() {
91 const QuickUnlockModeList modes =
92 ComputeActiveModes(chrome_details_.GetProfile());
93 return RespondNow(ArgumentList(GetActiveModes::Results::Create(modes)));
94 }
95
96 // quickUnlockPrivate.setModes
97
98 QuickUnlockPrivateSetModesFunction::QuickUnlockPrivateSetModesFunction()
99 : chrome_details_(this) {}
100
101 QuickUnlockPrivateSetModesFunction::~QuickUnlockPrivateSetModesFunction() {}
102
103 void QuickUnlockPrivateSetModesFunction::SetAuthenticatorAllocatorForTesting(
104 const QuickUnlockPrivateSetModesFunction::AuthenticatorAllocator&
105 allocator) {
106 authenticator_allocator_ = allocator;
107 }
108
109 void QuickUnlockPrivateSetModesFunction::SetModesChangedEventHandlerForTesting(
110 const ModesChangedEventHandler& handler) {
111 modes_changed_handler_ = handler;
112 }
113
114 ExtensionFunction::ResponseAction QuickUnlockPrivateSetModesFunction::Run() {
115 params_ = SetModes::Params::Create(*args_);
116 EXTENSION_FUNCTION_VALIDATE(params_.get());
117
118 if (params_->modes.size() != params_->credentials.size())
119 return RespondNow(Error(kModesAndCredentialsLengthMismatch));
120
121 if (params_->modes.size() > 1)
122 return RespondNow(Error(kMultipleModesNotSupported));
123
124 user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(
125 chrome_details_.GetProfile());
126 chromeos::UserContext user_context(user->GetAccountId());
127 user_context.SetKey(chromeos::Key(params_->account_password));
128
129 // Lazily allocate the authenticator. We do this here, instead of in the ctor,
130 // so that tests can install a fake.
131 if (authenticator_allocator_.is_null())
132 extended_authenticator_ = chromeos::ExtendedAuthenticator::Create(this);
133 else
134 extended_authenticator_ = authenticator_allocator_.Run(this);
135
136 // The extension function needs to stay alive while the authenticator is
137 // running the password check. Add a ref before the authenticator starts, and
138 // remove the ref after it invokes one of the OnAuth* callbacks. The PostTask
139 // call applies ref management to the extended_authenticator_ instance and not
140 // to the extension function instance, which is why the manual ref management
141 // is needed.
142 AddRef();
143
144 content::BrowserThread::PostTask(
145 content::BrowserThread::UI, FROM_HERE,
146 base::Bind(&chromeos::ExtendedAuthenticator::AuthenticateToCheck,
147 extended_authenticator_.get(), user_context, base::Closure()));
148
149 return RespondLater();
150 }
151
152 void QuickUnlockPrivateSetModesFunction::OnAuthFailure(
153 const chromeos::AuthFailure& error) {
154 Respond(ArgumentList(SetModes::Results::Create(false)));
155 Release(); // Balanced in Run().
156 }
157
158 void QuickUnlockPrivateSetModesFunction::OnAuthSuccess(
159 const chromeos::UserContext& user_context) {
160 const QuickUnlockModeList initial_modes =
161 ComputeActiveModes(chrome_details_.GetProfile());
162 ApplyModeChange();
163 const QuickUnlockModeList updated_modes =
164 ComputeActiveModes(chrome_details_.GetProfile());
165
166 if (!AreModesEqual(initial_modes, updated_modes))
167 FireEvent(updated_modes);
168
169 Respond(ArgumentList(SetModes::Results::Create(true)));
170 Release(); // Balanced in Run().
171 }
172
173 void QuickUnlockPrivateSetModesFunction::ApplyModeChange() {
174 // This function is setup so it is easy to add another quick unlock mode while
175 // following all of the invariants, which are:
176 //
177 // 1: If an unlock type is not specified, it should be deactivated.
178 // 2: If a credential for an unlock type is empty, it should not be touched.
179 // 3: Otherwise, the credential should be set to the new value.
180
181 bool update_pin = true;
182 std::string pin_credential;
183
184 // Compute needed changes.
185 for (size_t i = 0; i < params_->modes.size(); ++i) {
186 const QuickUnlockMode mode = params_->modes[i];
187 const std::string& credential = params_->credentials[i];
188
189 if (mode == quick_unlock_private::QUICK_UNLOCK_MODE_PIN) {
190 update_pin = !credential.empty();
191 pin_credential = credential;
192 }
193 }
194
195 // Apply changes.
196 if (update_pin) {
197 Profile* profile = chrome_details_.GetProfile();
198 chromeos::PinStorage* pin_storage =
199 chromeos::PinStorageFactory::GetForProfile(profile);
200
201 if (pin_credential.empty())
202 pin_storage->RemovePin();
203 else
204 pin_storage->SetPin(pin_credential);
205 }
206 }
207
208 // Triggers a quickUnlockPrivate.onActiveModesChanged change event.
209 void QuickUnlockPrivateSetModesFunction::FireEvent(
210 const QuickUnlockModeList& modes) {
211 // Allow unit tests to override how events are raised/handled.
212 if (!modes_changed_handler_.is_null()) {
213 modes_changed_handler_.Run(modes);
214 return;
215 }
216
217 std::unique_ptr<base::ListValue> args = OnActiveModesChanged::Create(modes);
218 std::unique_ptr<Event> event(
219 new Event(events::QUICK_UNLOCK_PRIVATE_ON_ACTIVE_MODES_CHANGED,
220 OnActiveModesChanged::kEventName, std::move(args)));
221 EventRouter::Get(browser_context())->BroadcastEvent(std::move(event));
222 }
223
224 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698