summaryrefslogtreecommitdiff
path: root/chromium/components/autofill/core/common/password_form_fill_data.cc
blob: db08ce036bbade84d1137fc79253379221f43212 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 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 "components/autofill/core/common/password_form_fill_data.h"

#include <tuple>

#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "components/autofill/core/common/form_field_data.h"

namespace autofill {

namespace {

bool IsPublicSuffixMatchOrAffiliationBasedMatch(const PasswordForm& form) {
  return form.is_public_suffix_match || form.is_affiliation_based_match;
}

}  // namespace

PasswordFormFillData::PasswordFormFillData() = default;

PasswordFormFillData::PasswordFormFillData(
    const PasswordForm& form_on_page,
    const std::map<base::string16, const PasswordForm*>& matches,
    const PasswordForm& preferred_match,
    bool wait_for_username)
    : form_renderer_id(form_on_page.form_data.unique_renderer_id),
      name(form_on_page.form_data.name),
      origin(form_on_page.origin),
      action(form_on_page.action),
      wait_for_username(wait_for_username),
      has_renderer_ids(form_on_page.has_renderer_ids) {
  // Note that many of the |FormFieldData| members are not initialized for
  // |username_field| and |password_field| because they are currently not used
  // by the password autocomplete code.
  username_field.value = preferred_match.username_value;
  password_field.value = preferred_match.password_value;
  if (!form_on_page.only_for_fallback &&
      (form_on_page.HasPasswordElement() || form_on_page.IsSingleUsername())) {
    // Fill fields identifying information only for non-fallback case when
    // password element is found. In other cases a fill popup is shown on
    // clicking on each password field so no need in any field identifiers.
    username_field.name = form_on_page.username_element;
    username_field.unique_renderer_id =
        form_on_page.username_element_renderer_id;
    username_may_use_prefilled_placeholder =
        form_on_page.username_may_use_prefilled_placeholder;

    password_field.name = form_on_page.password_element;
    password_field.unique_renderer_id =
        form_on_page.password_element_renderer_id;
    password_field.form_control_type = "password";

    // On iOS, use the unique_id field to refer to elements.
#if defined(OS_IOS)
    username_field.unique_id = form_on_page.username_element;
    password_field.unique_id = form_on_page.password_element;
#endif
  }

  if (IsPublicSuffixMatchOrAffiliationBasedMatch(preferred_match))
    preferred_realm = preferred_match.signon_realm;

  // Copy additional username/value pairs.
  for (const auto& it : matches) {
    if (it.second != &preferred_match) {
      PasswordAndRealm& value = additional_logins[it.first];
      value.password = it.second->password_value;
      if (IsPublicSuffixMatchOrAffiliationBasedMatch(*it.second))
        value.realm = it.second->signon_realm;
    }
  }
}

PasswordFormFillData::PasswordFormFillData(const PasswordFormFillData& other) =
    default;

PasswordFormFillData::~PasswordFormFillData() = default;

PasswordFormFillData MaybeClearPasswordValues(
    const PasswordFormFillData& data) {
  // In case when there is a username on a page (for example in a hidden field),
  // credentials from |additional_logins| could be used for filling on load. So
  // in case of filling on load nor |password_field| nor |additional_logins|
  // can't be cleared
  bool is_fallback =
      data.has_renderer_ids && data.password_field.unique_renderer_id ==
                                   FormFieldData::kNotSetFormControlRendererId;
  if (!data.wait_for_username && !is_fallback)
    return data;
  PasswordFormFillData result(data);
  result.password_field.value.clear();
  for (auto& credentials : result.additional_logins)
    credentials.second.password.clear();
  return result;
}

}  // namespace autofill