Commit 296a6c85 authored by Friedrich Horschig's avatar Friedrich Horschig Committed by Commit Bot

[Passwords] Listen to native leak status update events

This CL updates the status according to native events instead and
queries the status initially.
This enables continuous updates (e.g. during or after a password check).

Bug: 1047726
Change-Id: I075a56b4713782cc1df782b93d3569946e8d9ad4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2089769
Commit-Queue: Friedrich [CET] <fhorschig@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748264}
parent be1ab205
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
// 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.
(function() {
'use strict';
const CheckState = chrome.passwordsPrivate.PasswordCheckState;
Polymer({ Polymer({
is: 'settings-password-check', is: 'settings-password-check',
...@@ -28,8 +33,26 @@ Polymer({ ...@@ -28,8 +33,26 @@ Polymer({
// load. // load.
value: () => [], value: () => [],
}, },
/**
* The status indicates progress and affects banner, title and icon.
* @type {!PasswordManagerProxy.PasswordCheckStatus}
* @private
*/
status_: {
type: PasswordManagerProxy.PasswordCheckStatus,
value: () => {
return {state: CheckState.IDLE};
},
}
}, },
/**
* @type {?function(!PasswordManagerProxy.PasswordCheckStatus):void}
* @private
*/
statusChangedListener_: null,
/** /**
* @type {?function(!PasswordManagerProxy.CompromisedCredentialsInfo):void} * @type {?function(!PasswordManagerProxy.CompromisedCredentialsInfo):void}
* @private * @private
...@@ -53,25 +76,34 @@ Polymer({ ...@@ -53,25 +76,34 @@ Polymer({
// Set the manager. These can be overridden by tests. // Set the manager. These can be overridden by tests.
this.passwordManager_ = PasswordManagerImpl.getInstance(); this.passwordManager_ = PasswordManagerImpl.getInstance();
const statusChangeListener = status => this.status_ = status;
const setLeakedCredentialsListener = info => { const setLeakedCredentialsListener = info => {
this.leakedPasswords = info.compromisedCredentials; this.leakedPasswords = info.compromisedCredentials;
this.passwordLeakCount_ = info.compromisedCredentials.length; this.passwordLeakCount_ = info.compromisedCredentials.length;
this.lastCompletedCheck_ = info.elapsedTimeSinceLastCheck; this.lastCompletedCheck_ = info.elapsedTimeSinceLastCheck;
}; };
this.statusChangedListener_ = statusChangeListener;
this.leakedCredentialsListener_ = setLeakedCredentialsListener; this.leakedCredentialsListener_ = setLeakedCredentialsListener;
// Request initial data. // Request initial data.
this.passwordManager_.getPasswordCheckStatus().then(
this.statusChangedListener_);
this.passwordManager_.getCompromisedCredentialsInfo().then( this.passwordManager_.getCompromisedCredentialsInfo().then(
this.leakedCredentialsListener_); this.leakedCredentialsListener_);
// Listen for changes. // Listen for changes.
this.passwordManager_.addPasswordCheckStatusListener(
this.statusChangedListener_);
this.passwordManager_.addCompromisedCredentialsListener( this.passwordManager_.addCompromisedCredentialsListener(
this.leakedCredentialsListener_); this.leakedCredentialsListener_);
}, },
/** @override */ /** @override */
detached() { detached() {
this.passwordManager_.removePasswordCheckStatusListener(
assert(this.statusChangedListener_));
this.statusChangedListener_ = null;
this.passwordManager_.removeCompromisedCredentialsListener( this.passwordManager_.removeCompromisedCredentialsListener(
assert(this.leakedCredentialsListener_)); assert(this.leakedCredentialsListener_));
this.leakedCredentialsListener_ = null; this.leakedCredentialsListener_ = null;
...@@ -136,3 +168,4 @@ Polymer({ ...@@ -136,3 +168,4 @@ Polymer({
// TODO(crbug.com/1047726) Implement dialog. // TODO(crbug.com/1047726) Implement dialog.
}, },
}); });
})();
...@@ -160,6 +160,12 @@ class PasswordManagerProxy { ...@@ -160,6 +160,12 @@ class PasswordManagerProxy {
*/ */
getCompromisedCredentialsInfo() {} getCompromisedCredentialsInfo() {}
/**
* Returns the current status of the check via |callback|.
* @return {!Promise<(PasswordManagerProxy.PasswordCheckStatus)>}
*/
getPasswordCheckStatus() {}
/** /**
* Add an observer to the compromised passwords change. * Add an observer to the compromised passwords change.
* @param {function(!PasswordManagerProxy.CompromisedCredentialsInfo):void} * @param {function(!PasswordManagerProxy.CompromisedCredentialsInfo):void}
...@@ -173,6 +179,18 @@ class PasswordManagerProxy { ...@@ -173,6 +179,18 @@ class PasswordManagerProxy {
* listener * listener
*/ */
removeCompromisedCredentialsListener(listener) {} removeCompromisedCredentialsListener(listener) {}
/**
* Remove an observer to the compromised passwords change.
* @param {function(!PasswordManagerProxy.PasswordCheckStatus):void} listener
*/
addPasswordCheckStatusListener(listener) {}
/**
* Remove an observer to the compromised passwords change.
* @param {function(!PasswordManagerProxy.PasswordCheckStatus):void} listener
*/
removePasswordCheckStatusListener(listener) {}
} }
/** @typedef {chrome.passwordsPrivate.PasswordUiEntry} */ /** @typedef {chrome.passwordsPrivate.PasswordUiEntry} */
...@@ -198,6 +216,9 @@ PasswordManagerProxy.CompromisedCredential; ...@@ -198,6 +216,9 @@ PasswordManagerProxy.CompromisedCredential;
/** @typedef {chrome.passwordsPrivate.CompromisedCredentialsInfo} */ /** @typedef {chrome.passwordsPrivate.CompromisedCredentialsInfo} */
PasswordManagerProxy.CompromisedCredentialsInfo; PasswordManagerProxy.CompromisedCredentialsInfo;
/** @typedef {chrome.passwordsPrivate.PasswordCheckStatus} */
PasswordManagerProxy.PasswordCheckStatus;
/** /**
* Implementation that accesses the private API. * Implementation that accesses the private API.
* @implements {PasswordManagerProxy} * @implements {PasswordManagerProxy}
...@@ -321,6 +342,13 @@ class PasswordManagerImpl { ...@@ -321,6 +342,13 @@ class PasswordManagerImpl {
}); });
} }
/** @override */
getPasswordCheckStatus() {
return new Promise(resolve => {
chrome.passwordsPrivate.getPasswordCheckStatus(resolve);
});
}
/** @override */ /** @override */
startBulkPasswordCheck() { startBulkPasswordCheck() {
chrome.passwordsPrivate.startPasswordCheck(); chrome.passwordsPrivate.startPasswordCheck();
...@@ -344,6 +372,17 @@ class PasswordManagerImpl { ...@@ -344,6 +372,17 @@ class PasswordManagerImpl {
chrome.passwordsPrivate.onCompromisedCredentialsInfoChanged.removeListener( chrome.passwordsPrivate.onCompromisedCredentialsInfoChanged.removeListener(
listener); listener);
} }
/** @override */
addPasswordCheckStatusListener(listener) {
chrome.passwordsPrivate.onPasswordCheckStatusChanged.addListener(listener);
}
/** @override */
removePasswordCheckStatusListener(listener) {
chrome.passwordsPrivate.onPasswordCheckStatusChanged.removeListener(
listener);
}
} }
cr.addSingletonGetter(PasswordManagerImpl); cr.addSingletonGetter(PasswordManagerImpl);
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
/** @fileoverview Runs the Polymer Check Password tests. */ /** @fileoverview Runs the Polymer Check Password tests. */
cr.define('settings_passwords_check', function() { cr.define('settings_passwords_check', function() {
const PasswordCheckState = chrome.passwordsPrivate.PasswordCheckState;
function createCheckPasswordSection() { function createCheckPasswordSection() {
// Create a passwords-section to use for testing. // Create a passwords-section to use for testing.
const passwordsSection = const passwordsSection =
...@@ -147,5 +149,47 @@ cr.define('settings_passwords_check', function() { ...@@ -147,5 +149,47 @@ cr.define('settings_passwords_check', function() {
assertTrue(menu.open); assertTrue(menu.open);
}); });
}); });
// A changing status is immediately reflected in title, icon and banner.
test('testUpdatesNumberOfCheckedPasswordsWhileRunning', function() {
passwordManager.data.checkStatus =
autofill_test_util.makePasswordCheckStatus(
/*state=*/ PasswordCheckState.RUNNING,
/*checked=*/ 1,
/*remaining=*/ 1);
passwordManager.data.leakedCredentials =
autofill_test_util.makeCompromisedCredentialsInfo([], 'just now');
const section = createCheckPasswordSection();
return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
Polymer.dom.flush();
expectEquals(section.status_.state, PasswordCheckState.RUNNING);
// Change status from running to IDLE.
assert(!!passwordManager.lastCallback.addPasswordCheckStatusListener);
passwordManager.lastCallback.addPasswordCheckStatusListener(
autofill_test_util.makePasswordCheckStatus(
/*state=*/ PasswordCheckState.IDLE,
/*checked=*/ 2,
/*remaining=*/ 0));
Polymer.dom.flush();
expectEquals(section.status_.state, PasswordCheckState.IDLE);
});
});
// Tests that the status is queried right when the page loads.
test('testQueriesCheckedStatusImmediately', function() {
const data = passwordManager.data;
assertEquals(PasswordCheckState.IDLE, data.checkStatus.state);
assertEquals(0, data.leakedCredentials.compromisedCredentials.length);
const checkPasswordSection = createCheckPasswordSection();
return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
Polymer.dom.flush();
expectEquals(
checkPasswordSection.status_.state, PasswordCheckState.IDLE);
}, () => assert(false));
});
}); });
}); });
...@@ -145,6 +145,21 @@ cr.define('autofill_test_util', function() { ...@@ -145,6 +145,21 @@ cr.define('autofill_test_util', function() {
}; };
} }
/**
* Creates a new password check status.
* @param {!chrome.passwordsPrivate.PasswordCheckState} state
* @param {number} checked
* @param {number} remaining
* @return {!chrome.passwordsPrivate.PasswordCheckStatus}
*/
function makePasswordCheckStatus(state, checked, remaining) {
return {
state: state || chrome.passwordsPrivate.PasswordCheckState.IDLE,
alreadyProcessed: checked || 0,
remainingInQueue: remaining || 0
};
}
/** /**
* Creates a new random GUID for testing. * Creates a new random GUID for testing.
* @return {string} * @return {string}
...@@ -411,6 +426,7 @@ cr.define('autofill_test_util', function() { ...@@ -411,6 +426,7 @@ cr.define('autofill_test_util', function() {
createCreditCardEntry: createCreditCardEntry, createCreditCardEntry: createCreditCardEntry,
makeCompromisedCredentials: makeCompromisedCredentials, makeCompromisedCredentials: makeCompromisedCredentials,
makeCompromisedCredentialsInfo: makeCompromisedCredentialsInfo, makeCompromisedCredentialsInfo: makeCompromisedCredentialsInfo,
makePasswordCheckStatus: makePasswordCheckStatus,
TestPaymentsManager: TestPaymentsManager, TestPaymentsManager: TestPaymentsManager,
PaymentsManagerExpectations: PaymentsManagerExpectations, PaymentsManagerExpectations: PaymentsManagerExpectations,
TestAutofillManager: TestAutofillManager, TestAutofillManager: TestAutofillManager,
......
...@@ -15,6 +15,7 @@ class TestPasswordManagerProxy extends TestBrowserProxy { ...@@ -15,6 +15,7 @@ class TestPasswordManagerProxy extends TestBrowserProxy {
'requestPlaintextPassword', 'requestPlaintextPassword',
'startBulkPasswordCheck', 'startBulkPasswordCheck',
'getCompromisedCredentialsInfo', 'getCompromisedCredentialsInfo',
'getPasswordCheckStatus',
]); ]);
this.actual_ = new autofill_test_util.PasswordManagerExpectations(); this.actual_ = new autofill_test_util.PasswordManagerExpectations();
...@@ -25,10 +26,12 @@ class TestPasswordManagerProxy extends TestBrowserProxy { ...@@ -25,10 +26,12 @@ class TestPasswordManagerProxy extends TestBrowserProxy {
exceptions: [], exceptions: [],
leakedCredentials: leakedCredentials:
autofill_test_util.makeCompromisedCredentialsInfo([], ''), autofill_test_util.makeCompromisedCredentialsInfo([], ''),
checkStatus: autofill_test_util.makePasswordCheckStatus(),
}; };
// Holds the last callbacks so they can be called when needed/ // Holds the last callbacks so they can be called when needed/
this.lastCallback = { this.lastCallback = {
addPasswordCheckStatusListener: null,
addSavedPasswordListChangedListener: null, addSavedPasswordListChangedListener: null,
addExceptionListChangedListener: null, addExceptionListChangedListener: null,
requestPlaintextPassword: null, requestPlaintextPassword: null,
...@@ -156,9 +159,23 @@ class TestPasswordManagerProxy extends TestBrowserProxy { ...@@ -156,9 +159,23 @@ class TestPasswordManagerProxy extends TestBrowserProxy {
return Promise.resolve(this.data.leakedCredentials); return Promise.resolve(this.data.leakedCredentials);
} }
/** @override */
getPasswordCheckStatus() {
this.methodCalled('getPasswordCheckStatus');
return Promise.resolve(this.data.checkStatus);
}
/** @override */ /** @override */
addCompromisedCredentialsListener(listener) {} addCompromisedCredentialsListener(listener) {}
/** @override */ /** @override */
removeCompromisedCredentialsListener(listener) {} removeCompromisedCredentialsListener(listener) {}
/** @override */
addPasswordCheckStatusListener(listener) {
this.lastCallback.addPasswordCheckStatusListener = listener;
}
/** @override */
removePasswordCheckStatusListener(listener) {}
} }
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