File: password_credential.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (136 lines) | stat: -rw-r--r-- 5,035 bytes parent folder | download | duplicates (11)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/modules/credentialmanagement/password_credential.h"

#include "third_party/blink/renderer/bindings/core/v8/v8_union_file_usvstring.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_password_credential_data.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/forms/listed_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"

namespace blink {

namespace {
constexpr char kPasswordCredentialType[] = "password";
}

// https://w3c.github.io/webappsec-credential-management/#construct-passwordcredential-data
PasswordCredential* PasswordCredential::Create(
    const PasswordCredentialData* data,
    ExceptionState& exception_state) {
  if (data->id().empty()) {
    exception_state.ThrowTypeError("'id' must not be empty.");
    return nullptr;
  }
  if (data->password().empty()) {
    exception_state.ThrowTypeError("'password' must not be empty.");
    return nullptr;
  }

  KURL icon_url;
  if (data->hasIconURL())
    icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state);
  if (exception_state.HadException())
    return nullptr;

  String name;
  if (data->hasName())
    name = data->name();

  return MakeGarbageCollected<PasswordCredential>(data->id(), data->password(),
                                                  name, icon_url);
}

// https://w3c.github.io/webappsec-credential-management/#construct-passwordcredential-form
PasswordCredential* PasswordCredential::Create(
    HTMLFormElement* form,
    ExceptionState& exception_state) {
  // Extract data from the form, then use the extracted |form_data| object's
  // value to populate |data|.
  FormData* form_data = FormData::Create(form, exception_state);
  if (exception_state.HadException())
    return nullptr;

  PasswordCredentialData* data = PasswordCredentialData::Create();
  bool is_id_set = false;
  bool is_password_set = false;
  for (ListedElement* submittable_element : form->ListedElements()) {
    // The "form data set" contains an entry for a |submittable_element| only if
    // it has a non-empty `name` attribute.
    // https://html.spec.whatwg.org/C/#constructing-the-form-data-set
    if (submittable_element->GetName().empty())
      continue;

    V8FormDataEntryValue* value =
        form_data->get(submittable_element->GetName());
    if (!value || !value->IsUSVString())
      continue;
    const String& usv_string_value = value->GetAsUSVString();

    Vector<String> autofill_tokens;
    submittable_element->ToHTMLElement()
        .FastGetAttribute(html_names::kAutocompleteAttr)
        .GetString()
        .LowerASCII()
        .Split(' ', autofill_tokens);
    for (const auto& token : autofill_tokens) {
      if (token == "current-password" || token == "new-password") {
        data->setPassword(usv_string_value);
        is_password_set = true;
      } else if (token == "photo") {
        data->setIconURL(usv_string_value);
      } else if (token == "name" || token == "nickname") {
        data->setName(usv_string_value);
      } else if (token == "username") {
        data->setId(usv_string_value);
        is_id_set = true;
      }
    }
  }

  // Check required fields of PasswordCredentialData dictionary.
  if (!is_id_set) {
    exception_state.ThrowTypeError(
        "'username' must be specified in the form's autocomplete attribute.");
    return nullptr;
  }
  if (!is_password_set) {
    exception_state.ThrowTypeError(
        "Either 'current-password' or 'new-password' must be specified in the "
        "form's autocomplete attribute.");
    return nullptr;
  }

  // Create a PasswordCredential using the data gathered above.
  return PasswordCredential::Create(data, exception_state);
}

PasswordCredential* PasswordCredential::Create(const String& id,
                                               const String& password,
                                               const String& name,
                                               const KURL& icon_url) {
  return MakeGarbageCollected<PasswordCredential>(
      id, password, name, icon_url.IsEmpty() ? blink::KURL() : icon_url);
}

PasswordCredential::PasswordCredential(const String& id,
                                       const String& password,
                                       const String& name,
                                       const KURL& icon_url)
    : Credential(id, kPasswordCredentialType),
      password_(password),
      name_(name),
      icon_url_(icon_url) {
  DCHECK(!password.empty());
}

bool PasswordCredential::IsPasswordCredential() const {
  return true;
}

}  // namespace blink