Commit 3ddd59f4 authored by gcasto@chromium.org's avatar gcasto@chromium.org

[Password Manager] Don't prompt to save credentials used to sync passwords

TBR=dhollowa@chromium.org
BUG=386402

Review URL: https://codereview.chromium.org/385963003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282814 0039d316-1c4b-4281-b951-d872f2087c98
parent 3ecaffe9
...@@ -145,6 +145,8 @@ std::string GetStringFromID(SavePasswordProgressLogger::StringID id) { ...@@ -145,6 +145,8 @@ std::string GetStringFromID(SavePasswordProgressLogger::StringID id) {
return "Invalid form."; return "Invalid form.";
case SavePasswordProgressLogger::STRING_AUTOCOMPLETE_OFF: case SavePasswordProgressLogger::STRING_AUTOCOMPLETE_OFF:
return "Autocomplete=off."; return "Autocomplete=off.";
case SavePasswordProgressLogger::STRING_SYNC_CREDENTIAL:
return "Credential is used for syncing passwords.";
case SavePasswordProgressLogger::STRING_PROVISIONALLY_SAVED_FORM: case SavePasswordProgressLogger::STRING_PROVISIONALLY_SAVED_FORM:
return "provisionally_saved_form"; return "provisionally_saved_form";
case SavePasswordProgressLogger::STRING_IGNORE_POSSIBLE_USERNAMES: case SavePasswordProgressLogger::STRING_IGNORE_POSSIBLE_USERNAMES:
......
...@@ -91,6 +91,7 @@ class SavePasswordProgressLogger { ...@@ -91,6 +91,7 @@ class SavePasswordProgressLogger {
STRING_FORM_BLACKLISTED, STRING_FORM_BLACKLISTED,
STRING_INVALID_FORM, STRING_INVALID_FORM,
STRING_AUTOCOMPLETE_OFF, STRING_AUTOCOMPLETE_OFF,
STRING_SYNC_CREDENTIAL,
STRING_PROVISIONALLY_SAVED_FORM, STRING_PROVISIONALLY_SAVED_FORM,
STRING_IGNORE_POSSIBLE_USERNAMES, STRING_IGNORE_POSSIBLE_USERNAMES,
STRING_ON_PASSWORD_FORMS_RENDERED_METHOD, STRING_ON_PASSWORD_FORMS_RENDERED_METHOD,
......
...@@ -207,6 +207,14 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) { ...@@ -207,6 +207,14 @@ void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) {
return; return;
} }
// Don't save credentials for the syncing account. See crbug.com/365832 for
// background.
if (client_->IsPasswordSyncAccountCredential(
base::UTF16ToUTF8(form.username_value), form.signon_realm)) {
RecordFailure(SYNC_CREDENTIAL, form.origin.host(), logger.get());
return;
}
// Always save generated passwords, as the user expresses explicit intent for // Always save generated passwords, as the user expresses explicit intent for
// Chrome to manage such passwords. For other passwords, respect the // Chrome to manage such passwords. For other passwords, respect the
// autocomplete attribute if autocomplete='off' is not ignored. // autocomplete attribute if autocomplete='off' is not ignored.
...@@ -276,6 +284,9 @@ void PasswordManager::RecordFailure(ProvisionalSaveFailure failure, ...@@ -276,6 +284,9 @@ void PasswordManager::RecordFailure(ProvisionalSaveFailure failure,
case AUTOCOMPLETE_OFF: case AUTOCOMPLETE_OFF:
logger->LogMessage(Logger::STRING_AUTOCOMPLETE_OFF); logger->LogMessage(Logger::STRING_AUTOCOMPLETE_OFF);
break; break;
case SYNC_CREDENTIAL:
logger->LogMessage(Logger::STRING_SYNC_CREDENTIAL);
break;
case MAX_FAILURE_VALUE: case MAX_FAILURE_VALUE:
NOTREACHED(); NOTREACHED();
return; return;
......
...@@ -113,6 +113,7 @@ class PasswordManager : public LoginModel { ...@@ -113,6 +113,7 @@ class PasswordManager : public LoginModel {
FORM_BLACKLISTED, FORM_BLACKLISTED,
INVALID_FORM, INVALID_FORM,
AUTOCOMPLETE_OFF, AUTOCOMPLETE_OFF,
SYNC_CREDENTIAL,
MAX_FAILURE_VALUE MAX_FAILURE_VALUE
}; };
......
...@@ -43,6 +43,8 @@ namespace { ...@@ -43,6 +43,8 @@ namespace {
class MockPasswordManagerClient : public StubPasswordManagerClient { class MockPasswordManagerClient : public StubPasswordManagerClient {
public: public:
MOCK_CONST_METHOD0(IsPasswordManagerEnabledForCurrentPage, bool()); MOCK_CONST_METHOD0(IsPasswordManagerEnabledForCurrentPage, bool());
MOCK_CONST_METHOD2(IsPasswordSyncAccountCredential,
bool(const std::string&, const std::string&));
MOCK_METHOD1(PromptUserToSavePassword, void(PasswordFormManager*)); MOCK_METHOD1(PromptUserToSavePassword, void(PasswordFormManager*));
MOCK_METHOD0(GetPasswordStore, PasswordStore*()); MOCK_METHOD0(GetPasswordStore, PasswordStore*());
MOCK_METHOD0(GetPrefs, PrefService*()); MOCK_METHOD0(GetPrefs, PrefService*());
...@@ -85,6 +87,8 @@ class PasswordManagerTest : public testing::Test { ...@@ -85,6 +87,8 @@ class PasswordManagerTest : public testing::Test {
EXPECT_CALL(client_, IsPasswordManagerEnabledForCurrentPage()) EXPECT_CALL(client_, IsPasswordManagerEnabledForCurrentPage())
.WillRepeatedly(Return(true)); .WillRepeatedly(Return(true));
EXPECT_CALL(client_, IsPasswordSyncAccountCredential(_, _))
.WillRepeatedly(Return(false));
EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_)); EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_));
EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_)); EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_));
EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_)); EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_));
...@@ -706,4 +710,31 @@ TEST_F(PasswordManagerTest, AutofillingDisabledIfManagerDisabled) { ...@@ -706,4 +710,31 @@ TEST_F(PasswordManagerTest, AutofillingDisabledIfManagerDisabled) {
manager()->OnPasswordFormsParsed(forms); manager()->OnPasswordFormsParsed(forms);
} }
TEST_F(PasswordManagerTest, SyncCredentialsNotSaved) {
EXPECT_CALL(client_, IsPasswordSyncAccountCredential(_, _))
.WillRepeatedly(Return(true));
// Simulate loading a simple form with no existing stored password.
std::vector<PasswordForm*> result; // Empty password store.
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
form.password_autocomplete_set = false;
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed); // The initial load.
manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
// User should not be prompted and password should not be saved.
EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0));
// Submit form and finish navigation.
manager()->ProvisionallySavePassword(form);
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed, true);
}
} // namespace password_manager } // namespace password_manager
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