I'm sorry. This is a big change to recent stuff, and worst of all is a big commit. Decisions I made while implementing credential discovery backed me into a corner where I couldn't have the UI actually get rendered. Particularly around where the IPCs needed to happen and at what point we called into the main process and when we returned. The way it works now is that we do ONE IPC for a credentials.get call, doing most of the work in the main process and only maybe doing one IPC down to the content process to tell it to navigate. This is neater and more secure to a compromised content process. However, a lot happens in this patch. Differential Revision: https://phabricator.services.mozilla.com/D215009
106 lines
3.8 KiB
C++
106 lines
3.8 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "IdentityCredentialRequestManager.h"
|
|
#include "mozilla/dom/IdentityCredentialBinding.h"
|
|
#include "mozilla/dom/WindowGlobalParent.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsNetUtil.h"
|
|
#include "mozilla/BasePrincipal.h"
|
|
|
|
namespace mozilla {
|
|
|
|
NS_IMPL_ISUPPORTS0(IdentityCredentialRequestManager);
|
|
|
|
StaticRefPtr<IdentityCredentialRequestManager>
|
|
IdentityCredentialRequestManager::sSingleton;
|
|
|
|
// static
|
|
IdentityCredentialRequestManager*
|
|
IdentityCredentialRequestManager::GetInstance() {
|
|
if (!sSingleton) {
|
|
sSingleton = new IdentityCredentialRequestManager();
|
|
ClearOnShutdown(&sSingleton);
|
|
}
|
|
return sSingleton;
|
|
}
|
|
|
|
nsresult IdentityCredentialRequestManager::StorePendingRequest(
|
|
const nsCOMPtr<nsIPrincipal>& aRPPrincipal,
|
|
const dom::IdentityCredentialRequestOptions& aRequest,
|
|
const RefPtr<
|
|
dom::IdentityCredential::GetIPCIdentityCredentialPromise::Private>&
|
|
aPromise,
|
|
const RefPtr<dom::CanonicalBrowsingContext>& aBrowsingContext) {
|
|
MOZ_ASSERT(aRPPrincipal);
|
|
|
|
if (!aRequest.mProviders.WasPassed()) {
|
|
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
|
}
|
|
|
|
for (const auto& provider : aRequest.mProviders.Value()) {
|
|
if (!provider.mLoginURL.WasPassed()) {
|
|
continue;
|
|
}
|
|
nsCOMPtr<nsIURI> idpOriginURI;
|
|
nsAutoCString idpOriginString;
|
|
if (provider.mOrigin.WasPassed()) {
|
|
idpOriginString = provider.mOrigin.Value();
|
|
} else {
|
|
// Infer the origin from the loginURL if one wasn't provided
|
|
idpOriginString = provider.mLoginURL.Value();
|
|
}
|
|
nsresult rv = NS_NewURI(getter_AddRefs(idpOriginURI), idpOriginString);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
}
|
|
nsCOMPtr<nsIPrincipal> idpPrincipal = BasePrincipal::CreateContentPrincipal(
|
|
idpOriginURI, aRPPrincipal->OriginAttributesRef());
|
|
|
|
NS_ENSURE_TRUE(idpPrincipal, NS_ERROR_FAILURE);
|
|
nsTArray<PendingRequestEntry>& list =
|
|
mPendingRequests.LookupOrInsert(idpPrincipal);
|
|
list.AppendElement(PendingRequestEntry(aRPPrincipal, aRequest, aPromise,
|
|
aBrowsingContext));
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
void IdentityCredentialRequestManager::NotifyOfStoredCredential(
|
|
const nsCOMPtr<nsIPrincipal>& aIDPPrincipal,
|
|
const dom::IPCIdentityCredential& aCredential) {
|
|
MOZ_ASSERT(aIDPPrincipal);
|
|
auto listLookup = mPendingRequests.Lookup(aIDPPrincipal);
|
|
if (listLookup) {
|
|
for (auto& entry : listLookup.Data()) {
|
|
// Make sure we are only sending updates to fully active documents
|
|
if (!entry.mBrowsingContext ||
|
|
!entry.mBrowsingContext->GetCurrentWindowContext() ||
|
|
entry.mBrowsingContext->GetCurrentWindowContext()->IsDiscarded() ||
|
|
!entry.mBrowsingContext->GetCurrentWindowContext()->IsCurrent() ||
|
|
!entry.mBrowsingContext->AncestorsAreCurrent() ||
|
|
entry.mBrowsingContext->IsInBFCache()) {
|
|
continue;
|
|
}
|
|
// We must (asynchronously) test if this credential should be sent down
|
|
// to the site.
|
|
dom::IdentityCredential::AllowedToCollectCredential(
|
|
entry.mRPPrincipal, entry.mBrowsingContext, entry.mRequestOptions,
|
|
aCredential)
|
|
->Then(
|
|
GetCurrentSerialEventTarget(), __func__,
|
|
[aCredential, entry](bool effectiveCredential) {
|
|
if (effectiveCredential) {
|
|
entry.mPromise->Resolve(aCredential, __func__);
|
|
}
|
|
},
|
|
[]() {});
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace mozilla
|