/*
 * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "WebKitAuthenticationRequest.h"

#include "AuthenticationChallengeDisposition.h"
#include "AuthenticationDecisionListener.h"
#include "WebCredential.h"
#include "WebKitAuthenticationRequestPrivate.h"
#include "WebKitCredentialPrivate.h"
#include "WebProtectionSpace.h"
#include <WebCore/AuthenticationChallenge.h>
#include <WebCore/ProtectionSpace.h>
#include <glib/gi18n-lib.h>
#include <wtf/glib/WTFGType.h>
#include <wtf/text/CString.h>

using namespace WebKit;
using namespace WebCore;

/**
 * SECTION: WebKitAuthenticationRequest
 * @Short_description: Represents an authentication request
 * @Title: WebKitAuthenticationRequest
 * @See_also: #WebKitWebView
 *
 * Whenever a client attempts to load a page protected by HTTP
 * authentication, credentials will need to be provided to authorize access.
 * To allow the client to decide how it wishes to handle authentication,
 * WebKit will fire a #WebKitWebView::authenticate signal with a
 * WebKitAuthenticationRequest object to provide client side
 * authentication support. Credentials are exposed through the
 * #WebKitCredential object.
 *
 * In case the client application does not wish
 * to handle this signal WebKit will provide a default handler. To handle
 * authentication asynchronously, simply increase the reference count of the
 * WebKitAuthenticationRequest object.
 */

enum {
    CANCELLED,

    LAST_SIGNAL
};

struct _WebKitAuthenticationRequestPrivate {
    RefPtr<AuthenticationChallengeProxy> authenticationChallenge;
    bool privateBrowsingEnabled;
    bool handledRequest;
    CString host;
    CString realm;
};

static guint signals[LAST_SIGNAL] = { 0, };

WEBKIT_DEFINE_TYPE(WebKitAuthenticationRequest, webkit_authentication_request, G_TYPE_OBJECT)

static inline WebKitAuthenticationScheme toWebKitAuthenticationScheme(WebCore::ProtectionSpaceAuthenticationScheme coreScheme)
{
    switch (coreScheme) {
    case WebCore::ProtectionSpaceAuthenticationSchemeDefault:
        return WEBKIT_AUTHENTICATION_SCHEME_DEFAULT;
    case WebCore::ProtectionSpaceAuthenticationSchemeHTTPBasic:
        return WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC;
    case WebCore::ProtectionSpaceAuthenticationSchemeHTTPDigest:
        return WEBKIT_AUTHENTICATION_SCHEME_HTTP_DIGEST;
    case WebCore::ProtectionSpaceAuthenticationSchemeHTMLForm:
        return WEBKIT_AUTHENTICATION_SCHEME_HTML_FORM;
    case WebCore::ProtectionSpaceAuthenticationSchemeNTLM:
        return WEBKIT_AUTHENTICATION_SCHEME_NTLM;
    case WebCore::ProtectionSpaceAuthenticationSchemeNegotiate:
        return WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE;
    case WebCore::ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
        return WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED;
    case WebCore::ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
        return WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED;
    case WebCore::ProtectionSpaceAuthenticationSchemeUnknown:
        return WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN;
    default:
        ASSERT_NOT_REACHED();
        return WEBKIT_AUTHENTICATION_SCHEME_DEFAULT;
    }
}

static void webkitAuthenticationRequestDispose(GObject* object)
{
    WebKitAuthenticationRequest* request = WEBKIT_AUTHENTICATION_REQUEST(object);

    // Make sure the request is always handled before finalizing.
    if (!request->priv->handledRequest)
        webkit_authentication_request_cancel(request);

    G_OBJECT_CLASS(webkit_authentication_request_parent_class)->dispose(object);
}

static void webkit_authentication_request_class_init(WebKitAuthenticationRequestClass* requestClass)
{
    GObjectClass* objectClass = G_OBJECT_CLASS(requestClass);
    objectClass->dispose = webkitAuthenticationRequestDispose;

    /**
     * WebKitAuthenticationRequest::cancelled:
     * @request: the #WebKitAuthenticationRequest
     *
     * This signal is emitted when the user authentication request is
     * cancelled. It allows the application to dismiss its authentication
     * dialog in case of page load failure for example.
     *
     * Since: 2.2
     */
    signals[CANCELLED] =
        g_signal_new("cancelled",
            G_TYPE_FROM_CLASS(objectClass),
            G_SIGNAL_RUN_LAST,
            0, 0, 0,
            g_cclosure_marshal_VOID__VOID,
            G_TYPE_NONE, 0);
}

WebKitAuthenticationRequest* webkitAuthenticationRequestCreate(AuthenticationChallengeProxy* authenticationChallenge, bool privateBrowsingEnabled)
{
    WebKitAuthenticationRequest* request = WEBKIT_AUTHENTICATION_REQUEST(g_object_new(WEBKIT_TYPE_AUTHENTICATION_REQUEST, NULL));
    request->priv->authenticationChallenge = authenticationChallenge;
    request->priv->privateBrowsingEnabled = privateBrowsingEnabled;
    return request;
}

AuthenticationChallengeProxy* webkitAuthenticationRequestGetAuthenticationChallenge(WebKitAuthenticationRequest* request)
{
    return request->priv->authenticationChallenge.get();
}

/**
 * webkit_authentication_request_can_save_credentials:
 * @request: a #WebKitAuthenticationRequest
 *
 * Determine whether the authentication method associated with this
 * #WebKitAuthenticationRequest should allow the storage of credentials.
 * This will return %FALSE if WebKit doesn't support credential storing
 * or if private browsing is enabled.
 *
 * Returns: %TRUE if WebKit can store credentials or %FALSE otherwise.
 *
 * Since: 2.2
 */
