Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1288)

Side by Side Diff: third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp

Issue 2702653002: Patch #1 of multiple. Add webauth .mojom and initial usage of makeCredential. (Closed)
Patch Set: Restructured to only include mojom and usage for makeCredential call Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/webauth/WebAuthentication.h" 5 #include "modules/webauth/WebAuthentication.h"
6 6
7 #include "bindings/core/v8/ScriptPromise.h" 7 #include "bindings/core/v8/ScriptPromise.h"
8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "core/dom/DOMException.h"
10 #include "core/dom/Document.h"
11 #include "core/dom/ExceptionCode.h"
12 #include "core/frame/LocalFrame.h"
13 #include "core/frame/UseCounter.h"
14 #include "modules/webauth/RelyingPartyAccount.h"
15 #include "modules/webauth/ScopedCredential.h"
16 #include "modules/webauth/ScopedCredentialOptions.h"
17 #include "modules/webauth/ScopedCredentialParameters.h"
18 #include "public/platform/InterfaceProvider.h"
19
20 namespace {
21 const char kNoAuthenticatorError[] = "Authenticator unavailable.";
22 } // anonymous namespace
23
24 namespace mojo {
25
26 using webauth::mojom::blink::RelyingPartyAccount;
27 using webauth::mojom::blink::RelyingPartyAccountPtr;
28 using webauth::mojom::blink::ScopedCredentialOptions;
29 using webauth::mojom::blink::ScopedCredentialOptionsPtr;
30 using webauth::mojom::blink::ScopedCredentialParameters;
31 using webauth::mojom::blink::ScopedCredentialParametersPtr;
32 using webauth::mojom::blink::ScopedCredentialDescriptor;
33 using webauth::mojom::blink::ScopedCredentialType;
34 using webauth::mojom::blink::Transport;
35
36 Vector<uint8_t> convertBufferSource(const blink::BufferSource& buffer) {
37 DCHECK(buffer.isNull());
38 Vector<uint8_t> vector;
39 if (buffer.isArrayBuffer()) {
40 vector.append(static_cast<uint8_t*>(buffer.getAsArrayBuffer()->data()),
41 buffer.getAsArrayBuffer()->byteLength());
42 } else {
43 vector.append(
44 static_cast<uint8_t*>(buffer.getAsArrayBufferView()->baseAddress()),
45 buffer.getAsArrayBufferView()->byteLength());
46 }
47 return vector;
48 }
49
50 ScopedCredentialType convertScopedCredentialType(const WTF::String& credType) {
ikilpatrick 2017/02/28 19:18:18 is there a standard naming for these methods in th
kpaulhamus 2017/03/01 01:56:35 It doesn't really seem like it. Bluetooth doesn't
51 if (credType == "ScopedCred")
dcheng 2017/02/28 07:25:56 Unfortunately, mapping strings to enums is the bes
kpaulhamus 2017/03/01 01:56:35 Acknowledged.
52 return ScopedCredentialType::SCOPEDCRED;
53 NOTREACHED();
54 return ScopedCredentialType::SCOPEDCRED;
55 }
56
57 Transport convertTransport(const WTF::String& transport) {
58 if (transport == "usb")
59 return Transport::USB;
60 if (transport == "nfc")
61 return Transport::NFC;
62 if (transport == "ble")
63 return Transport::BLE;
64 NOTREACHED();
65 return Transport::USB;
66 }
67
68 RelyingPartyAccountPtr convertRelyingPartyAccount(
69 const blink::RelyingPartyAccount& accountInformation,
dcheng 2017/02/28 07:25:56 However, this can be implemented by using somethin
kpaulhamus 2017/03/01 01:56:34 Got it, I'll take a closer look.
70 blink::ScriptPromiseResolver* resolver) {
71 auto mojoAccount = RelyingPartyAccount::New();
72
73 mojoAccount->rpDisplayName = accountInformation.rpDisplayName();
74 mojoAccount->displayName = accountInformation.displayName();
75 mojoAccount->id = accountInformation.id();
76 mojoAccount->name = accountInformation.name();
77 mojoAccount->imageURL = accountInformation.imageURL();
78 return mojoAccount;
79 }
80
81 ScopedCredentialOptionsPtr convertScopedCredentialOptions(
82 const blink::ScopedCredentialOptions options,
83 blink::ScriptPromiseResolver* resolver) {
84 auto mojoOptions = ScopedCredentialOptions::New();
85 mojoOptions->timeoutSeconds = options.timeoutSeconds();
86 mojoOptions->rpId = options.rpId();
87
88 // Adds the excludeList members (which are ScopedCredentialDescriptors)
89 for (const auto& descriptor : options.excludeList()) {
90 auto mojoDescriptor = ScopedCredentialDescriptor::New();
91 mojoDescriptor->type = convertScopedCredentialType(descriptor.type());
92 mojoDescriptor->id = convertBufferSource(descriptor.id());
93 for (const auto& transport : descriptor.transports())
94 mojoDescriptor->transports.push_back(convertTransport(transport));
95 mojoOptions->excludeList.push_back(std::move(mojoDescriptor));
96 }
97 // TODO (kpaulhamus) add AuthenticationExtensions;
98 return mojoOptions;
99 }
100
101 ScopedCredentialParametersPtr convertScopedCredentialParameter(
102 const blink::ScopedCredentialParameters parameter,
103 blink::ScriptPromiseResolver* resolver) {
104 auto mojoParameter = ScopedCredentialParameters::New();
105 mojoParameter->type = convertScopedCredentialType(parameter.type());
106 // TODO (kpaulhamus) add AlgorithmIdentifier
107 return mojoParameter;
108 }
109 } // namespace mojo
8 110
9 namespace blink { 111 namespace blink {
10 112
11 WebAuthentication::WebAuthentication(LocalFrame& frame) {} 113 WebAuthentication::WebAuthentication(LocalFrame& frame)
114 : ContextLifecycleObserver(frame.document()) {
115 frame.interfaceProvider()->getInterface(mojo::MakeRequest(&m_authenticator));
116 m_authenticator.set_connection_error_handler(convertToBaseCallback(
117 WTF::bind(&WebAuthentication::onAuthenticatorConnectionError,
dcheng 2017/02/28 07:25:56 Usually, the renderer won't ever see a connection
kpaulhamus 2017/03/01 01:56:34 I don't know enough about the pipe life cycle to m
118 wrapWeakPersistent(this))));
119 }
12 120
13 WebAuthentication::~WebAuthentication() {} 121 WebAuthentication::~WebAuthentication() {
122 // |m_authenticator| may still be valid but there should be no more
123 // outstanding requests because each holds a persistent handle to this object.
124 DCHECK(m_authenticatorRequests.isEmpty());
125 }
14 126
15 void WebAuthentication::dispose() {} 127 void WebAuthentication::dispose() {}
16 128
17 ScriptPromise WebAuthentication::makeCredential( 129 ScriptPromise WebAuthentication::makeCredential(
18 ScriptState* scriptState, 130 ScriptState* scriptState,
19 const RelyingPartyAccount& accountInformation, 131 const RelyingPartyAccount& accountInformation,
20 const HeapVector<ScopedCredentialParameters> cryptoParameters, 132 const HeapVector<ScopedCredentialParameters> cryptoParameters,
21 const BufferSource& attestationChallenge, 133 const BufferSource& attestationChallenge,
22 ScopedCredentialOptions& options) { 134 ScopedCredentialOptions& options) {
23 NOTREACHED(); 135 ExecutionContext* executionContext = scriptState->getExecutionContext();
24 return ScriptPromise(); 136 UseCounter::count(executionContext, UseCounter::AuthenticationMakeCredential);
137
138 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
139 ScriptPromise promise = resolver->promise();
140 if (!m_authenticator) {
ikilpatrick 2017/02/28 19:18:18 can you un-nest these if stmts?, e.g. if (!m_auth
kpaulhamus 2017/03/01 01:56:34 Done.
141 resolver->reject(DOMException::create(NotSupportedError));
142 } else {
143 String errorMessage;
144 if (!executionContext->isSecureContext(errorMessage)) {
dcheng 2017/02/28 07:25:56 Do you know if there any plan to implement the [Se
kpaulhamus 2017/03/01 01:56:34 It's a work in progress: https://bugs.chromium.org
145 resolver->reject(DOMException::create(SecurityError, errorMessage));
146 } else {
147 // TODO(kpaulhamus) validate parameters according to spec
148 auto account =
149 mojo::convertRelyingPartyAccount(accountInformation, resolver);
150 Vector<uint8_t> buffer = mojo::convertBufferSource(attestationChallenge);
151 auto opts = mojo::convertScopedCredentialOptions(options, resolver);
152 Vector<webauth::mojom::blink::ScopedCredentialParametersPtr> parameters;
153 for (const auto& parameter : cryptoParameters) {
154 parameters.push_back(
155 mojo::convertScopedCredentialParameter(parameter, resolver));
156 }
157
158 m_authenticatorRequests.insert(resolver);
159 m_authenticator->makeCredential(
160 std::move(account), std::move(parameters), buffer, std::move(opts),
161 convertToBaseCallback(WTF::bind(&WebAuthentication::onMakeCredential,
162 wrapPersistent(this),
dcheng 2017/02/28 07:25:56 Should this be a weak persistent? If this object w
kpaulhamus 2017/03/01 01:56:34 I talked with reillyg about this, just because I w
163 wrapPersistent(resolver))));
164 }
165 }
166 return promise;
25 } 167 }
26 168
27 ScriptPromise WebAuthentication::getAssertion( 169 ScriptPromise WebAuthentication::getAssertion(
28 ScriptState* scriptState, 170 ScriptState* scriptState,
29 const BufferSource& assertionChallenge, 171 const BufferSource& assertionChallenge,
30 const AuthenticationAssertionOptions& options) { 172 const AuthenticationAssertionOptions& options) {
31 NOTREACHED(); 173 NOTREACHED();
32 return ScriptPromise(); 174 return ScriptPromise();
33 } 175 }
34 176
177 void WebAuthentication::contextDestroyed(ExecutionContext*) {
178 m_authenticator.reset();
179 m_authenticatorRequests.clear();
180 }
181
182 void WebAuthentication::onAuthenticatorConnectionError() {
183 m_authenticator.reset();
184 for (ScriptPromiseResolver* resolver : m_authenticatorRequests) {
185 resolver->reject(
186 DOMException::create(NotFoundError, kNoAuthenticatorError));
187 }
188 m_authenticatorRequests.clear();
189 }
190
191 void WebAuthentication::onMakeCredential(
192 ScriptPromiseResolver* resolver,
193 Vector<webauth::mojom::blink::ScopedCredentialInfoPtr> credentials) {
194 if (!markRequestComplete(resolver))
ikilpatrick 2017/02/28 19:18:18 Should this reject promise? Or DCHECK that this ne
kpaulhamus 2017/03/01 01:56:34 markRequestCompleted has the additional action of
195 return;
196
197 HeapVector<Member<ScopedCredentialInfo>> scopedCredentials;
198 for (auto& credential : credentials) {
199 if (credential->clientData.isEmpty() || credential->attestation.isEmpty()) {
200 resolver->reject(
ikilpatrick 2017/02/28 19:18:18 just rejectWithDOMException?
kpaulhamus 2017/03/01 01:56:34 Do you have an example for this where the callback
201 DOMException::create(NotFoundError, "No credentials returned."));
202 }
203 DOMArrayBuffer* clientDataBuffer = DOMArrayBuffer::create(
204 static_cast<void*>(&credential->clientData.front()),
205 credential->clientData.size());
206
207 DOMArrayBuffer* attestationBuffer = DOMArrayBuffer::create(
208 static_cast<void*>(&credential->attestation.front()),
209 credential->attestation.size());
210
211 scopedCredentials.push_back(
212 ScopedCredentialInfo::create(clientDataBuffer, attestationBuffer));
213 }
214 resolver->resolve(scopedCredentials);
215 m_authenticatorRequests.erase(resolver);
216 }
217
218 bool WebAuthentication::markRequestComplete(ScriptPromiseResolver* resolver) {
219 auto requestEntry = m_authenticatorRequests.find(resolver);
220 if (requestEntry == m_authenticatorRequests.end())
221 return false;
222 m_authenticatorRequests.erase(requestEntry);
223 return true;
224 }
225
226 DEFINE_TRACE(WebAuthentication) {
227 visitor->trace(m_authenticatorRequests);
228 ContextLifecycleObserver::trace(visitor);
229 }
230
35 } // namespace blink 231 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698