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

Unified 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: Addressing reviewer comments 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp
diff --git a/third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp b/third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp
index baecd1d0a595b24722d66a3c81d7288167138384..9ceeb8da358a3bcadb82157c71d7a8299c6b0cde 100644
--- a/third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp
+++ b/third_party/WebKit/Source/modules/webauth/WebAuthentication.cpp
@@ -5,12 +5,124 @@
#include "modules/webauth/WebAuthentication.h"
#include "bindings/core/v8/ScriptPromise.h"
+#include "bindings/core/v8/ScriptPromiseResolver.h"
+#include "core/dom/DOMException.h"
+#include "core/dom/Document.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
+#include "modules/webauth/RelyingPartyAccount.h"
+#include "modules/webauth/ScopedCredential.h"
+#include "modules/webauth/ScopedCredentialOptions.h"
+#include "modules/webauth/ScopedCredentialParameters.h"
+#include "public/platform/InterfaceProvider.h"
+
+namespace {
+const char kNoAuthenticatorError[] = "Authenticator unavailable.";
+} // anonymous namespace
+
+namespace mojo {
+
+using webauth::mojom::blink::RelyingPartyAccount;
+using webauth::mojom::blink::RelyingPartyAccountPtr;
+using webauth::mojom::blink::ScopedCredentialOptions;
+using webauth::mojom::blink::ScopedCredentialOptionsPtr;
+using webauth::mojom::blink::ScopedCredentialParameters;
+using webauth::mojom::blink::ScopedCredentialParametersPtr;
+using webauth::mojom::blink::ScopedCredentialDescriptor;
+using webauth::mojom::blink::ScopedCredentialType;
+using webauth::mojom::blink::Transport;
+
+Vector<uint8_t> convertBufferSource(const blink::BufferSource& buffer) {
+ DCHECK(buffer.isNull());
+ Vector<uint8_t> vector;
+ if (buffer.isArrayBuffer()) {
+ vector.append(static_cast<uint8_t*>(buffer.getAsArrayBuffer()->data()),
+ buffer.getAsArrayBuffer()->byteLength());
+ } else {
+ vector.append(
+ static_cast<uint8_t*>(buffer.getAsArrayBufferView()->baseAddress()),
+ buffer.getAsArrayBufferView()->byteLength());
+ }
+ return vector;
+}
+
+ScopedCredentialType convertScopedCredentialType(const WTF::String& credType) {
+ if (credType == "ScopedCred")
+ return ScopedCredentialType::SCOPEDCRED;
+ NOTREACHED();
+ return ScopedCredentialType::SCOPEDCRED;
+}
+
+Transport convertTransport(const WTF::String& transport) {
+ if (transport == "usb")
+ return Transport::USB;
+ if (transport == "nfc")
+ return Transport::NFC;
+ if (transport == "ble")
+ return Transport::BLE;
+ NOTREACHED();
+ return Transport::USB;
+}
+
+RelyingPartyAccountPtr convertRelyingPartyAccount(
+ const blink::RelyingPartyAccount& accountInformation,
+ blink::ScriptPromiseResolver* resolver) {
+ auto mojoAccount = RelyingPartyAccount::New();
+
+ mojoAccount->rp_display_name = accountInformation.rpDisplayName();
+ mojoAccount->display_name = accountInformation.displayName();
+ mojoAccount->id = accountInformation.id();
+ mojoAccount->name = accountInformation.name();
+ mojoAccount->image_url = accountInformation.imageURL();
+ return mojoAccount;
+}
+
+ScopedCredentialOptionsPtr convertScopedCredentialOptions(
+ const blink::ScopedCredentialOptions options,
+ blink::ScriptPromiseResolver* resolver) {
+ auto mojoOptions = ScopedCredentialOptions::New();
+ mojoOptions->timeout_seconds = options.timeoutSeconds();
+ mojoOptions->rp_id = options.rpId();
+
+ // Adds the excludeList members (which are ScopedCredentialDescriptors)
+ for (const auto& descriptor : options.excludeList()) {
+ auto mojoDescriptor = ScopedCredentialDescriptor::New();
+ mojoDescriptor->type = convertScopedCredentialType(descriptor.type());
+ mojoDescriptor->id = convertBufferSource(descriptor.id());
+ for (const auto& transport : descriptor.transports())
+ mojoDescriptor->transports.push_back(convertTransport(transport));
+ mojoOptions->exclude_list.push_back(std::move(mojoDescriptor));
+ }
+ // TODO (kpaulhamus) add AuthenticationExtensions;
+ return mojoOptions;
+}
+
+ScopedCredentialParametersPtr convertScopedCredentialParameter(
+ const blink::ScopedCredentialParameters parameter,
+ blink::ScriptPromiseResolver* resolver) {
+ auto mojoParameter = ScopedCredentialParameters::New();
+ mojoParameter->type = convertScopedCredentialType(parameter.type());
+ // TODO (kpaulhamus) add AlgorithmIdentifier
+ return mojoParameter;
+}
+} // namespace mojo
namespace blink {
-WebAuthentication::WebAuthentication(LocalFrame& frame) {}
+WebAuthentication::WebAuthentication(LocalFrame& frame)
+ : ContextLifecycleObserver(frame.document()) {
+ frame.interfaceProvider()->getInterface(mojo::MakeRequest(&m_authenticator));
+ m_authenticator.set_connection_error_handler(convertToBaseCallback(
+ WTF::bind(&WebAuthentication::onAuthenticatorConnectionError,
+ wrapWeakPersistent(this))));
+}
-WebAuthentication::~WebAuthentication() {}
+WebAuthentication::~WebAuthentication() {
+ // |m_authenticator| may still be valid but there should be no more
+ // outstanding requests because each holds a persistent handle to this object.
+ DCHECK(m_authenticatorRequests.isEmpty());
+}
void WebAuthentication::dispose() {}
@@ -20,8 +132,40 @@ ScriptPromise WebAuthentication::makeCredential(
const HeapVector<ScopedCredentialParameters> cryptoParameters,
const BufferSource& attestationChallenge,
ScopedCredentialOptions& options) {
- NOTREACHED();
- return ScriptPromise();
+ ExecutionContext* executionContext = scriptState->getExecutionContext();
+ UseCounter::count(executionContext, UseCounter::AuthenticationMakeCredential);
+
+ if (!m_authenticator) {
+ return ScriptPromise::rejectWithDOMException(
+ scriptState, DOMException::create(NotSupportedError));
+ }
+
+ String errorMessage;
+ if (!executionContext->isSecureContext(errorMessage)) {
+ return ScriptPromise::rejectWithDOMException(
+ scriptState, DOMException::create(SecurityError, errorMessage));
+ }
+
+ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+
+ // TODO(kpaulhamus) validate parameters according to spec
+ auto account = mojo::convertRelyingPartyAccount(accountInformation, resolver);
+ Vector<uint8_t> buffer = mojo::convertBufferSource(attestationChallenge);
+ auto opts = mojo::convertScopedCredentialOptions(options, resolver);
+ Vector<webauth::mojom::blink::ScopedCredentialParametersPtr> parameters;
+ for (const auto& parameter : cryptoParameters) {
+ parameters.push_back(
+ mojo::convertScopedCredentialParameter(parameter, resolver));
+ }
+
+ m_authenticatorRequests.insert(resolver);
+ m_authenticator->makeCredential(
+ std::move(account), std::move(parameters), buffer, std::move(opts),
+ convertToBaseCallback(WTF::bind(&WebAuthentication::onMakeCredential,
+ wrapPersistent(this),
+ wrapPersistent(resolver))));
+ return promise;
}
ScriptPromise WebAuthentication::getAssertion(
@@ -32,4 +176,59 @@ ScriptPromise WebAuthentication::getAssertion(
return ScriptPromise();
}
+void WebAuthentication::contextDestroyed(ExecutionContext*) {
+ m_authenticator.reset();
+ m_authenticatorRequests.clear();
+}
+
+void WebAuthentication::onAuthenticatorConnectionError() {
+ m_authenticator.reset();
+ for (ScriptPromiseResolver* resolver : m_authenticatorRequests) {
+ resolver->reject(
+ DOMException::create(NotFoundError, kNoAuthenticatorError));
+ }
+ m_authenticatorRequests.clear();
+}
+
+void WebAuthentication::onMakeCredential(
+ ScriptPromiseResolver* resolver,
+ Vector<webauth::mojom::blink::ScopedCredentialInfoPtr> credentials) {
+ if (!markRequestComplete(resolver))
+ return;
+
+ HeapVector<Member<ScopedCredentialInfo>> scopedCredentials;
+ for (auto& credential : credentials) {
+ if (credential->client_data.isEmpty() ||
+ credential->attestation.isEmpty()) {
+ resolver->reject(
+ DOMException::create(NotFoundError, "No credentials returned."));
+ }
+ DOMArrayBuffer* clientDataBuffer = DOMArrayBuffer::create(
+ static_cast<void*>(&credential->client_data.front()),
+ credential->client_data.size());
+
+ DOMArrayBuffer* attestationBuffer = DOMArrayBuffer::create(
+ static_cast<void*>(&credential->attestation.front()),
+ credential->attestation.size());
+
+ scopedCredentials.push_back(
+ ScopedCredentialInfo::create(clientDataBuffer, attestationBuffer));
+ }
+ resolver->resolve(scopedCredentials);
+ m_authenticatorRequests.erase(resolver);
+}
+
+bool WebAuthentication::markRequestComplete(ScriptPromiseResolver* resolver) {
+ auto requestEntry = m_authenticatorRequests.find(resolver);
+ if (requestEntry == m_authenticatorRequests.end())
+ return false;
+ m_authenticatorRequests.erase(requestEntry);
+ return true;
+}
+
+DEFINE_TRACE(WebAuthentication) {
+ visitor->trace(m_authenticatorRequests);
+ ContextLifecycleObserver::trace(visitor);
+}
+
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698