// 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/PasswordCredential.h"

#include "bindings/core/v8/Dictionary.h"
#include "bindings/core/v8/ExceptionState.h"
#include "core/HTMLNames.h"
#include "core/dom/ExecutionContext.h"
#include "core/dom/URLSearchParams.h"
#include "core/html/FormAssociatedElement.h"
#include "core/html/FormData.h"
#include "core/html/HTMLFormElement.h"
#include "modules/credentialmanager/FormDataOptions.h"
#include "modules/credentialmanager/PasswordCredentialData.h"
#include "platform/credentialmanager/PlatformPasswordCredential.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/WebCredential.h"
#include "public/platform/WebPasswordCredential.h"

namespace blink {

PasswordCredential* PasswordCredential::create(WebPasswordCredential* webPasswordCredential)
{
    return new PasswordCredential(webPasswordCredential);
}

PasswordCredential* PasswordCredential::create(const PasswordCredentialData& data, ExceptionState& exceptionState)
{
    if (data.id().isEmpty()) {
        exceptionState.throwTypeError("'id' must not be empty.");
        return nullptr;
    }
    if (data.password().isEmpty()) {
        exceptionState.throwTypeError("'password' must not be empty.");
        return nullptr;
    }

    KURL iconURL = parseStringAsURL(data.iconURL(), exceptionState);
    if (exceptionState.hadException())
        return nullptr;

    return new PasswordCredential(data.id(), data.password(), data.name(), iconURL);
}

// https://w3c.github.io/webappsec-credential-management/#passwordcredential-form-constructor
PasswordCredential* PasswordCredential::create(HTMLFormElement* form, ExceptionState& exceptionState)
{
    // Extract data from the form, then use the extracted |formData| object's
    // value to populate |data|.
    FormData* formData = FormData::create(form);
    PasswordCredentialData data;

    AtomicString idName;
    AtomicString passwordName;
    for (FormAssociatedElement* element : form->associatedElements()) {
        // If |element| isn't a "submittable element" with string data, then it
        // won't have a matching value in |formData|, and we can safely skip it.
        FileOrUSVString result;
        formData->get(element->name(), result);
        if (!result.isUSVString())
            continue;

        AtomicString autocomplete = toHTMLElement(element)->fastGetAttribute(HTMLNames::autocompleteAttr);
        if (equalIgnoringCase(autocomplete, "current-password") || equalIgnoringCase(autocomplete, "new-password")) {
            data.setPassword(result.getAsUSVString());
            passwordName = element->name();
        } else if (equalIgnoringCase(autocomplete, "photo")) {
            data.setIconURL(result.getAsUSVString());
        } else if (equalIgnoringCase(autocomplete, "name") || equalIgnoringCase(autocomplete, "nickname")) {
            data.setName(result.getAsUSVString());
        } else if (equalIgnoringCase(autocomplete, "username")) {
            data.setId(result.getAsUSVString());
            idName = element->name();
        }
    }

    // Create a PasswordCredential using the data gathered above.
    PasswordCredential* credential = PasswordCredential::create(data, exceptionState);
    if (exceptionState.hadException())
        return nullptr;
    ASSERT(credential);

    // After creating the Credential, populate its 'additionalData', 'idName', and 'passwordName' attributes.
    // If the form's 'enctype' is anything other than multipart, generate a URLSearchParams using the
    // data in |formData|.
    credential->setIdName(idName);
    credential->setPasswordName(passwordName);

    FormDataOrURLSearchParams additionalData;
    if (form->enctype() == "multipart/form-data") {
        additionalData.setFormData(formData);
    } else {
        URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit());
        for (const FormData::Entry* entry : formData->entries()) {
            if (entry->isString())
                params->append(entry->name().data(), entry->value().data());
        }
        additionalData.setURLSearchParams(params);
    }

    credential->setAdditionalData(additionalData);
    return credential;
}

PasswordCredential::PasswordCredential(WebPasswordCredential* webPasswordCredential)
    : SiteBoundCredential(webPasswordCredential->getPlatformCredential())
    , m_idName("username")
    , m_passwordName("password")
{
}

PasswordCredential::PasswordCredential(const String& id, const String& password, const String& name, const KURL& icon)
    : SiteBoundCredential(PlatformPasswordCredential::create(id, password, name, icon))
    , m_idName("username")
    , m_passwordName("password")
{
}

PassRefPtr<EncodedFormData> PasswordCredential::encodeFormData(String& contentType) const
{
    if (m_additionalData.isURLSearchParams()) {
        // If |additionalData| is a 'URLSearchParams' object, build a urlencoded response.
        URLSearchParams* params = URLSearchParams::create(URLSearchParamsInit());
        URLSearchParams* additionalData = m_additionalData.getAsURLSearchParams();
        for (const auto& param : additionalData->params()) {
            const String& name = param.first;
            if (name != idName() && name != passwordName())
                params->append(name, param.second);
        }
        params->append(idName(), id());
        params->append(passwordName(), password());

        contentType = AtomicString("application/x-www-form-urlencoded;charset=UTF-8");

        return params->encodeFormData();
    }

    // Otherwise, we'll build a multipart response.
    FormData* formData = FormData::create(nullptr);
    if (m_additionalData.isFormData()) {
        FormData* additionalData = m_additionalData.getAsFormData();
        for (const FormData::Entry* entry : additionalData->entries()) {
            const String& name = formData->decode(entry->name());
            if (name == idName() || name == passwordName())
                continue;

            if (entry->blob())
                formData->append(name, entry->blob(), entry->filename());
            else
                formData->append(name, formData->decode(entry->value()));
        }
    }
    formData->append(idName(), id());
    formData->append(passwordName(), password());

    RefPtr<EncodedFormData> encodedData = formData->encodeMultiPartFormData();
    contentType = AtomicString("multipart/form-data; boundary=") + encodedData->boundary().data();
    return encodedData.release();
}

const String& PasswordCredential::password() const
{
    return static_cast<PlatformPasswordCredential*>(m_platformCredential.get())->password();
}

DEFINE_TRACE(PasswordCredential)
{
    SiteBoundCredential::trace(visitor);
    visitor->trace(m_additionalData);
}

} // namespace blink
