aboutsummaryrefslogblamecommitdiffstats
path: root/libemail-engine/e-mail-authenticator.c
blob: 9729d35e1fe8e5088cc452201bba1e63fa5fa6ba (plain) (tree)










































































































































































































































































                                                                              
/*
 * e-mail-authenticator.c
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) version 3.
 *
 * This program 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with the program; if not, see <http://www.gnu.org/licenses/>
 *
 */

#include "e-mail-authenticator.h"

#include <config.h>
#include <glib/gi18n-lib.h>

#define E_MAIL_AUTHENTICATOR_GET_PRIVATE(obj) \
    (G_TYPE_INSTANCE_GET_PRIVATE \
    ((obj), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticatorPrivate))

struct _EMailAuthenticatorPrivate {
    CamelService *service;
    gchar *mechanism;
};

enum {
    PROP_0,
    PROP_MECHANISM,
    PROP_SERVICE
};

/* Forward Declarations */
static void e_mail_authenticator_interface_init
                (ESourceAuthenticatorInterface *interface);

G_DEFINE_TYPE_WITH_CODE (
    EMailAuthenticator,
    e_mail_authenticator,
    G_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE (
        E_TYPE_SOURCE_AUTHENTICATOR,
        e_mail_authenticator_interface_init))

static void
mail_authenticator_set_mechanism (EMailAuthenticator *auth,
                                  const gchar *mechanism)
{
    g_return_if_fail (auth->priv->mechanism == NULL);

    auth->priv->mechanism = g_strdup (mechanism);
}

static void
mail_authenticator_set_service (EMailAuthenticator *auth,
                                CamelService *service)
{
    g_return_if_fail (CAMEL_IS_SERVICE (service));
    g_return_if_fail (auth->priv->service == NULL);

    auth->priv->service = g_object_ref (service);
}

static void
mail_authenticator_set_property (GObject *object,
                                 guint property_id,
                                 const GValue *value,
                                 GParamSpec *pspec)
{
    switch (property_id) {
        case PROP_MECHANISM:
            mail_authenticator_set_mechanism (
                E_MAIL_AUTHENTICATOR (object),
                g_value_get_string (value));
            return;

        case PROP_SERVICE:
            mail_authenticator_set_service (
                E_MAIL_AUTHENTICATOR (object),
                g_value_get_object (value));
            return;
    }

    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}

static void
mail_authenticator_get_property (GObject *object,
                                 guint property_id,
                                 GValue *value,
                                 GParamSpec *pspec)
{
    switch (property_id) {
        case PROP_MECHANISM:
            g_value_set_string (
                value,
                e_mail_authenticator_get_mechanism (
                E_MAIL_AUTHENTICATOR (object)));
            return;

        case PROP_SERVICE:
            g_value_set_object (
                value,
                e_mail_authenticator_get_service (
                E_MAIL_AUTHENTICATOR (object)));
            return;
    }

    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}

static void
mail_authenticator_dispose (GObject *object)
{
    EMailAuthenticatorPrivate *priv;

    priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (object);

    if (priv->service != NULL) {
        g_object_unref (priv->service);
        priv->service = NULL;
    }

    /* Chain up to parent's dispose() method. */
    G_OBJECT_CLASS (e_mail_authenticator_parent_class)->dispose (object);
}

static void
mail_authenticator_finalize (GObject *object)
{
    EMailAuthenticatorPrivate *priv;

    priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (object);

    g_free (priv->mechanism);

    /* Chain up to parent's finalize() method. */
    G_OBJECT_CLASS (e_mail_authenticator_parent_class)->finalize (object);
}

static ESourceAuthenticationResult
mail_authenticator_try_password_sync (ESourceAuthenticator *auth,
                                      const GString *password,
                                      GCancellable *cancellable,
                                      GError **error)
{
    CamelService *service;
    EMailAuthenticator *mail_auth;
    CamelAuthenticationResult camel_result;
    ESourceAuthenticationResult source_result;
    const gchar *mechanism;

    mail_auth = E_MAIL_AUTHENTICATOR (auth);
    service = e_mail_authenticator_get_service (mail_auth);
    mechanism = e_mail_authenticator_get_mechanism (mail_auth);

    camel_service_set_password (service, password->str);

    camel_result = camel_service_authenticate_sync (
        service, mechanism, cancellable, error);

    switch (camel_result) {
        case CAMEL_AUTHENTICATION_ERROR:
            source_result = E_SOURCE_AUTHENTICATION_ERROR;
            break;
        case CAMEL_AUTHENTICATION_ACCEPTED:
            source_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
            break;
        case CAMEL_AUTHENTICATION_REJECTED:
            source_result = E_SOURCE_AUTHENTICATION_REJECTED;
            break;
        default:
            g_set_error (
                error, CAMEL_SERVICE_ERROR,
                CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
                _("Invalid authentication result code (%d)"),
                camel_result);
            source_result = E_SOURCE_AUTHENTICATION_ERROR;
            break;
    }

    return source_result;
}

static void
e_mail_authenticator_class_init (EMailAuthenticatorClass *class)
{
    GObjectClass *object_class;

    g_type_class_add_private (class, sizeof (EMailAuthenticatorPrivate));

    object_class = G_OBJECT_CLASS (class);
    object_class->set_property = mail_authenticator_set_property;
    object_class->get_property = mail_authenticator_get_property;
    object_class->dispose = mail_authenticator_dispose;
    object_class->finalize = mail_authenticator_finalize;

    g_object_class_install_property (
        object_class,
        PROP_MECHANISM,
        g_param_spec_string (
            "mechanism",
            "Mechanism",
            "Authentication mechanism",
            NULL,
            G_PARAM_READWRITE |
            G_PARAM_CONSTRUCT_ONLY |
            G_PARAM_STATIC_STRINGS));

    g_object_class_install_property (
        object_class,
        PROP_SERVICE,
        g_param_spec_object (
            "service",
            "Service",
            "The CamelService to authenticate",
            CAMEL_TYPE_SERVICE,
            G_PARAM_READWRITE |
            G_PARAM_CONSTRUCT_ONLY |
            G_PARAM_STATIC_STRINGS));
}

static void
e_mail_authenticator_interface_init (ESourceAuthenticatorInterface *interface)
{
    interface->try_password_sync = mail_authenticator_try_password_sync;
}

static void
e_mail_authenticator_init (EMailAuthenticator *auth)
{
    auth->priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (auth);
}

ESourceAuthenticator *
e_mail_authenticator_new (CamelService *service,
                          const gchar *mechanism)
{
    g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL);

    return g_object_new (
        E_TYPE_MAIL_AUTHENTICATOR,
        "service", service, "mechanism", mechanism, NULL);
}

CamelService *
e_mail_authenticator_get_service (EMailAuthenticator *auth)
{
    g_return_val_if_fail (E_IS_MAIL_AUTHENTICATOR (auth), NULL);

    return auth->priv->service;
}

const gchar *
e_mail_authenticator_get_mechanism (EMailAuthenticator *auth)
{
    g_return_val_if_fail (E_IS_MAIL_AUTHENTICATOR (auth), NULL);

    return auth->priv->mechanism;
}