/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Network Auth module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qoauth1signature.h"
#include "qoauth1signature_p.h"

#include <QtCore/qurlquery.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qmessageauthenticationcode.h>

#include <QtNetwork/qnetworkaccessmanager.h>

#include <functional>
#include <type_traits>

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(loggingCategory, "qt.networkauth.oauth1.signature")

/*!
    \class QOAuth1Signature
    \inmodule QtNetworkAuth
    \ingroup oauth
    \brief Implements OAuth 1 signature methods.
    \since 5.8

    OAuth-authenticated requests can have two sets of credentials:
    those passed via the "oauth_consumer_key" parameter and those in
    the "oauth_token" parameter.  In order for the server to verify
    the authenticity of the request and prevent unauthorized access,
    the client needs to prove that it is the rightful owner of the
    credentials.  This is accomplished using the shared-secret (or
    RSA key) part of each set of credentials.

    OAuth specifies three methods for the client to establish its
    rightful ownership of the credentials: "HMAC-SHA1", "RSA-SHA1",
    and "PLAINTEXT".  Each generates a "signature" with which the
    request is "signed"; the first two use a digest of the data
    signed in generating this, though the last does not.  The
    "RSA-SHA1" method is not supported here; it would use an RSA key
    rather than the shared-secret associated with the client
    credentials.
*/

/*!
    \enum QOAuth1Signature::HttpRequestMethod

    Indicates the HTTP request method.

    \value Head     HEAD method.
    \value Get      GET method.
    \value Put      PUT method.
    \value Post     POST method.
    \value Delete   DELETE method.
    \value Custom   Identifies a custom method.
    \value Unknown  Method not set.
*/

static_assert(static_cast<int>(QOAuth1Signature::HttpRequestMethod::Head) ==
              static_cast<int>(QNetworkAccessManager::HeadOperation) &&
              static_cast<int>(QOAuth1Signature::HttpRequestMethod::Get) ==
              static_cast<int>(QNetworkAccessManager::GetOperation) &&
              static_cast<int>(QOAuth1Signature::HttpRequestMethod::Put) ==
              static_cast<int>(QNetworkAccessManager::PutOperation) &&
              static_cast<int>(QOAuth1Signature::HttpRequestMethod::Post) ==
              static_cast<int>(QNetworkAccessManager::PostOperation) &&
              static_cast<int>(QOAuth1Signature::HttpRequestMethod::Delete) ==
              static_cast<int>(QNetworkAccessManager::DeleteOperation),
              "Invalid QOAuth1Signature::HttpRequestMethod enumeration values");

QOAuth1SignaturePrivate QOAuth1SignaturePrivate::shared_null;

QOAuth1SignaturePrivate::QOAuth1SignaturePrivate(const QUrl &url,
                                                 QOAuth1Signature::HttpRequestMethod method,
                                                 const QVariantMap &parameters,
                                                 const QString &clientSharedKey,
                                                 const QString &tokenSecret) :
    method(method), url(url), clientSharedKey(clientSharedKey), tokenSecret(tokenSecret),
    parameters(parameters)
{}

QByteArray QOAuth1SignaturePrivate::signatureBaseString() const
{
    // https://tools.ietf.org/html/rfc5849#section-3.4.1
    QByteArray base;

    switch (method) {
    case QOAuth1Signature::HttpRequestMethod::Head:
        base.append("HEAD");
        break;
    case QOAuth1Signature::HttpRequestMethod::Get:
        base.append("GET");
        break;
    case QOAuth1Signature::HttpRequestMethod::Put:
        base.append("PUT");
        break;
    case QOAuth1Signature::HttpRequestMethod::Post:
        base.append("POST");
        break;
    case QOAuth1Signature::HttpRequestMethod::Delete:
        base.append("DELETE");
        break;
    case QOAuth1Signature::HttpRequestMethod::Custom:
        if (!customVerb.isEmpty()) {
            base.append(customVerb);
        } else {
            qCCritical(loggingCategory, "QOAuth1Signature: HttpRequestMethod::Custom requires "
                                        "the verb to be set via setCustomMethodString");
        }
        break;
    default:
        qCCritical(loggingCategory, "QOAuth1Signature: HttpRequestMethod not supported");
    }
    base.append('&');
    base.append(QUrl::toPercentEncoding(url.toString(QUrl::RemoveQuery)) + "&");

    QVariantMap p = parameters;
    {
        // replace '+' with spaces now before decoding so that '%2B' gets left as '+'
        const QString query = url.query().replace(QLatin1Char('+'), QLatin1Char(' '));
        const auto queryItems = QUrlQuery(query).queryItems(QUrl::FullyDecoded);
        for (auto it = queryItems.begin(), end = queryItems.end(); it != end; ++it)
            p.insert(it->first, it->second);
    }
    base.append(encodeHeaders(p));
    return base;
}

