Commit 05f2ff8a authored by mkwst's avatar mkwst Committed by Commit bot

Credential Manager: Wire `notifySignedOut` to the PasswordStore.

When `notifySignedOut` is called, we need to ensure that we stop
automagically providing a user's credentials to the website that
triggered the notification. This CL does that in the brute-force
way that we all know and love: grab all forms, walk through each
and set a flag for matching origins.

BUG=450581

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

Cr-Commit-Position: refs/heads/master@{#315016}
parent c3d07759
...@@ -487,6 +487,9 @@ void BrowsingDataRemover::RemoveImpl(int remove_mask, ...@@ -487,6 +487,9 @@ void BrowsingDataRemover::RemoveImpl(int remove_mask,
} }
#endif #endif
MediaDeviceIDSalt::Reset(profile_->GetPrefs()); MediaDeviceIDSalt::Reset(profile_->GetPrefs());
// TODO(mkwst): If we're not removing passwords, then clear the 'zero-click'
// flag for all credentials in the password store.
} }
// Channel IDs are not separated for protected and unprotected web // Channel IDs are not separated for protected and unprotected web
......
...@@ -261,13 +261,32 @@ TEST_F(CredentialManagerDispatcherTest, CredentialManagerIncognitoSignedIn) { ...@@ -261,13 +261,32 @@ TEST_F(CredentialManagerDispatcherTest, CredentialManagerIncognitoSignedIn) {
} }
TEST_F(CredentialManagerDispatcherTest, CredentialManagerOnNotifySignedOut) { TEST_F(CredentialManagerDispatcherTest, CredentialManagerOnNotifySignedOut) {
store_->AddLogin(form_);
store_->AddLogin(cross_origin_form_);
RunAllPendingTasks();
TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
EXPECT_EQ(2U, passwords.size());
EXPECT_EQ(1U, passwords[form_.signon_realm].size());
EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
dispatcher()->OnNotifySignedOut(kRequestId); dispatcher()->OnNotifySignedOut(kRequestId);
RunAllPendingTasks();
const uint32 kMsgID = CredentialManagerMsg_AcknowledgeSignedOut::ID; const uint32 kMsgID = CredentialManagerMsg_AcknowledgeSignedOut::ID;
const IPC::Message* message = const IPC::Message* message =
process()->sink().GetFirstMessageMatching(kMsgID); process()->sink().GetFirstMessageMatching(kMsgID);
EXPECT_TRUE(message); EXPECT_TRUE(message);
process()->sink().ClearMessages(); process()->sink().ClearMessages();
passwords = store_->stored_passwords();
EXPECT_EQ(2U, passwords.size());
EXPECT_EQ(1U, passwords[form_.signon_realm].size());
EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
} }
TEST_F(CredentialManagerDispatcherTest, TEST_F(CredentialManagerDispatcherTest,
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
namespace password_manager { namespace password_manager {
// CredentialManagerDispatcher::PendingRequestTask -----------------------------
class CredentialManagerDispatcher::PendingRequestTask class CredentialManagerDispatcher::PendingRequestTask
: public PasswordStoreConsumer { : public PasswordStoreConsumer {
public: public:
...@@ -102,6 +104,60 @@ class CredentialManagerDispatcher::PendingRequestTask ...@@ -102,6 +104,60 @@ class CredentialManagerDispatcher::PendingRequestTask
DISALLOW_COPY_AND_ASSIGN(PendingRequestTask); DISALLOW_COPY_AND_ASSIGN(PendingRequestTask);
}; };
// CredentialManagerDispatcher::PendingSignedOutTask ---------------------------
class CredentialManagerDispatcher::PendingSignedOutTask
: public PasswordStoreConsumer {
public:
PendingSignedOutTask(CredentialManagerDispatcher* const dispatcher,
const GURL& origin);
void AddOrigin(const GURL& origin);
// PasswordStoreConsumer implementation.
void OnGetPasswordStoreResults(
const std::vector<autofill::PasswordForm*>& results) override;
private:
// Backlink to the CredentialManagerDispatcher that owns this object.
CredentialManagerDispatcher* const dispatcher_;
std::set<std::string> origins_;
DISALLOW_COPY_AND_ASSIGN(PendingSignedOutTask);
};
CredentialManagerDispatcher::PendingSignedOutTask::PendingSignedOutTask(
CredentialManagerDispatcher* const dispatcher,
const GURL& origin)
: dispatcher_(dispatcher) {
origins_.insert(origin.spec());
}
void CredentialManagerDispatcher::PendingSignedOutTask::AddOrigin(
const GURL& origin) {
origins_.insert(origin.spec());
}
void CredentialManagerDispatcher::PendingSignedOutTask::
OnGetPasswordStoreResults(
const std::vector<autofill::PasswordForm*>& results) {
PasswordStore* store = dispatcher_->GetPasswordStore();
for (autofill::PasswordForm* form : results) {
if (origins_.count(form->origin.spec())) {
form->skip_zero_click = true;
store->UpdateLogin(*form);
}
// We own the PasswordForms, so we need to dispose of them. This is safe to
// do, as ::UpdateLogin ends up copying the form while posting a task to
// update the PasswordStore.
delete form;
}
dispatcher_->DoneSigningOut();
}
// CredentialManagerDispatcher -------------------------------------------------
CredentialManagerDispatcher::CredentialManagerDispatcher( CredentialManagerDispatcher::CredentialManagerDispatcher(
content::WebContents* web_contents, content::WebContents* web_contents,
PasswordManagerClient* client) PasswordManagerClient* client)
...@@ -153,6 +209,7 @@ void CredentialManagerDispatcher::OnNotifySignedIn( ...@@ -153,6 +209,7 @@ void CredentialManagerDispatcher::OnNotifySignedIn(
scoped_ptr<autofill::PasswordForm> form(CreatePasswordFormFromCredentialInfo( scoped_ptr<autofill::PasswordForm> form(CreatePasswordFormFromCredentialInfo(
credential, web_contents()->GetLastCommittedURL().GetOrigin())); credential, web_contents()->GetLastCommittedURL().GetOrigin()));
form->skip_zero_click = !IsZeroClickAllowed();
// TODO(mkwst): This is a stub; we should be checking the PasswordStore to // TODO(mkwst): This is a stub; we should be checking the PasswordStore to
// determine whether or not the credential exists, and calling UpdateLogin // determine whether or not the credential exists, and calling UpdateLogin
...@@ -168,7 +225,22 @@ void CredentialManagerDispatcher::OnProvisionalSaveComplete() { ...@@ -168,7 +225,22 @@ void CredentialManagerDispatcher::OnProvisionalSaveComplete() {
void CredentialManagerDispatcher::OnNotifySignedOut(int request_id) { void CredentialManagerDispatcher::OnNotifySignedOut(int request_id) {
DCHECK(request_id); DCHECK(request_id);
// TODO(mkwst): This is a stub.
PasswordStore* store = GetPasswordStore();
if (store) {
if (!pending_sign_out_) {
pending_sign_out_.reset(new PendingSignedOutTask(
this, web_contents()->GetLastCommittedURL().GetOrigin()));
// This will result in a callback to
// PendingSignedOutTask::OnGetPasswordStoreResults().
store->GetAutofillableLogins(pending_sign_out_.get());
} else {
pending_sign_out_->AddOrigin(
web_contents()->GetLastCommittedURL().GetOrigin());
}
}
web_contents()->GetRenderViewHost()->Send( web_contents()->GetRenderViewHost()->Send(
new CredentialManagerMsg_AcknowledgeSignedOut( new CredentialManagerMsg_AcknowledgeSignedOut(
web_contents()->GetRenderViewHost()->GetRoutingID(), request_id)); web_contents()->GetRenderViewHost()->GetRoutingID(), request_id));
...@@ -234,6 +306,9 @@ void CredentialManagerDispatcher::SendCredential(int request_id, ...@@ -234,6 +306,9 @@ void CredentialManagerDispatcher::SendCredential(int request_id,
const CredentialInfo& info) { const CredentialInfo& info) {
DCHECK(pending_request_); DCHECK(pending_request_);
DCHECK_EQ(pending_request_->id(), request_id); DCHECK_EQ(pending_request_->id(), request_id);
// TODO(mkwst): We need to update the underlying PasswordForm if the user
// has enabled zeroclick globally, and clicks through a non-zeroclick form
// for an origin.
web_contents()->GetRenderViewHost()->Send( web_contents()->GetRenderViewHost()->Send(
new CredentialManagerMsg_SendCredential( new CredentialManagerMsg_SendCredential(
web_contents()->GetRenderViewHost()->GetRoutingID(), web_contents()->GetRenderViewHost()->GetRoutingID(),
...@@ -241,4 +316,9 @@ void CredentialManagerDispatcher::SendCredential(int request_id, ...@@ -241,4 +316,9 @@ void CredentialManagerDispatcher::SendCredential(int request_id,
pending_request_.reset(); pending_request_.reset();
} }
void CredentialManagerDispatcher::DoneSigningOut() {
DCHECK(pending_sign_out_);
pending_sign_out_.reset();
}
} // namespace password_manager } // namespace password_manager
...@@ -72,6 +72,7 @@ class CredentialManagerDispatcher : public content::WebContentsObserver { ...@@ -72,6 +72,7 @@ class CredentialManagerDispatcher : public content::WebContentsObserver {
private: private:
class PendingRequestTask; class PendingRequestTask;
class PendingSignedOutTask;
PasswordStore* GetPasswordStore(); PasswordStore* GetPasswordStore();
...@@ -83,6 +84,7 @@ class CredentialManagerDispatcher : public content::WebContentsObserver { ...@@ -83,6 +84,7 @@ class CredentialManagerDispatcher : public content::WebContentsObserver {
virtual base::WeakPtr<PasswordManagerDriver> GetDriver(); virtual base::WeakPtr<PasswordManagerDriver> GetDriver();
void SendCredential(int request_id, const CredentialInfo& info); void SendCredential(int request_id, const CredentialInfo& info);
void DoneSigningOut();
PasswordManagerClient* client_; PasswordManagerClient* client_;
scoped_ptr<CredentialManagerPasswordFormManager> form_manager_; scoped_ptr<CredentialManagerPasswordFormManager> form_manager_;
...@@ -95,6 +97,7 @@ class CredentialManagerDispatcher : public content::WebContentsObserver { ...@@ -95,6 +97,7 @@ class CredentialManagerDispatcher : public content::WebContentsObserver {
// they can properly respond to the request once the PasswordStore gives // they can properly respond to the request once the PasswordStore gives
// us data. // us data.
scoped_ptr<PendingRequestTask> pending_request_; scoped_ptr<PendingRequestTask> pending_request_;
scoped_ptr<PendingSignedOutTask> pending_sign_out_;
DISALLOW_COPY_AND_ASSIGN(CredentialManagerDispatcher); DISALLOW_COPY_AND_ASSIGN(CredentialManagerDispatcher);
}; };
......
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