Commit 06c1f04a authored by Martin Kreichgauer's avatar Martin Kreichgauer Committed by Commit Bot

Settings UI: Split up security key-related browser proxies and message handlers

The Security Key settings subpage currently has a single monolithic
browser proxy and associated message handler for three sets of logically
independent functionality (PIN, credential management and reset). This
change, splits them into three individual parts.

This is a structural change only. No functional/behavior changes
intended.

Change-Id: Ie167ed58b4bd293764d6e784d80f922a43296551
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1688206
Commit-Queue: Martin Kreichgauer <martinkr@google.com>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#680566}
parent 381033f4
...@@ -28,7 +28,7 @@ let Credential; ...@@ -28,7 +28,7 @@ let Credential;
cr.define('settings', function() { cr.define('settings', function() {
/** @interface */ /** @interface */
class SecurityKeysBrowserProxy { class SecurityKeysPINBrowserProxy {
/** /**
* Starts a PIN set/change operation by flashing all security keys. Resolves * Starts a PIN set/change operation by flashing all security keys. Resolves
* with a pair of numbers. The first is one if the process has immediately * with a pair of numbers. The first is one if the process has immediately
...@@ -50,6 +50,12 @@ cr.define('settings', function() { ...@@ -50,6 +50,12 @@ cr.define('settings', function() {
*/ */
setPIN(oldPIN, newPIN) {} setPIN(oldPIN, newPIN) {}
/** Cancels all outstanding operations. */
close() {}
}
/** @interface */
class SecurityKeysCredentialBrowserProxy {
/** /**
* Starts a credential management operation. * Starts a credential management operation.
* *
...@@ -70,24 +76,30 @@ cr.define('settings', function() { ...@@ -70,24 +76,30 @@ cr.define('settings', function() {
* @return {!Promise<?number>} a promise that resolves with null if the PIN * @return {!Promise<?number>} a promise that resolves with null if the PIN
* was correct or the number of retries remaining otherwise. * was correct or the number of retries remaining otherwise.
*/ */
credentialManagementProvidePIN(pin) {} providePIN(pin) {}
/** /**
* Enumerates credentials on the authenticator. A correct PIN must have * Enumerates credentials on the authenticator. A correct PIN must have
* previously been supplied via credentialManagementProvidePIN() before this * previously been supplied via providePIN() before this
* method may be called. * method may be called.
* @return {!Promise<!Array<!Credential>>} * @return {!Promise<!Array<!Credential>>}
*/ */
credentialManagementEnumerate() {} enumerateCredentials() {}
/** /**
* Deletes the credentials with the given IDs from the security key. * Deletes the credentials with the given IDs from the security key.
* @param {!Array<!string>} ids * @param {!Array<string>} ids
* @return {!Promise<!string>} a localized response message to display to * @return {!Promise<string>} a localized response message to display to
* the user (on either success or error) * the user (on either success or error)
*/ */
credentialManagementDeleteCredentials(ids) {} deleteCredentials(ids) {}
/** Cancels all outstanding operations. */
close() {}
}
/** @interface */
class SecurityKeysResetBrowserProxy {
/** /**
* Starts a reset operation by flashing all security keys and sending a * Starts a reset operation by flashing all security keys and sending a
* reset command to the one that the user activates. Resolves with a CTAP * reset command to the one that the user activates. Resolves with a CTAP
...@@ -102,16 +114,12 @@ cr.define('settings', function() { ...@@ -102,16 +114,12 @@ cr.define('settings', function() {
*/ */
completeReset() {} completeReset() {}
/** /** Cancels all outstanding operations. */
* Cancel all outstanding operations.
*/
close() {} close() {}
} }
/** /** @implements {settings.SecurityKeysPINBrowserProxy} */
* @implements {settings.SecurityKeysBrowserProxy} class SecurityKeysPINBrowserProxyImpl {
*/
class SecurityKeysBrowserProxyImpl {
/** @override */ /** @override */
startSetPIN() { startSetPIN() {
return cr.sendWithPromise('securityKeyStartSetPIN'); return cr.sendWithPromise('securityKeyStartSetPIN');
...@@ -122,26 +130,42 @@ cr.define('settings', function() { ...@@ -122,26 +130,42 @@ cr.define('settings', function() {
return cr.sendWithPromise('securityKeySetPIN', oldPIN, newPIN); return cr.sendWithPromise('securityKeySetPIN', oldPIN, newPIN);
} }
/** @override */
close() {
return chrome.send('securityKeyPINClose');
}
}
/** @implements {settings.SecurityKeysCredentialBrowserProxy} */
class SecurityKeysCredentialBrowserProxyImpl {
/** @override */ /** @override */
startCredentialManagement() { startCredentialManagement() {
return cr.sendWithPromise('securityKeyCredentialManagement'); return cr.sendWithPromise('securityKeyCredentialManagementStart');
} }
/** @override */ /** @override */
credentialManagementProvidePIN(pin) { providePIN(pin) {
return cr.sendWithPromise('securityKeyCredentialManagementPIN', pin); return cr.sendWithPromise('securityKeyCredentialManagementPIN', pin);
} }
/** @override */ /** @override */
credentialManagementEnumerate() { enumerateCredentials() {
return cr.sendWithPromise('securityKeyCredentialManagementEnumerate'); return cr.sendWithPromise('securityKeyCredentialManagementEnumerate');
} }
/** @override */ /** @override */
credentialManagementDeleteCredentials(ids) { deleteCredentials(ids) {
return cr.sendWithPromise('securityKeyCredentialManagementDelete', ids); return cr.sendWithPromise('securityKeyCredentialManagementDelete', ids);
} }
/** @override */
close() {
return chrome.send('securityKeyCredentialManagementClose');
}
}
/** @implements {settings.SecurityKeysResetBrowserProxy} */
class SecurityKeysResetBrowserProxyImpl {
/** @override */ /** @override */
reset() { reset() {
return cr.sendWithPromise('securityKeyReset'); return cr.sendWithPromise('securityKeyReset');
...@@ -154,16 +178,23 @@ cr.define('settings', function() { ...@@ -154,16 +178,23 @@ cr.define('settings', function() {
/** @override */ /** @override */
close() { close() {
return chrome.send('securityKeyClose'); return chrome.send('securityKeyResetClose');
} }
} }
// The singleton instance_ is replaced with a test version of this wrapper // The singleton instance_ is replaced with a test version of this wrapper
// during testing. // during testing.
cr.addSingletonGetter(SecurityKeysBrowserProxyImpl); cr.addSingletonGetter(SecurityKeysPINBrowserProxyImpl);
cr.addSingletonGetter(SecurityKeysCredentialBrowserProxyImpl);
cr.addSingletonGetter(SecurityKeysResetBrowserProxyImpl);
return { return {
SecurityKeysBrowserProxy: SecurityKeysBrowserProxy, SecurityKeysPINBrowserProxy: SecurityKeysPINBrowserProxy,
SecurityKeysBrowserProxyImpl: SecurityKeysBrowserProxyImpl, SecurityKeysPINBrowserProxyImpl: SecurityKeysPINBrowserProxyImpl,
SecurityKeysCredentialBrowserProxy: SecurityKeysCredentialBrowserProxy,
SecurityKeysCredentialBrowserProxyImpl:
SecurityKeysCredentialBrowserProxyImpl,
SecurityKeysResetBrowserProxy: SecurityKeysResetBrowserProxy,
SecurityKeysResetBrowserProxyImpl: SecurityKeysResetBrowserProxyImpl,
}; };
}); });
...@@ -59,7 +59,7 @@ Polymer({ ...@@ -59,7 +59,7 @@ Polymer({
deleteInProgress_: Boolean, deleteInProgress_: Boolean,
}, },
/** @private {?settings.SecurityKeysBrowserProxy} */ /** @private {?settings.SecurityKeysCredentialBrowserProxy} */
browserProxy_: null, browserProxy_: null,
/** @private {?Set<string>} */ /** @private {?Set<string>} */
...@@ -72,7 +72,8 @@ Polymer({ ...@@ -72,7 +72,8 @@ Polymer({
'security-keys-credential-management-finished', 'security-keys-credential-management-finished',
this.onError_.bind(this)); this.onError_.bind(this));
this.checkedCredentialIds_ = new Set(); this.checkedCredentialIds_ = new Set();
this.browserProxy_ = settings.SecurityKeysBrowserProxyImpl.getInstance(); this.browserProxy_ =
settings.SecurityKeysCredentialBrowserProxyImpl.getInstance();
this.browserProxy_.startCredentialManagement().then( this.browserProxy_.startCredentialManagement().then(
this.collectPin_.bind(this)); this.collectPin_.bind(this));
}, },
...@@ -97,14 +98,13 @@ Polymer({ ...@@ -97,14 +98,13 @@ Polymer({
if (!this.$.pin.validate()) { if (!this.$.pin.validate()) {
return; return;
} }
this.browserProxy_.credentialManagementProvidePIN(this.$.pin.value) this.browserProxy_.providePIN(this.$.pin.value).then((retries) => {
.then((retries) => {
if (retries != null) { if (retries != null) {
this.$.pin.showIncorrectPINError(retries); this.$.pin.showIncorrectPINError(retries);
this.collectPin_(); this.collectPin_();
return; return;
} }
this.browserProxy_.credentialManagementEnumerate().then( this.browserProxy_.enumerateCredentials().then(
this.onCredentials_.bind(this)); this.onCredentials_.bind(this));
}); });
}, },
...@@ -257,9 +257,7 @@ Polymer({ ...@@ -257,9 +257,7 @@ Polymer({
assert(this.checkedCredentialIds_.size > 0); assert(this.checkedCredentialIds_.size > 0);
this.deleteInProgress_ = true; this.deleteInProgress_ = true;
this.browserProxy_ this.browserProxy_.deleteCredentials(Array.from(this.checkedCredentialIds_))
.credentialManagementDeleteCredentials(
Array.from(this.checkedCredentialIds_))
.then((err) => { .then((err) => {
this.deleteInProgress_ = false; this.deleteInProgress_ = false;
this.onError_(err); this.onError_(err);
......
...@@ -42,13 +42,14 @@ Polymer({ ...@@ -42,13 +42,14 @@ Polymer({
title_: String, title_: String,
}, },
/** @private {?settings.SecurityKeysBrowserProxy} */ /** @private {?settings.SecurityKeysResetBrowserProxy} */
browserProxy_: null, browserProxy_: null,
/** @override */ /** @override */
attached: function() { attached: function() {
this.title_ = this.i18n('securityKeysResetTitle'); this.title_ = this.i18n('securityKeysResetTitle');
this.browserProxy_ = settings.SecurityKeysBrowserProxyImpl.getInstance(); this.browserProxy_ =
settings.SecurityKeysResetBrowserProxyImpl.getInstance();
this.$.dialog.showModal(); this.$.dialog.showModal();
this.browserProxy_.reset().then(code => { this.browserProxy_.reset().then(code => {
......
...@@ -140,13 +140,13 @@ Polymer({ ...@@ -140,13 +140,13 @@ Polymer({
title_: String, title_: String,
}, },
/** @private {?settings.SecurityKeysBrowserProxy} */ /** @private {?settings.SecurityKeysPINBrowserProxy} */
browserProxy_: null, browserProxy_: null,
/** @override */ /** @override */
attached: function() { attached: function() {
this.title_ = this.i18n('securityKeysSetPINInitialTitle'); this.title_ = this.i18n('securityKeysSetPINInitialTitle');
this.browserProxy_ = settings.SecurityKeysBrowserProxyImpl.getInstance(); this.browserProxy_ = settings.SecurityKeysPINBrowserProxyImpl.getInstance();
this.$.dialog.showModal(); this.$.dialog.showModal();
this.browserProxy_.startSetPIN().then(([success, errorCode]) => { this.browserProxy_.startSetPIN().then(([success, errorCode]) => {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <utility> #include <utility>
#include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
...@@ -34,81 +35,54 @@ base::flat_set<device::FidoTransportProtocol> supported_transports() { ...@@ -34,81 +35,54 @@ base::flat_set<device::FidoTransportProtocol> supported_transports() {
return {device::FidoTransportProtocol::kUsbHumanInterfaceDevice}; return {device::FidoTransportProtocol::kUsbHumanInterfaceDevice};
} }
void HandleClose(base::Closure close_callback, const base::ListValue* args) {
DCHECK_EQ(0u, args->GetSize());
close_callback.Run();
}
} // namespace } // namespace
namespace settings { namespace settings {
SecurityKeysHandler::SecurityKeysHandler() void SecurityKeysHandlerBase::OnJavascriptAllowed() {}
: state_(State::kNone),
weak_factory_(new base::WeakPtrFactory<SecurityKeysHandler>(this)) {} void SecurityKeysHandlerBase::OnJavascriptDisallowed() {
// If Javascript is disallowed, |Close| will invalidate all current WeakPtrs
// and thus drop all pending callbacks. This means that
// |IsJavascriptAllowed| doesn't need to be tested before each callback
// because, if the callback into this object happened, then Javascript is
// allowed.
Close();
}
SecurityKeysHandler::~SecurityKeysHandler() = default; SecurityKeysPINHandler::SecurityKeysPINHandler() = default;
SecurityKeysPINHandler::~SecurityKeysPINHandler() = default;
void SecurityKeysHandler::RegisterMessages() { void SecurityKeysPINHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback( web_ui()->RegisterMessageCallback(
"securityKeyStartSetPIN", "securityKeyStartSetPIN",
base::BindRepeating(&SecurityKeysHandler::HandleStartSetPIN, base::BindRepeating(&SecurityKeysPINHandler::HandleStartSetPIN,
base::Unretained(this))); base::Unretained(this)));
web_ui()->RegisterMessageCallback( web_ui()->RegisterMessageCallback(
"securityKeySetPIN", "securityKeySetPIN",
base::BindRepeating(&SecurityKeysHandler::HandleSetPIN, base::BindRepeating(&SecurityKeysPINHandler::HandleSetPIN,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyClose", base::BindRepeating(&SecurityKeysHandler::HandleClose,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyReset", base::BindRepeating(&SecurityKeysHandler::HandleReset,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyCompleteReset",
base::BindRepeating(&SecurityKeysHandler::HandleCompleteReset,
base::Unretained(this))); base::Unretained(this)));
web_ui()->RegisterMessageCallback( web_ui()->RegisterMessageCallback(
"securityKeyCredentialManagement", "securityKeyPINClose",
base::BindRepeating(&SecurityKeysHandler::HandleCredentialManagement, base::BindRepeating(&HandleClose,
base::Unretained(this))); base::BindRepeating(&SecurityKeysPINHandler::Close,
web_ui()->RegisterMessageCallback( base::Unretained(this))));
"securityKeyCredentialManagementPIN",
base::BindRepeating(&SecurityKeysHandler::HandleCredentialManagementPIN,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyCredentialManagementEnumerate",
base::BindRepeating(
&SecurityKeysHandler::HandleCredentialManagementEnumerate,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyCredentialManagementDelete",
base::BindRepeating(
&SecurityKeysHandler::HandleCredentialManagementDelete,
base::Unretained(this)));
} }
void SecurityKeysHandler::OnJavascriptAllowed() {} void SecurityKeysPINHandler::Close() {
void SecurityKeysHandler::OnJavascriptDisallowed() {
// If Javascript is disallowed, |Close| will invalidate all current WeakPtrs
// and thus drop all pending callbacks. This means that
// |IsJavascriptAllowed| doesn't need to be tested before each callback
// because, if the callback into this object happened, then Javascript is
// allowed.
Close();
}
void SecurityKeysHandler::Close() {
// Invalidate all existing WeakPtrs so that no stale callbacks occur. // Invalidate all existing WeakPtrs so that no stale callbacks occur.
weak_factory_ = weak_factory_.InvalidateWeakPtrs();
std::make_unique<base::WeakPtrFactory<SecurityKeysHandler>>(this);
state_ = State::kNone; state_ = State::kNone;
set_pin_.reset(); set_pin_.reset();
reset_.reset();
discovery_factory_.reset();
credential_management_.reset();
callback_id_.clear(); callback_id_.clear();
credential_management_provide_pin_cb_.Reset();
DCHECK(!credential_management_provide_pin_cb_);
} }
void SecurityKeysHandler::HandleStartSetPIN(const base::ListValue* args) { void SecurityKeysPINHandler::HandleStartSetPIN(const base::ListValue* args) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(State::kNone, state_); DCHECK_EQ(State::kNone, state_);
DCHECK_EQ(1u, args->GetSize()); DCHECK_EQ(1u, args->GetSize());
...@@ -119,13 +93,13 @@ void SecurityKeysHandler::HandleStartSetPIN(const base::ListValue* args) { ...@@ -119,13 +93,13 @@ void SecurityKeysHandler::HandleStartSetPIN(const base::ListValue* args) {
state_ = State::kStartSetPIN; state_ = State::kStartSetPIN;
set_pin_ = std::make_unique<device::SetPINRequestHandler>( set_pin_ = std::make_unique<device::SetPINRequestHandler>(
content::GetSystemConnector(), supported_transports(), content::GetSystemConnector(), supported_transports(),
base::BindOnce(&SecurityKeysHandler::OnGatherPIN, base::BindOnce(&SecurityKeysPINHandler::OnGatherPIN,
weak_factory_->GetWeakPtr()), weak_factory_.GetWeakPtr()),
base::BindRepeating(&SecurityKeysHandler::OnSetPINComplete, base::BindRepeating(&SecurityKeysPINHandler::OnSetPINComplete,
weak_factory_->GetWeakPtr())); weak_factory_.GetWeakPtr()));
} }
void SecurityKeysHandler::OnGatherPIN(base::Optional<int64_t> num_retries) { void SecurityKeysPINHandler::OnGatherPIN(base::Optional<int64_t> num_retries) {
DCHECK_EQ(State::kStartSetPIN, state_); DCHECK_EQ(State::kStartSetPIN, state_);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
...@@ -143,7 +117,7 @@ void SecurityKeysHandler::OnGatherPIN(base::Optional<int64_t> num_retries) { ...@@ -143,7 +117,7 @@ void SecurityKeysHandler::OnGatherPIN(base::Optional<int64_t> num_retries) {
base::Value(std::move(list))); base::Value(std::move(list)));
} }
void SecurityKeysHandler::OnSetPINComplete( void SecurityKeysPINHandler::OnSetPINComplete(
device::CtapDeviceResponseCode code) { device::CtapDeviceResponseCode code) {
DCHECK(state_ == State::kStartSetPIN || state_ == State::kSettingPIN); DCHECK(state_ == State::kStartSetPIN || state_ == State::kSettingPIN);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
...@@ -163,7 +137,7 @@ void SecurityKeysHandler::OnSetPINComplete( ...@@ -163,7 +137,7 @@ void SecurityKeysHandler::OnSetPINComplete(
base::Value(std::move(list))); base::Value(std::move(list)));
} }
void SecurityKeysHandler::HandleSetPIN(const base::ListValue* args) { void SecurityKeysPINHandler::HandleSetPIN(const base::ListValue* args) {
DCHECK(state_ == State::kGatherNewPIN || state_ == State::kGatherChangePIN); DCHECK(state_ == State::kGatherNewPIN || state_ == State::kGatherChangePIN);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(3u, args->GetSize()); DCHECK_EQ(3u, args->GetSize());
...@@ -180,7 +154,34 @@ void SecurityKeysHandler::HandleSetPIN(const base::ListValue* args) { ...@@ -180,7 +154,34 @@ void SecurityKeysHandler::HandleSetPIN(const base::ListValue* args) {
set_pin_->ProvidePIN(old_pin, new_pin); set_pin_->ProvidePIN(old_pin, new_pin);
} }
void SecurityKeysHandler::HandleReset(const base::ListValue* args) { SecurityKeysResetHandler::SecurityKeysResetHandler() = default;
SecurityKeysResetHandler::~SecurityKeysResetHandler() = default;
void SecurityKeysResetHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"securityKeyReset",
base::BindRepeating(&SecurityKeysResetHandler::HandleReset,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyCompleteReset",
base::BindRepeating(&SecurityKeysResetHandler::HandleCompleteReset,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyResetClose",
base::BindRepeating(&HandleClose,
base::BindRepeating(&SecurityKeysResetHandler::Close,
base::Unretained(this))));
}
void SecurityKeysResetHandler::Close() {
// Invalidate all existing WeakPtrs so that no stale callbacks occur.
weak_factory_.InvalidateWeakPtrs();
state_ = State::kNone;
reset_.reset();
callback_id_.clear();
}
void SecurityKeysResetHandler::HandleReset(const base::ListValue* args) {
DCHECK_EQ(State::kNone, state_); DCHECK_EQ(State::kNone, state_);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(1u, args->GetSize()); DCHECK_EQ(1u, args->GetSize());
...@@ -192,13 +193,13 @@ void SecurityKeysHandler::HandleReset(const base::ListValue* args) { ...@@ -192,13 +193,13 @@ void SecurityKeysHandler::HandleReset(const base::ListValue* args) {
state_ = State::kStartReset; state_ = State::kStartReset;
reset_ = std::make_unique<device::ResetRequestHandler>( reset_ = std::make_unique<device::ResetRequestHandler>(
content::GetSystemConnector(), supported_transports(), content::GetSystemConnector(), supported_transports(),
base::BindOnce(&SecurityKeysHandler::OnResetSent, base::BindOnce(&SecurityKeysResetHandler::OnResetSent,
weak_factory_->GetWeakPtr()), weak_factory_.GetWeakPtr()),
base::BindOnce(&SecurityKeysHandler::OnResetFinished, base::BindOnce(&SecurityKeysResetHandler::OnResetFinished,
weak_factory_->GetWeakPtr())); weak_factory_.GetWeakPtr()));
} }
void SecurityKeysHandler::OnResetSent() { void SecurityKeysResetHandler::OnResetSent() {
DCHECK_EQ(State::kStartReset, state_); DCHECK_EQ(State::kStartReset, state_);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
...@@ -210,7 +211,8 @@ void SecurityKeysHandler::OnResetSent() { ...@@ -210,7 +211,8 @@ void SecurityKeysHandler::OnResetSent() {
base::Value(0 /* success */)); base::Value(0 /* success */));
} }
void SecurityKeysHandler::HandleCompleteReset(const base::ListValue* args) { void SecurityKeysResetHandler::HandleCompleteReset(
const base::ListValue* args) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(1u, args->GetSize()); DCHECK_EQ(1u, args->GetSize());
...@@ -238,7 +240,7 @@ void SecurityKeysHandler::HandleCompleteReset(const base::ListValue* args) { ...@@ -238,7 +240,7 @@ void SecurityKeysHandler::HandleCompleteReset(const base::ListValue* args) {
} }
} }
void SecurityKeysHandler::OnResetFinished( void SecurityKeysResetHandler::OnResetFinished(
device::CtapDeviceResponseCode result) { device::CtapDeviceResponseCode result) {
switch (state_) { switch (state_) {
case State::kWaitingForResetNoCallbackYet: case State::kWaitingForResetNoCallbackYet:
...@@ -267,8 +269,46 @@ void SecurityKeysHandler::OnResetFinished( ...@@ -267,8 +269,46 @@ void SecurityKeysHandler::OnResetFinished(
} }
} }
void SecurityKeysHandler::HandleCredentialManagement( SecurityKeysCredentialHandler::SecurityKeysCredentialHandler() = default;
const base::ListValue* args) { SecurityKeysCredentialHandler::~SecurityKeysCredentialHandler() = default;
void SecurityKeysCredentialHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"securityKeyCredentialManagementStart",
base::BindRepeating(&SecurityKeysCredentialHandler::HandleStart,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyCredentialManagementPIN",
base::BindRepeating(&SecurityKeysCredentialHandler::HandlePIN,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyCredentialManagementEnumerate",
base::BindRepeating(&SecurityKeysCredentialHandler::HandleEnumerate,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyCredentialManagementDelete",
base::BindRepeating(&SecurityKeysCredentialHandler::HandleDelete,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"securityKeyCredentialManagementClose",
base::BindRepeating(
&HandleClose,
base::BindRepeating(&SecurityKeysCredentialHandler::Close,
base::Unretained(this))));
}
void SecurityKeysCredentialHandler::Close() {
// Invalidate all existing WeakPtrs so that no stale callbacks occur.
weak_factory_.InvalidateWeakPtrs();
state_ = State::kNone;
discovery_factory_.reset();
credential_management_.reset();
callback_id_.clear();
credential_management_provide_pin_cb_.Reset();
DCHECK(!credential_management_provide_pin_cb_);
}
void SecurityKeysCredentialHandler::HandleStart(const base::ListValue* args) {
DCHECK_EQ(State::kNone, state_); DCHECK_EQ(State::kNone, state_);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(1u, args->GetSize()); DCHECK_EQ(1u, args->GetSize());
...@@ -279,24 +319,23 @@ void SecurityKeysHandler::HandleCredentialManagement( ...@@ -279,24 +319,23 @@ void SecurityKeysHandler::HandleCredentialManagement(
DCHECK(callback_id_.empty()); DCHECK(callback_id_.empty());
callback_id_ = args->GetList()[0].GetString(); callback_id_ = args->GetList()[0].GetString();
state_ = State::kCredentialManagementStart; state_ = State::kStart;
discovery_factory_ = std::make_unique<device::FidoDiscoveryFactory>(); discovery_factory_ = std::make_unique<device::FidoDiscoveryFactory>();
credential_management_ = credential_management_ =
std::make_unique<device::CredentialManagementHandler>( std::make_unique<device::CredentialManagementHandler>(
content::ServiceManagerConnection::GetForProcess()->GetConnector(), content::ServiceManagerConnection::GetForProcess()->GetConnector(),
discovery_factory_.get(), supported_transports(), discovery_factory_.get(), supported_transports(),
base::BindOnce(&SecurityKeysHandler::OnCredentialManagementReady, base::BindOnce(
weak_factory_->GetWeakPtr()), &SecurityKeysCredentialHandler::OnCredentialManagementReady,
base::BindRepeating( weak_factory_.GetWeakPtr()),
&SecurityKeysHandler::OnCredentialManagementGatherPIN, base::BindRepeating(&SecurityKeysCredentialHandler::OnGatherPIN,
weak_factory_->GetWeakPtr()), weak_factory_.GetWeakPtr()),
base::BindOnce(&SecurityKeysHandler::OnCredentialManagementFinished, base::BindOnce(&SecurityKeysCredentialHandler::OnFinished,
weak_factory_->GetWeakPtr())); weak_factory_.GetWeakPtr()));
} }
void SecurityKeysHandler::HandleCredentialManagementPIN( void SecurityKeysCredentialHandler::HandlePIN(const base::ListValue* args) {
const base::ListValue* args) { DCHECK_EQ(State::kPIN, state_);
DCHECK_EQ(State::kCredentialManagementPIN, state_);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(2u, args->GetSize()); DCHECK_EQ(2u, args->GetSize());
DCHECK(credential_management_); DCHECK(credential_management_);
...@@ -309,29 +348,29 @@ void SecurityKeysHandler::HandleCredentialManagementPIN( ...@@ -309,29 +348,29 @@ void SecurityKeysHandler::HandleCredentialManagementPIN(
std::move(credential_management_provide_pin_cb_).Run(pin); std::move(credential_management_provide_pin_cb_).Run(pin);
} }
void SecurityKeysHandler::HandleCredentialManagementEnumerate( void SecurityKeysCredentialHandler::HandleEnumerate(
const base::ListValue* args) { const base::ListValue* args) {
DCHECK_EQ(state_, State::kCredentialManagementReady); DCHECK_EQ(state_, State::kReady);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(1u, args->GetSize()); DCHECK_EQ(1u, args->GetSize());
DCHECK(credential_management_); DCHECK(credential_management_);
DCHECK(callback_id_.empty()); DCHECK(callback_id_.empty());
state_ = State::kCredentialManagementGettingCredentials; state_ = State::kGettingCredentials;
callback_id_ = args->GetList()[0].GetString(); callback_id_ = args->GetList()[0].GetString();
credential_management_->GetCredentials(base::BindOnce( credential_management_->GetCredentials(
&SecurityKeysHandler::OnHaveCredentials, weak_factory_->GetWeakPtr())); base::BindOnce(&SecurityKeysCredentialHandler::OnHaveCredentials,
weak_factory_.GetWeakPtr()));
} }
void SecurityKeysHandler::HandleCredentialManagementDelete( void SecurityKeysCredentialHandler::HandleDelete(const base::ListValue* args) {
const base::ListValue* args) { DCHECK_EQ(State::kReady, state_);
DCHECK_EQ(State::kCredentialManagementReady, state_);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(2u, args->GetSize()); DCHECK_EQ(2u, args->GetSize());
DCHECK(credential_management_); DCHECK(credential_management_);
DCHECK(callback_id_.empty()); DCHECK(callback_id_.empty());
state_ = State::kCredentialManagementDeleting; state_ = State::kDeletingCredentials;
callback_id_ = args->GetList()[0].GetString(); callback_id_ = args->GetList()[0].GetString();
std::vector<std::vector<uint8_t>> credential_ids; std::vector<std::vector<uint8_t>> credential_ids;
for (const base::Value& el : args->GetList()[1].GetList()) { for (const base::Value& el : args->GetList()[1].GetList()) {
...@@ -344,40 +383,38 @@ void SecurityKeysHandler::HandleCredentialManagementDelete( ...@@ -344,40 +383,38 @@ void SecurityKeysHandler::HandleCredentialManagementDelete(
} }
credential_management_->DeleteCredentials( credential_management_->DeleteCredentials(
std::move(credential_ids), std::move(credential_ids),
base::BindOnce(&SecurityKeysHandler::OnCredentialsDeleted, base::BindOnce(&SecurityKeysCredentialHandler::OnCredentialsDeleted,
weak_factory_->GetWeakPtr())); weak_factory_.GetWeakPtr()));
} }
void SecurityKeysHandler::OnCredentialManagementReady() { void SecurityKeysCredentialHandler::OnCredentialManagementReady() {
DCHECK(state_ == State::kCredentialManagementStart || DCHECK(state_ == State::kStart || state_ == State::kPIN);
state_ == State::kCredentialManagementPIN);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(credential_management_); DCHECK(credential_management_);
DCHECK(!callback_id_.empty()); DCHECK(!callback_id_.empty());
state_ = State::kCredentialManagementReady; state_ = State::kReady;
ResolveJavascriptCallback(base::Value(std::move(callback_id_)), ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
base::Value()); base::Value());
} }
void SecurityKeysHandler::OnHaveCredentials( void SecurityKeysCredentialHandler::OnHaveCredentials(
device::CtapDeviceResponseCode status, device::CtapDeviceResponseCode status,
base::Optional<std::vector<device::AggregatedEnumerateCredentialsResponse>> base::Optional<std::vector<device::AggregatedEnumerateCredentialsResponse>>
responses, responses,
base::Optional<size_t> remaining_credentials) { base::Optional<size_t> remaining_credentials) {
DCHECK_EQ(State::kCredentialManagementGettingCredentials, state_); DCHECK_EQ(State::kGettingCredentials, state_);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(credential_management_); DCHECK(credential_management_);
DCHECK(!callback_id_.empty()); DCHECK(!callback_id_.empty());
if (status != device::CtapDeviceResponseCode::kSuccess) { if (status != device::CtapDeviceResponseCode::kSuccess) {
OnCredentialManagementFinished( OnFinished(device::FidoReturnCode::kAuthenticatorResponseInvalid);
device::FidoReturnCode::kAuthenticatorResponseInvalid);
return; return;
} }
DCHECK(responses); DCHECK(responses);
DCHECK(remaining_credentials); DCHECK(remaining_credentials);
state_ = State::kCredentialManagementReady; state_ = State::kReady;
base::Value::ListStorage credentials; base::Value::ListStorage credentials;
for (const auto& response : *responses) { for (const auto& response : *responses) {
...@@ -403,7 +440,7 @@ void SecurityKeysHandler::OnHaveCredentials( ...@@ -403,7 +440,7 @@ void SecurityKeysHandler::OnHaveCredentials(
base::ListValue(std::move(credentials))); base::ListValue(std::move(credentials)));
} }
void SecurityKeysHandler::OnCredentialManagementGatherPIN( void SecurityKeysCredentialHandler::OnGatherPIN(
int64_t num_retries, int64_t num_retries,
base::OnceCallback<void(std::string)> callback) { base::OnceCallback<void(std::string)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
...@@ -412,29 +449,29 @@ void SecurityKeysHandler::OnCredentialManagementGatherPIN( ...@@ -412,29 +449,29 @@ void SecurityKeysHandler::OnCredentialManagementGatherPIN(
credential_management_provide_pin_cb_ = std::move(callback); credential_management_provide_pin_cb_ = std::move(callback);
if (state_ == State::kCredentialManagementStart) { if (state_ == State::kStart) {
// Resolve the promise to startCredentialManagement(). // Resolve the promise to startCredentialManagement().
state_ = State::kCredentialManagementPIN; state_ = State::kPIN;
ResolveJavascriptCallback(base::Value(std::move(callback_id_)), ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
base::Value()); base::Value());
return; return;
} }
// Resolve the promise to credentialManagementProvidePIN(). // Resolve the promise to credentialManagementProvidePIN().
DCHECK_EQ(state_, State::kCredentialManagementPIN); DCHECK_EQ(state_, State::kPIN);
ResolveJavascriptCallback(base::Value(std::move(callback_id_)), ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
base::Value(static_cast<int>(num_retries))); base::Value(static_cast<int>(num_retries)));
} }
void SecurityKeysHandler::OnCredentialsDeleted( void SecurityKeysCredentialHandler::OnCredentialsDeleted(
device::CtapDeviceResponseCode status) { device::CtapDeviceResponseCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(State::kCredentialManagementDeleting, state_); DCHECK_EQ(State::kDeletingCredentials, state_);
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(credential_management_); DCHECK(credential_management_);
DCHECK(!callback_id_.empty()); DCHECK(!callback_id_.empty());
state_ = State::kCredentialManagementReady; state_ = State::kReady;
ResolveJavascriptCallback( ResolveJavascriptCallback(
base::Value(std::move(callback_id_)), base::Value(std::move(callback_id_)),
...@@ -444,8 +481,7 @@ void SecurityKeysHandler::OnCredentialsDeleted( ...@@ -444,8 +481,7 @@ void SecurityKeysHandler::OnCredentialsDeleted(
: IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_FAILED))); : IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_FAILED)));
} }
void SecurityKeysHandler::OnCredentialManagementFinished( void SecurityKeysCredentialHandler::OnFinished(device::FidoReturnCode status) {
device::FidoReturnCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
int error; int error;
...@@ -479,9 +515,4 @@ void SecurityKeysHandler::OnCredentialManagementFinished( ...@@ -479,9 +515,4 @@ void SecurityKeysHandler::OnCredentialManagementFinished(
base::Value(l10n_util::GetStringUTF8(std::move(error)))); base::Value(l10n_util::GetStringUTF8(std::move(error))));
} }
void SecurityKeysHandler::HandleClose(const base::ListValue* args) {
DCHECK_EQ(0u, args->GetSize());
Close();
}
} // namespace settings } // namespace settings
...@@ -28,59 +28,118 @@ class ResetRequestHandler; ...@@ -28,59 +28,118 @@ class ResetRequestHandler;
namespace settings { namespace settings {
// SecurityKeysHandler processes messages from the "Security Keys" section of a // Base class for message handlers on the "Security Keys" settings subpage.
// settings page. An instance of this class is created for each settings tab and class SecurityKeysHandlerBase : public SettingsPageUIHandler {
// is destroyed when the tab is closed. See the comments in protected:
// security_keys_browser_proxy.js about the interface. SecurityKeysHandlerBase() = default;
class SecurityKeysHandler : public SettingsPageUIHandler {
public:
SecurityKeysHandler();
~SecurityKeysHandler() override;
void RegisterMessages() override; // Subclasses must implement close to invalidate all pending callbacks.
virtual void Close() = 0;
private:
void OnJavascriptAllowed() override; void OnJavascriptAllowed() override;
void OnJavascriptDisallowed() override; void OnJavascriptDisallowed() override;
SecurityKeysHandlerBase(const SecurityKeysHandlerBase&) = delete;
SecurityKeysHandlerBase& operator=(const SecurityKeysHandlerBase&) = delete;
};
// SecurityKeysPINHandler processes messages from the "Create a PIN" dialog of
// the "Security Keys" settings subpage. An instance of this class is created
// for each settings tab and is destroyed when the tab is closed. See
// SecurityKeysPINBrowserProxy about the interface.
class SecurityKeysPINHandler : public SecurityKeysHandlerBase {
public:
SecurityKeysPINHandler();
~SecurityKeysPINHandler() override;
private: private:
enum class State { enum class State {
kNone, kNone,
kStartSetPIN, kStartSetPIN,
kGatherNewPIN, kGatherNewPIN,
kGatherChangePIN, kGatherChangePIN,
kSettingPIN, kSettingPIN,
kStartReset,
kWaitingForResetNoCallbackYet,
kWaitingForResetHaveCallback,
kWaitingForCompleteReset,
kCredentialManagementStart,
kCredentialManagementPIN,
kCredentialManagementReady,
kCredentialManagementGettingCredentials,
kCredentialManagementDeleting,
}; };
void Close(); void RegisterMessages() override;
void Close() override;
// PIN
void HandleStartSetPIN(const base::ListValue* args); void HandleStartSetPIN(const base::ListValue* args);
void OnGatherPIN(base::Optional<int64_t> num_retries); void OnGatherPIN(base::Optional<int64_t> num_retries);
void OnSetPINComplete(device::CtapDeviceResponseCode code); void OnSetPINComplete(device::CtapDeviceResponseCode code);
void HandleSetPIN(const base::ListValue* args); void HandleSetPIN(const base::ListValue* args);
// Reset State state_ = State::kNone;
std::unique_ptr<device::SetPINRequestHandler> set_pin_;
std::string callback_id_;
base::WeakPtrFactory<SecurityKeysPINHandler> weak_factory_{this};
};
// SecurityKeysResetHandler processes messages from the "Reset your Security
// Key" dialog of the "Security Keys" settings subpage. An instance of this
// class is created for each settings tab and is destroyed when the tab is
// closed. See SecurityKeysResetBrowserProxy about the interface.
class SecurityKeysResetHandler : public SecurityKeysHandlerBase {
public:
SecurityKeysResetHandler();
~SecurityKeysResetHandler() override;
private:
enum class State {
kNone,
kStartReset,
kWaitingForResetNoCallbackYet,
kWaitingForResetHaveCallback,
kWaitingForCompleteReset,
};
void RegisterMessages() override;
void Close() override;
void HandleReset(const base::ListValue* args); void HandleReset(const base::ListValue* args);
void OnResetSent(); void OnResetSent();
void HandleCompleteReset(const base::ListValue* args); void HandleCompleteReset(const base::ListValue* args);
void OnResetFinished(device::CtapDeviceResponseCode result); void OnResetFinished(device::CtapDeviceResponseCode result);
// Credential Management State state_ = State::kNone;
void HandleCredentialManagement(const base::ListValue* args);
void HandleCredentialManagementPIN(const base::ListValue* args); std::unique_ptr<device::ResetRequestHandler> reset_;
void HandleCredentialManagementEnumerate(const base::ListValue* args); base::Optional<device::CtapDeviceResponseCode> reset_result_;
void HandleCredentialManagementDelete(const base::ListValue* args);
std::string callback_id_;
base::WeakPtrFactory<SecurityKeysResetHandler> weak_factory_{this};
};
// SecurityKeysCredentialHandler processes messages from the "Manage
// sign-in data" dialog of the "Security Keys" settings subpage. An instance of
// this class is created for each settings tab and is destroyed when the tab is
// closed. See SecurityKeysCredentialBrowserProxy about the interface.
class SecurityKeysCredentialHandler : public SecurityKeysHandlerBase {
public:
SecurityKeysCredentialHandler();
~SecurityKeysCredentialHandler() override;
private:
enum class State {
kNone,
kStart,
kPIN,
kReady,
kGettingCredentials,
kDeletingCredentials,
};
void RegisterMessages() override;
void Close() override;
void HandleStart(const base::ListValue* args);
void HandlePIN(const base::ListValue* args);
void HandleEnumerate(const base::ListValue* args);
void HandleDelete(const base::ListValue* args);
void OnCredentialManagementReady(); void OnCredentialManagementReady();
void OnHaveCredentials( void OnHaveCredentials(
device::CtapDeviceResponseCode status, device::CtapDeviceResponseCode status,
...@@ -88,24 +147,18 @@ class SecurityKeysHandler : public SettingsPageUIHandler { ...@@ -88,24 +147,18 @@ class SecurityKeysHandler : public SettingsPageUIHandler {
std::vector<device::AggregatedEnumerateCredentialsResponse>> std::vector<device::AggregatedEnumerateCredentialsResponse>>
responses, responses,
base::Optional<size_t> remaining_credentials); base::Optional<size_t> remaining_credentials);
void OnCredentialManagementGatherPIN(int64_t num_retries, void OnGatherPIN(int64_t num_retries, base::OnceCallback<void(std::string)>);
base::OnceCallback<void(std::string)>);
void OnCredentialsDeleted(device::CtapDeviceResponseCode status); void OnCredentialsDeleted(device::CtapDeviceResponseCode status);
void OnCredentialManagementFinished(device::FidoReturnCode status); void OnFinished(device::FidoReturnCode status);
void HandleClose(const base::ListValue* args); State state_ = State::kNone;
State state_;
base::OnceCallback<void(std::string)> credential_management_provide_pin_cb_; base::OnceCallback<void(std::string)> credential_management_provide_pin_cb_;
std::unique_ptr<device::FidoDiscoveryFactory> discovery_factory_; std::unique_ptr<device::FidoDiscoveryFactory> discovery_factory_;
std::unique_ptr<device::SetPINRequestHandler> set_pin_;
std::unique_ptr<device::CredentialManagementHandler> credential_management_; std::unique_ptr<device::CredentialManagementHandler> credential_management_;
std::unique_ptr<device::ResetRequestHandler> reset_;
base::Optional<device::CtapDeviceResponseCode> reset_result_;
std::string callback_id_;
std::unique_ptr<base::WeakPtrFactory<SecurityKeysHandler>> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SecurityKeysHandler); std::string callback_id_;
base::WeakPtrFactory<SecurityKeysCredentialHandler> weak_factory_{this};
}; };
} // namespace settings } // namespace settings
......
...@@ -230,7 +230,9 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) ...@@ -230,7 +230,9 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
AddSettingsPageUIHandler(std::make_unique<SearchEnginesHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<SearchEnginesHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<SiteSettingsHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<SiteSettingsHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<StartupPagesHandler>(web_ui)); AddSettingsPageUIHandler(std::make_unique<StartupPagesHandler>(web_ui));
AddSettingsPageUIHandler(std::make_unique<SecurityKeysHandler>()); AddSettingsPageUIHandler(std::make_unique<SecurityKeysPINHandler>());
AddSettingsPageUIHandler(std::make_unique<SecurityKeysResetHandler>());
AddSettingsPageUIHandler(std::make_unique<SecurityKeysCredentialHandler>());
#if defined(OS_WIN) || defined(OS_MACOSX) #if defined(OS_WIN) || defined(OS_MACOSX)
AddSettingsPageUIHandler(std::make_unique<CaptionsHandler>()); AddSettingsPageUIHandler(std::make_unique<CaptionsHandler>());
......
...@@ -2,18 +2,12 @@ ...@@ -2,18 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/** @implements {settings.SecurityKeysBrowserProxy} */ /** @implements {settings.SecurityKeysPINBrowserProxy} */
class TestSecurityKeysBrowserProxy extends TestBrowserProxy { class TestSecurityKeysPINBrowserProxy extends TestBrowserProxy {
constructor() { constructor() {
super([ super([
'startSetPIN', 'startSetPIN',
'setPIN', 'setPIN',
'reset',
'completeReset',
'startCredentialManagement',
'credentialManagementProvidePIN',
'credentialManagementEnumerate',
'credentialManagementDeleteCredentials',
'close', 'close',
]); ]);
...@@ -62,6 +56,56 @@ class TestSecurityKeysBrowserProxy extends TestBrowserProxy { ...@@ -62,6 +56,56 @@ class TestSecurityKeysBrowserProxy extends TestBrowserProxy {
return this.handleMethod_('setPIN', {oldPIN, newPIN}); return this.handleMethod_('setPIN', {oldPIN, newPIN});
} }
/** @override */
close() {
this.methodCalled('close');
}
}
/** @implements {settings.SecurityKeysResetBrowserProxy} */
class TestSecurityKeysResetBrowserProxy extends TestBrowserProxy {
constructor() {
super([
'reset',
'completeReset',
'close',
]);
/**
* A map from method names to a promise to return when that method is
* called. (If no promise is installed, a never-resolved promise is
* returned.)
* @private {!Map<string, !Promise>}
*/
this.promiseMap_ = new Map();
}
/**
* @param {string} methodName
* @param {!Promise} promise
*/
setResponseFor(methodName, promise) {
this.promiseMap_.set(methodName, promise);
}
/**
* @param {string} methodName
* @param {*} opt_arg
* @return {!Promise}
* @private
*/
handleMethod_(methodName, opt_arg) {
this.methodCalled(methodName, opt_arg);
const promise = this.promiseMap_.get(methodName);
if (promise != undefined) {
this.promiseMap_.delete(methodName);
return promise;
}
// Return a Promise that never resolves.
return new Promise(() => {});
}
/** @override */ /** @override */
reset() { reset() {
return this.handleMethod_('reset'); return this.handleMethod_('reset');
...@@ -72,24 +116,76 @@ class TestSecurityKeysBrowserProxy extends TestBrowserProxy { ...@@ -72,24 +116,76 @@ class TestSecurityKeysBrowserProxy extends TestBrowserProxy {
return this.handleMethod_('completeReset'); return this.handleMethod_('completeReset');
} }
/** @override */
close() {
this.methodCalled('close');
}
}
/** @implements {settings.SecurityKeysCredentialBrowserProxy} */
class TestSecurityKeysCredentialBrowserProxy extends TestBrowserProxy {
constructor() {
super([
'startCredentialManagement',
'providePIN',
'enumerateCredentials',
'deleteCredentials',
'close',
]);
/**
* A map from method names to a promise to return when that method is
* called. (If no promise is installed, a never-resolved promise is
* returned.)
* @private {!Map<string, !Promise>}
*/
this.promiseMap_ = new Map();
}
/**
* @param {string} methodName
* @param {!Promise} promise
*/
setResponseFor(methodName, promise) {
this.promiseMap_.set(methodName, promise);
}
/**
* @param {string} methodName
* @param {*} opt_arg
* @return {!Promise}
* @private
*/
handleMethod_(methodName, opt_arg) {
this.methodCalled(methodName, opt_arg);
const promise = this.promiseMap_.get(methodName);
if (promise != undefined) {
this.promiseMap_.delete(methodName);
return promise;
}
// Return a Promise that never resolves.
return new Promise(() => {});
}
/** @override */ /** @override */
startCredentialManagement() { startCredentialManagement() {
return this.handleMethod_('startCredentialManagement'); return this.handleMethod_('startCredentialManagement');
} }
/** @override */ /** @override */
credentialManagementProvidePIN(pin) { providePIN(pin) {
return this.handleMethod_('credentialManagementProvidePIN', pin); return this.handleMethod_('providePIN', pin);
} }
/** @override */ /** @override */
credentialManagementEnumerate() { enumerateCredentials() {
return this.handleMethod_('credentialManagementEnumerate'); return this.handleMethod_('enumerateCredentials');
} }
/** @override */ /** @override */
credentialManagementDeleteCredentials(ids) { deleteCredentials(ids) {
return this.handleMethod_('credentialManagementDeleteCredentials', ids); return this.handleMethod_('deleteCredentials', ids);
} }
/** @override */ /** @override */
...@@ -102,8 +198,8 @@ suite('SecurityKeysResetDialog', function() { ...@@ -102,8 +198,8 @@ suite('SecurityKeysResetDialog', function() {
let dialog = null; let dialog = null;
setup(function() { setup(function() {
browserProxy = new TestSecurityKeysBrowserProxy(); browserProxy = new TestSecurityKeysResetBrowserProxy();
settings.SecurityKeysBrowserProxyImpl.instance_ = browserProxy; settings.SecurityKeysResetBrowserProxyImpl.instance_ = browserProxy;
PolymerTest.clearBody(); PolymerTest.clearBody();
dialog = document.createElement('settings-security-keys-reset-dialog'); dialog = document.createElement('settings-security-keys-reset-dialog');
}); });
...@@ -221,8 +317,8 @@ suite('SecurityKeysSetPINDialog', function() { ...@@ -221,8 +317,8 @@ suite('SecurityKeysSetPINDialog', function() {
let dialog = null; let dialog = null;
setup(function() { setup(function() {
browserProxy = new TestSecurityKeysBrowserProxy(); browserProxy = new TestSecurityKeysPINBrowserProxy();
settings.SecurityKeysBrowserProxyImpl.instance_ = browserProxy; settings.SecurityKeysPINBrowserProxyImpl.instance_ = browserProxy;
PolymerTest.clearBody(); PolymerTest.clearBody();
dialog = document.createElement('settings-security-keys-set-pin-dialog'); dialog = document.createElement('settings-security-keys-set-pin-dialog');
}); });
...@@ -476,8 +572,8 @@ suite('SecurityKeysCredentialManagement', function() { ...@@ -476,8 +572,8 @@ suite('SecurityKeysCredentialManagement', function() {
let dialog = null; let dialog = null;
setup(function() { setup(function() {
browserProxy = new TestSecurityKeysBrowserProxy(); browserProxy = new TestSecurityKeysCredentialBrowserProxy();
settings.SecurityKeysBrowserProxyImpl.instance_ = browserProxy; settings.SecurityKeysCredentialBrowserProxyImpl.instance_ = browserProxy;
PolymerTest.clearBody(); PolymerTest.clearBody();
dialog = document.createElement( dialog = document.createElement(
'settings-security-keys-credential-management-dialog'); 'settings-security-keys-credential-management-dialog');
...@@ -530,14 +626,12 @@ suite('SecurityKeysCredentialManagement', function() { ...@@ -530,14 +626,12 @@ suite('SecurityKeysCredentialManagement', function() {
browserProxy.setResponseFor( browserProxy.setResponseFor(
'startCredentialManagement', startCredentialManagementResolver.promise); 'startCredentialManagement', startCredentialManagementResolver.promise);
const pinResolver = new PromiseResolver(); const pinResolver = new PromiseResolver();
browserProxy.setResponseFor( browserProxy.setResponseFor('providePIN', pinResolver.promise);
'credentialManagementProvidePIN', pinResolver.promise);
const enumerateResolver = new PromiseResolver(); const enumerateResolver = new PromiseResolver();
browserProxy.setResponseFor( browserProxy.setResponseFor(
'credentialManagementEnumerate', enumerateResolver.promise); 'enumerateCredentials', enumerateResolver.promise);
const deleteResolver = new PromiseResolver(); const deleteResolver = new PromiseResolver();
browserProxy.setResponseFor( browserProxy.setResponseFor('deleteCredentials', deleteResolver.promise);
'credentialManagementDeleteCredentials', deleteResolver.promise);
document.body.appendChild(dialog); document.body.appendChild(dialog);
await browserProxy.whenCalled('startCredentialManagement'); await browserProxy.whenCalled('startCredentialManagement');
...@@ -551,12 +645,12 @@ suite('SecurityKeysCredentialManagement', function() { ...@@ -551,12 +645,12 @@ suite('SecurityKeysCredentialManagement', function() {
assertShown('pinPrompt'); assertShown('pinPrompt');
dialog.$.pin.value = '0000'; dialog.$.pin.value = '0000';
dialog.$.confirmButton.click(); dialog.$.confirmButton.click();
const pin = await browserProxy.whenCalled('credentialManagementProvidePIN'); const pin = await browserProxy.whenCalled('providePIN');
assertEquals(pin, '0000'); assertEquals(pin, '0000');
// Show a list of three credentials. // Show a list of three credentials.
pinResolver.resolve(); pinResolver.resolve();
await browserProxy.whenCalled('credentialManagementEnumerate'); await browserProxy.whenCalled('enumerateCredentials');
uiReady = test_util.eventToPromise( uiReady = test_util.eventToPromise(
'credential-management-dialog-ready-for-testing', dialog); 'credential-management-dialog-ready-for-testing', dialog);
const credentials = [ const credentials = [
...@@ -596,8 +690,7 @@ suite('SecurityKeysCredentialManagement', function() { ...@@ -596,8 +690,7 @@ suite('SecurityKeysCredentialManagement', function() {
assertFalse(dialog.$.confirmButton.disabled); assertFalse(dialog.$.confirmButton.disabled);
dialog.$.confirmButton.click(); dialog.$.confirmButton.click();
const credentialIds = const credentialIds = await browserProxy.whenCalled('deleteCredentials');
await browserProxy.whenCalled('credentialManagementDeleteCredentials');
assertDeepEquals(credentialIds, ['bbbbbb', 'cccccc']); assertDeepEquals(credentialIds, ['bbbbbb', 'cccccc']);
uiReady = test_util.eventToPromise( uiReady = test_util.eventToPromise(
'credential-management-dialog-ready-for-testing', dialog); 'credential-management-dialog-ready-for-testing', dialog);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment