[no-behavior-changed] Add extension API to allow password migration
No behavior is changed. This CL introduces a new extension API to allow Password Settings to move a user password from the device to their account. The API is not called yet and is left with NOTIMPLEMENTED(); Future CLs will: a) add the relevant logic to PasswordManagerPresenter, the same way it is done for most passwords JS APIs; b) call the API from the new "Passwords on this device" page (crrev.com/c/2228159). As a note, the method in the PasswordsPrivateDelegate takes the sender web contents because it will be needed to retrieve the password manager client. Bug: 1090372 Change-Id: I76859af0ab22fa074a802d785ad7c9a0fc3fa912 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2232371 Reviewed-by: Karan Bhatia <karandeepb@chromium.org> Reviewed-by: dpapad <dpapad@chromium.org> Commit-Queue: Victor Vianna <victorvianna@google.com> Cr-Commit-Position: refs/heads/master@{#777316}
This commit is contained in:

committed by
Commit Bot

parent
79a6108a6a
commit
aa498efcd6
chrome
browser
extensions
common
extensions
test
data
extensions
api_test
passwords_private
extensions/browser
third_party/closure_compiler/externs
tools/metrics/histograms
@@ -194,6 +194,16 @@ void PasswordsPrivateGetPasswordExceptionListFunction::GotList(
|
||||
entries)));
|
||||
}
|
||||
|
||||
// PasswordsPrivateMovePasswordToAccountFunction
|
||||
ResponseAction PasswordsPrivateMovePasswordToAccountFunction::Run() {
|
||||
auto parameters =
|
||||
api::passwords_private::MovePasswordToAccount::Params::Create(*args_);
|
||||
EXTENSION_FUNCTION_VALIDATE(parameters);
|
||||
GetDelegate(browser_context())
|
||||
->MovePasswordToAccount(parameters->id, GetSenderWebContents());
|
||||
return RespondNow(NoArguments());
|
||||
}
|
||||
|
||||
// PasswordsPrivateImportPasswordsFunction
|
||||
ResponseAction PasswordsPrivateImportPasswordsFunction::Run() {
|
||||
GetDelegate(browser_context())->ImportPasswords(GetSenderWebContents());
|
||||
|
@@ -156,6 +156,18 @@ class PasswordsPrivateGetPasswordExceptionListFunction
|
||||
void GotList(const PasswordsPrivateDelegate::ExceptionEntries& entries);
|
||||
};
|
||||
|
||||
class PasswordsPrivateMovePasswordToAccountFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("passwordsPrivate.movePasswordToAccount",
|
||||
PASSWORDSPRIVATE_MOVEPASSWORDTOACCOUNT)
|
||||
|
||||
protected:
|
||||
~PasswordsPrivateMovePasswordToAccountFunction() override = default;
|
||||
|
||||
// ExtensionFunction overrides.
|
||||
ResponseAction Run() override;
|
||||
};
|
||||
|
||||
class PasswordsPrivateImportPasswordsFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("passwordsPrivate.importPasswords",
|
||||
|
@@ -108,6 +108,10 @@ class PasswordsPrivateApiTest : public ExtensionApiTest {
|
||||
s_test_delegate_->AddCompromisedCredential(id);
|
||||
}
|
||||
|
||||
base::Optional<int> last_moved_password() const {
|
||||
return s_test_delegate_->last_moved_password();
|
||||
}
|
||||
|
||||
private:
|
||||
TestPasswordsPrivateDelegate* s_test_delegate_ = nullptr;
|
||||
|
||||
@@ -271,4 +275,10 @@ IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest, GetPasswordCheckStatus) {
|
||||
EXPECT_TRUE(RunPasswordsSubtest("getPasswordCheckStatus")) << message_;
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest, MovePasswordToAccount) {
|
||||
EXPECT_FALSE(last_moved_password().has_value());
|
||||
EXPECT_TRUE(RunPasswordsSubtest("movePasswordToAccount")) << message_;
|
||||
EXPECT_EQ(42, last_moved_password());
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
|
@@ -90,6 +90,15 @@ class PasswordsPrivateDelegate : public KeyedService {
|
||||
PlaintextPasswordCallback callback,
|
||||
content::WebContents* web_contents) = 0;
|
||||
|
||||
// Moves a password currently stored on the device to being stored in the
|
||||
// signed-in, non-syncing Google Account. The result is a no-op if any of
|
||||
// these is true: |id| is invalid; |id| corresponds to a password already
|
||||
// stored in the account; the user is not in Passwords Account Storage mode
|
||||
// (kEnablePasswordsAccountStorage enabled, signed-in, not syncing and
|
||||
// opted-in to the feature).
|
||||
virtual void MovePasswordToAccount(int id,
|
||||
content::WebContents* web_contents) = 0;
|
||||
|
||||
// Trigger the password import procedure, allowing the user to select a file
|
||||
// containing passwords to import.
|
||||
virtual void ImportPasswords(content::WebContents* web_contents) = 0;
|
||||
|
@@ -403,6 +403,12 @@ void PasswordsPrivateDelegateImpl::SetPasswordExceptionList(
|
||||
get_password_exception_list_callbacks_.clear();
|
||||
}
|
||||
|
||||
void PasswordsPrivateDelegateImpl::MovePasswordToAccount(
|
||||
int id,
|
||||
content::WebContents* web_contents) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void PasswordsPrivateDelegateImpl::ImportPasswords(
|
||||
content::WebContents* web_contents) {
|
||||
password_manager_porter_->set_web_contents(web_contents);
|
||||
|
@@ -60,6 +60,8 @@ class PasswordsPrivateDelegateImpl : public PasswordsPrivateDelegate,
|
||||
api::passwords_private::PlaintextReason reason,
|
||||
PlaintextPasswordCallback callback,
|
||||
content::WebContents* web_contents) override;
|
||||
void MovePasswordToAccount(int id,
|
||||
content::WebContents* web_contents) override;
|
||||
void ImportPasswords(content::WebContents* web_contents) override;
|
||||
void ExportPasswords(base::OnceCallback<void(const std::string&)> accepted,
|
||||
content::WebContents* web_contents) override;
|
||||
|
@@ -136,6 +136,12 @@ void TestPasswordsPrivateDelegate::RequestPlaintextPassword(
|
||||
std::move(callback).Run(plaintext_password_);
|
||||
}
|
||||
|
||||
void TestPasswordsPrivateDelegate::MovePasswordToAccount(
|
||||
int id,
|
||||
content::WebContents* web_contents) {
|
||||
last_moved_password_ = id;
|
||||
}
|
||||
|
||||
void TestPasswordsPrivateDelegate::ImportPasswords(
|
||||
content::WebContents* web_contents) {
|
||||
// The testing of password importing itself should be handled via
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#ifndef CHROME_BROWSER_EXTENSIONS_API_PASSWORDS_PRIVATE_TEST_PASSWORDS_PRIVATE_DELEGATE_H_
|
||||
#define CHROME_BROWSER_EXTENSIONS_API_PASSWORDS_PRIVATE_TEST_PASSWORDS_PRIVATE_DELEGATE_H_
|
||||
|
||||
#include "base/optional.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
@@ -33,6 +34,8 @@ class TestPasswordsPrivateDelegate : public PasswordsPrivateDelegate {
|
||||
api::passwords_private::PlaintextReason reason,
|
||||
PlaintextPasswordCallback callback,
|
||||
content::WebContents* web_contents) override;
|
||||
void MovePasswordToAccount(int id,
|
||||
content::WebContents* web_contents) override;
|
||||
void ImportPasswords(content::WebContents* web_contents) override;
|
||||
void ExportPasswords(base::OnceCallback<void(const std::string&)> callback,
|
||||
content::WebContents* web_contents) override;
|
||||
@@ -84,6 +87,10 @@ class TestPasswordsPrivateDelegate : public PasswordsPrivateDelegate {
|
||||
start_password_check_state_ = state;
|
||||
}
|
||||
|
||||
base::Optional<int> last_moved_password() const {
|
||||
return last_moved_password_;
|
||||
}
|
||||
|
||||
private:
|
||||
void SendSavedPasswordsList();
|
||||
void SendPasswordExceptionsList();
|
||||
@@ -122,6 +129,9 @@ class TestPasswordsPrivateDelegate : public PasswordsPrivateDelegate {
|
||||
bool stop_password_check_triggered_ = false;
|
||||
password_manager::BulkLeakCheckService::State start_password_check_state_ =
|
||||
password_manager::BulkLeakCheckService::State::kRunning;
|
||||
|
||||
// Records the id of the last password that was moved.
|
||||
base::Optional<int> last_moved_password_ = base::nullopt;
|
||||
};
|
||||
} // namespace extensions
|
||||
|
||||
|
@@ -252,6 +252,15 @@ namespace passwordsPrivate {
|
||||
// |callback|: Called with the list of password exceptions.
|
||||
static void getPasswordExceptionList(ExceptionListCallback callback);
|
||||
|
||||
// Moves a password currently stored on the device to being stored in the
|
||||
// signed-in, non-syncing Google Account. The result is a no-op if any of
|
||||
// these is true: |id| is invalid; |id| corresponds to a password already
|
||||
// stored in the account; the user is not in Passwords Account Storage mode
|
||||
// (kEnablePasswordsAccountStorage enabled, signed-in, not syncing and
|
||||
// opted-in to the feature).
|
||||
// |id|: The id for the password entry being moved.
|
||||
static void movePasswordToAccount(long id);
|
||||
|
||||
// Triggers the Password Manager password import functionality.
|
||||
static void importPasswords();
|
||||
|
||||
|
@@ -463,6 +463,11 @@ var availableTests = [
|
||||
chrome.test.succeed();
|
||||
});
|
||||
},
|
||||
|
||||
function movePasswordToAccount() {
|
||||
chrome.passwordsPrivate.movePasswordToAccount(42);
|
||||
chrome.test.succeed();
|
||||
}
|
||||
];
|
||||
|
||||
var testToRun = window.location.search.substring(1);
|
||||
|
@@ -1540,6 +1540,7 @@ enum HistogramValue {
|
||||
PASSWORDSPRIVATE_REMOVEPASSWORDEXCEPTIONS = 1477,
|
||||
AUTOTESTPRIVATE_WAITFORAMBIENTPHOTOANIMATION = 1478,
|
||||
INPUT_IME_SETASSISTIVEWINDOWPROPERTIES = 1479,
|
||||
PASSWORDSPRIVATE_MOVEPASSWORDTOACCOUNT = 1480,
|
||||
// Last entry: Add new entries above, then run:
|
||||
// python tools/metrics/histograms/update_extension_histograms.py
|
||||
ENUM_BOUNDARY
|
||||
|
@@ -199,6 +199,17 @@ chrome.passwordsPrivate.getSavedPasswordList = function(callback) {};
|
||||
*/
|
||||
chrome.passwordsPrivate.getPasswordExceptionList = function(callback) {};
|
||||
|
||||
/**
|
||||
* Moves a password currently stored on the device to being stored in the
|
||||
* signed-in, non-syncing Google Account. The result is a no-op if any of
|
||||
* these is true: |id| is invalid; |id| corresponds to a password already
|
||||
* stored in the account; the user is not in Passwords Account Storage mode
|
||||
* (kEnablePasswordsAccountStorage enabled, signed-in, not syncing and
|
||||
* opted-in to the feature).
|
||||
* @param {number} id The id for the password entry being moved.
|
||||
*/
|
||||
chrome.passwordsPrivate.movePasswordToAccount = function(id) {};
|
||||
|
||||
/**
|
||||
* Triggers the Password Manager password import functionality.
|
||||
*/
|
||||
|
@@ -23230,6 +23230,7 @@ Called by update_extension_histograms.py.-->
|
||||
<int value="1477" label="PASSWORDSPRIVATE_REMOVEPASSWORDEXCEPTIONS"/>
|
||||
<int value="1478" label="AUTOTESTPRIVATE_WAITFORAMBIENTPHOTOANIMATION"/>
|
||||
<int value="1479" label="INPUT_IME_SETASSISTIVEWINDOWPROPERTIES"/>
|
||||
<int value="1480" label="PASSWORDSPRIVATE_MOVEPASSWORDTOACCOUNT"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ExtensionIconState">
|
||||
|
Reference in New Issue
Block a user