Commit c6997594 authored by Viktor Semeniuk's avatar Viktor Semeniuk Committed by Commit Bot

[Passwords] Append/Delete to compromised creadentials list

This change allows adding new entities to the bottom of the compromised
credentials list. Special sorting applied. Also, deleted elements are
removed from the list.

Bug: 1047726
Change-Id: I3af45a94670091b61cf517d0637877f9f852901b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2094983
Commit-Queue: Viktor Semeniuk <vsemeniuk@google.com>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#749574}
parent 44f7f578
...@@ -85,7 +85,7 @@ Polymer({ ...@@ -85,7 +85,7 @@ Polymer({
const statusChangeListener = status => this.status_ = status; const statusChangeListener = status => this.status_ = status;
const setLeakedCredentialsListener = compromisedCredentials => { const setLeakedCredentialsListener = compromisedCredentials => {
this.leakedPasswords = compromisedCredentials; this.updateList(compromisedCredentials);
settings.PluralStringProxyImpl.getInstance() settings.PluralStringProxyImpl.getInstance()
.getPluralString('compromisedPasswords', this.leakedPasswords.length) .getPluralString('compromisedPasswords', this.leakedPasswords.length)
...@@ -412,5 +412,40 @@ Polymer({ ...@@ -412,5 +412,40 @@ Polymer({
} }
throw 'Not specified whether to show passwords for state: ' + status.state; throw 'Not specified whether to show passwords for state: ' + status.state;
}, },
/**
* Function to update compromised credentials in a proper way. New entities
* should appear in the bottom.
* @param {!Array<!PasswordManagerProxy.CompromisedCredential>} newList
* @private
*/
updateList(newList) {
const oldList = this.leakedPasswords.slice();
const map = new Map();
newList.forEach(item => map.set(item.id, item));
const resultList = [];
oldList.forEach((item, index) => {
// If element is present in newList
if (map.has(item.id)) {
// Replace old version with new
resultList.push(map.get(item.id));
map.delete(item.id);
}
});
const addedResults = Array.from(map.values());
addedResults.sort((lhs, rhs) => {
// Phished passwords are always shown above
if (lhs.compromiseType != rhs.compromiseType) {
return lhs.compromiseType ==
chrome.passwordsPrivate.CompromiseType.PHISHED ? -1 : 1;
}
return rhs.compromiseTime - lhs.compromiseTime;
});
this.leakedPasswords = resultList.concat(addedResults);
},
}); });
})(); })();
...@@ -43,6 +43,22 @@ cr.define('settings_passwords_check', function() { ...@@ -43,6 +43,22 @@ cr.define('settings_passwords_check', function() {
element.offsetParent !== null; // Considers parents hiding |element|. element.offsetParent !== null; // Considers parents hiding |element|.
} }
/**
* Helper method used to randomize array.
* @param {!Array<!chrome.passwordsPrivate.CompromisedCredential>} array
* @return {!Array<!chrome.passwordsPrivate.CompromisedCredential>}
*/
function shuffleArray(array) {
const copy = array.slice();
for (let i = copy.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = copy[i];
copy[i] = copy[j];
copy[j] = temp;
}
return copy;
}
/** /**
* Helper method that validates a that elements in the compromised credentials * Helper method that validates a that elements in the compromised credentials
* list match the expected data. * list match the expected data.
...@@ -235,9 +251,9 @@ cr.define('settings_passwords_check', function() { ...@@ -235,9 +251,9 @@ cr.define('settings_passwords_check', function() {
test('testSomeCompromisedCredentials', function() { test('testSomeCompromisedCredentials', function() {
const leakedPasswords = [ const leakedPasswords = [
autofill_test_util.makeCompromisedCredential( autofill_test_util.makeCompromisedCredential(
'one.com', 'test4', 'LEAKED'), 'one.com', 'test4', 'PHISHED', 1, 1),
autofill_test_util.makeCompromisedCredential( autofill_test_util.makeCompromisedCredential(
'two.com', 'test3', 'PHISHED'), 'two.com', 'test3', 'LEAKED', 2, 2),
]; ];
passwordManager.data.leakedCredentials = leakedPasswords; passwordManager.data.leakedCredentials = leakedPasswords;
const checkPasswordSection = createCheckPasswordSection(); const checkPasswordSection = createCheckPasswordSection();
...@@ -749,6 +765,58 @@ cr.define('settings_passwords_check', function() { ...@@ -749,6 +765,58 @@ cr.define('settings_passwords_check', function() {
expectFalse(isElementVisible(checkPasswordSection.$$('#bannerImage'))); expectFalse(isElementVisible(checkPasswordSection.$$('#bannerImage')));
}); });
}); });
// Test verifies that new credentials are added to the bottom
test('testAppendCompromisedCredentials', function() {
const leakedPasswords = [
autofill_test_util.makeCompromisedCredential(
'one.com', 'test4', 'LEAKED', 1, 0),
autofill_test_util.makeCompromisedCredential(
'two.com', 'test3', 'LEAKED', 2, 0),
];
const checkPasswordSection = createCheckPasswordSection();
checkPasswordSection.updateList(leakedPasswords);
Polymer.dom.flush();
validateLeakedPasswordsList(checkPasswordSection, leakedPasswords);
leakedPasswords.push(autofill_test_util.makeCompromisedCredential(
'three.com', 'test2', 'PHISHED', 3, 3));
leakedPasswords.push(autofill_test_util.makeCompromisedCredential(
'four.com', 'test1', 'LEAKED', 4, 5));
leakedPasswords.push(autofill_test_util.makeCompromisedCredential(
'five.com', 'test0', 'LEAKED', 5, 4));
checkPasswordSection.updateList(shuffleArray(leakedPasswords));
Polymer.dom.flush();
validateLeakedPasswordsList(checkPasswordSection, leakedPasswords);
});
// Test verifies that deleting and adding works as it should
test('testDeleteComrpomisedCredemtials', function() {
const leakedPasswords = [
autofill_test_util.makeCompromisedCredential(
'one.com', 'test4', 'PHISHED', 0, 0),
autofill_test_util.makeCompromisedCredential(
'two.com', 'test3', 'LEAKED', 1, 2),
autofill_test_util.makeCompromisedCredential(
'three.com', 'test2', 'LEAKED', 2, 2),
autofill_test_util.makeCompromisedCredential(
'four.com', 'test2', 'LEAKED', 3, 2),
];
const checkPasswordSection = createCheckPasswordSection();
checkPasswordSection.updateList(leakedPasswords);
Polymer.dom.flush();
validateLeakedPasswordsList(checkPasswordSection, leakedPasswords);
// remove 2nd and 3rd elements
leakedPasswords.splice(1, 2);
leakedPasswords.push(autofill_test_util.makeCompromisedCredential(
'five.com', 'test2', 'LEAKED', 4, 3));
checkPasswordSection.updateList(shuffleArray(leakedPasswords));
Polymer.dom.flush();
validateLeakedPasswordsList(checkPasswordSection, leakedPasswords);
});
}); });
// #cr_define_end // #cr_define_end
}); });
...@@ -122,16 +122,21 @@ cr.define('autofill_test_util', function() { ...@@ -122,16 +122,21 @@ cr.define('autofill_test_util', function() {
* @param {string=} url * @param {string=} url
* @param {string=} username * @param {string=} username
* @param {string=} type * @param {string=} type
* @param {number=} id
* @param {number=} createTime
* @return {chrome.passwordsPrivate.CompromisedCredential} * @return {chrome.passwordsPrivate.CompromisedCredential}
* @private * @private
*/ */
/* #export */ function makeCompromisedCredential(url, username, type) { /* #export */ function makeCompromisedCredential(
url, username, type, id, createTime) {
return { return {
id: id,
formattedOrigin: url, formattedOrigin: url,
changePasswordUrl: 'http://${url}/', changePasswordUrl: 'http://${url}/',
username: username, username: username,
elapsedTimeSinceCompromise: elapsedTimeSinceCompromise:
(Math.floor(Math.random() * 60)).toString() + ' min ago', (Math.floor(Math.random() * 60)).toString() + ' min ago',
compromiseTime: createTime,
compromiseType: type, compromiseType: type,
}; };
} }
......
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