root/chrome/browser/ui/passwords/password_manager_presenter.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. password_view_
  2. Initialize
  3. OnLoginsChanged
  4. GetPasswordStore
  5. UpdatePasswordLists
  6. RemoveSavedPassword
  7. RemovePasswordException
  8. RequestShowPassword
  9. GetPassword
  10. GetPasswordException
  11. SetPasswordList
  12. SetPasswordExceptionList
  13. IsAuthenticationRequired
  14. OnGetPasswordStoreResults
  15. PasswordExceptionListPopulater
  16. OnGetPasswordStoreResults

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/passwords/password_manager_presenter.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/prefs/pref_service.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/password_manager/password_manager_util.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/ui/passwords/password_ui_view.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"

PasswordManagerPresenter::PasswordManagerPresenter(
    PasswordUIView* password_view)
    : populater_(this),
      exception_populater_(this),
      password_view_(password_view) {
  DCHECK(password_view_);
  require_reauthentication_ = !CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kDisablePasswordManagerReauthentication);
}

PasswordManagerPresenter::~PasswordManagerPresenter() {
  PasswordStore* store = GetPasswordStore();
  if (store)
    store->RemoveObserver(this);
}

void PasswordManagerPresenter::Initialize() {
  // Due to the way that handlers are (re)initialized under certain types of
  // navigation, the presenter may already be initialized. (See bugs 88986
  // and 86448). If this is the case, return immediately. This is a hack.
  // TODO(mdm): remove this hack once it is no longer necessary.
  if (!show_passwords_.GetPrefName().empty())
    return;

  show_passwords_.Init(
      prefs::kPasswordManagerAllowShowPasswords,
      password_view_->GetProfile()->GetPrefs(),
      base::Bind(&PasswordManagerPresenter::UpdatePasswordLists,
                 base::Unretained(this)));
  // TODO(jhawkins) We should not cache web_ui()->GetProfile().See
  // crosbug.com/6304.
  PasswordStore* store = GetPasswordStore();
  if (store)
    store->AddObserver(this);
}

void PasswordManagerPresenter::OnLoginsChanged(
    const PasswordStoreChangeList& changes) {
  // Entire list is updated for convenience.
  UpdatePasswordLists();
}

PasswordStore* PasswordManagerPresenter::GetPasswordStore() {
  return PasswordStoreFactory::GetForProfile(password_view_->GetProfile(),
                                             Profile::EXPLICIT_ACCESS).get();
}

void PasswordManagerPresenter::UpdatePasswordLists() {
  // Reset so that showing a password will require re-authentication.
  last_authentication_time_ = base::TimeTicks();

  // Reset the current lists.
  password_list_.clear();
  password_exception_list_.clear();

  populater_.Populate();
  exception_populater_.Populate();
}

void PasswordManagerPresenter::RemoveSavedPassword(size_t index) {
  DCHECK_LT(index, password_list_.size());
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  store->RemoveLogin(*password_list_[index]);
  content::RecordAction(
      base::UserMetricsAction("PasswordManager_RemoveSavedPassword"));
}

void PasswordManagerPresenter::RemovePasswordException(size_t index) {
  DCHECK_LT(index, password_exception_list_.size());
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  store->RemoveLogin(*password_exception_list_[index]);
  content::RecordAction(
      base::UserMetricsAction("PasswordManager_RemovePasswordException"));
}

void PasswordManagerPresenter::RequestShowPassword(size_t index) {
#if !defined(OS_ANDROID) // This is never called on Android.
  DCHECK_LT(index, password_list_.size());
  if (IsAuthenticationRequired()) {
    if (password_manager_util::AuthenticateUser(
        password_view_->GetNativeWindow()))
      last_authentication_time_ = base::TimeTicks::Now();
    else
      return;
  }
  // Call back the front end to reveal the password.
  password_view_->ShowPassword(index, password_list_[index]->password_value);
#endif
}

const autofill::PasswordForm& PasswordManagerPresenter::GetPassword(
    size_t index) {
  DCHECK_LT(index, password_list_.size());
  return *password_list_[index];
}

const autofill::PasswordForm& PasswordManagerPresenter::GetPasswordException(
    size_t index) {
  DCHECK_LT(index, password_exception_list_.size());
  return *password_exception_list_[index];
}

void PasswordManagerPresenter::SetPasswordList() {
  // Due to the way that handlers are (re)initialized under certain types of
  // navigation, the presenter may already be initialized. (See bugs 88986
  // and 86448). If this is the case, return immediately. This is a hack.
  // If this is the case, initialize on demand. This is a hack.
  // TODO(mdm): remove this hack once it is no longer necessary.
  if (show_passwords_.GetPrefName().empty())
    Initialize();

  bool show_passwords = *show_passwords_ && !require_reauthentication_;
  password_view_->SetPasswordList(password_list_, show_passwords);
}

void PasswordManagerPresenter::SetPasswordExceptionList() {
  password_view_->SetPasswordExceptionList(password_exception_list_);
}

bool PasswordManagerPresenter::IsAuthenticationRequired() {
  base::TimeDelta delta = base::TimeDelta::FromSeconds(60);
  return require_reauthentication_ &&
      (base::TimeTicks::Now() - last_authentication_time_) > delta;
}

PasswordManagerPresenter::ListPopulater::ListPopulater(
    PasswordManagerPresenter* page) : page_(page) {
}

PasswordManagerPresenter::ListPopulater::~ListPopulater() {
}

PasswordManagerPresenter::PasswordListPopulater::PasswordListPopulater(
    PasswordManagerPresenter* page) : ListPopulater(page) {
}

void PasswordManagerPresenter::PasswordListPopulater::Populate() {
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL) {
    cancelable_task_tracker()->TryCancelAll();
    store->GetAutofillableLogins(this);
  } else {
    LOG(ERROR) << "No password store! Cannot display passwords.";
  }
}

void PasswordManagerPresenter::PasswordListPopulater::OnGetPasswordStoreResults(
    const std::vector<autofill::PasswordForm*>& results) {
  page_->password_list_.clear();
  page_->password_list_.insert(page_->password_list_.end(),
                               results.begin(), results.end());
  page_->SetPasswordList();
}

PasswordManagerPresenter::PasswordExceptionListPopulater::
    PasswordExceptionListPopulater(PasswordManagerPresenter* page)
        : ListPopulater(page) {
}

void PasswordManagerPresenter::PasswordExceptionListPopulater::Populate() {
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL) {
    cancelable_task_tracker()->TryCancelAll();
    store->GetBlacklistLogins(this);
  } else {
    LOG(ERROR) << "No password store! Cannot display exceptions.";
  }
}

void PasswordManagerPresenter::PasswordExceptionListPopulater::
    OnGetPasswordStoreResults(
        const std::vector<autofill::PasswordForm*>& results) {
  page_->password_exception_list_.clear();
  page_->password_exception_list_.insert(page_->password_exception_list_.end(),
                                         results.begin(), results.end());
  page_->SetPasswordExceptionList();
}

/* [<][>][^][v][top][bottom][index][help] */