From 551bcffa0abb103ec733ec8d2cf84d0631618dc9 Mon Sep 17 00:00:00 2001 From: John Brooks Date: Fri, 7 Dec 2012 13:04:16 -0700 Subject: [PATCH] Add mcp-account-manager-uoa from Empathy --- README | 9 +- mcp-account-manager-uoa/config.h | 0 .../empathy-webcredentials-monitor.c | 283 ++++++ .../empathy-webcredentials-monitor.h | 59 ++ .../mcp-account-manager-uoa.c | 834 ++++++++++++++++++ .../mcp-account-manager-uoa.h | 68 ++ .../mcp-account-manager-uoa.pro | 16 + .../mission-control-plugin.c | 47 + telepathy-accounts-signon.pro | 4 + telepathy-sasl-signon.pro | 41 - .../SaslSignonAuth.client | 0 .../empathy-auth-client.c | 0 .../empathy-auth-factory.c | 0 .../empathy-auth-factory.h | 0 .../empathy-debug.h | 0 .../empathy-keyring.c | 0 .../empathy-keyring.h | 0 .../empathy-sasl-mechanisms.c | 0 .../empathy-sasl-mechanisms.h | 0 .../empathy-server-sasl-handler.c | 0 .../empathy-server-sasl-handler.h | 0 .../empathy-server-tls-handler.c | 0 .../empathy-server-tls-handler.h | 0 .../empathy-uoa-auth-handler.c | 0 .../empathy-uoa-auth-handler.h | 0 .../empathy-uoa-utils.c | 0 .../empathy-uoa-utils.h | 0 .../empathy-utils.h | 0 ...op.Telepathy.Client.SaslSignonAuth.service | 0 .../telepathy-sasl-signon.pro | 41 + 30 files changed, 1356 insertions(+), 46 deletions(-) create mode 100644 mcp-account-manager-uoa/config.h create mode 100644 mcp-account-manager-uoa/empathy-webcredentials-monitor.c create mode 100644 mcp-account-manager-uoa/empathy-webcredentials-monitor.h create mode 100644 mcp-account-manager-uoa/mcp-account-manager-uoa.c create mode 100644 mcp-account-manager-uoa/mcp-account-manager-uoa.h create mode 100644 mcp-account-manager-uoa/mcp-account-manager-uoa.pro create mode 100644 mcp-account-manager-uoa/mission-control-plugin.c create mode 100644 telepathy-accounts-signon.pro delete mode 100644 telepathy-sasl-signon.pro rename SaslSignonAuth.client => telepathy-sasl-signon/SaslSignonAuth.client (100%) rename {src => telepathy-sasl-signon}/empathy-auth-client.c (100%) rename {src => telepathy-sasl-signon}/empathy-auth-factory.c (100%) rename {src => telepathy-sasl-signon}/empathy-auth-factory.h (100%) rename {src => telepathy-sasl-signon}/empathy-debug.h (100%) rename {src => telepathy-sasl-signon}/empathy-keyring.c (100%) rename {src => telepathy-sasl-signon}/empathy-keyring.h (100%) rename {src => telepathy-sasl-signon}/empathy-sasl-mechanisms.c (100%) rename {src => telepathy-sasl-signon}/empathy-sasl-mechanisms.h (100%) rename {src => telepathy-sasl-signon}/empathy-server-sasl-handler.c (100%) rename {src => telepathy-sasl-signon}/empathy-server-sasl-handler.h (100%) rename {src => telepathy-sasl-signon}/empathy-server-tls-handler.c (100%) rename {src => telepathy-sasl-signon}/empathy-server-tls-handler.h (100%) rename {src => telepathy-sasl-signon}/empathy-uoa-auth-handler.c (100%) rename {src => telepathy-sasl-signon}/empathy-uoa-auth-handler.h (100%) rename {src => telepathy-sasl-signon}/empathy-uoa-utils.c (100%) rename {src => telepathy-sasl-signon}/empathy-uoa-utils.h (100%) rename {src => telepathy-sasl-signon}/empathy-utils.h (100%) rename org.freedesktop.Telepathy.Client.SaslSignonAuth.service => telepathy-sasl-signon/org.freedesktop.Telepathy.Client.SaslSignonAuth.service (100%) create mode 100644 telepathy-sasl-signon/telepathy-sasl-signon.pro diff --git a/README b/README index 9cbb874..6bef046 100644 --- a/README +++ b/README @@ -1,8 +1,7 @@ -This is a telepathy authentication handler using libaccounts and libsignon, -kindly borrowed from Empathy's ubuntu-online-account support. Along with a -mission-control plugin (not included) providing a bridge between libaccounts -and telepathy, this allows proper use of libaccounts and libsignon to control -telepathy accounts. +A mission control plugin and authentication handler for Telepathy, integrating +with libaccounts and libsignon to provide IM accounts and authentication. +This code is kindly borrowed from Empathy's ubuntu-online-account support, +but not intended to keep compatibility with UOA. The code is deliberately kept mostly similar to the upstream empathy code for now, since there's limited effort towards maintaining it separately. diff --git a/mcp-account-manager-uoa/config.h b/mcp-account-manager-uoa/config.h new file mode 100644 index 0000000..e69de29 diff --git a/mcp-account-manager-uoa/empathy-webcredentials-monitor.c b/mcp-account-manager-uoa/empathy-webcredentials-monitor.c new file mode 100644 index 0000000..439bbda --- /dev/null +++ b/mcp-account-manager-uoa/empathy-webcredentials-monitor.c @@ -0,0 +1,283 @@ +#include "config.h" + +#include + +#include + +#include + +#include "empathy-webcredentials-monitor.h" + +G_DEFINE_TYPE (EmpathyWebcredentialsMonitor, empathy_webcredentials_monitor, G_TYPE_OBJECT) + +#define WEBCRED_BUS_NAME "com.canonical.indicators.webcredentials" +#define WEBCRED_PATH "/com/canonical/indicators/webcredentials" +#define WEBCRED_IFACE "com.canonical.indicators.webcredentials" + +#define FAILURES_PROP "Failures" + +enum +{ + PROP_MANAGER = 1, + N_PROPS +}; + +enum +{ + SIG_FAILURE_ADDED, + SIG_FAILURE_REMOVED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +struct _EmpathyWebcredentialsMonitorPriv +{ + AgManager *manager; + GDBusProxy *proxy; + + /* array of owned AgAccount */ + GPtrArray *failures; +}; + +static void +empathy_webcredentials_monitor_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object); + + switch (property_id) + { + case PROP_MANAGER: + g_value_set_object (value, self->priv->manager); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +empathy_webcredentials_monitor_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object); + + switch (property_id) + { + case PROP_MANAGER: + g_assert (self->priv->manager == NULL); /* construct only */ + self->priv->manager = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +empathy_webcredentials_monitor_constructed (GObject *object) +{ + EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object); + void (*chain_up) (GObject *) = + ((GObjectClass *) empathy_webcredentials_monitor_parent_class)->constructed; + + chain_up (object); + + g_assert (AG_IS_MANAGER (self->priv->manager)); +} + +static void +empathy_webcredentials_monitor_dispose (GObject *object) +{ + EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object); + void (*chain_up) (GObject *) = + ((GObjectClass *) empathy_webcredentials_monitor_parent_class)->dispose; + + g_clear_object (&self->priv->manager); + g_clear_object (&self->priv->proxy); + + chain_up (object); +} + +static void +empathy_webcredentials_monitor_finalize (GObject *object) +{ + EmpathyWebcredentialsMonitor *self = EMPATHY_WEBCREDENTIALS_MONITOR (object); + void (*chain_up) (GObject *) = + ((GObjectClass *) empathy_webcredentials_monitor_parent_class)->finalize; + + g_ptr_array_unref (self->priv->failures); + + chain_up (object); +} + +static void +empathy_webcredentials_monitor_class_init ( + EmpathyWebcredentialsMonitorClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GParamSpec *spec; + + oclass->get_property = empathy_webcredentials_monitor_get_property; + oclass->set_property = empathy_webcredentials_monitor_set_property; + oclass->constructed = empathy_webcredentials_monitor_constructed; + oclass->dispose = empathy_webcredentials_monitor_dispose; + oclass->finalize = empathy_webcredentials_monitor_finalize; + + spec = g_param_spec_object ("manager", "Manager", + "AgManager", + AG_TYPE_MANAGER, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_MANAGER, spec); + + signals[SIG_FAILURE_ADDED] = g_signal_new ("failure-added", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 1, AG_TYPE_ACCOUNT); + + signals[SIG_FAILURE_REMOVED] = g_signal_new ("failure-removed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 1, AG_TYPE_ACCOUNT); + + g_type_class_add_private (klass, sizeof (EmpathyWebcredentialsMonitorPriv)); +} + +static void +update_failures (EmpathyWebcredentialsMonitor *self) +{ + GVariant *failures, *f; + GVariantIter iter; + GList *new_list = NULL; + guint i; + + failures = g_dbus_proxy_get_cached_property (self->priv->proxy, + FAILURES_PROP); + if (failures == NULL) + { + g_debug ("Does not implement Failures property"); + return; + } + + g_variant_iter_init (&iter, failures); + while ((f = g_variant_iter_next_value (&iter)) != NULL) + { + guint32 id; + AgAccount *account; + + id = g_variant_get_uint32 (f); + + account = ag_manager_get_account (self->priv->manager, id); + if (account == NULL) + continue; + + /* Pass ownership of 'account' to the list */ + new_list = g_list_append (new_list, account); + + if (!tp_g_ptr_array_contains (self->priv->failures, account)) + { + g_ptr_array_add (self->priv->failures, g_object_ref (account)); + + g_signal_emit (self, signals[SIG_FAILURE_ADDED], 0, account); + } + + g_variant_unref (f); + } + + g_variant_unref (failures); + + for (i = 0; i < self->priv->failures->len; i++) + { + AgAccount *account = g_ptr_array_index (self->priv->failures, i); + + if (g_list_find (new_list, account) == NULL) + { + g_object_ref (account); + g_ptr_array_remove (self->priv->failures, account); + + g_signal_emit (self, signals[SIG_FAILURE_REMOVED], 0, account); + g_object_unref (account); + } + } + + g_list_free_full (new_list, g_object_unref); +} + +static void +properties_changed_cb (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + EmpathyWebcredentialsMonitor *self) +{ + if (g_variant_lookup_value (changed_properties, FAILURES_PROP, NULL) == NULL) + return; + + update_failures (self); +} + +static void +proxy_new_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyWebcredentialsMonitor *self; + TpWeakRef *wr = user_data; + GError *error = NULL; + + self = tp_weak_ref_dup_object (wr); + if (self == NULL) + goto out; + + self->priv->proxy = g_dbus_proxy_new_for_bus_finish (result, &error); + if (self->priv->proxy == NULL) + { + g_debug ("Failed to create webcredentials proxy: %s", error->message); + g_error_free (error); + goto out; + } + + update_failures (self); + + g_signal_connect (self->priv->proxy, "g-properties-changed", + G_CALLBACK (properties_changed_cb), self); + +out: + tp_weak_ref_destroy (wr); + g_clear_object (&self); +} + +static void +empathy_webcredentials_monitor_init (EmpathyWebcredentialsMonitor *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + EMPATHY_TYPE_WEBCREDENTIALS_MONITOR, EmpathyWebcredentialsMonitorPriv); + + self->priv->failures = g_ptr_array_new_with_free_func (g_object_unref); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, + WEBCRED_BUS_NAME, WEBCRED_PATH, WEBCRED_IFACE, + NULL, proxy_new_cb, tp_weak_ref_new (self, NULL, NULL)); +} + +EmpathyWebcredentialsMonitor * +empathy_webcredentials_monitor_new (AgManager *manager) +{ + return g_object_new (EMPATHY_TYPE_WEBCREDENTIALS_MONITOR, + "manager", manager, + NULL); +} + +GPtrArray * +empathy_webcredentials_get_failures (EmpathyWebcredentialsMonitor *self) +{ + return self->priv->failures; +} diff --git a/mcp-account-manager-uoa/empathy-webcredentials-monitor.h b/mcp-account-manager-uoa/empathy-webcredentials-monitor.h new file mode 100644 index 0000000..cf373a2 --- /dev/null +++ b/mcp-account-manager-uoa/empathy-webcredentials-monitor.h @@ -0,0 +1,59 @@ +#ifndef __EMPATHY_WEBCREDENTIALS_MONITOR_H__ +#define __EMPATHY_WEBCREDENTIALS_MONITOR_H__ + +#include + +#include + +G_BEGIN_DECLS + +typedef struct _EmpathyWebcredentialsMonitor EmpathyWebcredentialsMonitor; +typedef struct _EmpathyWebcredentialsMonitorClass EmpathyWebcredentialsMonitorClass; +typedef struct _EmpathyWebcredentialsMonitorPriv EmpathyWebcredentialsMonitorPriv; + +struct _EmpathyWebcredentialsMonitorClass +{ + /**/ + GObjectClass parent_class; +}; + +struct _EmpathyWebcredentialsMonitor +{ + /**/ + GObject parent; + EmpathyWebcredentialsMonitorPriv *priv; +}; + +GType empathy_webcredentials_monitor_get_type (void); + +/* TYPE MACROS */ +#define EMPATHY_TYPE_WEBCREDENTIALS_MONITOR \ + (empathy_webcredentials_monitor_get_type ()) +#define EMPATHY_WEBCREDENTIALS_MONITOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + EMPATHY_TYPE_WEBCREDENTIALS_MONITOR, \ + EmpathyWebcredentialsMonitor)) +#define EMPATHY_WEBCREDENTIALS_MONITOR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + EMPATHY_TYPE_WEBCREDENTIALS_MONITOR, \ + EmpathyWebcredentialsMonitorClass)) +#define EMPATHY_IS_WEBCREDENTIALS_MONITOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + EMPATHY_TYPE_WEBCREDENTIALS_MONITOR)) +#define EMPATHY_IS_WEBCREDENTIALS_MONITOR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), \ + EMPATHY_TYPE_WEBCREDENTIALS_MONITOR)) +#define EMPATHY_WEBCREDENTIALS_MONITOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + EMPATHY_TYPE_WEBCREDENTIALS_MONITOR, \ + EmpathyWebcredentialsMonitorClass)) + +EmpathyWebcredentialsMonitor * empathy_webcredentials_monitor_new ( + AgManager *manager); + +GPtrArray * empathy_webcredentials_get_failures ( + EmpathyWebcredentialsMonitor *self); + +G_END_DECLS + +#endif /* #ifndef __EMPATHY_WEBCREDENTIALS_MONITOR_H__*/ diff --git a/mcp-account-manager-uoa/mcp-account-manager-uoa.c b/mcp-account-manager-uoa/mcp-account-manager-uoa.c new file mode 100644 index 0000000..93cf723 --- /dev/null +++ b/mcp-account-manager-uoa/mcp-account-manager-uoa.c @@ -0,0 +1,834 @@ +/* + * Copyright © 2012 Collabora Ltd. + * + * This library 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.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "mcp-account-manager-uoa.h" + +#include + +#include +#include +#include +#include + +#include +#include + +#include "empathy-webcredentials-monitor.h" + +#define EMPATHY_UOA_PROVIDER "im.telepathy.Account.Storage.UOA" + +#define PLUGIN_NAME "uoa" +#define PLUGIN_PRIORITY (MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_KEYRING + 10) +#define PLUGIN_DESCRIPTION "Provide Telepathy Accounts from UOA via libaccounts-glib" +#define PLUGIN_PROVIDER EMPATHY_UOA_PROVIDER + +#define DEBUG g_debug + +#define SERVICE_TYPE "IM" +#define KEY_PREFIX "telepathy/" +#define KEY_ACCOUNT_NAME "mc-account-name" +#define KEY_READONLY_PARAMS "mc-readonly-params" + +static void account_storage_iface_init (McpAccountStorageIface *iface); + +G_DEFINE_TYPE_WITH_CODE (McpAccountManagerUoa, mcp_account_manager_uoa, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (MCP_TYPE_ACCOUNT_STORAGE, + account_storage_iface_init)); + +struct _McpAccountManagerUoaPrivate +{ + McpAccountManager *am; + + AgManager *manager; + EmpathyWebcredentialsMonitor *monitor; + + /* alloc'ed string -> ref'ed AgAccountService + * The key is the account_name, an MC unique identifier. + * Note: There could be multiple services in this table having the same + * AgAccount, even if unlikely. */ + GHashTable *accounts; + + /* Queue of owned DelayedSignalData */ + GQueue *pending_signals; + + gboolean loaded; + gboolean ready; +}; + +typedef enum { + DELAYED_CREATE, + DELAYED_DELETE, +} DelayedSignal; + +typedef struct { + DelayedSignal signal; + AgAccountId account_id; +} DelayedSignalData; + + +static gchar * +_service_dup_tp_value (AgAccountService *service, + const gchar *key) +{ + gchar *real_key = g_strdup_printf (KEY_PREFIX "%s", key); + GValue value = { 0, }; + gchar *ret; + + g_value_init (&value, G_TYPE_STRING); + ag_account_service_get_value (service, real_key, &value); + ret = g_value_dup_string (&value); + g_value_unset (&value); + + return ret; +} + +static void +_service_set_tp_value (AgAccountService *service, + const gchar *key, + const gchar *value) +{ + gchar *real_key = g_strdup_printf (KEY_PREFIX "%s", key); + + if (value != NULL) + { + GValue gvalue = { 0, }; + + g_value_init (&gvalue, G_TYPE_STRING); + g_value_set_string (&gvalue, value); + ag_account_service_set_value (service, real_key, &gvalue); + g_value_unset (&gvalue); + g_free (real_key); + } + else + { + ag_account_service_set_value (service, real_key, NULL); + } +} + +/* Returns NULL if the account never has been imported into MC before */ +static gchar * +_service_dup_tp_account_name (AgAccountService *service) +{ + return _service_dup_tp_value (service, KEY_ACCOUNT_NAME); +} + +static void +_service_set_tp_account_name (AgAccountService *service, + const gchar *account_name) +{ + _service_set_tp_value (service, KEY_ACCOUNT_NAME, account_name); +} + +static void +_service_enabled_cb (AgAccountService *service, + gboolean enabled, + McpAccountManagerUoa *self) +{ + gchar *account_name = _service_dup_tp_account_name (service); + + if (!self->priv->ready || account_name == NULL) + return; + + DEBUG ("UOA account %s toggled: %s", account_name, + enabled ? "enabled" : "disabled"); + + g_signal_emit_by_name (self, "toggled", account_name, enabled); + + g_free (account_name); +} + +static void +_service_changed_cb (AgAccountService *service, + McpAccountManagerUoa *self) +{ + gchar *account_name = _service_dup_tp_account_name (service); + + if (!self->priv->ready || account_name == NULL) + return; + + DEBUG ("UOA account %s changed", account_name); + + /* FIXME: Could use ag_account_service_get_changed_fields() + * and emit "altered-one" */ + g_signal_emit_by_name (self, "altered", account_name); + + g_free (account_name); +} + +static void +_account_stored_cb (AgAccount *account, + const GError *error, + gpointer user_data) +{ + if (error != NULL) + { + DEBUG ("Error storing UOA account '%s': %s", + ag_account_get_display_name (account), + error->message); + } +} + +static gboolean +_add_service (McpAccountManagerUoa *self, + AgAccountService *service, + const gchar *account_name) +{ + DEBUG ("UOA account %s added", account_name); + + if (g_hash_table_contains (self->priv->accounts, account_name)) + { + DEBUG ("Already exists, ignoring"); + return FALSE; + } + + g_hash_table_insert (self->priv->accounts, + g_strdup (account_name), + g_object_ref (service)); + + g_signal_connect (service, "enabled", + G_CALLBACK (_service_enabled_cb), self); + g_signal_connect (service, "changed", + G_CALLBACK (_service_changed_cb), self); + + return TRUE; +} + +static void +_account_created_cb (AgManager *manager, + AgAccountId id, + McpAccountManagerUoa *self) +{ + AgAccount *account; + GList *l; + + if (!self->priv->ready) + { + DelayedSignalData *data = g_slice_new0 (DelayedSignalData); + + data->signal = DELAYED_CREATE; + data->account_id = id; + + g_queue_push_tail (self->priv->pending_signals, data); + return; + } + + account = ag_manager_get_account (self->priv->manager, id); + + l = ag_account_list_services_by_type (account, SERVICE_TYPE); + while (l != NULL) + { + AgAccountService *service = ag_account_service_new (account, l->data); + gchar *account_name = _service_dup_tp_account_name (service); + + /* If this is the first time we see this service, we have to generate an + * account_name for it. */ + if (account_name == NULL) + { + gchar *cm_name = NULL; + gchar *protocol_name = NULL; + gchar *account_param = NULL; + + cm_name = _service_dup_tp_value (service, "manager"); + protocol_name = _service_dup_tp_value (service, "protocol"); + account_param = _service_dup_tp_value (service, "param-account"); + + if (!tp_str_empty (cm_name) && + !tp_str_empty (protocol_name) && + !tp_str_empty (account_param)) + { + GHashTable *params; + + params = tp_asv_new ( + "account", G_TYPE_STRING, account_param, + NULL); + + account_name = mcp_account_manager_get_unique_name (self->priv->am, + cm_name, protocol_name, params); + _service_set_tp_account_name (service, account_name); + + ag_account_store (account, _account_stored_cb, self); + + g_hash_table_unref (params); + } + + g_free (cm_name); + g_free (protocol_name); + g_free (account_param); + } + + if (account_name != NULL) + { + if (_add_service (self, service, account_name)) + g_signal_emit_by_name (self, "created", account_name); + } + + g_free (account_name); + g_object_unref (service); + ag_service_unref (l->data); + l = g_list_delete_link (l, l); + } + + g_object_unref (account); +} + +static void +_account_deleted_cb (AgManager *manager, + AgAccountId id, + McpAccountManagerUoa *self) +{ + GHashTableIter iter; + gpointer value; + + if (!self->priv->ready) + { + DelayedSignalData *data = g_slice_new0 (DelayedSignalData); + + data->signal = DELAYED_DELETE; + data->account_id = id; + + g_queue_push_tail (self->priv->pending_signals, data); + return; + } + + g_hash_table_iter_init (&iter, self->priv->accounts); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + AgAccountService *service = value; + AgAccount *account = ag_account_service_get_account (service); + gchar *account_name; + + if (account->id != id) + continue; + + account_name = _service_dup_tp_account_name (service); + if (account_name == NULL) + continue; + + DEBUG ("UOA account %s deleted", account_name); + + g_hash_table_iter_remove (&iter); + g_signal_emit_by_name (self, "deleted", account_name); + + g_free (account_name); + } +} + +static void +mcp_account_manager_uoa_dispose (GObject *object) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) object; + + tp_clear_object (&self->priv->am); + tp_clear_object (&self->priv->manager); + tp_clear_pointer (&self->priv->accounts, g_hash_table_unref); + tp_clear_object (&self->priv->monitor); + + G_OBJECT_CLASS (mcp_account_manager_uoa_parent_class)->dispose (object); +} + +static void +mcp_account_manager_uoa_init (McpAccountManagerUoa *self) +{ + DEBUG ("UOA MC plugin initialised"); + + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + MCP_TYPE_ACCOUNT_MANAGER_UOA, McpAccountManagerUoaPrivate); + + self->priv->accounts = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_object_unref); + self->priv->pending_signals = g_queue_new (); + + self->priv->manager = ag_manager_new_for_service_type (SERVICE_TYPE); + g_return_if_fail (self->priv->manager != NULL); + + g_signal_connect (self->priv->manager, "account-created", + G_CALLBACK (_account_created_cb), self); + g_signal_connect (self->priv->manager, "account-deleted", + G_CALLBACK (_account_deleted_cb), self); + + self->priv->monitor = empathy_webcredentials_monitor_new ( + self->priv->manager); +} + +static void +mcp_account_manager_uoa_class_init (McpAccountManagerUoaClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = mcp_account_manager_uoa_dispose; + + g_type_class_add_private (gobject_class, + sizeof (McpAccountManagerUoaPrivate)); +} + +static void +_ensure_loaded (McpAccountManagerUoa *self) +{ + GList *services; + + if (self->priv->loaded) + return; + + self->priv->loaded = TRUE; + + g_assert (!self->priv->ready); + + services = ag_manager_get_account_services (self->priv->manager); + while (services != NULL) + { + AgAccountService *service = services->data; + AgAccount *account = ag_account_service_get_account (service); + gchar *account_name = _service_dup_tp_account_name (service); + + if (account_name != NULL) + { + /* This service was already known, we can add it now */ + _add_service (self, service, account_name); + g_free (account_name); + } + else + { + DelayedSignalData *data = g_slice_new0 (DelayedSignalData); + + /* This service was created while MC was not running, delay its + * creation until MC is ready */ + data->signal = DELAYED_CREATE; + data->account_id = account->id; + + g_queue_push_tail (self->priv->pending_signals, data); + } + + g_object_unref (services->data); + services = g_list_delete_link (services, services); + } +} + +static GList * +account_manager_uoa_list (const McpAccountStorage *storage, + const McpAccountManager *am) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + GList *accounts = NULL; + GHashTableIter iter; + gpointer key; + + DEBUG (G_STRFUNC); + + g_return_val_if_fail (self->priv->manager != NULL, NULL); + + _ensure_loaded (self); + + g_hash_table_iter_init (&iter, self->priv->accounts); + while (g_hash_table_iter_next (&iter, &key, NULL)) + accounts = g_list_prepend (accounts, g_strdup (key)); + + return accounts; +} + +static const gchar * +provider_to_tp_service_name (const gchar *provider_name) +{ + /* Well known services are defined in Telepathy spec: + * http://telepathy.freedesktop.org/spec/Account.html#Property:Service */ + if (!tp_strdiff (provider_name, "google")) + return "google-talk"; + + return provider_name; +} + +static gboolean +account_manager_uoa_get (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *account_name, + const gchar *key) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + AgAccountService *service; + AgAccount *account; + AgService *s; + gboolean handled = FALSE; + + g_return_val_if_fail (self->priv->manager != NULL, FALSE); + + service = g_hash_table_lookup (self->priv->accounts, account_name); + if (service == NULL) + return FALSE; + + DEBUG ("%s: %s, %s", G_STRFUNC, account_name, key); + + account = ag_account_service_get_account (service); + s = ag_account_service_get_service (service); + + /* NULL key means we want all settings */ + if (key == NULL) + { + AgAccountSettingIter iter; + const gchar *k; + const GValue *v; + + ag_account_service_settings_iter_init (service, &iter, KEY_PREFIX); + while (ag_account_service_settings_iter_next (&iter, &k, &v)) + { + if (!G_VALUE_HOLDS_STRING (v)) + continue; + + mcp_account_manager_set_value (am, account_name, + k, g_value_get_string (v)); + } + } + + /* Some special keys that are not stored in setting */ + if (key == NULL || !tp_strdiff (key, "Enabled")) + { + mcp_account_manager_set_value (am, account_name, "Enabled", + ag_account_service_get_enabled (service) ? "true" : "false"); + handled = TRUE; + } + + if (key == NULL || !tp_strdiff (key, "DisplayName")) + { + mcp_account_manager_set_value (am, account_name, "DisplayName", + ag_account_get_display_name (account)); + handled = TRUE; + } + + if (key == NULL || !tp_strdiff (key, "Service")) + { + mcp_account_manager_set_value (am, account_name, "Service", + provider_to_tp_service_name (ag_account_get_provider_name (account))); + handled = TRUE; + } + + if (key == NULL || !tp_strdiff (key, "Icon")) + { + mcp_account_manager_set_value (am, account_name, "Icon", + ag_service_get_icon_name (s)); + handled = TRUE; + } + + /* If it was none of the above, then just lookup in service' settings */ + if (!handled) + { + gchar *value = _service_dup_tp_value (service, key); + + mcp_account_manager_set_value (am, account_name, key, value); + g_free (value); + } + + return TRUE; +} + +static gboolean +account_manager_uoa_set (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *account_name, + const gchar *key, + const gchar *val) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + AgAccountService *service; + AgAccount *account; + + g_return_val_if_fail (self->priv->manager != NULL, FALSE); + + service = g_hash_table_lookup (self->priv->accounts, account_name); + if (service == NULL) + return FALSE; + + account = ag_account_service_get_account (service); + + DEBUG ("%s: %s, %s, %s", G_STRFUNC, account_name, key, val); + + if (!tp_strdiff (key, "Enabled")) + { + /* Enabled is a global setting on the account, not per-services, + * unfortunately */ + ag_account_select_service (account, NULL); + ag_account_set_enabled (account, !tp_strdiff (val, "true")); + } + else if (!tp_strdiff (key, "DisplayName")) + { + ag_account_set_display_name (account, val); + } + else + { + _service_set_tp_value (service, key, val); + } + + return TRUE; +} + +static gchar * +account_manager_uoa_create (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *cm_name, + const gchar *protocol_name, + GHashTable *params, + GError **error) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + gchar *account_name; + AgAccount *account; + AgAccountService *service; + GList *l; + + g_return_val_if_fail (self->priv->manager != NULL, NULL); + + if (!self->priv->ready) + { + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "Cannot create account before being ready"); + return NULL; + } + + DEBUG (G_STRFUNC); + + /* Create a new AgAccountService and keep it internally. This won't save it + * into persistent storage until account_manager_uoa_commit() is called. + * We assume there is only one IM service */ + account = ag_manager_create_account (self->priv->manager, protocol_name); + l = ag_account_list_services_by_type (account, SERVICE_TYPE); + if (l == NULL) + { + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "Cannot create a %s service for %s provider", + SERVICE_TYPE, protocol_name); + g_object_unref (account); + return NULL; + } + service = ag_account_service_new (account, l->data); + ag_service_list_free (l); + g_object_unref (account); + + account_name = mcp_account_manager_get_unique_name (self->priv->am, + cm_name, protocol_name, params); + _service_set_tp_account_name (service, account_name); + g_assert (_add_service (self, service, account_name)); + + /* MC will set all params on the account and commit */ + + return account_name; +} + +static gboolean +account_manager_uoa_delete (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *account_name, + const gchar *key) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + AgAccountService *service; + AgAccount *account; + + g_return_val_if_fail (self->priv->manager != NULL, FALSE); + + service = g_hash_table_lookup (self->priv->accounts, account_name); + if (service == NULL) + return FALSE; + + account = ag_account_service_get_account (service); + + DEBUG ("%s: %s, %s", G_STRFUNC, account_name, key); + + if (key == NULL) + { + ag_account_delete (account); + g_hash_table_remove (self->priv->accounts, account_name); + } + else + { + _service_set_tp_value (service, key, NULL); + } + + return TRUE; +} + +static gboolean +account_manager_uoa_commit (const McpAccountStorage *storage, + const McpAccountManager *am) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + GHashTableIter iter; + gpointer value; + + DEBUG (G_STRFUNC); + + g_return_val_if_fail (self->priv->manager != NULL, FALSE); + + g_hash_table_iter_init (&iter, self->priv->accounts); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + AgAccountService *service = value; + AgAccount *account = ag_account_service_get_account (service); + + ag_account_store (account, _account_stored_cb, self); + } + + return TRUE; +} + +static void +failure_removed_cb (EmpathyWebcredentialsMonitor *monitor, + AgAccount *account, + McpAccountManagerUoa *self) +{ + GList *l; + + DEBUG ("Account '%u' is not failing any more", account->id); + + l = ag_account_list_services_by_type (account, SERVICE_TYPE); + while (l != NULL) + { + AgAccountService *service = ag_account_service_new (account, l->data); + gchar *account_name = _service_dup_tp_account_name (service); + + if (account_name != NULL) + { + DEBUG ("Reconnect account %s", account_name); + + mcp_account_storage_emit_reconnect (MCP_ACCOUNT_STORAGE (self), + account_name); + } + + g_free (account_name); + g_object_unref (service); + ag_service_unref (l->data); + l = g_list_delete_link (l, l); + } +} + +static void +account_manager_uoa_ready (const McpAccountStorage *storage, + const McpAccountManager *am) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + DelayedSignalData *data; + + g_return_if_fail (self->priv->manager != NULL); + + if (self->priv->ready) + return; + + DEBUG (G_STRFUNC); + + self->priv->ready = TRUE; + self->priv->am = g_object_ref (G_OBJECT (am)); + + while ((data = g_queue_pop_head (self->priv->pending_signals)) != NULL) + { + switch (data->signal) + { + case DELAYED_CREATE: + _account_created_cb (self->priv->manager, data->account_id, self); + break; + case DELAYED_DELETE: + _account_deleted_cb (self->priv->manager, data->account_id, self); + break; + default: + g_assert_not_reached (); + } + + g_slice_free (DelayedSignalData, data); + } + + g_queue_free (self->priv->pending_signals); + self->priv->pending_signals = NULL; + + g_signal_connect (self->priv->monitor, "failure-removed", + G_CALLBACK (failure_removed_cb), self); +} + +static void +account_manager_uoa_get_identifier (const McpAccountStorage *storage, + const gchar *account_name, + GValue *identifier) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + AgAccountService *service; + AgAccount *account; + + g_return_if_fail (self->priv->manager != NULL); + + service = g_hash_table_lookup (self->priv->accounts, account_name); + if (service == NULL) + return; + + account = ag_account_service_get_account (service); + + g_value_init (identifier, G_TYPE_UINT); + g_value_set_uint (identifier, account->id); +} + +static guint +account_manager_uoa_get_restrictions (const McpAccountStorage *storage, + const gchar *account_name) +{ + McpAccountManagerUoa *self = (McpAccountManagerUoa *) storage; + AgAccountService *service; + guint restrictions = TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_SERVICE; + GValue value = G_VALUE_INIT; + + g_return_val_if_fail (self->priv->manager != NULL, 0); + + /* If we don't know this account, we cannot do anything */ + service = g_hash_table_lookup (self->priv->accounts, account_name); + if (service == NULL) + return G_MAXUINT; + + g_value_init (&value, G_TYPE_BOOLEAN); + ag_account_service_get_value (service, + KEY_PREFIX KEY_READONLY_PARAMS, &value); + + if (g_value_get_boolean (&value)) + restrictions |= TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PARAMETERS; + + g_value_unset (&value); + + /* FIXME: We can't set Icon either, but there is no flag for that */ + return restrictions; +} + +static void +account_storage_iface_init (McpAccountStorageIface *iface) +{ + mcp_account_storage_iface_set_name (iface, PLUGIN_NAME); + mcp_account_storage_iface_set_desc (iface, PLUGIN_DESCRIPTION); + mcp_account_storage_iface_set_priority (iface, PLUGIN_PRIORITY); + mcp_account_storage_iface_set_provider (iface, PLUGIN_PROVIDER); + +#define IMPLEMENT(x) mcp_account_storage_iface_implement_##x(iface, \ + account_manager_uoa_##x) + IMPLEMENT (get); + IMPLEMENT (list); + IMPLEMENT (set); + IMPLEMENT (create); + IMPLEMENT (delete); + IMPLEMENT (commit); + IMPLEMENT (ready); + IMPLEMENT (get_identifier); + IMPLEMENT (get_restrictions); +#undef IMPLEMENT +} + +McpAccountManagerUoa * +mcp_account_manager_uoa_new (void) +{ + return g_object_new (MCP_TYPE_ACCOUNT_MANAGER_UOA, NULL); +} diff --git a/mcp-account-manager-uoa/mcp-account-manager-uoa.h b/mcp-account-manager-uoa/mcp-account-manager-uoa.h new file mode 100644 index 0000000..291aeb8 --- /dev/null +++ b/mcp-account-manager-uoa/mcp-account-manager-uoa.h @@ -0,0 +1,68 @@ +/* + * Copyright © 2012 Collabora Ltd. + * + * This library 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.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#ifndef __MCP_ACCOUNT_MANAGER_UOA_H__ +#define __MCP_ACCOUNT_MANAGER_UOA_H__ + +G_BEGIN_DECLS + +#define MCP_TYPE_ACCOUNT_MANAGER_UOA \ + (mcp_account_manager_uoa_get_type ()) + +#define MCP_ACCOUNT_MANAGER_UOA(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), MCP_TYPE_ACCOUNT_MANAGER_UOA, \ + McpAccountManagerUoa)) + +#define MCP_ACCOUNT_MANAGER_UOA_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST((k), MCP_TYPE_ACCOUNT_MANAGER_UOA, \ + McpAccountManagerUoaClass)) + +#define MCP_IS_ACCOUNT_MANAGER_UOA(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), MCP_TYPE_ACCOUNT_MANAGER_UOA)) + +#define MCP_IS_ACCOUNT_MANAGER_UOA_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MCP_TYPE_ACCOUNT_MANAGER_UOA)) + +#define MCP_ACCOUNT_MANAGER_UOA_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MCP_TYPE_ACCOUNT_MANAGER_UOA, \ + McpAccountManagerUoaClass)) + +typedef struct _McpAccountManagerUoaPrivate McpAccountManagerUoaPrivate; + +typedef struct { + GObject parent; + + McpAccountManagerUoaPrivate *priv; +} _McpAccountManagerUoa; + +typedef struct { + GObjectClass parent_class; +} _McpAccountManagerUoaClass; + +typedef _McpAccountManagerUoa McpAccountManagerUoa; +typedef _McpAccountManagerUoaClass McpAccountManagerUoaClass; + +GType mcp_account_manager_uoa_get_type (void) G_GNUC_CONST; + +McpAccountManagerUoa *mcp_account_manager_uoa_new (void); + +G_END_DECLS + +#endif diff --git a/mcp-account-manager-uoa/mcp-account-manager-uoa.pro b/mcp-account-manager-uoa/mcp-account-manager-uoa.pro new file mode 100644 index 0000000..4ceb45d --- /dev/null +++ b/mcp-account-manager-uoa/mcp-account-manager-uoa.pro @@ -0,0 +1,16 @@ +TEMPLATE = lib +TARGET = mcp-account-manager-uoa + +CONFIG += link_pkgconfig use_c_linker plugin no_plugin_name_prefix +CONFIG -= qt +PKGCONFIG += mission-control-plugins libaccounts-glib + +SOURCES = empathy-webcredentials-monitor.c \ + mcp-account-manager-uoa.c \ + mission-control-plugin.c + +HEADERS = mcp-account-manager-uoa.h\ + empathy-webcredentials-monitor.h + +target.path = $$system(pkg-config --variable=plugindir mission-control-plugins) +INSTALLS += target diff --git a/mcp-account-manager-uoa/mission-control-plugin.c b/mcp-account-manager-uoa/mission-control-plugin.c new file mode 100644 index 0000000..d7a33fd --- /dev/null +++ b/mcp-account-manager-uoa/mission-control-plugin.c @@ -0,0 +1,47 @@ +/* + * mission-control-plugin.c + * + * A Mission Control plugin to expose Ubuntu Online Accounts with chat + * capabilities (e.g. Facebook) to Mission Control + * + * Copyright (C) 2012 Collabora Ltd. + * + * This library 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.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * Authors: Xavier Claessens + */ + +#include + +#include "mcp-account-manager-uoa.h" + +GObject * +mcp_plugin_ref_nth_object (guint n) +{ + static void *plugin_0 = NULL; + + switch (n) + { + case 0: + if (plugin_0 == NULL) + plugin_0 = g_object_new (MCP_TYPE_ACCOUNT_MANAGER_UOA, NULL); + else + g_object_ref (plugin_0); + + return plugin_0; + + default: + return NULL; + } +} diff --git a/telepathy-accounts-signon.pro b/telepathy-accounts-signon.pro new file mode 100644 index 0000000..b1581dd --- /dev/null +++ b/telepathy-accounts-signon.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS += mcp-account-manager-uoa \ + telepathy-sasl-signon diff --git a/telepathy-sasl-signon.pro b/telepathy-sasl-signon.pro deleted file mode 100644 index c9efc21..0000000 --- a/telepathy-sasl-signon.pro +++ /dev/null @@ -1,41 +0,0 @@ -TEMPLATE = app - -CONFIG += link_pkgconfig -PKGCONFIG += libsignon-glib telepathy-glib libaccounts-glib libsoup-2.4 - -INCLUDEPATH += src -DEFINES += HAVE_UOA \ - EMPATHY_UOA_PROVIDER=\\\"im.telepathy.Account.Storage.UOA\\\" - -SOURCES += src/empathy-auth-client.c \ - src/empathy-auth-factory.c \ - src/empathy-server-sasl-handler.c \ - src/empathy-server-tls-handler.c \ - src/empathy-keyring.c \ - src/empathy-uoa-utils.c \ - src/empathy-sasl-mechanisms.c \ - src/empathy-uoa-auth-handler.c - -HEADERS += src/empathy-auth-factory.h \ - src/empathy-debug.h \ - src/empathy-keyring.h \ - src/empathy-sasl-mechanisms.h \ - src/empathy-server-sasl-handler.h \ - src/empathy-server-tls-handler.h \ - src/empathy-uoa-utils.h \ - src/empathy-utils.h \ - src/empathy-uoa-auth-handler.h - -OTHER_FILES += org.freedesktop.Telepathy.Client.SaslSignonAuth.service \ - SaslSignonAuth.client - -target.path = /usr/libexec/ - -service.files = org.freedesktop.Telepathy.Client.SaslSignonAuth.service -service.path = /usr/share/dbus-1/services/ - -client.files = SaslSignonAuth.client -client.path = /usr/share/telepathy/clients/ - -INSTALLS += target service client - diff --git a/SaslSignonAuth.client b/telepathy-sasl-signon/SaslSignonAuth.client similarity index 100% rename from SaslSignonAuth.client rename to telepathy-sasl-signon/SaslSignonAuth.client diff --git a/src/empathy-auth-client.c b/telepathy-sasl-signon/empathy-auth-client.c similarity index 100% rename from src/empathy-auth-client.c rename to telepathy-sasl-signon/empathy-auth-client.c diff --git a/src/empathy-auth-factory.c b/telepathy-sasl-signon/empathy-auth-factory.c similarity index 100% rename from src/empathy-auth-factory.c rename to telepathy-sasl-signon/empathy-auth-factory.c diff --git a/src/empathy-auth-factory.h b/telepathy-sasl-signon/empathy-auth-factory.h similarity index 100% rename from src/empathy-auth-factory.h rename to telepathy-sasl-signon/empathy-auth-factory.h diff --git a/src/empathy-debug.h b/telepathy-sasl-signon/empathy-debug.h similarity index 100% rename from src/empathy-debug.h rename to telepathy-sasl-signon/empathy-debug.h diff --git a/src/empathy-keyring.c b/telepathy-sasl-signon/empathy-keyring.c similarity index 100% rename from src/empathy-keyring.c rename to telepathy-sasl-signon/empathy-keyring.c diff --git a/src/empathy-keyring.h b/telepathy-sasl-signon/empathy-keyring.h similarity index 100% rename from src/empathy-keyring.h rename to telepathy-sasl-signon/empathy-keyring.h diff --git a/src/empathy-sasl-mechanisms.c b/telepathy-sasl-signon/empathy-sasl-mechanisms.c similarity index 100% rename from src/empathy-sasl-mechanisms.c rename to telepathy-sasl-signon/empathy-sasl-mechanisms.c diff --git a/src/empathy-sasl-mechanisms.h b/telepathy-sasl-signon/empathy-sasl-mechanisms.h similarity index 100% rename from src/empathy-sasl-mechanisms.h rename to telepathy-sasl-signon/empathy-sasl-mechanisms.h diff --git a/src/empathy-server-sasl-handler.c b/telepathy-sasl-signon/empathy-server-sasl-handler.c similarity index 100% rename from src/empathy-server-sasl-handler.c rename to telepathy-sasl-signon/empathy-server-sasl-handler.c diff --git a/src/empathy-server-sasl-handler.h b/telepathy-sasl-signon/empathy-server-sasl-handler.h similarity index 100% rename from src/empathy-server-sasl-handler.h rename to telepathy-sasl-signon/empathy-server-sasl-handler.h diff --git a/src/empathy-server-tls-handler.c b/telepathy-sasl-signon/empathy-server-tls-handler.c similarity index 100% rename from src/empathy-server-tls-handler.c rename to telepathy-sasl-signon/empathy-server-tls-handler.c diff --git a/src/empathy-server-tls-handler.h b/telepathy-sasl-signon/empathy-server-tls-handler.h similarity index 100% rename from src/empathy-server-tls-handler.h rename to telepathy-sasl-signon/empathy-server-tls-handler.h diff --git a/src/empathy-uoa-auth-handler.c b/telepathy-sasl-signon/empathy-uoa-auth-handler.c similarity index 100% rename from src/empathy-uoa-auth-handler.c rename to telepathy-sasl-signon/empathy-uoa-auth-handler.c diff --git a/src/empathy-uoa-auth-handler.h b/telepathy-sasl-signon/empathy-uoa-auth-handler.h similarity index 100% rename from src/empathy-uoa-auth-handler.h rename to telepathy-sasl-signon/empathy-uoa-auth-handler.h diff --git a/src/empathy-uoa-utils.c b/telepathy-sasl-signon/empathy-uoa-utils.c similarity index 100% rename from src/empathy-uoa-utils.c rename to telepathy-sasl-signon/empathy-uoa-utils.c diff --git a/src/empathy-uoa-utils.h b/telepathy-sasl-signon/empathy-uoa-utils.h similarity index 100% rename from src/empathy-uoa-utils.h rename to telepathy-sasl-signon/empathy-uoa-utils.h diff --git a/src/empathy-utils.h b/telepathy-sasl-signon/empathy-utils.h similarity index 100% rename from src/empathy-utils.h rename to telepathy-sasl-signon/empathy-utils.h diff --git a/org.freedesktop.Telepathy.Client.SaslSignonAuth.service b/telepathy-sasl-signon/org.freedesktop.Telepathy.Client.SaslSignonAuth.service similarity index 100% rename from org.freedesktop.Telepathy.Client.SaslSignonAuth.service rename to telepathy-sasl-signon/org.freedesktop.Telepathy.Client.SaslSignonAuth.service diff --git a/telepathy-sasl-signon/telepathy-sasl-signon.pro b/telepathy-sasl-signon/telepathy-sasl-signon.pro new file mode 100644 index 0000000..d935496 --- /dev/null +++ b/telepathy-sasl-signon/telepathy-sasl-signon.pro @@ -0,0 +1,41 @@ +TEMPLATE = app +CONFIG -= qt + +CONFIG += link_pkgconfig +PKGCONFIG += libsignon-glib telepathy-glib libaccounts-glib libsoup-2.4 + +DEFINES += HAVE_UOA \ + EMPATHY_UOA_PROVIDER=\\\"im.telepathy.Account.Storage.UOA\\\" + +SOURCES += empathy-auth-client.c \ + empathy-auth-factory.c \ + empathy-server-sasl-handler.c \ + empathy-server-tls-handler.c \ + empathy-keyring.c \ + empathy-uoa-utils.c \ + empathy-sasl-mechanisms.c \ + empathy-uoa-auth-handler.c + +HEADERS += empathy-auth-factory.h \ + empathy-debug.h \ + empathy-keyring.h \ + empathy-sasl-mechanisms.h \ + empathy-server-sasl-handler.h \ + empathy-server-tls-handler.h \ + empathy-uoa-utils.h \ + empathy-utils.h \ + empathy-uoa-auth-handler.h + +OTHER_FILES += org.freedesktop.Telepathy.Client.SaslSignonAuth.service \ + SaslSignonAuth.client + +target.path = /usr/libexec/ + +service.files = org.freedesktop.Telepathy.Client.SaslSignonAuth.service +service.path = /usr/share/dbus-1/services/ + +client.files = SaslSignonAuth.client +client.path = /usr/share/telepathy/clients/ + +INSTALLS += target service client +