QByteArray QOAuth1SignaturePrivate::secret() const
{
    QByteArray secret;
    secret.append(QUrl::toPercentEncoding(clientSharedKey));
    secret.append('&');
    secret.append(QUrl::toPercentEncoding(tokenSecret));
    return secret;
}

QByteArray QOAuth1SignaturePrivate::parameterString(const QVariantMap &parameters)
{
    QByteArray ret;
    auto previous = parameters.end();
    for (auto it = parameters.begin(), end = parameters.end(); it != end; previous = it++) {
        if (previous != parameters.end()) {
            if (Q_UNLIKELY(previous.key() == it.key()))
                qCWarning(loggingCategory, "duplicated key %s", qPrintable(it.key()));
            ret.append("&");
        }
        ret.append(QUrl::toPercentEncoding(it.key()));
        ret.append("=");
        ret.append(QUrl::toPercentEncoding(it.value().toString()));
    }
    return ret;
}

QByteArray QOAuth1SignaturePrivate::encodeHeaders(const QVariantMap &headers)
{
    return QUrl::toPercentEncoding(QString::fromLatin1(parameterString(headers)));
}

/*!
    Creates a QOAuth1Signature using
    \list
        \li \a url as the target address
        \li \a method as the HTTP method used to send the request
        \li and the given user \a parameters to augment the request.
    \endlist
*/
QOAuth1Signature::QOAuth1Signature(const QUrl &url, QOAuth1Signature::HttpRequestMethod method,
                                   const QVariantMap &parameters) :
    d(new QOAuth1SignaturePrivate(url, method, parameters))
{}

/*!
    Creates a QOAuth1Signature using
    \list
        \li \a url as the target address
        \li \a clientSharedKey as the user token used to verify the
        signature
        \li \a tokenSecret as the negotiated token used to verify
        the signature
        \li \a method as the HTTP method used to send the request
        \li and the given user \a parameters to augment the request.
    \endlist
*/
QOAuth1Signature::QOAuth1Signature(const QUrl &url, const QString &clientSharedKey,
                                   const QString &tokenSecret, HttpRequestMethod method,
                                   const QVariantMap &parameters) :
    d(new QOAuth1SignaturePrivate(url, method, parameters, clientSharedKey, tokenSecret))
{}

/*!
    Creates a copy of \a other.
*/
QOAuth1Signature::QOAuth1Signature(const QOAuth1Signature &other) : d(other.d)
{}

/*!
    Move-constructs a QOAuth1Signature instance, taking over the
    private data \a other was using.
*/
QOAuth1Signature::QOAuth1Signature(QOAuth1Signature &&other) : d(std::move(other.d))
{
}

/*!
    Destroys the QOAuth1Signature.
*/
QOAuth1Signature::~QOAuth1Signature()
{}

/*!
    Returns the request method.
*/
QOAuth1Signature::HttpRequestMethod QOAuth1Signature::httpRequestMethod() const
{
    return d->method;
}

/*!
    Sets the request \a method.
*/
void QOAuth1Signature::setHttpRequestMethod(QOAuth1Signature::HttpRequestMethod method)
{
    d->method = method;
}

/*!
    \since 5.13

    Returns the custom method string.

    \sa httpRequestMethod()
*/
QByteArray QOAuth1Signature::customMethodString() const
{
    return d->customVerb;
}

/*!
    \since 5.13

    Sets a custom request method. Will set the httpRequestMethod
    to QOAuth1Signature::HttpRequestMethod::Custom and store the
    \a verb to use it for the generation of the signature.

    \note Using this method is required when working with custom verbs.
    Setting only the request method will fail, as the signure needs to
    know the actual verb.

    \sa setHttpRequestMethod(), HttpRequestMethod
*/
void QOAuth1Signature::setCustomMethodString(const QByteArray &verb)
{
    d->method = QOAuth1Signature::HttpRequestMethod::Custom;
    d->customVerb = verb;
}

