CredentialsContainer.cpp [plain text]
#include "config.h"
#include "CredentialsContainer.h"
#include "AbortSignal.h"
#include "CredentialCreationOptions.h"
#include "CredentialRequestOptions.h"
#include "Document.h"
#include "ExceptionOr.h"
#include "JSBasicCredential.h"
#include "PublicKeyCredential.h"
#include "SecurityOrigin.h"
namespace WebCore {
CredentialsContainer::CredentialsContainer(WeakPtr<Document>&& document)
: m_document(WTFMove(document))
, m_workQueue(WorkQueue::create("com.apple.WebKit.CredentialQueue"))
{
}
bool CredentialsContainer::doesHaveSameOriginAsItsAncestors()
{
if (!m_document)
return false;
auto& origin = m_document->securityOrigin();
for (auto* document = m_document->parentDocument(); document; document = document->parentDocument()) {
if (!originsMatch(document->securityOrigin(), origin))
return false;
}
return true;
}
template<typename OperationType>
void CredentialsContainer::dispatchTask(OperationType&& operation, Ref<DeferredPromise>&& promise)
{
auto* promiseIndex = promise.ptr();
m_pendingPromises.add(promiseIndex, WTFMove(promise));
auto weakThis = m_weakPtrFactory.createWeakPtr(*this);
auto task = [promiseIndex, weakThis, isSameOriginWithItsAncestors = doesHaveSameOriginAsItsAncestors(), operation = WTFMove(operation)] () {
auto result = operation(isSameOriginWithItsAncestors);
callOnMainThread([promiseIndex, weakThis, result = WTFMove(result)] () mutable {
if (weakThis) {
if (auto promise = weakThis->m_pendingPromises.take(promiseIndex)) {
if (result.hasException())
promise.value()->reject(result.releaseException());
else
promise.value()->resolve<IDLNullable<IDLInterface<BasicCredential>>>(result.releaseReturnValue().get());
}
}
});
};
m_workQueue->dispatch(WTFMove(task));
}
void CredentialsContainer::get(CredentialRequestOptions&& options, Ref<DeferredPromise>&& promise)
{
if ((!options.signal && !options.publicKey) || !m_document) {
promise->reject(Exception { NotSupportedError });
return;
}
if (options.signal && options.signal->aborted()) {
promise->reject(Exception { AbortError });
return;
}
ASSERT(m_document->isSecureContext());
if (!options.publicKey) {
promise->reject(Exception { NotSupportedError });
return;
}
auto operation = [options = WTFMove(options)] (bool isSameOriginWithItsAncestors) {
return PublicKeyCredential::discoverFromExternalSource(options, isSameOriginWithItsAncestors);
};
dispatchTask(WTFMove(operation), WTFMove(promise));
}
void CredentialsContainer::store(const BasicCredential&, Ref<DeferredPromise>&& promise)
{
promise->reject(Exception { NotSupportedError });
}
void CredentialsContainer::isCreate(CredentialCreationOptions&& options, Ref<DeferredPromise>&& promise)
{
if ((!options.signal && !options.publicKey) || !m_document) {
promise->reject(Exception { NotSupportedError });
return;
}
if (options.signal && options.signal->aborted()) {
promise->reject(Exception { AbortError });
return;
}
ASSERT(m_document->isSecureContext());
if (!options.publicKey) {
promise->reject(Exception { NotSupportedError });
return;
}
auto operation = [options = WTFMove(options)] (bool isSameOriginWithItsAncestors) {
return PublicKeyCredential::create(options, isSameOriginWithItsAncestors);
};
dispatchTask(WTFMove(operation), WTFMove(promise));
}
void CredentialsContainer::preventSilentAccess(Ref<DeferredPromise>&& promise)
{
promise->reject(Exception { NotSupportedError });
}
}