gboolean webkit_authentication_request_can_save_credentials(WebKitAuthenticationRequest* request)
{
    g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), FALSE);

#if USE(LIBSECRET)
    return !request->priv->privateBrowsingEnabled;
#else
    return FALSE;
#endif
}

/**
 * webkit_authentication_request_get_proposed_credential:
 * @request: a #WebKitAuthenticationRequest
 *
 * Get the #WebKitCredential of the proposed authentication challenge that was
 * stored from a previous session. The client can use this directly for
 * authentication or construct their own #WebKitCredential.
 *
 * Returns: (transfer full): A #WebKitCredential encapsulating credential details
 * or %NULL if there is no stored credential.
 *
 * Since: 2.2
 */
WebKitCredential* webkit_authentication_request_get_proposed_credential(WebKitAuthenticationRequest* request)
{
    g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), 0);

    const auto& credential = request->priv->authenticationChallenge->core().proposedCredential();
    if (credential.isEmpty())
        return 0;

    return webkitCredentialCreate(credential);
}

/**
 * webkit_authentication_request_get_host:
 * @request: a #WebKitAuthenticationRequest
 *
 * Get the host that this authentication challenge is applicable to.
 *
 * Returns: The host of @request.
 *
 * Since: 2.2
 */
const gchar* webkit_authentication_request_get_host(WebKitAuthenticationRequest* request)
{
    g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), 0);

    if (request->priv->host.isNull())
        request->priv->host = request->priv->authenticationChallenge->core().protectionSpace().host().utf8();
    return request->priv->host.data();
}

/**
 * webkit_authentication_request_get_port:
 * @request: a #WebKitAuthenticationRequest
 *
 * Get the port that this authentication challenge is applicable to.
 *
 * Returns: The port of @request.
 *
 * Since: 2.2
 */
guint webkit_authentication_request_get_port(WebKitAuthenticationRequest* request)
{
    g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), 0);

    return request->priv->authenticationChallenge->core().protectionSpace().port();
}

/**
 * webkit_authentication_request_get_realm:
 * @request: a #WebKitAuthenticationRequest
 *
 * Get the realm that this authentication challenge is applicable to.
 *
 * Returns: The realm of @request.
 *
 * Since: 2.2
 */
const gchar* webkit_authentication_request_get_realm(WebKitAuthenticationRequest* request)
{
    g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), 0);

    if (request->priv->realm.isNull())
        request->priv->realm = request->priv->authenticationChallenge->core().protectionSpace().realm().utf8();
    return request->priv->realm.data();
}

/**
 * webkit_authentication_request_get_scheme:
 * @request: a #WebKitAuthenticationRequest
 *
 * Get the authentication scheme of the authentication challenge.
 *
 * Returns: The #WebKitAuthenticationScheme of @request.
 *
 * Since: 2.2
 */
WebKitAuthenticationScheme webkit_authentication_request_get_scheme(WebKitAuthenticationRequest* request)
{
    g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN);

    return toWebKitAuthenticationScheme(request->priv->authenticationChallenge->core().protectionSpace().authenticationScheme());
}

/**
 * webkit_authentication_request_is_for_proxy:
 * @request: a #WebKitAuthenticationRequest
 *
 * Determine whether the authentication challenge is associated with a proxy server rather than an "origin" server.
 *
 * Returns: %TRUE if authentication is for a proxy or %FALSE otherwise.
 *
 * Since: 2.2
 */
gboolean webkit_authentication_request_is_for_proxy(WebKitAuthenticationRequest* request)
{
    g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), FALSE);

    return request->priv->authenticationChallenge->core().protectionSpace().isProxy();
}

/**
 * webkit_authentication_request_is_retry:
 * @request: a #WebKitAuthenticationRequest
 *
 * Determine whether this this is a first attempt or a retry for this authentication challenge.
 *
 * Returns: %TRUE if authentication attempt is a retry or %FALSE otherwise.
 *
 * Since: 2.2
 */
gboolean webkit_authentication_request_is_retry(WebKitAuthenticationRequest* request)
{
    g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), 0);

    return request->priv->authenticationChallenge->core().previousFailureCount() ? TRUE : FALSE;
}

/**
 * webkit_authentication_request_authenticate:
 * @request: a #WebKitAuthenticationRequest
 * @credential: (transfer none) (allow-none): A #WebKitCredential, or %NULL
 *
 * Authenticate the #WebKitAuthenticationRequest using the #WebKitCredential
 * supplied. To continue without credentials, pass %NULL as @credential.
 *
 * Since: 2.2
 */
void webkit_authentication_request_authenticate(WebKitAuthenticationRequest* request, WebKitCredential* credential)
{
    g_return_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request));

    request->priv->authenticationChallenge->listener().completeChallenge(WebKit::AuthenticationChallengeDisposition::UseCredential, credential ? webkitCredentialGetCredential(credential) : WebCore::Credential());

    request->priv->handledRequest = true;
}

/**
 * webkit_authentication_request_cancel:
 * @request: a #WebKitAuthenticationRequest
 *
 * Cancel the authentication challenge. This will also cancel the page loading and result in a
 * #WebKitWebView::load-failed signal with a #WebKitNetworkError of type %WEBKIT_NETWORK_ERROR_CANCELLED being emitted.
 *
 * Since: 2.2
 */
void webkit_authentication_request_cancel(WebKitAuthenticationRequest* request)
{
    g_return_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request));

    request->priv->authenticationChallenge->listener().completeChallenge(WebKit::AuthenticationChallengeDisposition::Cancel);

    g_signal_emit(request, signals[CANCELLED], 0);
}