/*!
    Returns the URL.
*/
QUrl QOAuth1Signature::url() const
{
    return d->url;
}

/*!
    Sets the URL to \a url.
*/
void QOAuth1Signature::setUrl(const QUrl &url)
{
    d->url = url;
}

/*!
    Returns the parameters.
*/
QVariantMap QOAuth1Signature::parameters() const
{
    return d->parameters;
}

/*!
    Sets the \a parameters.
*/
void QOAuth1Signature::setParameters(const QVariantMap &parameters)
{
    d->parameters = parameters;
}

/*!
    Adds the request \a body to the signature. When a POST request
    body contains arguments they should be included in the signed
    data.
*/
void QOAuth1Signature::addRequestBody(const QUrlQuery &body)
{
    const auto list = body.queryItems();
    for (auto it = list.begin(), end = list.end(); it != end; ++it)
        d->parameters.insert(it->first, it->second);
}

/*!
    Inserts a new pair \a key, \a value into the signature. When a
    POST request body contains arguments they should be included in
    the signed data.
*/
void QOAuth1Signature::insert(const QString &key, const QVariant &value)
{
    d->parameters.insert(key, value);
}

/*!
    Retrieves the list of keys of parameters included in the signed
    data.
*/
QList<QString> QOAuth1Signature::keys() const
{
    return d->parameters.uniqueKeys();
}

/*!
    Removes \a key and any associated value from the signed data.
*/
QVariant QOAuth1Signature::take(const QString &key)
{
    return d->parameters.take(key);
}

/*!
    Returns the value associated with \a key, if present in the
    signed data, otherwise \a defaultValue.
*/
QVariant QOAuth1Signature::value(const QString &key, const QVariant &defaultValue) const
{
    return d->parameters.value(key, defaultValue);
}

/*!
    Returns the user secret used to generate the signature.
*/
QString QOAuth1Signature::clientSharedKey() const
{
    return d->clientSharedKey;
}

/*!
    Sets \a secret as the user secret used to generate the signature.
*/
void QOAuth1Signature::setClientSharedKey(const QString &secret)
{
    d->clientSharedKey = secret;
}

/*!
    Returns the negotiated secret used to generate the signature.
*/
QString QOAuth1Signature::tokenSecret() const
{
    return d->tokenSecret;
}

/*!
    Sets \a secret as the negotiated secret used to generate the
    signature.
*/
void QOAuth1Signature::setTokenSecret(const QString &secret)
{
    d->tokenSecret = secret;
}

/*!
    Generates the HMAC-SHA1 signature using the client shared secret
    and, where available, token secret.
*/
QByteArray QOAuth1Signature::hmacSha1() const
{
    QMessageAuthenticationCode code(QCryptographicHash::Sha1);
    code.setKey(d->secret());
    code.addData(d->signatureBaseString());
    return code.result();
}

/*!
    Generates the RSA-SHA1 signature.

    \note Currently this method is not supported.
*/
QByteArray QOAuth1Signature::rsaSha1() const
{
    qCCritical(loggingCategory, "RSA-SHA1 signing method not supported");
    return QByteArray();
}

/*!
    Generates the PLAINTEXT signature.
*/
QByteArray QOAuth1Signature::plainText() const
{
    return plainText(d->clientSharedKey, d->tokenSecret);
}

/*!
    Generates a PLAINTEXT signature from the client secret
    \a clientSharedKey and the token secret \a tokenSecret.
*/
QByteArray QOAuth1Signature::plainText(const QString &clientSharedKey,
                                       const QString &tokenSecret)
{
    QByteArray ret;
    ret += clientSharedKey.toUtf8() + '&' + tokenSecret.toUtf8();
    return ret;
}

/*!
    Swaps signature \a other with this signature. This operation is
    very fast and never fails.
*/
void QOAuth1Signature::swap(QOAuth1Signature &other)
{
    qSwap(d, other.d);
}

QOAuth1Signature &QOAuth1Signature::operator=(const QOAuth1Signature &other)
{
    if (d != other.d) {
        QOAuth1Signature tmp(other);
        tmp.swap(*this);
    }
    return *this;
}

/*!
    Move-assignment operator.
*/
QOAuth1Signature &QOAuth1Signature::operator=(QOAuth1Signature &&other)
{
    QOAuth1Signature moved(std::move(other));
    swap(moved);
    return *this;
}

QT_END_NAMESPACE
