// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "modules/credentialmanager/CredentialsContainer.h"

#include "bindings/core/v8/Dictionary.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/dom/ExecutionContext.h"
#include "core/frame/Frame.h"
#include "core/frame/UseCounter.h"
#include "core/page/FrameTree.h"
#include "modules/credentialmanager/Credential.h"
#include "modules/credentialmanager/CredentialManagerClient.h"
#include "modules/credentialmanager/CredentialRequestOptions.h"
#include "modules/credentialmanager/FederatedCredential.h"
#include "modules/credentialmanager/FederatedCredentialRequestOptions.h"
#include "modules/credentialmanager/PasswordCredential.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCredential.h"
#include "public/platform/WebCredentialManagerClient.h"
#include "public/platform/WebCredentialManagerError.h"
#include "public/platform/WebFederatedCredential.h"
#include "public/platform/WebPasswordCredential.h"
#include "wtf/PtrUtil.h"
#include <memory>

namespace blink {

static void rejectDueToCredentialManagerError(
    ScriptPromiseResolver* resolver,
    WebCredentialManagerError reason) {
  switch (reason) {
    case WebCredentialManagerDisabledError:
      resolver->reject(DOMException::create(
          InvalidStateError, "The credential manager is disabled."));
      break;
    case WebCredentialManagerPendingRequestError:
      resolver->reject(DOMException::create(InvalidStateError,
                                            "A 'get()' request is pending."));
      break;
    case WebCredentialManagerUnknownError:
    default:
      resolver->reject(DOMException::create(NotReadableError,
                                            "An unknown error occurred while "
                                            "talking to the credential "
                                            "manager."));
      break;
  }
}

class NotificationCallbacks
    : public WebCredentialManagerClient::NotificationCallbacks {
  WTF_MAKE_NONCOPYABLE(NotificationCallbacks);

 public:
  explicit NotificationCallbacks(ScriptPromiseResolver* resolver)
      : m_resolver(resolver) {}
  ~NotificationCallbacks() override {}

  void onSuccess() override {
    Frame* frame =
        toDocument(m_resolver->getScriptState()->getExecutionContext())
            ->frame();
    SECURITY_CHECK(!frame || frame == frame->tree().top());

    m_resolver->resolve();
  }

  void onError(WebCredentialManagerError reason) override {
    rejectDueToCredentialManagerError(m_resolver, reason);
  }

 private:
  const Persistent<ScriptPromiseResolver> m_resolver;
};

class RequestCallbacks : public WebCredentialManagerClient::RequestCallbacks {
  WTF_MAKE_NONCOPYABLE(RequestCallbacks);

 public:
  explicit RequestCallbacks(ScriptPromiseResolver* resolver)
      : m_resolver(resolver) {}
  ~RequestCallbacks() override {}

  void onSuccess(std::unique_ptr<WebCredential> webCredential) override {
    Frame* frame =
        toDocument(m_resolver->getScriptState()->getExecutionContext())
            ->frame();
    SECURITY_CHECK(!frame || frame == frame->tree().top());

    std::unique_ptr<WebCredential> credential =
        WTF::wrapUnique(webCredential.release());
    if (!credential || !frame) {
      m_resolver->resolve();
      return;
    }

    ASSERT(credential->isPasswordCredential() ||
           credential->isFederatedCredential());
    UseCounter::count(m_resolver->getScriptState()->getExecutionContext(),
                      UseCounter::CredentialManagerGetReturnedCredential);
    if (credential->isPasswordCredential())
      m_resolver->resolve(PasswordCredential::create(
          static_cast<WebPasswordCredential*>(credential.get())));
    else
      m_resolver->resolve(FederatedCredential::create(
          static_cast<WebFederatedCredential*>(credential.get())));
  }

  void onError(WebCredentialManagerError reason) override {
    rejectDueToCredentialManagerError(m_resolver, reason);
  }

 private:
  const Persistent<ScriptPromiseResolver> m_resolver;
};

CredentialsContainer* CredentialsContainer::create() {
  return new CredentialsContainer();
}

CredentialsContainer::CredentialsContainer() {}

static bool checkBoilerplate(ScriptPromiseResolver* resolver) {
  Frame* frame =
      toDocument(resolver->getScriptState()->getExecutionContext())->frame();
  if (!frame || frame != frame->tree().top()) {
    resolver->reject(DOMException::create(SecurityError,
                                          "CredentialContainer methods may "
                                          "only be executed in a top-level "
                                          "document."));
    return false;
  }

  String errorMessage;
  if (!resolver->getScriptState()->getExecutionContext()->isSecureContext(
          errorMessage)) {
    resolver->reject(DOMException::create(SecurityError, errorMessage));
    return false;
  }

  CredentialManagerClient* client = CredentialManagerClient::from(
      resolver->getScriptState()->getExecutionContext());
  if (!client) {
    resolver->reject(DOMException::create(
        InvalidStateError,
        "Could not establish connection to the credential manager."));
    return false;
  }

  return true;
}

ScriptPromise CredentialsContainer::get(
    ScriptState* scriptState,
    const CredentialRequestOptions& options) {
  ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
  ScriptPromise promise = resolver->promise();
  if (!checkBoilerplate(resolver))
    return promise;

  Vector<KURL> providers;
  if (options.hasFederated() && options.federated().hasProviders()) {
    // TODO(mkwst): CredentialRequestOptions::federated() needs to return a
    // reference, not a value.  Because it returns a temporary value now, a for
    // loop that directly references the value generates code that holds a
    // reference to a value that no longer exists by the time the loop starts
    // looping. In order to avoid this crazyness for the moment, we're making a
    // copy of the vector. https://crbug.com/587088
    const Vector<String> providerStrings = options.federated().providers();
    for (const auto& string : providerStrings) {
      KURL url = KURL(KURL(), string);
      if (url.isValid())
        providers.push_back(url);
    }
  }

  UseCounter::count(scriptState->getExecutionContext(),
                    options.unmediated()
                        ? UseCounter::CredentialManagerGetWithoutUI
                        : UseCounter::CredentialManagerGetWithUI);

  CredentialManagerClient::from(scriptState->getExecutionContext())
      ->dispatchGet(options.unmediated(), options.password(), providers,
                    new RequestCallbacks(resolver));
  return promise;
}

ScriptPromise CredentialsContainer::store(ScriptState* scriptState,
                                          Credential* credential) {
  ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
  ScriptPromise promise = resolver->promise();
  if (!checkBoilerplate(resolver))
    return promise;

  auto webCredential =
      WebCredential::create(credential->getPlatformCredential());
  CredentialManagerClient::from(scriptState->getExecutionContext())
      ->dispatchStore(*webCredential, new NotificationCallbacks(resolver));
  return promise;
}

ScriptPromise CredentialsContainer::requireUserMediation(
    ScriptState* scriptState) {
  ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
  ScriptPromise promise = resolver->promise();
  if (!checkBoilerplate(resolver))
    return promise;

  CredentialManagerClient::from(scriptState->getExecutionContext())
      ->dispatchRequireUserMediation(new NotificationCallbacks(resolver));
  return promise;
}

}  // namespace blink
