summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2014-01-13 13:29:14 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2014-01-13 13:29:14 +0000
commit879a1b06aa945dfb7a4d3df2dd5ce80b7f946f69 (patch)
treef82899a1138b40ffaad54cb7b95e399ce5f43644
parent590079eb30d75b148237a86f21637e36a853b14f (diff)
parent37365d623ad78997b47be1da78e422fbc1cbeea1 (diff)
downloadtelepathy-mission-control-879a1b06aa945dfb7a4d3df2dd5ce80b7f946f69.tar.gz
Merge remote-tracking branch 'origin/master' into nexttelepathy-mission-control-5.99.6
Conflicts: src/connectivity-monitor.c src/mcd-connection.c tests/twisted/account-storage/libaccounts-sso-storage.py
-rw-r--r--NEWS5
-rw-r--r--configure.ac66
-rw-r--r--plugins/mcp-dbus-aegis-acl.h34
-rw-r--r--src/Makefile.am23
-rw-r--r--src/connectivity-monitor.c18
-rw-r--r--src/mcd-account-manager-sso.c1749
-rw-r--r--src/mcd-account-manager-sso.h101
-rw-r--r--src/mcd-account-manager.c12
-rw-r--r--src/mcd-account-priv.h2
-rw-r--r--src/mcd-account.c150
-rw-r--r--src/mcd-account.h5
-rw-r--r--src/mcd-client-priv.h2
-rw-r--r--src/mcd-client.c17
-rw-r--r--src/mcd-connection.c8
-rw-r--r--src/mcd-dispatch-operation.c41
-rw-r--r--src/mcd-dispatcher.c10
-rw-r--r--src/mcd-storage.c13
-rw-r--r--src/plugin-loader.c16
-rw-r--r--tests/Makefile.am6
-rw-r--r--tests/account-store-libaccounts.c630
-rw-r--r--tests/account-store-libaccounts.h44
-rw-r--r--tests/account-store.c13
-rw-r--r--tests/twisted/Makefile.am10
-rw-r--r--tests/twisted/account-manager/backend-makes-changes.py3
-rw-r--r--tests/twisted/account-manager/restricted-storage.py185
-rw-r--r--tests/twisted/account-manager/update-parameters.py6
-rw-r--r--tests/twisted/account-storage/libaccounts-sso-storage.py89
-rw-r--r--tests/twisted/constants.py6
-rw-r--r--tests/twisted/dbus-account-plugin.c32
-rw-r--r--tests/twisted/dispatcher/bypass-observers.py291
-rw-r--r--tests/twisted/fakeaccountsservice.py105
-rw-r--r--tests/twisted/mctest.py9
-rw-r--r--tests/twisted/run-test.sh.in9
33 files changed, 397 insertions, 3313 deletions
diff --git a/NEWS b/NEWS
index 2dd22f4f..e2eb77b8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+telepathy-mission-control 5.99.6 (2014-01-13)
+=============================================
+
+• Telepathy 1.0 branch
+
telepathy-mission-control 5.17.0 (UNRELEASED)
=============================================
diff --git a/configure.ac b/configure.ac
index bcac85c0..28948668 100644
--- a/configure.ac
+++ b/configure.ac
@@ -150,63 +150,8 @@ fi
AC_SUBST(ACCOUNTS_CACHE_DIR)
AC_DEFINE_UNQUOTED(ACCOUNTS_CACHE_DIR,"$ACCOUNTS_CACHE_DIR", [Directory for account/connection mapping for crash recovery])
-aegis_enabled="no"
-AC_MSG_CHECKING([whether to build with Aegis (libcreds) support])
-AC_ARG_ENABLE(aegis,
- AC_HELP_STRING([--enable-aegis],
- [Aegis security framework support]),
- [
- AC_CHECK_LIB(creds, creds_init,
- [
- AC_DEFINE([ENABLE_AEGIS], [1],
- [Define if Aegis is supported])
- AC_SUBST([AEGIS_LIBS], [-lcreds])
- ],
- [ AC_MSG_ERROR([Aegis: libcreds not found]) ])
- aegis_enabled="yes"
- ],
- [
- aegis_enabled="no"
- AC_MSG_RESULT(no)
- AC_DEFINE([ENABLE_AEGIS], [0], [Define if Aegis is supported])
- ])
-
-AM_CONDITIONAL(ENABLE_AEGIS, [test x$aegis_enabled = xyes])
-
PKG_PROG_PKG_CONFIG()
-dnl libaccounts-glib SSO
-libaccounts_sso_enabled="no"
-AC_MSG_CHECKING(whether to build with libaccounts-glib SSO suport)
-
-AC_ARG_ENABLE([libaccounts-sso],
- AC_HELP_STRING([--enable-libaccounts-sso],
- [build with SSO suport. default=no]),
- [ AC_MSG_RESULT(${enableval})
- libaccounts_sso_enabled="${enableval}" ],
- [ AC_MSG_RESULT(no) ] )
-
-AS_IF([ test "x$libaccounts_sso_enabled" = xauto ],
- [ PKG_CHECK_EXISTS([libaccounts-glib],
- [libaccounts_sso_enabled=yes],
- [libaccounts_sso_enabled=no]) ])
-
-dnl set up the shell/make variable, the #define and check the package version
-AS_IF([ test "x$libaccounts_sso_enabled" = xyes ],
- [ ENABLE_LIBACCOUNTS_SSO=yes
- AC_DEFINE(ENABLE_LIBACCOUNTS_SSO, [1],
- [Define if libaccounts SSO support is required])
- PKG_CHECK_MODULES([LIBACCOUNTS_SSO], [libaccounts-glib >= 0.26]) ],
- [ AC_DEFINE(ENABLE_LIBACCOUNTS_SSO, [0]) ])
-
-dnl export the CFLAGS and LDFLAGS equivalents determined by PKG_CHECK_MODULES
-AC_SUBST(LIBACCOUNTS_SSO_CFLAGS)
-AC_SUBST(LIBACCOUNTS_SSO_LIBS)
-
-dnl the automake conditional
-AM_CONDITIONAL(ENABLE_LIBACCOUNTS_SSO, [test x$libaccounts_sso_enabled = xyes])
-dnl /libaccounts-glib SSO
-
PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.95, dbus-glib-1 >= 0.82])
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
@@ -233,13 +178,6 @@ PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0],
AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_30], [Ignore post 2.30 deprecations])
AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_36], [Prevent post 2.36 APIs])
-dnl Check for MCE, a Maemo service used to determine when the device is idle.
-PKG_CHECK_MODULES([MCE], mce >= 1.5, [HAVE_MCE=yes], [HAVE_MCE=no])
-AM_CONDITIONAL([HAVE_MCE], [test x"$HAVE_MCE" = xyes])
-if test x"$HAVE_MCE" = xyes; then
- AC_DEFINE([HAVE_MCE], [1], [Define if mce is available])
-fi
-
# -----------------------------------------------------------
# Connectivity integration
# -----------------------------------------------------------
@@ -334,9 +272,5 @@ Configure summary:
Features:
Plugin API documentation.....: ${enable_gtk_doc}
Network Manager integration..: ${have_nm}
- ConnMan integration..........: ${have_connman}
Connectivity GSetting........: ${enable_conn_setting}
- Aegis........................: ${aegis_enabled}
- libaccounts-glib backend.....: ${libaccounts_sso_enabled}
- Nokia Mode Control Entity....: ${HAVE_MCE}
"
diff --git a/plugins/mcp-dbus-aegis-acl.h b/plugins/mcp-dbus-aegis-acl.h
deleted file mode 100644
index 96baaf46..00000000
--- a/plugins/mcp-dbus-aegis-acl.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * A pseudo-plugin that checks the caller's Aegis permission tokens
- *
- * Copyright © 2010-2011 Nokia Corporation
- * Copyright © 2010-2011 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
- */
-
-#ifndef AEGIS_ACL_H
-#define AEGIS_ACL_H
-
-#include <mission-control-plugins/mission-control-plugins.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-GObject *aegis_acl_new (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 42489779..138c43ef 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,7 +3,6 @@ AM_CPPFLAGS = \
$(DBUS_CFLAGS) \
$(GLIB_CFLAGS) \
$(NETWORK_MANAGER_CFLAGS) \
- $(CONNMAN_CFLAGS) \
-DG_LOG_DOMAIN=\"mcd\" \
-DMCD_PLUGIN_LOADER_DIR=\"@libdir@/mission-control-plugins.@MCP_ABI_VERSION@\" \
-DMC_DISABLE_DEPRECATED -I$(top_srcdir)
@@ -26,12 +25,6 @@ mc_headers = \
mcd-service.h \
mcd-storage.h
-if ENABLE_LIBACCOUNTS_SSO
-mc_headers += \
- mcd-account-manager-sso.h \
- $(NULL)
-endif
-
mc_gen_headers = \
_gen/cli-Connection_Manager_Interface_Account_Storage.h \
_gen/enums.h \
@@ -71,18 +64,8 @@ libmcd_convenience_la_LIBADD = \
$(DBUS_LIBS) \
$(GLIB_LIBS) \
$(NETWORK_MANAGER_LIBS) \
- $(CONNMAN_LIBS) \
$(NULL)
-if ENABLE_LIBACCOUNTS_SSO
-libmcd_convenience_la_LIBADD += $(LIBACCOUNTS_SSO_LIBS)
-AM_CPPFLAGS += $(LIBACCOUNTS_SSO_CFLAGS)
-endif
-
-if ENABLE_AEGIS
-libmcd_convenience_la_LIBADD += $(top_builddir)/plugins/libmcp-aegis.la
-endif
-
noinst_LTLIBRARIES = libmcd-convenience.la
libmcd_convenience_la_SOURCES = \
@@ -144,12 +127,6 @@ libmcd_convenience_la_SOURCES = \
sp_timestamp.h \
$(mc_headers)
-if ENABLE_LIBACCOUNTS_SSO
-libmcd_convenience_la_SOURCES += \
- mcd-account-manager-sso.c \
- $(NULL)
-endif
-
mcd-enum-types.h: stamp-mcd-enum-types.h
$(AM_V_GEN)true
stamp-mcd-enum-types.h: Makefile $(mc_headers) mcd-enum-types.c
diff --git a/src/connectivity-monitor.c b/src/connectivity-monitor.c
index 9510cf14..59434a61 100644
--- a/src/connectivity-monitor.c
+++ b/src/connectivity-monitor.c
@@ -477,9 +477,9 @@ mcd_connectivity_monitor_init (McdConnectivityMonitor *connectivity_monitor)
#ifdef ENABLE_CONN_SETTING
priv->settings = g_settings_new ("im.telepathy.v1.MissionControl.FromEmpathy");
- g_settings_bind (priv->settings, "use-conn",
- connectivity_monitor, "use-conn",
- G_SETTINGS_BIND_GET);
+ /* We'll call g_settings_bind() in constructed because default values of
+ * properties haven't been set yet at this point and we don't want them to
+ * override the value from GSettings. */
#endif
#ifdef HAVE_NM
@@ -503,6 +503,17 @@ mcd_connectivity_monitor_init (McdConnectivityMonitor *connectivity_monitor)
}
static void
+connectivity_monitor_constructed (GObject *object)
+{
+#ifdef ENABLE_CONN_SETTING
+ McdConnectivityMonitor *self = MCD_CONNECTIVITY_MONITOR (object);
+
+ g_settings_bind (self->priv->settings, "use-conn",
+ self, "use-conn", G_SETTINGS_BIND_GET);
+#endif
+}
+
+static void
connectivity_monitor_finalize (GObject *object)
{
#if defined(HAVE_NM)
@@ -626,6 +637,7 @@ mcd_connectivity_monitor_class_init (McdConnectivityMonitorClass *klass)
oclass->finalize = connectivity_monitor_finalize;
oclass->dispose = connectivity_monitor_dispose;
oclass->constructor = connectivity_monitor_constructor;
+ oclass->constructed = connectivity_monitor_constructed;
oclass->get_property = connectivity_monitor_get_property;
oclass->set_property = connectivity_monitor_set_property;
diff --git a/src/mcd-account-manager-sso.c b/src/mcd-account-manager-sso.c
deleted file mode 100644
index 9226bbb8..00000000
--- a/src/mcd-account-manager-sso.c
+++ /dev/null
@@ -1,1749 +0,0 @@
-/*
- * A pseudo-plugin that stores/fetches accounts in/from the SSO via libaccounts
- *
- * Copyright © 2010-2011 Nokia Corporation
- * Copyright © 2010-2011 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 "mcd-account-manager-sso.h"
-#include "mcd-debug.h"
-
-#include <telepathy-glib/telepathy-glib.h>
-
-#include <libaccounts-glib/ag-account.h>
-#include <libaccounts-glib/ag-service.h>
-
-#include <string.h>
-#include <ctype.h>
-
-#define PLUGIN_PRIORITY (MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_KEYRING + 10)
-#define PLUGIN_NAME "maemo-libaccounts"
-#define PLUGIN_DESCRIPTION \
- "Account storage in the Maemo SSO store via libaccounts-glib API"
-#define PLUGIN_PROVIDER "org.maemo.Telepathy.Account.Storage.LibAccounts"
-
-#define MCPP "param-"
-#define AGPP "parameters/"
-#define LIBACCT_ID_KEY "libacct-uid"
-
-#define MC_ENABLED_KEY "Enabled"
-#define AG_ENABLED_KEY "enabled"
-
-#define AG_LABEL_KEY "name"
-#define MC_LABEL_KEY "DisplayName"
-
-#define AG_ACCOUNT_KEY "username"
-#define MC_ACCOUNT_KEY "account"
-#define PASSWORD_KEY "password"
-#define AG_ACCOUNT_ALT_KEY AGPP "account"
-
-#define MC_CMANAGER_KEY "manager"
-#define MC_PROTOCOL_KEY "protocol"
-#define MC_IDENTITY_KEY "tmc-uid"
-
-#define SERVICES_KEY "sso-services"
-
-#define MC_SERVICE_KEY "Service"
-
-#define AG_ACCOUNT_WRITE_INTERVAL 5
-
-static const gchar *exported_settings[] = { "CredentialsId", NULL };
-
-typedef enum {
- DELAYED_CREATE,
- DELAYED_DELETE,
-} DelayedSignal;
-
-typedef struct {
- gchar *mc_name;
- gchar *ag_name;
- gboolean global; /* global ag setting or service specific? */
- gboolean readable; /* does the _standard_ read method copy this into MC? */
- gboolean writable; /* does the _standard_ write method copy this into AG? */
- gboolean freeable; /* should clear_setting_data deallocate the names? */
-} Setting;
-
-#define GLOBAL TRUE
-#define SERVICE FALSE
-#define READABLE TRUE
-#define UNREADABLE FALSE
-#define WRITABLE TRUE
-#define UNWRITABLE FALSE
-
-typedef enum {
- SETTING_MC,
- SETTING_AG,
-} SettingType;
-
-/* IMPORTANT IMPLEMENTATION NOTE:
- *
- * The mapping between telepathy settings and parameter names
- * and ag account (libaccounts) settings, and whether those settings
- * are stored in the global or service specific ag section is a
- * finicky beast - the mapping below has been arrived at empirically
- * Take care when altering it.
- *
- * Settings not mentioned explicitly are:
- * • given the same name on both MC and AG sides
- * • assigned to the service specific section
- * • automatically prefixed (param- vs parameters/) for each side if necessary
- *
- * So if your setting fits these criteria, you do not need to add it at all.
- */
-Setting setting_map[] = {
- { MC_ENABLED_KEY , AG_ENABLED_KEY , GLOBAL , UNREADABLE, UNWRITABLE },
- { MCPP MC_ACCOUNT_KEY, AG_ACCOUNT_KEY , GLOBAL , READABLE , UNWRITABLE },
- { MCPP PASSWORD_KEY , PASSWORD_KEY , GLOBAL , READABLE , WRITABLE },
- { MC_LABEL_KEY , AG_LABEL_KEY , GLOBAL , READABLE , WRITABLE },
- { LIBACCT_ID_KEY , LIBACCT_ID_KEY , GLOBAL , UNREADABLE, UNWRITABLE },
- { MC_IDENTITY_KEY , MC_IDENTITY_KEY, SERVICE, READABLE , WRITABLE },
- { MC_CMANAGER_KEY , MC_CMANAGER_KEY, SERVICE, READABLE , UNWRITABLE },
- { MC_PROTOCOL_KEY , MC_PROTOCOL_KEY, SERVICE, READABLE , UNWRITABLE },
- { MC_SERVICE_KEY , MC_SERVICE_KEY , SERVICE, UNREADABLE, UNWRITABLE },
- { SERVICES_KEY , SERVICES_KEY , GLOBAL , UNREADABLE, UNWRITABLE },
- { NULL }
-};
-
-typedef struct {
- DelayedSignal signal;
- AgAccountId account_id;
-} DelayedSignalData;
-
-typedef struct {
- McdAccountManagerSso *sso;
- struct {
- AgAccountWatch service;
- AgAccountWatch global;
- } watch;
-} WatchData;
-
-static Setting *
-setting_data (const gchar *name, SettingType type)
-{
- guint i = 0;
- static Setting parameter = { NULL, NULL, SERVICE, READABLE, WRITABLE, TRUE };
- const gchar *prefix;
-
- for (; setting_map[i].mc_name != NULL; i++)
- {
- const gchar *setting_name = NULL;
-
- if (type == SETTING_MC)
- setting_name = setting_map[i].mc_name;
- else
- setting_name = setting_map[i].ag_name;
-
- if (g_strcmp0 (name, setting_name) == 0)
- return &setting_map[i];
- }
-
- prefix = (type == SETTING_MC) ? MCPP : AGPP;
-
- if (!g_str_has_prefix (name, prefix))
- { /* a non-parameter setting */
- parameter.mc_name = g_strdup (name);
- parameter.ag_name = g_strdup (name);
- }
- else
- { /* a setting that is a parameter on both sides (AG & MC) */
- const guint plength = strlen (prefix);
-
- parameter.mc_name = g_strdup_printf ("%s%s", MCPP, name + plength);
- parameter.ag_name = g_strdup_printf ("%s%s", AGPP, name + plength);
- }
-
- return &parameter;
-}
-
-static void
-clear_setting_data (Setting *setting)
-{
- if (setting == NULL)
- return;
-
- if (!setting->freeable)
- return;
-
- g_free (setting->mc_name);
- g_free (setting->ag_name);
- setting->mc_name = NULL;
- setting->ag_name = NULL;
-}
-
-static gboolean _sso_account_enabled (
- McdAccountManagerSso *self,
- AgAccount *account,
- AgService *service);
-
-static void account_storage_iface_init (McpAccountStorageIface *,
- gpointer);
-
-static gchar *
-_ag_accountid_to_mc_key (McdAccountManagerSso *sso,
- AgAccountId id,
- gboolean create);
-
-static void _ag_account_stored_cb (AgAccount *acct,
- const GError *err,
- gpointer ignore);
-
-static void _sso_created (GObject *object,
- AgAccountId id,
- gpointer user_data);
-
-static void _sso_toggled (GObject *object,
- AgAccountId id,
- gpointer data);
-
-static gboolean save_setting (
- McdAccountManagerSso *self,
- AgAccount *account,
- const Setting *setting,
- const gchar *val);
-
-G_DEFINE_TYPE_WITH_CODE (McdAccountManagerSso, mcd_account_manager_sso,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (MCP_TYPE_ACCOUNT_STORAGE,
- account_storage_iface_init));
-
-static gchar *
-_gvalue_to_string (const GValue *val)
-{
- switch (G_VALUE_TYPE (val))
- {
- case G_TYPE_STRING:
- return g_value_dup_string (val);
- case G_TYPE_BOOLEAN:
- return g_strdup (g_value_get_boolean (val) ? "true" : "false");
- case G_TYPE_CHAR:
- return g_strdup_printf ("%c", g_value_get_uchar (val));
- case G_TYPE_UCHAR:
- return g_strdup_printf ("%c", g_value_get_char (val));
- case G_TYPE_INT:
- return g_strdup_printf ("%i", g_value_get_int (val));
- case G_TYPE_UINT:
- return g_strdup_printf ("%u", g_value_get_uint (val));
- case G_TYPE_LONG:
- return g_strdup_printf ("%ld", g_value_get_long (val));
- case G_TYPE_ULONG:
- return g_strdup_printf ("%lu", g_value_get_ulong (val));
- case G_TYPE_INT64:
- return g_strdup_printf ("%" G_GINT64_FORMAT, g_value_get_int64 (val));
- case G_TYPE_UINT64:
- return g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (val));
- case G_TYPE_ENUM:
- return g_strdup_printf ("%d" , g_value_get_enum (val));
- case G_TYPE_FLAGS:
- return g_strdup_printf ("%u", g_value_get_flags (val));
- case G_TYPE_FLOAT:
- return g_strdup_printf ("%f", g_value_get_float (val));
- case G_TYPE_DOUBLE:
- return g_strdup_printf ("%g", g_value_get_double (val));
- default:
- DEBUG ("Unsupported type %s", G_VALUE_TYPE_NAME (val));
- return NULL;
- }
-}
-
-static const gchar *
-account_manager_sso_get_service_type (McdAccountManagerSso *self)
-{
- McdAccountManagerSsoClass *klass = MCD_ACCOUNT_MANAGER_SSO_GET_CLASS (self);
-
- g_assert (klass->service_type != NULL);
-
- return klass->service_type;
-}
-
-static gboolean
-_ag_account_select_default_im_service (
- McdAccountManagerSso *self,
- AgAccount *account)
-{
- const gchar *service_type = account_manager_sso_get_service_type (self);
- gboolean have_service = FALSE;
- GList *first = ag_account_list_services_by_type (account, service_type);
-
- if (first != NULL && first->data != NULL)
- {
- have_service = TRUE;
- DEBUG ("default %s service %s", service_type,
- ag_service_get_name (first->data));
- ag_account_select_service (account, first->data);
- }
-
- ag_service_list_free (first);
-
- return have_service;
-}
-
-static AgSettingSource
-_ag_account_global_value (AgAccount *account,
- const gchar *key,
- GValue *value)
-{
- AgSettingSource src = AG_SETTING_SOURCE_NONE;
- AgService *service = ag_account_get_selected_service (account);
-
- if (service != NULL)
- {
- ag_account_select_service (account, NULL);
- src = ag_account_get_value (account, key, value);
- ag_account_select_service (account, service);
- }
- else
- {
- src = ag_account_get_value (account, key, value);
- }
-
- return src;
-}
-
-static AgSettingSource
-_ag_account_local_value (
- McdAccountManagerSso *self,
- AgAccount *account,
- const gchar *key,
- GValue *value)
-{
- AgSettingSource src = AG_SETTING_SOURCE_NONE;
- AgService *service = ag_account_get_selected_service (account);
-
- if (service != NULL)
- {
- src = ag_account_get_value (account, key, value);
- }
- else
- {
- _ag_account_select_default_im_service (self, account);
- src = ag_account_get_value (account, key, value);
- ag_account_select_service (account, NULL);
- }
-
- return src;
-}
-
-/* AG_ACCOUNT_ALT_KEY from service overrides global AG_ACCOUNT_KEY if set */
-static void
-_maybe_set_account_param_from_service (
- McdAccountManagerSso *self,
- const McpAccountManager *am,
- AgAccount *ag_account,
- const gchar *mc_account)
-{
- Setting *setting = setting_data (AG_ACCOUNT_KEY, SETTING_AG);
- AgSettingSource source = AG_SETTING_SOURCE_NONE;
- GValue ag_value = G_VALUE_INIT;
-
- g_return_if_fail (setting != NULL);
- g_return_if_fail (ag_account != NULL);
-
- g_value_init (&ag_value, G_TYPE_STRING);
-
- source = _ag_account_local_value (self, ag_account, AG_ACCOUNT_ALT_KEY,
- &ag_value);
-
- if (source != AG_SETTING_SOURCE_NONE)
- {
- gchar *value = _gvalue_to_string (&ag_value);
-
- DEBUG ("overriding global %s param with %s: %s",
- AG_ACCOUNT_KEY, AG_ACCOUNT_ALT_KEY, value);
- mcp_account_manager_set_value (am, mc_account, setting->mc_name, value);
- g_free (value);
- }
-
- g_value_unset (&ag_value);
- clear_setting_data (setting);
-}
-
-static WatchData *
-make_watch_data (McdAccountManagerSso *sso)
-{
- WatchData *data = g_slice_new0 (WatchData);
-
- data->sso = g_object_ref (sso);
-
- return data;
-}
-
-static void
-free_watch_data (gpointer data)
-{
- WatchData *wd = data;
-
- if (wd == NULL)
- return;
-
- tp_clear_object (&wd->sso);
- g_slice_free (WatchData, wd);
-}
-
-static void unwatch_account_keys (McdAccountManagerSso *sso,
- AgAccountId id)
-{
- gpointer watch_key = GUINT_TO_POINTER (id);
- WatchData *wd = g_hash_table_lookup (sso->watches, watch_key);
- AgAccount *account = ag_manager_get_account (sso->ag_manager, id);
-
- if (wd != NULL && account != NULL)
- {
- ag_account_remove_watch (account, wd->watch.global);
- ag_account_remove_watch (account, wd->watch.service);
- }
-
- g_hash_table_remove (sso->watches, watch_key);
-}
-
-/* There are two types of ag watch: ag_account_watch_key and *
- * ag_account_watch_dir. _key passees us the watched key when invoking this *
- * callback, dir watches only a prefix, and passes the watched prefix *
- * (not the actual updated setting) - we now watch with _dir since _key *
- * doesn't allow us to watch for keys-that-are-not-set at creation time *
- * (since those cannot be known in advance): This means that in this *
- * callback we must compare what we have in MC with what's in AG and issue *
- * update notices accordingly (and remember to handle deleted keys). *
- * It also means the const gchar *what-was-updated parameter is not useful */
-static void _sso_updated (AgAccount *account,
- const gchar *unused,
- gpointer data)
-{
- WatchData *wd = data;
- McdAccountManagerSso *sso = wd->sso;
- McpAccountManager *am = sso->manager_interface;
- McpAccountStorage *mcpa = MCP_ACCOUNT_STORAGE (sso);
- gpointer id = GUINT_TO_POINTER (account->id);
- const gchar *name = g_hash_table_lookup (sso->id_name_map, id);
- AgService *service = ag_account_get_selected_service (account);
- GStrv keys = NULL;
- GHashTable *unseen = NULL;
- GHashTableIter deleted_iter = { 0 };
- const gchar *deleted_key;
- guint i;
- gboolean params_updated = FALSE;
- const gchar *immutables[] = { MC_SERVICE_KEY, SERVICES_KEY, NULL };
-
- /* account has no name yet: might be time to create it */
- if (name == NULL)
- return _sso_created (G_OBJECT (sso->ag_manager), account->id, sso);
-
- DEBUG ("update for account %s", name);
-
- /* list the keys we know about so we can tell if one has been deleted */
- keys = mcp_account_manager_list_keys (am, name);
- unseen = g_hash_table_new (g_str_hash, g_str_equal);
-
- for (i = 0; keys != NULL && keys[i] != NULL; i++)
- g_hash_table_insert (unseen, keys[i], GUINT_TO_POINTER (TRUE));
-
- /* now iterate over ag settings, global then service specific: */
- ag_account_select_service (account, NULL);
-
- for (i = 0; i < 2; i++)
- {
- AgAccountSettingIter iter = { 0 };
- const gchar *ag_key = NULL;
- const GValue *ag_val = NULL;
-
- if (i == 1)
- _ag_account_select_default_im_service (sso, account);
-
- ag_account_settings_iter_init (account, &iter, NULL);
-
- while (ag_account_settings_iter_next (&iter, &ag_key, &ag_val))
- {
- Setting *setting = setting_data (ag_key, SETTING_AG);
- const gchar *mc_key;
- gchar *ag_str;
- gchar *mc_str;
-
- if (setting == NULL)
- continue;
-
- mc_key = setting->mc_name;
- mc_str = mcp_account_manager_get_value (am, name, mc_key);
- ag_str = _gvalue_to_string (ag_val);
- g_hash_table_remove (unseen, mc_key);
-
- if (tp_strdiff (ag_str, mc_str))
- {
- mcp_account_manager_set_value (am, name, mc_key, ag_str);
-
- if (sso->ready)
- {
- if (g_str_has_prefix (mc_key, MCPP))
- params_updated = TRUE;
- else
- mcp_account_storage_emit_altered_one (mcpa, name, mc_key);
- }
- }
-
- g_free (mc_str);
- g_free (ag_str);
- clear_setting_data (setting);
- }
- }
-
- /* special case values always exist and therefore cannot be deleted */
- for (i = 0; immutables[i] != NULL; i++)
- {
- Setting *immutable = setting_data (immutables[i], SETTING_AG);
-
- g_hash_table_remove (unseen, immutable->ag_name);
- clear_setting_data (immutable);
- }
-
- /* signal (and update) deleted settings: */
- g_hash_table_iter_init (&deleted_iter, unseen);
-
- while (g_hash_table_iter_next (&deleted_iter, (gpointer *)&deleted_key, NULL))
- {
- mcp_account_manager_set_value (am, name, deleted_key, NULL);
-
- if (g_str_has_prefix (deleted_key, MCPP))
- params_updated = TRUE;
- else
- mcp_account_storage_emit_altered_one (mcpa, name, deleted_key);
- }
-
- g_hash_table_unref (unseen);
- g_strfreev (keys);
-
- if (params_updated)
- mcp_account_storage_emit_altered_one (mcpa, name, "Parameters");
-
- /* put the selected service back the way it was when we found it */
- ag_account_select_service (account, service);
-}
-
-static void watch_for_updates (McdAccountManagerSso *sso,
- AgAccount *account)
-{
- WatchData *data;
- gpointer id = GUINT_TO_POINTER (account->id);
- AgService *service;
-
- /* already watching account? let's be idempotent */
- if (g_hash_table_lookup (sso->watches, id) != NULL)
- return;
-
- DEBUG ("watching AG ID %u for updates", account->id);
-
- service = ag_account_get_selected_service (account);
-
- data = make_watch_data (sso);
-
- ag_account_select_service (account, NULL);
- data->watch.global = ag_account_watch_dir (account, "", _sso_updated, data);
-
- _ag_account_select_default_im_service (sso, account);
- data->watch.service = ag_account_watch_dir (account, "", _sso_updated, data);
-
- g_hash_table_insert (sso->watches, id, data);
- ag_account_select_service (account, service);
-}
-
-static void _sso_toggled (GObject *object,
- AgAccountId id,
- gpointer data)
-{
- AgManager *manager = AG_MANAGER (object);
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (data);
- McpAccountStorage *mcpa = MCP_ACCOUNT_STORAGE (sso);
- AgAccount *account = NULL;
- gboolean on = FALSE;
- const gchar *name = NULL;
-
- /* If the account manager isn't ready, account state changes are of no *
- * interest to us: it will pick up the then-current state of the account *
- * when it does become ready, and anything that happens between now and *
- * then is not important: */
- if (!sso->ready)
- return;
-
- account = ag_manager_get_account (manager, id);
-
- if (account != NULL)
- {
- on = _sso_account_enabled (sso, account, NULL);
- name = g_hash_table_lookup (sso->id_name_map, GUINT_TO_POINTER (id));
- }
-
- if (name != NULL)
- {
- const gchar *value = on ? "true" : "false";
- McpAccountManager *am = sso->manager_interface;
-
- mcp_account_manager_set_value (am, name, "Enabled", value);
- mcp_account_storage_emit_toggled (mcpa, name, on);
- }
- else
- {
- DEBUG ("received enabled=%u signal for unknown SSO account %u", on, id);
- }
-}
-
-static void _sso_deleted (GObject *object,
- AgAccountId id,
- gpointer user_data)
-{
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (user_data);
-
- if (sso->ready)
- {
- const gchar *name =
- g_hash_table_lookup (sso->id_name_map, GUINT_TO_POINTER (id));
-
- /* if the account was in our cache, then this was a 3rd party delete *
- * op that someone did behind our back: fire the signal and clean up */
- if (name != NULL)
- {
- McpAccountStorage *mcpa = MCP_ACCOUNT_STORAGE (sso);
- gchar *signalled_name = g_strdup (name);
-
- /* forget id->name map first, so the signal can't start a loop */
- g_hash_table_remove (sso->id_name_map, GUINT_TO_POINTER (id));
- g_hash_table_remove (sso->accounts, signalled_name);
-
- /* stop watching for updates */
- unwatch_account_keys (sso, id);
-
- mcp_account_storage_emit_deleted (mcpa, signalled_name);
-
- g_free (signalled_name);
- }
- }
- else
- {
- DelayedSignalData *sig_data = g_slice_new0 (DelayedSignalData);
-
- sig_data->signal = DELAYED_DELETE;
- sig_data->account_id = id;
- g_queue_push_tail (sso->pending_signals, sig_data);
- }
-}
-
-/* return TRUE if we actually changed any state, FALSE otherwise */
-static gboolean _sso_account_enable (
- McdAccountManagerSso *self,
- AgAccount *account,
- AgService *service,
- gboolean on)
-{
- AgService *original = ag_account_get_selected_service (account);
-
- /* the setting account is already in one of the global+service
- configurations that corresponds to our current state: don't touch it */
- if (_sso_account_enabled (self, account, service) == on)
- return FALSE;
-
- /* turn the local enabled flag on/off as required */
- if (service != NULL)
- ag_account_select_service (account, service);
- else
- _ag_account_select_default_im_service (self, account);
-
- ag_account_set_enabled (account, on);
-
- /* if we are turning the account on, the global flag must also be set *
- * NOTE: this isn't needed when turning the account off */
- if (on)
- {
- ag_account_select_service (account, NULL);
- ag_account_set_enabled (account, on);
- }
-
- ag_account_select_service (account, original);
-
- return TRUE;
-}
-
-static gboolean _sso_account_enabled (
- McdAccountManagerSso *self,
- AgAccount *account,
- AgService *service)
-{
- gboolean local = FALSE;
- gboolean global = FALSE;
- AgService *original = ag_account_get_selected_service (account);
-
- if (service == NULL)
- {
- _ag_account_select_default_im_service (self, account);
- local = ag_account_get_enabled (account);
- }
- else
- {
- if (original != service)
- ag_account_select_service (account, service);
-
- local = ag_account_get_enabled (account);
- }
-
- ag_account_select_service (account, NULL);
- global = ag_account_get_enabled (account);
-
- ag_account_select_service (account, original);
-
- DEBUG ("_sso_account_enabled: global:%d && local:%d", global, local);
-
- return local && global;
-}
-
-static void _sso_created (GObject *object,
- AgAccountId id,
- gpointer user_data)
-{
- AgManager *ag_manager = AG_MANAGER (object);
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (user_data);
- gchar *name =
- g_hash_table_lookup (sso->id_name_map, GUINT_TO_POINTER (id));
-
- if (sso->ready)
- {
- /* if we already know the account's name, we shouldn't fire the new *
- * account signal as it is one we (and our superiors) already have *
- * This could happen as a result of multiple updates being set off *
- * before we are ready, for example */
- if (name == NULL)
- {
- McpAccountStorage *mcpa = MCP_ACCOUNT_STORAGE (sso);
- AgAccount *account = ag_manager_get_account (ag_manager, id);
-
- if (account != NULL)
- {
- /* this will be owned by the ag account hash, do not free it */
- name = _ag_accountid_to_mc_key (sso, id, TRUE);
-
- if (name != NULL)
- {
- Setting *setting = setting_data (MC_IDENTITY_KEY, SETTING_MC);
-
- g_hash_table_insert (sso->accounts, name, account);
- g_hash_table_insert (sso->id_name_map, GUINT_TO_POINTER (id),
- g_strdup (name));
-
- save_setting (sso, account, setting, name);
-
- ag_account_store (account, _ag_account_stored_cb, sso);
-
- mcp_account_storage_emit_created (mcpa, name);
-
- clear_setting_data (setting);
- }
- else
- {
- /* not enough data to name the account: wait for an update */
- DEBUG ("SSO account #%u is currently unnameable", id);
- }
-
- /* in either case, add the account to the watched list */
- watch_for_updates (sso, account);
- }
- }
- }
- else
- {
- DelayedSignalData *sig_data = g_slice_new0 (DelayedSignalData);
-
- sig_data->signal = DELAYED_CREATE;
- sig_data->account_id = id;
- g_queue_push_tail (sso->pending_signals, sig_data);
- }
-}
-
-static void
-mcd_account_manager_sso_init (McdAccountManagerSso *self)
-{
- self->accounts =
- g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
- self->id_name_map =
- g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
- self->watches =
- g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
- (GDestroyNotify) free_watch_data);
- self->pending_signals = g_queue_new ();
-
-}
-
-static void
-mcd_account_manager_sso_constructed (GObject *object)
-{
- McdAccountManagerSso *self = MCD_ACCOUNT_MANAGER_SSO (object);
- GObjectClass *parent_class =
- G_OBJECT_CLASS (mcd_account_manager_sso_parent_class);
- const gchar *service_type = account_manager_sso_get_service_type (self);
-
- if (parent_class->constructed != NULL)
- parent_class->constructed (object);
-
- DEBUG ("Watching for services of type '%s'", service_type);
- self->ag_manager = ag_manager_new_for_service_type (service_type);
-
- g_signal_connect(self->ag_manager, "enabled-event",
- G_CALLBACK (_sso_toggled), self);
- g_signal_connect(self->ag_manager, "account-deleted",
- G_CALLBACK (_sso_deleted), self);
- g_signal_connect(self->ag_manager, "account-created",
- G_CALLBACK (_sso_created), self);
-}
-
-static void
-mcd_account_manager_sso_class_init (McdAccountManagerSsoClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->constructed = mcd_account_manager_sso_constructed;
-
- klass->service_type = "IM";
-}
-
-static void
-_ag_account_stored_cb (
- AgAccount *account,
- const GError *err,
- gpointer user_data)
-{
- McdAccountManagerSso *self = MCD_ACCOUNT_MANAGER_SSO (user_data);
- GValue uid = G_VALUE_INIT;
- const gchar *name = NULL;
- AgSettingSource src = AG_SETTING_SOURCE_NONE;
-
- g_value_init (&uid, G_TYPE_STRING);
-
- src = _ag_account_local_value (self, account, MC_IDENTITY_KEY, &uid);
-
- if (src != AG_SETTING_SOURCE_NONE && G_VALUE_HOLDS_STRING (&uid))
- {
- name = g_value_get_string (&uid);
- DEBUG ("%p:%s stored: %s", account, name, err ? err->message : "-");
- g_value_unset (&uid);
- }
- else
- {
- DEBUG ("%p:%s not stored? %s", acct,
- ag_account_get_display_name (account), err ? err->message : "-");
- }
-}
-
-static gchar *
-_ag_accountid_to_mc_key (McdAccountManagerSso *sso,
- AgAccountId id,
- gboolean create)
-{
- AgAccount *account = ag_manager_get_account (sso->ag_manager, id);
- AgSettingSource src = AG_SETTING_SOURCE_NONE;
- AgService *service = NULL;
- GValue value = G_VALUE_INIT;
-
- if (account == NULL)
- {
- DEBUG ("AG Account ID %u invalid", id);
- return NULL;
- }
-
- service = ag_account_get_selected_service (account);
-
- DEBUG ("AG Account ID: %u", id);
-
- g_value_init (&value, G_TYPE_STRING);
-
- /* first look for the stored TMC uid */
- src = _ag_account_local_value (sso, account, MC_IDENTITY_KEY, &value);
-
- /* if we found something, our work here is done: */
- if (src != AG_SETTING_SOURCE_NONE)
- {
- gchar *uid = g_value_dup_string (&value);
- g_value_unset (&value);
- return uid;
- }
-
- if (!create)
- {
- g_value_unset (&value);
- return NULL;
- }
-
- DEBUG ("no " MC_IDENTITY_KEY " found, synthesising one:");
-
- src = _ag_account_global_value (account, AG_ACCOUNT_KEY, &value);
-
- /* fall back to the alernative account-naming setting if necessary: */
- if (src == AG_SETTING_SOURCE_NONE)
- {
- _ag_account_select_default_im_service (sso, account);
- src = _ag_account_local_value (sso, account, AG_ACCOUNT_ALT_KEY, &value);
- }
-
- if (src != AG_SETTING_SOURCE_NONE && G_VALUE_HOLDS_STRING (&value))
- {
- AgAccountSettingIter iter;
- const gchar *k;
- const GValue *v;
- GValue cmanager = G_VALUE_INIT;
- GValue protocol = G_VALUE_INIT;
- const gchar *cman, *proto;
- McpAccountManager *am = sso->manager_interface;
- GHashTable *params = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, NULL);
- gchar *name = NULL;
-
- g_value_init (&cmanager, G_TYPE_STRING);
- g_value_init (&protocol, G_TYPE_STRING);
-
- /* if we weren't on a service when got here, pick the most likely one: */
- if (service == NULL)
- _ag_account_select_default_im_service (sso, account);
-
- ag_account_get_value (account, MC_CMANAGER_KEY, &cmanager);
- cman = g_value_get_string (&cmanager);
-
- if (cman == NULL)
- goto cleanup;
-
- ag_account_get_value (account, MC_PROTOCOL_KEY, &protocol);
- proto = g_value_get_string (&protocol);
-
- if (proto == NULL)
- goto cleanup;
-
- /* prepare the hash of MC param keys -> GValue */
- /* NOTE: some AG bare settings map to MC parameters, *
- * so we must iterate over all AG settings, parameters *
- * and bare settings included */
-
- /* first any matching global values: */
- ag_account_select_service (account, NULL);
- ag_account_settings_iter_init (account, &iter, NULL);
-
- while (ag_account_settings_iter_next (&iter, &k, &v))
- {
- Setting *setting = setting_data (k, SETTING_AG);
-
- if (setting != NULL && g_str_has_prefix (setting->mc_name, MCPP))
- {
- gchar *param_key = g_strdup (setting->mc_name + strlen (MCPP));
-
- g_hash_table_insert (params, param_key, (gpointer) v);
- }
-
- clear_setting_data (setting);
- }
-
- /* then any service specific settings */
- if (service != NULL)
- ag_account_select_service (account, service);
- else
- _ag_account_select_default_im_service (sso, account);
-
- ag_account_settings_iter_init (account, &iter, NULL);
- while (ag_account_settings_iter_next (&iter, &k, &v))
- {
- Setting *setting = setting_data (k, SETTING_AG);
-
- if (setting != NULL && g_str_has_prefix (setting->mc_name, MCPP))
- {
- gchar *param_key = g_strdup (setting->mc_name + strlen (MCPP));
-
- g_hash_table_insert (params, param_key, (gpointer) v);
- }
-
- clear_setting_data (setting);
- }
-
- /* we want this to override any other settings for uid generation */
- g_hash_table_insert (params, g_strdup (MC_ACCOUNT_KEY), &value);
-
- /* FIXME: We should call IdentifyAccount(params) really. But this
- * plugin probably doesn't even compile any more, so, whatever;
- * just use the "account name". */
- name = mcp_account_manager_get_unique_name (am, cman, proto,
- g_value_get_string (&value));
-
- cleanup:
- ag_account_select_service (account, service);
- g_hash_table_unref (params);
- g_value_unset (&value);
- g_value_unset (&cmanager);
- g_value_unset (&protocol);
-
- DEBUG (MC_IDENTITY_KEY " value %p:%s synthesised", name, name);
- return name;
- }
- else
- {
- g_value_unset (&value);
- }
-
- DEBUG (MC_IDENTITY_KEY " not synthesised, returning NULL");
- return NULL;
-}
-
-static AgAccount *
-get_ag_account (const McdAccountManagerSso *sso,
- const McpAccountManager *am,
- const gchar *name,
- AgAccountId *id)
-{
- AgAccount *account;
-
- g_return_val_if_fail (id != NULL, NULL);
-
- /* we have a cached account, just return that */
- account = g_hash_table_lookup (sso->accounts, name);
- if (account != NULL)
- {
- *id = account->id;
- return account;
- }
-
- *id = 0;
-
- return NULL;
-}
-
-/* returns true if it actually changed an account's state */
-static gboolean
-save_setting (
- McdAccountManagerSso *self,
- AgAccount *account,
- const Setting *setting,
- const gchar *val)
-{
- gboolean changed = FALSE;
- AgService *service = ag_account_get_selected_service (account);
-
- if (!setting->writable)
- return FALSE;
-
- if (setting->global)
- ag_account_select_service (account, NULL);
- else if (service == NULL)
- _ag_account_select_default_im_service (self, account);
-
- if (setting->readable)
- {
- GValue old = G_VALUE_INIT;
- AgSettingSource src = AG_SETTING_SOURCE_NONE;
-
- g_value_init (&old, G_TYPE_STRING);
-
- if (setting->global)
- src = _ag_account_global_value (account, setting->ag_name, &old);
- else
- src = _ag_account_local_value (self, account, setting->ag_name, &old);
-
- /* unsetting an already unset value, bail out */
- if (val == NULL && src == AG_SETTING_SOURCE_NONE)
- goto done;
-
- /* assigning a value to one which _is_ set: check it actually changed */
- if (val != NULL && src != AG_SETTING_SOURCE_NONE)
- {
- gchar *str = _gvalue_to_string (&old);
- gboolean noop = g_strcmp0 (str, val) == 0;
-
- g_value_unset (&old);
- g_free (str);
-
- if (noop)
- goto done;
- }
- }
-
- /* if we got this far, we're changing the stored state: */
- changed = TRUE;
-
- if (val != NULL)
- {
- GValue value = G_VALUE_INIT;
-
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, val);
- ag_account_set_value (account, setting->ag_name, &value);
- g_value_unset (&value);
- }
- else
- {
- ag_account_set_value (account, setting->ag_name, NULL);
- }
-
- /* leave the selected service as we found it: */
- done:
- ag_account_select_service (account, service);
-
- return changed;
-}
-
-static gboolean
-_set (const McpAccountStorage *self,
- const McpAccountManager *am,
- const gchar *account_suffix,
- const gchar *key,
- const gchar *val)
-{
- AgAccountId id;
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (self);
- AgAccount *account = get_ag_account (sso, am, account_suffix, &id);
- Setting *setting = NULL;
- gboolean updated = FALSE;
-
- /* can't store a setting with no name */
- g_return_val_if_fail (key != NULL, FALSE);
-
- /* we no longer create accounts in libaccount: either an account exists *
- * in libaccount as a result of some 3rd party intervention, or it is *
- * not an account that this plugin should ever concern itself with */
-
- if (account != NULL)
- setting = setting_data (key, SETTING_MC);
- else
- return FALSE;
-
- if (setting != NULL)
- {
- /* Enabled is both a global and a local value, for extra fun: */
- if (g_str_equal (setting->mc_name, MC_ENABLED_KEY))
- {
- gboolean on = g_str_equal (val, "true");
-
- DEBUG ("setting enabled flag: '%d'", on);
- updated = _sso_account_enable (sso, account, NULL, on);
- }
- else
- {
- updated = save_setting (sso, account, setting, val);
- }
-
- if (updated)
- sso->save = TRUE;
-
- clear_setting_data (setting);
- }
-
- /* whether or not we stored this value, if we got this far it's our *
- * setting and no-one else is allowed to claim it: so return TRUE */
- return TRUE;
-}
-
-/* Implements the half of the _get method where key is not NULL. */
-static void
-account_manager_sso_get_one (
- McdAccountManagerSso *sso,
- const McpAccountManager *am,
- const gchar *account_suffix,
- const gchar *key,
- AgAccount *account,
- AgService *service)
-{
- if (g_str_equal (key, MC_ENABLED_KEY))
- {
- const gchar *v = NULL;
-
- v = _sso_account_enabled (sso, account, service) ? "true" : "false";
- mcp_account_manager_set_value (am, account_suffix, key, v);
- }
- else if (g_str_equal (key, SERVICES_KEY))
- {
- GString *result = g_string_new ("");
- AgManager * agm = ag_account_get_manager (account);
- GList *services = ag_manager_list_services (agm);
- GList *item = NULL;
-
- for (item = services; item != NULL; item = g_list_next (item))
- {
- const gchar *name = ag_service_get_name (item->data);
-
- g_string_append_printf (result, "%s;", name);
- }
-
- mcp_account_manager_set_value (am, account_suffix, key, result->str);
-
- ag_service_list_free (services);
- g_string_free (result, TRUE);
- }
- else if (g_str_equal (key, MC_SERVICE_KEY))
- {
- const gchar *service_name = NULL;
- AgService *im_service = NULL;
-
- _ag_account_select_default_im_service (sso, account);
- im_service = ag_account_get_selected_service (account);
- service_name = ag_service_get_name (im_service);
- mcp_account_manager_set_value (am, account_suffix, key, service_name);
- }
- else
- {
- GValue v = G_VALUE_INIT;
- AgSettingSource src = AG_SETTING_SOURCE_NONE;
- Setting *setting = setting_data (key, SETTING_MC);
-
- if (setting == NULL)
- return;
-
- g_value_init (&v, G_TYPE_STRING);
-
- if (setting->global)
- src = _ag_account_global_value (account, setting->ag_name, &v);
- else
- src = _ag_account_local_value (sso, account, setting->ag_name, &v);
-
- if (src != AG_SETTING_SOURCE_NONE)
- {
- gchar *val = _gvalue_to_string (&v);
-
- mcp_account_manager_set_value (am, account_suffix, key, val);
-
- g_free (val);
- }
-
- if (g_str_equal (key, MCPP MC_ACCOUNT_KEY))
- _maybe_set_account_param_from_service (sso, am, account,
- account_suffix);
-
- g_value_unset (&v);
- clear_setting_data (setting);
- }
-}
-
-/* Implements the half of the _get method where key == NULL, which is an
- * instruction from MC that we should look up all of this account's properties
- * and stash them with mcp_account_manager_set_value().
- */
-static void
-account_manager_sso_get_all (
- McdAccountManagerSso *sso,
- const McpAccountManager *am,
- const gchar *account_suffix,
- AgAccount *account,
- AgService *service)
-{
- AgAccountSettingIter ag_setting;
- const gchar *k;
- const GValue *v;
- const gchar *on = NULL;
- AgService *im_service = NULL;
-
- /* pick the IM service if we haven't got one set */
- if (service == NULL)
- _ag_account_select_default_im_service (sso, account);
-
- /* special case, not stored as a normal setting */
- im_service = ag_account_get_selected_service (account);
- mcp_account_manager_set_value (am, account_suffix, MC_SERVICE_KEY,
- ag_service_get_name (im_service));
-
- ag_account_settings_iter_init (account, &ag_setting, NULL);
- while (ag_account_settings_iter_next (&ag_setting, &k, &v))
- {
- Setting *setting = setting_data (k, SETTING_AG);
-
- if (setting != NULL && setting->readable && !setting->global)
- {
- gchar *value = _gvalue_to_string (v);
-
- mcp_account_manager_set_value (am, account_suffix,
- setting->mc_name, value);
-
- g_free (value);
- }
-
- clear_setting_data (setting);
- }
-
- /* deselect any service we may have to get global settings */
- ag_account_select_service (account, NULL);
- ag_account_settings_iter_init (account, &ag_setting, NULL);
-
- while (ag_account_settings_iter_next (&ag_setting, &k, &v))
- {
- Setting *setting = setting_data (k, SETTING_AG);
-
- if (setting != NULL && setting->readable && setting->global)
- {
- gchar *value = _gvalue_to_string (v);
-
- mcp_account_manager_set_value (am, account_suffix,
- setting->mc_name, value);
-
- g_free (value);
- }
-
- clear_setting_data (setting);
- }
-
- /* special case, actually two separate but related flags in SSO */
- on = _sso_account_enabled (sso, account, NULL) ? "true" : "false";
- mcp_account_manager_set_value (am, account_suffix, MC_ENABLED_KEY, on);
-
- _maybe_set_account_param_from_service (sso, am, account, account_suffix);
-}
-
-gboolean
-_mcd_account_manager_sso_get (
- const McpAccountStorage *self,
- const McpAccountManager *am,
- const gchar *account_suffix,
- const gchar *key)
-{
- AgAccountId id;
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (self);
- AgAccount *account = get_ag_account (sso, am, account_suffix, &id);
- AgService *service = ag_account_get_selected_service (account);
-
- if (account == NULL)
- return FALSE;
-
- /* Delegate to one of the two relatively-orthogonal meanings of this
- * method... */
- if (key != NULL)
- account_manager_sso_get_one (sso, am, account_suffix, key, account,
- service);
- else
- account_manager_sso_get_all (sso, am, account_suffix, account, service);
-
- /* leave the selected service as we found it */
- ag_account_select_service (account, service);
- return TRUE;
-}
-
-static gboolean
-_delete (const McpAccountStorage *self,
- const McpAccountManager *am,
- const gchar *account_suffix,
- const gchar *key)
-{
- AgAccountId id;
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (self);
- AgAccount *account = get_ag_account (sso, am, account_suffix, &id);
- gboolean updated = FALSE;
-
- /* have no values for this account, nothing to do here: */
- if (account == NULL)
- return TRUE;
-
- if (key == NULL)
- {
- ag_account_delete (account);
- g_hash_table_remove (sso->accounts, account_suffix);
- g_hash_table_remove (sso->id_name_map, GUINT_TO_POINTER (id));
-
- /* stop watching for updates */
- unwatch_account_keys (sso, id);
- updated = TRUE;
- }
- else
- {
- Setting *setting = setting_data (key, SETTING_MC);
-
- if (setting != NULL)
- updated = save_setting (sso, account, setting, NULL);
-
- clear_setting_data (setting);
- }
-
- if (updated)
- sso->save = TRUE;
-
- return TRUE;
-}
-
-static gboolean
-_commit_real (gpointer user_data)
-{
- McpAccountStorage *self = MCP_ACCOUNT_STORAGE (user_data);
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (self);
- GHashTableIter iter;
- gchar *key;
- AgAccount *account;
-
- g_hash_table_iter_init (&iter, sso->accounts);
-
- /* for each account, set its telepathy uid MC_IDENTITY_KEY in the *
- * AgAccount structure, and then flush any changes to said account *
- * to long term storage with ag_account_store() *
- * The actual changes are those pushed into the AgAccount in _set *
- * and _delete */
- while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &account))
- {
- Setting *setting = setting_data (MC_IDENTITY_KEY, SETTING_MC);
- /* this value ties MC accounts to SSO accounts */
- save_setting (sso, account, setting, key);
- ag_account_store (account, _ag_account_stored_cb, sso);
- }
-
- sso->commit_source = 0;
-
- /* any pending changes should now have been pushed, clear the save-me flag */
- sso->save = FALSE;
-
- return FALSE;
-}
-
-static gboolean
-_commit (const McpAccountStorage *self,
- const McpAccountManager *am)
-{
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (self);
-
- if (!sso->save)
- return TRUE;
-
- if (sso->commit_source == 0)
- {
- DEBUG ("Deferring commit for %d seconds", AG_ACCOUNT_WRITE_INTERVAL);
- sso->commit_source = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
- AG_ACCOUNT_WRITE_INTERVAL,
- _commit_real, g_object_ref (sso), g_object_unref);
- }
- else
- {
- DEBUG ("Already deferred commit");
- }
-
- return TRUE;
-}
-
-static void
-_load_from_libaccounts (McdAccountManagerSso *sso,
- const McpAccountManager *am)
-{
- GList *ag_ids = ag_manager_list_by_service_type (sso->ag_manager,
- account_manager_sso_get_service_type (sso));
- GList *ag_id;
-
- for (ag_id = ag_ids; ag_id != NULL; ag_id = g_list_next (ag_id))
- {
- const gchar *key;
- const GValue *val;
- AgAccountSettingIter iter;
- AgAccountId id = GPOINTER_TO_UINT (ag_id->data);
- AgAccount *account = ag_manager_get_account (sso->ag_manager, id);
-
- if (account != NULL)
- {
- AgService *service = ag_account_get_selected_service (account);
- gchar *name = _ag_accountid_to_mc_key (sso, id, FALSE);
-
- if (name != NULL)
- {
- AgService *im_service = NULL;
- gchar *ident = g_strdup_printf ("%u", id);
- GStrv mc_id = g_strsplit (name, "/", 3);
- gboolean enabled;
-
- /* cache the account object, and the ID->name maping: the *
- * latter is required because we might receive an async *
- * delete signal with the ID after libaccounts-glib has *
- * purged all its account data, so we couldn't rely on the *
- * MC_IDENTITY_KEY setting. */
- g_hash_table_insert (sso->accounts, name, account);
- g_hash_table_insert (sso->id_name_map, GUINT_TO_POINTER (id),
- g_strdup (name));
-
- if (service == NULL)
- _ag_account_select_default_im_service (sso, account);
-
- /* special case, not stored as a normal setting */
- im_service = ag_account_get_selected_service (account);
- mcp_account_manager_set_value (am, name, MC_SERVICE_KEY,
- ag_service_get_name (im_service));
-
- ag_account_settings_iter_init (account, &iter, NULL);
-
- while (ag_account_settings_iter_next (&iter, &key, &val))
- {
- Setting *setting = setting_data (key, SETTING_AG);
-
- if (setting != NULL && !setting->global && setting->readable)
- {
- gchar *value = _gvalue_to_string (val);
-
- mcp_account_manager_set_value (am, name, setting->mc_name,
- value);
-
- g_free (value);
- }
-
- clear_setting_data (setting);
- }
-
- ag_account_select_service (account, NULL);
- ag_account_settings_iter_init (account, &iter, NULL);
-
- while (ag_account_settings_iter_next (&iter, &key, &val))
- {
- Setting *setting = setting_data (key, SETTING_AG);
-
- if (setting != NULL && setting->global && setting->readable)
- {
- gchar *value = _gvalue_to_string (val);
-
- mcp_account_manager_set_value (am, name, setting->mc_name,
- value);
-
- g_free (value);
- }
-
- clear_setting_data (setting);
- }
-
- /* special case, actually two separate but related flags in SSO */
- enabled = _sso_account_enabled (sso, account, NULL);
-
- mcp_account_manager_set_value (am, name, MC_ENABLED_KEY,
- enabled ? "true" : "false");
- mcp_account_manager_set_value (am, name, LIBACCT_ID_KEY, ident);
- mcp_account_manager_set_value (am, name, MC_CMANAGER_KEY, mc_id[0]);
- mcp_account_manager_set_value (am, name, MC_PROTOCOL_KEY, mc_id[1]);
- mcp_account_manager_set_value (am, name, MC_IDENTITY_KEY, name);
- _maybe_set_account_param_from_service (sso, am, account, name);
-
- /* force the services value to be synthesised + cached */
- _mcd_account_manager_sso_get (MCP_ACCOUNT_STORAGE (sso), am,
- name, SERVICES_KEY);
-
- ag_account_select_service (account, service);
-
- watch_for_updates (sso, account);
-
- g_strfreev (mc_id);
- g_free (ident);
- }
- }
- }
-
- sso->loaded = TRUE;
- ag_manager_list_free (ag_ids);
-}
-
-static GList *
-_list (const McpAccountStorage *self,
- const McpAccountManager *am)
-{
- GList *rval = NULL;
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (self);
- GList *ag_ids = NULL;
- GList *ag_id;
-
- if (!sso->loaded)
- _load_from_libaccounts (sso, am);
-
- ag_ids = ag_manager_list_by_service_type (sso->ag_manager,
- account_manager_sso_get_service_type (sso));
-
- for (ag_id = ag_ids; ag_id != NULL; ag_id = g_list_next (ag_id))
- {
- AgAccountId id = GPOINTER_TO_UINT (ag_id->data);
- gchar *name = NULL;
-
- name = _ag_accountid_to_mc_key (sso, id, FALSE);
-
- if (name != NULL)
- {
- DEBUG ("account %s listed", name);
- rval = g_list_prepend (rval, name);
- }
- else
- {
- DelayedSignalData *data = g_slice_new0 (DelayedSignalData);
-
- DEBUG ("account %u delayed", id);
- data->signal = DELAYED_CREATE;
- data->account_id = id;
- g_queue_push_tail (sso->pending_signals, data);
- }
- }
-
- ag_manager_list_free (ag_ids);
-
- return rval;
-}
-
-static void
-_ready (const McpAccountStorage *self,
- const McpAccountManager *am)
-{
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (self);
-
- if (sso->ready)
- return;
-
- g_assert (sso->manager_interface == NULL);
- sso->manager_interface = g_object_ref (G_OBJECT (am));
- sso->ready = TRUE;
-
- while (g_queue_get_length (sso->pending_signals) > 0)
- {
- DelayedSignalData *data = g_queue_pop_head (sso->pending_signals);
- GObject *signal_source = G_OBJECT (sso->ag_manager);
-
- switch (data->signal)
- {
- case DELAYED_CREATE:
- _sso_created (signal_source, data->account_id, sso);
- break;
- case DELAYED_DELETE:
- _sso_deleted (signal_source, data->account_id, sso);
- break;
- default:
- g_assert_not_reached ();
- }
-
- g_slice_free (DelayedSignalData, data);
- }
-
- g_queue_free (sso->pending_signals);
- sso->pending_signals = NULL;
-}
-
-static gboolean
-_find_account (McdAccountManagerSso *sso,
- const gchar *account_name,
- AgAccountId *account_id)
-{
- GList *ag_ids = NULL;
- GList *ag_id;
- gboolean found = FALSE;
-
- g_return_val_if_fail (account_id != NULL, found);
-
- ag_ids = ag_manager_list_by_service_type (sso->ag_manager,
- account_manager_sso_get_service_type (sso));
-
- for (ag_id = ag_ids; ag_id != NULL; ag_id = g_list_next (ag_id))
- {
- AgAccountId id = GPOINTER_TO_UINT (ag_id->data);
- gchar *name = NULL;
-
- name = _ag_accountid_to_mc_key (sso, id, FALSE);
-
- if (g_strcmp0 (name, account_name) == 0)
- {
- found = TRUE;
- *account_id = id;
- }
-
- g_free (name);
-
- if (found)
- break;
- }
-
- ag_manager_list_free (ag_ids);
-
- return found;
-}
-
-static void
-_get_identifier (const McpAccountStorage *self,
- const gchar *account,
- GValue *identifier)
-{
- AgAccountId account_id = 0;
-
- if (!_find_account (MCD_ACCOUNT_MANAGER_SSO (self), account, &account_id))
- g_warning ("Didn't find account %s in %s", account, PLUGIN_NAME);
-
- g_value_init (identifier, G_TYPE_UINT);
-
- g_value_set_uint (identifier, account_id);
-}
-
-static GHashTable *
-_get_additional_info (const McpAccountStorage *self,
- const gchar *account_suffix)
-{
- AgAccountId account_id = 0;
- McdAccountManagerSso *sso = MCD_ACCOUNT_MANAGER_SSO (self);
- GHashTable *additional_info = NULL;
- AgAccount *account;
- AgService *service;
- AgAccountSettingIter iter;
- const GValue *val;
- const gchar *key;
-
- if (!_find_account (sso, account_suffix, &account_id))
- {
- g_warning ("Didn't find account %s in %s", account_suffix, PLUGIN_NAME);
- return NULL;
- }
-
- account = ag_manager_get_account (sso->ag_manager, account_id);
-
- g_return_val_if_fail (account != NULL, NULL);
-
- service = ag_account_get_selected_service (account);
-
- additional_info = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free, (GDestroyNotify) tp_g_value_slice_free);
-
- if (service == NULL)
- _ag_account_select_default_im_service (sso, account);
-
- ag_account_settings_iter_init (account, &iter, NULL);
-
- while (ag_account_settings_iter_next (&iter, &key, &val))
- {
- if (tp_strv_contains (exported_settings, key))
- g_hash_table_insert (additional_info, g_strdup (key),
- tp_g_value_slice_dup (val));
- }
-
- ag_account_select_service (account, NULL);
- ag_account_settings_iter_init (account, &iter, NULL);
-
- while (ag_account_settings_iter_next (&iter, &key, &val))
- {
- if (tp_strv_contains (exported_settings, key))
- g_hash_table_insert (additional_info, g_strdup (key),
- tp_g_value_slice_dup (val));
- }
-
- ag_account_select_service (account, service);
-
- g_object_unref (account);
-
- return additional_info;
-}
-
-static void
-account_storage_iface_init (McpAccountStorageIface *iface,
- gpointer unused G_GNUC_UNUSED)
-{
- iface->name = PLUGIN_NAME;
- iface->desc = PLUGIN_DESCRIPTION;
- iface->priority = PLUGIN_PRIORITY;
- iface->provider = PLUGIN_PROVIDER;
-
- iface->get = _mcd_account_manager_sso_get;
- iface->set = _set;
- iface->delete = _delete;
- iface->commit = _commit;
- iface->list = _list;
- iface->ready = _ready;
- iface->get_identifier = _get_identifier;
- iface->get_additional_info = _get_additional_info;
-}
-
-McdAccountManagerSso *
-mcd_account_manager_sso_new (void)
-{
- return g_object_new (MCD_TYPE_ACCOUNT_MANAGER_SSO, NULL);
-}
diff --git a/src/mcd-account-manager-sso.h b/src/mcd-account-manager-sso.h
deleted file mode 100644
index 12e616f8..00000000
--- a/src/mcd-account-manager-sso.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * The SSO/libaccounts-glib manager keyfile storage pseudo-plugin
- *
- * Copyright © 2010 Nokia Corporation
- * Copyright © 2010 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 <mission-control-plugins/mission-control-plugins.h>
-#include <libaccounts-glib/ag-manager.h>
-
-#ifndef __MCD_ACCOUNT_MANAGER_SSO_H__
-#define __MCD_ACCOUNT_MANAGER_SSO_H__
-
-G_BEGIN_DECLS
-
-#define MCD_TYPE_ACCOUNT_MANAGER_SSO \
- (mcd_account_manager_sso_get_type ())
-
-#define MCD_ACCOUNT_MANAGER_SSO(o) \
- (G_TYPE_CHECK_INSTANCE_CAST ((o), MCD_TYPE_ACCOUNT_MANAGER_SSO, \
- McdAccountManagerSso))
-
-#define MCD_ACCOUNT_MANAGER_SSO_CLASS(k) \
- (G_TYPE_CHECK_CLASS_CAST((k), MCD_TYPE_ACCOUNT_MANAGER_SSO, \
- McdAccountManagerSsoClass))
-
-#define MCD_IS_ACCOUNT_MANAGER_SSO(o) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((o), MCD_TYPE_ACCOUNT_MANAGER_SSO))
-
-#define MCD_IS_ACCOUNT_MANAGER_SSO_CLASS(k) \
- (G_TYPE_CHECK_CLASS_TYPE ((k), MCD_TYPE_ACCOUNT_MANAGER_SSO))
-
-#define MCD_ACCOUNT_MANAGER_SSO_GET_CLASS(o) \
- (G_TYPE_INSTANCE_GET_CLASS ((o), MCD_TYPE_ACCOUNT_MANAGER_SSO, \
- McdAccountManagerSsoClass))
-
-typedef struct {
- GObject parent;
- GHashTable *accounts;
- GHashTable *id_name_map;
- GHashTable *watches;
- GQueue *pending_signals;
- AgManager *ag_manager;
- McpAccountManager *manager_interface;
- gboolean ready;
- gboolean save;
- gboolean loaded;
- guint commit_source;
-} _McdAccountManagerSso;
-
-typedef struct {
- GObjectClass parent_class;
-
- /* In the libaccounts model, each account has a number of associated
- * 'services'; for example, you might have a Google account with Google Talk,
- * Google Mail, Google Calendar, etc. services. Each service is of a
- * particular service type; for instance, the service named "google-talk" is
- * of type "IM".
- *
- * Typically we care about the "IM" service type for Telepathy purposes; but
- * we allow for the possibility of a subclass which cares about some other
- * service type.
- */
- const gchar *service_type;
-} _McdAccountManagerSsoClass;
-
-typedef _McdAccountManagerSso McdAccountManagerSso;
-typedef _McdAccountManagerSsoClass McdAccountManagerSsoClass;
-
-GType mcd_account_manager_sso_get_type (void) G_GNUC_CONST;
-
-McdAccountManagerSso *mcd_account_manager_sso_new (void);
-
-/* FIXME: we shouldn't need to expose this. Subclasses should be able to chain
- * up to the parent class's implementation of the interface method, but they
- * can't because McpAccountStorageIface isn't exposed. See
- * <https://bugs.freedesktop.org//show_bug.cgi?id=32914>.
- */
-gboolean _mcd_account_manager_sso_get (
- const McpAccountStorage *self,
- const McpAccountManager *am,
- const gchar *account_suffix,
- const gchar *key);
-
-G_END_DECLS
-
-#endif
diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c
index 2675dd97..45c180e3 100644
--- a/src/mcd-account-manager.c
+++ b/src/mcd-account-manager.c
@@ -336,7 +336,7 @@ toggled_cb (GObject *plugin, const gchar *name, gboolean on, gpointer data)
}
_mcd_account_set_enabled (account, on, FALSE,
- MCD_DBUS_PROP_SET_FLAG_NONE, &error);
+ MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE, &error);
if (error != NULL)
{
@@ -398,7 +398,9 @@ deleted_cb (GObject *plugin, const gchar *name, gpointer data)
/* this unhooks the account's signal handlers */
g_hash_table_remove (manager->priv->accounts, name);
tp_svc_account_manager_emit_account_removed (manager, object_path);
- mcd_account_delete (account, _mcd_account_delete_cb, NULL);
+ mcd_account_delete (account,
+ MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE,
+ _mcd_account_delete_cb, NULL);
}
}
@@ -710,7 +712,8 @@ complete_account_creation_finish (McdAccount *account,
if (!cad->ok)
{
- mcd_account_delete (account, NULL, NULL);
+ mcd_account_delete (account, MCD_DBUS_PROP_SET_FLAG_NONE,
+ NULL, NULL);
tp_clear_object (&account);
}
@@ -1166,7 +1169,8 @@ migrate_create_account_cb (McdAccountManager *account_manager,
DEBUG ("Account %s migrated, removing it",
mcd_account_get_unique_name (ctx->account));
- mcd_account_delete (ctx->account, migrate_delete_account_cb, ctx);
+ mcd_account_delete (ctx->account, MCD_DBUS_PROP_SET_FLAG_NONE,
+ migrate_delete_account_cb, ctx);
}
static void
diff --git a/src/mcd-account-priv.h b/src/mcd-account-priv.h
index 649efa63..cf682f25 100644
--- a/src/mcd-account-priv.h
+++ b/src/mcd-account-priv.h
@@ -152,8 +152,6 @@ G_GNUC_INTERNAL gboolean _mcd_account_check_request_real (McdAccount *account,
GHashTable *request,
GError **error);
-G_GNUC_INTERNAL gboolean _mcd_account_get_always_on (McdAccount *self);
-
G_GNUC_INTERNAL void _mcd_account_set_changing_presence (McdAccount *self,
gboolean value);
G_GNUC_INTERNAL gboolean _mcd_account_set_enabled (McdAccount *account,
diff --git a/src/mcd-account.c b/src/mcd-account.c
index 43fc862c..b9d87dd0 100644
--- a/src/mcd-account.c
+++ b/src/mcd-account.c
@@ -158,7 +158,6 @@ struct _McdAccountPrivate
gboolean loaded;
gboolean has_been_online;
gboolean removed;
- gboolean always_on;
gboolean changing_presence;
gboolean setting_avatar;
gboolean waiting_for_initial_avatar;
@@ -183,7 +182,6 @@ enum
PROP_CONNECTIVITY_MONITOR,
PROP_STORAGE,
PROP_NAME,
- PROP_ALWAYS_ON,
};
enum
@@ -673,8 +671,12 @@ account_delete_identify_account_cb (TpProxy *protocol,
g_object_unref (account);
}
+static TpStorageRestrictionFlags mcd_account_get_storage_restrictions (
+ McdAccount *account);
+
void
mcd_account_delete (McdAccount *account,
+ McdDBusPropSetFlags flags,
McdAccountDeleteCb callback,
gpointer user_data)
{
@@ -684,6 +686,23 @@ mcd_account_delete (McdAccount *account,
const gchar *name = mcd_account_get_unique_name (account);
TpConnectionManager *cm = mcd_account_get_cm (account);
+ /* We don't really have a flag for "cannot delete accounts" yet, but
+ * it seems reasonable that if you can't disable it or put it
+ * offline, you shouldn't be able to delete it. Also, we're going
+ * to try to disable it in a moment anyway. */
+ if ((flags & MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE) == 0 &&
+ (mcd_account_get_storage_restrictions (account) &
+ (TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED |
+ TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PRESENCE)) != 0)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
+ "Storage plugin for %s does not allow deleting it",
+ name);
+ callback (account, error, user_data);
+ g_error_free (error);
+ return;
+ }
+
/* if the CM implements CM.I.AccountStorage, we need to tell the CM
* to forget any account credentials it knows */
if (tp_proxy_has_interface_by_id (cm,
@@ -707,7 +726,7 @@ mcd_account_delete (McdAccount *account,
/* got to turn the account off before removing it, otherwise we can *
* end up with an orphaned CM holding the account online */
if (!_mcd_account_set_enabled (account, FALSE, FALSE,
- MCD_DBUS_PROP_SET_FLAG_NONE, &error))
+ flags, &error))
{
g_warning ("could not disable account %s (%s)", name, error->message);
callback (account, error, user_data);
@@ -1153,19 +1172,21 @@ _mcd_account_set_enabled (McdAccount *account,
{
McdAccountPrivate *priv = account->priv;
- if (priv->always_on && !enabled)
- {
- g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
- "Account %s cannot be disabled",
- priv->unique_name);
- return FALSE;
- }
-
if (priv->enabled != enabled)
{
GValue value = G_VALUE_INIT;
const gchar *name = mcd_account_get_unique_name (account);
+ if ((flags & MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE) == 0 &&
+ (mcd_account_get_storage_restrictions (account) &
+ TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED) != 0)
+ {
+ g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
+ "Storage plugin for %s does not allow changing "
+ "its Enabled property", name);
+ return FALSE;
+ }
+
if (!enabled && priv->connection != NULL)
_mcd_connection_request_presence (priv->connection,
TP_CONNECTION_PRESENCE_TYPE_OFFLINE,
@@ -1693,6 +1714,16 @@ set_automatic_presence (TpSvcDBusProperties *self,
return FALSE;
}
+ if ((flags & MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE) == 0 &&
+ (mcd_account_get_storage_restrictions (account) &
+ TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PRESENCE) != 0)
+ {
+ g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
+ "Storage plugin for %s does not allow changing "
+ "its presence", priv->unique_name);
+ return FALSE;
+ }
+
DEBUG ("setting automatic presence: %d, %s, %s", type, status, message);
if (priv->auto_presence_type != type)
@@ -1774,18 +1805,24 @@ set_connect_automatically (TpSvcDBusProperties *self,
connect_automatically = g_value_get_boolean (value);
- if (priv->always_on && !connect_automatically)
- {
- g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
- "Account %s always connects automatically",
- priv->unique_name);
- return FALSE;
- }
-
if (priv->connect_automatically != connect_automatically)
{
const gchar *account_name = mcd_account_get_unique_name (account);
+ /* We use CANNOT_SET_PRESENCE to control access to
+ * ConnectAutomatically, because RequestedPresence is not stored,
+ * but it can be derived from ConnectAutomatically and
+ * AutomaticPresence */
+ if ((flags & MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE) == 0 &&
+ (mcd_account_get_storage_restrictions (account) &
+ TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PRESENCE) != 0)
+ {
+ g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
+ "Storage plugin for %s does not allow changing "
+ "its ConnectAutomatically property", account_name);
+ return FALSE;
+ }
+
if (!(flags & MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE))
{
mcd_storage_set_attribute (priv->storage, account_name,
@@ -1927,10 +1964,13 @@ set_requested_presence (TpSvcDBusProperties *self,
status = g_value_get_string (va->values + 1);
message = g_value_get_string (va->values + 2);
- if (priv->always_on && !_presence_type_is_online (type))
+ if ((flags & MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE) == 0 &&
+ (mcd_account_get_storage_restrictions (account) &
+ TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PRESENCE) != 0)
{
g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED,
- "Account %s cannot be taken offline", priv->unique_name);
+ "Storage plugin for %s does not allow changing "
+ "its presence", priv->unique_name);
return FALSE;
}
@@ -2137,22 +2177,24 @@ get_storage_specific_info (TpSvcDBusProperties *self,
g_value_take_boxed (value, storage_specific_info);
}
+static TpStorageRestrictionFlags
+mcd_account_get_storage_restrictions (McdAccount *self)
+{
+ McpAccountStorage *storage_plugin = get_storage_plugin (self);
+
+ g_return_val_if_fail (storage_plugin != NULL, 0);
+
+ return mcp_account_storage_get_restrictions (storage_plugin,
+ self->priv->unique_name);
+}
+
static void
get_storage_restrictions (TpSvcDBusProperties *self,
const gchar *name, GValue *value)
{
- TpStorageRestrictionFlags flags;
- McdAccount *account = MCD_ACCOUNT (self);
- McpAccountStorage *storage_plugin = get_storage_plugin (account);
-
g_value_init (value, G_TYPE_UINT);
-
- g_return_if_fail (storage_plugin != NULL);
-
- flags = mcp_account_storage_get_restrictions (storage_plugin,
- account->priv->unique_name);
-
- g_value_set_uint (value, flags);
+ g_value_set_uint (value,
+ mcd_account_get_storage_restrictions (MCD_ACCOUNT (self)));
}
static const McdDBusProp account_properties[] = {
@@ -2419,7 +2461,8 @@ account_remove (TpSvcAccount *svc, DBusGMethodInvocation *context)
data->context = context;
DEBUG ("called");
- mcd_account_delete (self, account_remove_delete_cb, data);
+ mcd_account_delete (self, MCD_DBUS_PROP_SET_FLAG_NONE,
+ account_remove_delete_cb, data);
}
/*
@@ -3235,15 +3278,11 @@ mcd_account_setup (McdAccount *account)
priv->object_path = g_strconcat (TP_ACCOUNT_OBJECT_PATH_BASE, name, NULL);
- if (!priv->always_on)
- {
- priv->enabled =
- mcd_storage_get_boolean (storage, name, MC_ACCOUNTS_KEY_ENABLED);
+ priv->enabled = mcd_storage_get_boolean (storage, name,
+ MC_ACCOUNTS_KEY_ENABLED);
- priv->connect_automatically =
- mcd_storage_get_boolean (storage, name,
- MC_ACCOUNTS_KEY_CONNECT_AUTOMATICALLY);
- }
+ priv->connect_automatically = mcd_storage_get_boolean (storage, name,
+ MC_ACCOUNTS_KEY_CONNECT_AUTOMATICALLY);
priv->has_been_online =
mcd_storage_get_boolean (storage, name, MC_ACCOUNTS_KEY_HAS_BEEN_ONLINE);
@@ -3393,19 +3432,6 @@ set_property (GObject *obj, guint prop_id,
priv->unique_name = g_value_dup_string (val);
break;
- case PROP_ALWAYS_ON:
- priv->always_on = g_value_get_boolean (val);
-
- if (priv->always_on)
- {
- priv->enabled = TRUE;
- priv->connect_automatically = TRUE;
- priv->req_presence_type = priv->auto_presence_type;
- priv->req_presence_status = g_strdup (priv->auto_presence_status);
- priv->req_presence_message = g_strdup (priv->auto_presence_message);
- }
-
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -3657,13 +3683,6 @@ mcd_account_class_init (McdAccountClass * klass)
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property
- (object_class, PROP_ALWAYS_ON,
- g_param_spec_boolean ("always-on", "Always on?", "Always on?",
- FALSE,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
/* Signals */
_mcd_account_signals[USABILITY_CHANGED] =
g_signal_new ("usability-changed",
@@ -3705,7 +3724,6 @@ mcd_account_init (McdAccount *account)
priv->curr_presence_status = g_strdup ("offline");
priv->curr_presence_message = g_strdup ("");
- priv->always_on = FALSE;
priv->always_dispatch = FALSE;
priv->enabled = FALSE;
priv->connect_automatically = FALSE;
@@ -5131,14 +5149,6 @@ _mcd_account_set_connection_context (McdAccount *self,
}
gboolean
-_mcd_account_get_always_on (McdAccount *self)
-{
- g_return_val_if_fail (MCD_IS_ACCOUNT (self), FALSE);
-
- return self->priv->always_on;
-}
-
-gboolean
_mcd_account_needs_dispatch (McdAccount *self)
{
g_return_val_if_fail (MCD_IS_ACCOUNT (self), FALSE);
diff --git a/src/mcd-account.h b/src/mcd-account.h
index a7489f72..b01cfe5a 100644
--- a/src/mcd-account.h
+++ b/src/mcd-account.h
@@ -40,6 +40,7 @@ typedef struct _McdAccountClass McdAccountClass;
#include "mcd-connection.h"
#include "mcd-account-manager.h"
+#include "mcd-dbusprop.h"
struct _McdAccount
{
@@ -84,7 +85,9 @@ McdAccount *mcd_account_new (McdAccountManager *account_manager,
const gchar *name,
McdConnectivityMonitor *minotaur);
-void mcd_account_delete (McdAccount *account, McdAccountDeleteCb callback,
+void mcd_account_delete (McdAccount *account,
+ McdDBusPropSetFlags flags,
+ McdAccountDeleteCb callback,
gpointer user_data);
const gchar *mcd_account_get_unique_name (McdAccount *account);
diff --git a/src/mcd-client-priv.h b/src/mcd-client-priv.h
index c00ce13a..069d2a67 100644
--- a/src/mcd-client-priv.h
+++ b/src/mcd-client-priv.h
@@ -97,8 +97,6 @@ G_GNUC_INTERNAL const GList *_mcd_client_proxy_get_handler_filters
(McdClientProxy *self);
G_GNUC_INTERNAL gboolean _mcd_client_proxy_get_bypass_approval
(McdClientProxy *self);
-G_GNUC_INTERNAL gboolean _mcd_client_proxy_get_bypass_observers
- (McdClientProxy *self);
G_GNUC_INTERNAL gboolean _mcd_client_proxy_get_delay_approvers
(McdClientProxy *self);
diff --git a/src/mcd-client.c b/src/mcd-client.c
index 0a232c89..d51dc1e7 100644
--- a/src/mcd-client.c
+++ b/src/mcd-client.c
@@ -68,7 +68,6 @@ struct _McdClientProxyPrivate
gboolean introspect_started;
gboolean ready;
gboolean bypass_approval;
- gboolean bypass_observers;
gboolean delay_approvers;
gboolean recover;
@@ -400,10 +399,6 @@ parse_client_file (McdClientProxy *client,
g_key_file_get_boolean (file, TP_IFACE_CLIENT_HANDLER,
"BypassApproval", NULL);
- client->priv->bypass_observers =
- g_key_file_get_boolean (file, TP_IFACE_CLIENT_HANDLER,
- "BypassObservers", NULL);
-
client->priv->delay_approvers =
g_key_file_get_boolean (file, TP_IFACE_CLIENT_OBSERVER,
"DelayApprovers", NULL);
@@ -664,10 +659,6 @@ _mcd_client_proxy_handler_get_all_cb (TpProxy *proxy,
self->priv->bypass_approval = bypass;
DEBUG ("%s has BypassApproval=%c", bus_name, bypass ? 'T' : 'F');
- bypass = tp_asv_get_boolean (properties, "BypassObservers", NULL);
- self->priv->bypass_observers = bypass;
- DEBUG ("%s has BypassObservers=%c", bus_name, bypass ? 'T' : 'F');
-
/* don't emit handler-capabilities-changed if we're not actually available
* any more - if that's the case, then we already signalled our loss of
* any capabilities */
@@ -1369,14 +1360,6 @@ _mcd_client_proxy_get_bypass_approval (McdClientProxy *self)
}
gboolean
-_mcd_client_proxy_get_bypass_observers (McdClientProxy *self)
-{
- g_return_val_if_fail (MCD_IS_CLIENT_PROXY (self), FALSE);
-
- return self->priv->bypass_observers;
-}
-
-gboolean
_mcd_client_proxy_get_delay_approvers (McdClientProxy *self)
{
g_return_val_if_fail (MCD_IS_CLIENT_PROXY (self), FALSE);
diff --git a/src/mcd-connection.c b/src/mcd-connection.c
index e5a6dd6c..0d941f4b 100644
--- a/src/mcd-connection.c
+++ b/src/mcd-connection.c
@@ -1537,10 +1537,10 @@ on_inactivity_changed (McdSlacker *slacker,
McdConnection *self)
{
McdConnectionPrivate *priv = self->priv;
- DEBUG ("%sactive, %s have power saving iface.", inactive ? "in" : "",
- priv->has_power_saving_if ? "has" : "doesn't");
+ DEBUG ("%sactive, connection %s have power saving iface.", inactive ? "in" : "",
+ priv->has_power_saving_if ? "does" : "doesn't");
- if (priv->has_power_saving_if)
+ if (priv->tp_conn != NULL && priv->has_power_saving_if)
tp_cli_connection_interface_power_saving1_call_set_power_saving (priv->tp_conn, -1,
inactive, NULL, NULL, NULL, NULL);
}
@@ -1832,7 +1832,7 @@ mcd_connection_class_init (McdConnectionClass * klass)
g_object_class_install_property
(object_class, PROP_SLACKER,
g_param_spec_object ("slacker",
- "MCE slacker",
+ "Slacker",
"Slacker object notifies us of user inactivity",
MCD_TYPE_SLACKER,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
diff --git a/src/mcd-dispatch-operation.c b/src/mcd-dispatch-operation.c
index 020d6b87..5299a5b3 100644
--- a/src/mcd-dispatch-operation.c
+++ b/src/mcd-dispatch-operation.c
@@ -388,8 +388,6 @@ static void mcd_dispatch_operation_set_channel_handled_by (
const gchar *well_known_name);
static gboolean _mcd_dispatch_operation_handlers_can_bypass_approval (
McdDispatchOperation *self);
-static gboolean _mcd_dispatch_operation_handlers_can_bypass_observers (
- McdDispatchOperation *self);
static void
_mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self)
@@ -1828,34 +1826,6 @@ _mcd_dispatch_operation_handlers_can_bypass_approval (
return FALSE;
}
-/* this is analogous to *_can_bypass_handlers() method above */
-static gboolean
-_mcd_dispatch_operation_handlers_can_bypass_observers (
- McdDispatchOperation *self)
-{
- gchar **iter;
-
- for (iter = self->priv->possible_handlers;
- iter != NULL && *iter != NULL;
- iter++)
- {
- McdClientProxy *handler = _mcd_client_registry_lookup (
- self->priv->client_registry, *iter);
-
- if (handler != NULL)
- {
- gboolean bypass = _mcd_client_proxy_get_bypass_observers (
- handler);
-
- DEBUG ("%s has BypassObservers=%c", *iter, bypass ? 'T' : 'F');
- return bypass;
- }
- }
-
- return FALSE;
-}
-
-
gboolean
_mcd_dispatch_operation_has_channel (McdDispatchOperation *self,
McdChannel *channel)
@@ -2240,15 +2210,8 @@ _mcd_dispatch_operation_run_clients (McdDispatchOperation *self)
{
const GList *mini_plugins;
- if (_mcd_dispatch_operation_handlers_can_bypass_observers (self))
- {
- DEBUG ("Bypassing observers");
- }
- else
- {
- DEBUG ("Running observers");
- _mcd_dispatch_operation_run_observers (self);
- }
+ DEBUG ("Running observers");
+ _mcd_dispatch_operation_run_observers (self);
for (mini_plugins = mcp_list_objects ();
mini_plugins != NULL;
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index bf310c27..8fecbd55 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -589,17 +589,7 @@ mcd_dispatcher_client_needs_recovery_cb (McdClientProxy *client,
for (list = channels; list; list = list->next)
{
TpChannel *channel = list->data;
- const gchar *object_path = tp_proxy_get_object_path (channel);
GVariant *properties;
- McdClientProxy *handler;
-
- /* FIXME: This is not exactly the right behaviour, see fd.o#40305 */
- handler = _mcd_dispatcher_lookup_handler (self, channel, NULL);
- if (handler && _mcd_client_proxy_get_bypass_observers (handler))
- {
- DEBUG ("skipping unobservable channel %s", object_path);
- continue;
- }
properties = tp_channel_dup_immutable_properties (channel);
diff --git a/src/mcd-storage.c b/src/mcd-storage.c
index c4f11ed3..648419c7 100644
--- a/src/mcd-storage.c
+++ b/src/mcd-storage.c
@@ -41,10 +41,6 @@
/* these pseudo-plugins take care of the actual account storage/retrieval */
#include "mcd-account-manager-default.h"
-#if ENABLE_LIBACCOUNTS_SSO
-#include "mcd-account-manager-sso.h"
-#endif
-
#define MAX_KEY_LENGTH (DBUS_MAXIMUM_NAME_LENGTH + 6)
static GList *stores = NULL;
@@ -697,14 +693,6 @@ add_storage_plugin (McpAccountStorage *plugin)
}
static void
-add_libaccounts_plugins_if_enabled (void)
-{
-#if ENABLE_LIBACCOUNTS_SSO
- add_storage_plugin (MCP_ACCOUNT_STORAGE (mcd_account_manager_sso_new ()));
-#endif
-}
-
-static void
sort_and_cache_plugins ()
{
const GList *p;
@@ -718,7 +706,6 @@ sort_and_cache_plugins ()
/* Add compiled-in plugins */
add_storage_plugin (MCP_ACCOUNT_STORAGE (mcd_account_manager_default_new ()));
- add_libaccounts_plugins_if_enabled ();
for (p = mcp_list_objects(); p != NULL; p = g_list_next (p))
{
diff --git a/src/plugin-loader.c b/src/plugin-loader.c
index 7062c3a2..d6beefdc 100644
--- a/src/plugin-loader.c
+++ b/src/plugin-loader.c
@@ -27,10 +27,6 @@
#include "mcd-debug.h"
-#if ENABLE_AEGIS
-#include "plugins/mcp-dbus-aegis-acl.h"
-#endif
-
static gsize ready = 0;
void
@@ -38,9 +34,6 @@ _mcd_plugin_loader_init (void)
{
if (g_once_init_enter (&ready))
{
-#if ENABLE_AEGIS
- GObject *pseudo_plugin;
-#endif
const gchar *dir = g_getenv ("MC_FILTER_PLUGIN_DIR");
if (dir == NULL)
@@ -48,15 +41,6 @@ _mcd_plugin_loader_init (void)
mcp_read_dir (dir);
-#if ENABLE_AEGIS
- /* The last object added by mcp_add_object() will be treated as highest
- * priority, at least for the interfaces used here */
- DEBUG ("Initialising built-in Aegis ACL plugin");
- pseudo_plugin = G_OBJECT (aegis_acl_new ());
- mcp_add_object (pseudo_plugin);
- g_object_unref (pseudo_plugin);
-#endif
-
g_once_init_leave (&ready, 1);
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bc558876..a808ac7a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -42,9 +42,3 @@ account_store_SOURCES = \
account-store-variant-file.c \
account-store-variant-file.h \
$(NULL)
-
-if ENABLE_LIBACCOUNTS_SSO
-account_store_SOURCES += account-store-libaccounts.c account-store-libaccounts.h
-account_store_LDADD += $(LIBACCOUNTS_SSO_LIBS)
-AM_CPPFLAGS += $(LIBACCOUNTS_SSO_CFLAGS)
-endif
diff --git a/tests/account-store-libaccounts.c b/tests/account-store-libaccounts.c
deleted file mode 100644
index 26112742..00000000
--- a/tests/account-store-libaccounts.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * MC account storage backend inspector, libaccounts backend
- *
- * Copyright © 2010 Nokia Corporation
- * Copyright © 2010 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 "account-store-libaccounts.h"
-
-#include <libaccounts-glib/ag-manager.h>
-#include <libaccounts-glib/ag-account.h>
-#include <libaccounts-glib/ag-service.h>
-
-#include <string.h>
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "account-store-libaccounts"
-
-/* MC <-> AG global/local setting meta data */
-#define MCPP "param-"
-#define AGPP "parameters/"
-#define LIBACCT_ID_KEY "libacct-uid"
-
-#define MC_ENABLED_KEY "Enabled"
-#define AG_ENABLED_KEY "enabled"
-
-#define AG_LABEL_KEY "name"
-#define MC_LABEL_KEY "DisplayName"
-
-#define AG_ACCOUNT_KEY "username"
-#define MC_ACCOUNT_KEY "account"
-#define PASSWORD_KEY "password"
-#define AG_ACCOUNT_ALT_KEY AGPP "account"
-
-#define MC_CMANAGER_KEY "manager"
-#define MC_PROTOCOL_KEY "protocol"
-#define MC_IDENTITY_KEY "tmc-uid"
-
-#define SERVICES_KEY "sso-services"
-
-#define MC_SERVICE_KEY "Service"
-
-typedef struct {
- gchar *mc_name;
- gchar *ag_name;
- gboolean global; /* global ag setting or service specific? */
- gboolean readable; /* does the _standard_ read method copy this into MC? */
- gboolean writable; /* does the _standard_ write method copy this into AG? */
- gboolean freeable; /* should clear_setting_data deallocate the names? */
-} Setting;
-
-#define GLOBAL TRUE
-#define SERVICE FALSE
-#define READABLE TRUE
-#define UNREADABLE FALSE
-#define WRITABLE TRUE
-#define UNWRITABLE FALSE
-
-typedef enum {
- SETTING_MC,
- SETTING_AG,
-} SettingType;
-
-Setting setting_map[] = {
- { MC_ENABLED_KEY , AG_ENABLED_KEY , GLOBAL , UNREADABLE, UNWRITABLE },
- { MCPP MC_ACCOUNT_KEY, AG_ACCOUNT_KEY , GLOBAL , READABLE , UNWRITABLE },
- { MCPP PASSWORD_KEY , PASSWORD_KEY , GLOBAL , READABLE , WRITABLE },
- { MC_LABEL_KEY , AG_LABEL_KEY , GLOBAL , READABLE , WRITABLE },
- { LIBACCT_ID_KEY , LIBACCT_ID_KEY , GLOBAL , UNREADABLE, UNWRITABLE },
- { MC_IDENTITY_KEY , MC_IDENTITY_KEY, SERVICE, READABLE , WRITABLE },
- { MC_CMANAGER_KEY , MC_CMANAGER_KEY, SERVICE, READABLE , UNWRITABLE },
- { MC_PROTOCOL_KEY , MC_PROTOCOL_KEY, SERVICE, READABLE , UNWRITABLE },
- { MC_SERVICE_KEY , MC_SERVICE_KEY , SERVICE, UNREADABLE, UNWRITABLE },
- { SERVICES_KEY , SERVICES_KEY , GLOBAL , UNREADABLE, UNWRITABLE },
- { NULL , NULL , SERVICE, UNREADABLE, UNWRITABLE }
-};
-
-static void
-clear_setting_data (Setting *setting)
-{
- if (setting == NULL)
- return;
-
- if (!setting->freeable)
- return;
-
- g_free (setting->mc_name);
- g_free (setting->ag_name);
- setting->mc_name = NULL;
- setting->ag_name = NULL;
-}
-
-static Setting *
-setting_data (const gchar *name, SettingType type)
-{
- guint i = 0;
- static Setting parameter = { NULL, NULL, SERVICE, READABLE, WRITABLE, TRUE };
- const gchar *prefix;
-
- for (; setting_map[i].mc_name != NULL; i++)
- {
- const gchar *setting_name = NULL;
-
- if (type == SETTING_MC)
- setting_name = setting_map[i].mc_name;
- else
- setting_name = setting_map[i].ag_name;
-
- if (g_strcmp0 (name, setting_name) == 0)
- return &setting_map[i];
- }
-
- prefix = (type == SETTING_MC) ? MCPP : AGPP;
-
- if (!g_str_has_prefix (name, prefix))
- { /* a non-parameter setting */
- parameter.mc_name = g_strdup (name);
- parameter.ag_name = g_strdup (name);
- }
- else
- { /* a setting that is a parameter on both sides (AG & MC) */
- const guint plength = strlen (prefix);
-
- parameter.mc_name = g_strdup_printf ("%s%s", MCPP, name + plength);
- parameter.ag_name = g_strdup_printf ("%s%s", AGPP, name + plength);
- }
-
- return &parameter;
-}
-
-
-/* logging helpers: */
-static void
-_g_log_handler (const gchar *log_domain,
- GLogLevelFlags log_level,
- const gchar *message,
- gpointer unused_data)
-{
- /* the libaccounts code is currently very chatty when debugging: *
- * we are only interested in or own debugging output for now. */
- if ((gchar *)log_domain != (gchar *)G_LOG_DOMAIN)
- return;
-
- g_log_default_handler (log_domain, log_level, message, unused_data);
-}
-
-static void
-toggle_mute (void)
-{
- static GLogFunc old = NULL;
-
- if (old == NULL)
- {
- old = g_log_set_default_handler (_g_log_handler, NULL);
- }
- else
- {
- g_log_set_default_handler (old, NULL);
- old = NULL;
- }
-}
-
-static gchar *
-_gvalue_to_string (const GValue *val)
-{
- switch (G_VALUE_TYPE (val))
- {
- case G_TYPE_STRING:
- return g_value_dup_string (val);
- case G_TYPE_BOOLEAN:
- return g_strdup (g_value_get_boolean (val) ? "true" : "false");
- case G_TYPE_CHAR:
- return g_strdup_printf ("%c", g_value_get_uchar (val));
- case G_TYPE_UCHAR:
- return g_strdup_printf ("%c", g_value_get_char (val));
- case G_TYPE_INT:
- return g_strdup_printf ("%i", g_value_get_int (val));
- case G_TYPE_UINT:
- return g_strdup_printf ("%u", g_value_get_uint (val));
- case G_TYPE_LONG:
- return g_strdup_printf ("%ld", g_value_get_long (val));
- case G_TYPE_ULONG:
- return g_strdup_printf ("%lu", g_value_get_ulong (val));
- case G_TYPE_INT64:
- return g_strdup_printf ("%" G_GINT64_FORMAT, g_value_get_int64 (val));
- case G_TYPE_UINT64:
- return g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (val));
- case G_TYPE_ENUM:
- return g_strdup_printf ("%d" , g_value_get_enum (val));
- case G_TYPE_FLAGS:
- return g_strdup_printf ("%u", g_value_get_flags (val));
- case G_TYPE_FLOAT:
- return g_strdup_printf ("%f", g_value_get_float (val));
- case G_TYPE_DOUBLE:
- return g_strdup_printf ("%g", g_value_get_double (val));
- default:
- g_warning ("Unsupported type %s", G_VALUE_TYPE_NAME (val));
- return NULL;
- }
-}
-
-static AgManager *
-get_ag_manager (void)
-{
- static AgManager *agm = NULL;
-
- toggle_mute ();
-
- if (agm != NULL)
- return agm;
-
- agm = ag_manager_new ();
-
- toggle_mute ();
-
- return agm;
-}
-
-static AgAccount *
-get_ag_account (const gchar *mc_account)
-{
- AgAccount *ag_account = NULL;
- AgManager *ag_manager = get_ag_manager ();
- GList *ag_ids = NULL;
- GList *ag_id;
-
- toggle_mute ();
-
- ag_ids = ag_manager_list_by_service_type (ag_manager, "IM");
- g_debug ("%d accounts in SSO", g_list_length (ag_ids));
-
- for (ag_id = ag_ids; ag_id != NULL; ag_id = g_list_next (ag_id))
- {
- AgAccountId id = GPOINTER_TO_UINT (ag_id->data);
- AgAccount *account = ag_manager_get_account (ag_manager, id);
-
- if (account != NULL)
- {
- GValue value = G_VALUE_INIT;
- AgSettingSource source = AG_SETTING_SOURCE_NONE;
-
- g_value_init (&value, G_TYPE_STRING);
- ag_account_select_service (account, NULL);
-
- source = ag_account_get_value (account, MC_IDENTITY_KEY, &value);
-
- if (source != AG_SETTING_SOURCE_NONE)
- {
- if (g_str_equal (g_value_get_string (&value), mc_account))
- {
- ag_account = g_object_ref (account);
- ag_id = NULL;
- }
-
- g_value_unset (&value);
- }
-
- g_object_unref (account);
- }
- }
-
- ag_manager_list_free (ag_ids);
-
- toggle_mute ();
-
- return ag_account;
-}
-
-static gboolean
-_ag_account_select_default_im_service (AgAccount *account)
-{
- gboolean have_im_service = FALSE;
- GList *first = ag_account_list_services_by_type (account, "IM");
-
- if (first != NULL && first->data != NULL)
- {
- have_im_service = TRUE;
- ag_account_select_service (account, first->data);
- }
-
- ag_service_list_free (first);
-
- return have_im_service;
-}
-
-/* enabled is actually a tri-state<->boolean mapping */
-static gboolean _sso_account_enabled (AgAccount *account, AgService *service)
-{
- gboolean local = FALSE;
- gboolean global = FALSE;
- AgService *original = ag_account_get_selected_service (account);
-
- if (service == NULL)
- {
- _ag_account_select_default_im_service (account);
- local = ag_account_get_enabled (account);
- }
- else
- {
- if (original != service)
- ag_account_select_service (account, service);
-
- local = ag_account_get_enabled (account);
- }
-
- ag_account_select_service (account, NULL);
- global = ag_account_get_enabled (account);
-
- ag_account_select_service (account, original);
-
- g_debug ("_sso_account_enabled: global:%d && local:%d", global, local);
-
- return local && global;
-}
-
-static void _sso_account_enable (AgAccount *account,
- AgService *service,
- gboolean on)
-{
- AgService *original = ag_account_get_selected_service (account);
-
- /* turn the local enabled flag on/off as required */
- if (service != NULL)
- ag_account_select_service (account, service);
- else
- _ag_account_select_default_im_service (account);
-
- ag_account_set_enabled (account, on);
-
- /* if we are turning the account on, the global flag must also be set *
- * NOTE: this isn't needed when turning the account off */
- if (on)
- {
- ag_account_select_service (account, NULL);
- ag_account_set_enabled (account, on);
- }
-
- ag_account_select_service (account, original);
-}
-
-/* saving settings other than the enabled tri-state */
-static void
-save_setting (AgAccount *account,
- const Setting *setting,
- const gchar *val)
-{
- AgService *service = ag_account_get_selected_service (account);
-
- if (!setting->writable)
- return;
-
- if (setting->global)
- ag_account_select_service (account, NULL);
- else if (service == NULL)
- _ag_account_select_default_im_service (account);
-
- if (val != NULL)
- {
- GValue value = G_VALUE_INIT;
-
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, val);
- ag_account_set_value (account, setting->ag_name, &value);
- g_value_unset (&value);
- }
- else
- {
- ag_account_set_value (account, setting->ag_name, NULL);
- }
-
- /* leave the selected service as we found it: */
- ag_account_select_service (account, service);
-}
-
-gchar *
-libaccounts_get (const gchar *mc_account, const gchar *key)
-{
- gchar *rval = NULL;
- AgAccount *ag_account = get_ag_account (mc_account);
- Setting *setting = setting_data (key, SETTING_MC);
-
- toggle_mute ();
-
- if (ag_account != NULL)
- {
-
- if (setting == NULL)
- {
- g_debug ("setting %s is unknown/unmapped, aborting update", key);
- rval = g_strdup ("");
- goto done;
- }
-
- g_debug ("MC key %s -> AG key %s", key, setting->ag_name);
-
- if (g_str_equal (setting->ag_name, AG_ENABLED_KEY))
- {
- gboolean on = _sso_account_enabled (ag_account, NULL);
-
- rval = g_strdup (on ? "true" : "false");
- goto done;
- }
- else
- {
- GValue value = G_VALUE_INIT;
- AgSettingSource source = AG_SETTING_SOURCE_NONE;
-
- g_value_init (&value, G_TYPE_STRING);
-
- /* the 'account' parameter is a special case for historical reasons */
- if (g_str_equal (key, MCPP MC_ACCOUNT_KEY))
- {
- _ag_account_select_default_im_service (ag_account);
- source =
- ag_account_get_value (ag_account, AG_ACCOUNT_ALT_KEY, &value);
-
- if (source != AG_SETTING_SOURCE_NONE)
- goto found;
- }
-
- if (setting->global)
- ag_account_select_service (ag_account, NULL);
- else
- _ag_account_select_default_im_service (ag_account);
-
- source = ag_account_get_value (ag_account, setting->ag_name, &value);
-
- found:
- if (source != AG_SETTING_SOURCE_NONE)
- {
- rval = _gvalue_to_string (&value);
- g_value_unset (&value);
- }
- }
- }
-
- done:
- toggle_mute ();
-
- if (ag_account)
- g_object_unref (ag_account);
-
- clear_setting_data (setting);
-
- return rval;
-}
-
-gboolean
-libaccounts_set (const gchar *mc_account,
- const gchar *key,
- const gchar *value)
-{
- gboolean done = FALSE;
- AgAccount *ag_account = get_ag_account (mc_account);
- Setting *setting = setting_data (key, SETTING_MC);
-
- toggle_mute ();
-
- if (ag_account != NULL)
- {
- if (setting == NULL)
- {
- g_debug ("setting %s is unknown/unmapped, aborting update", key);
- goto done;
- }
-
- if (g_str_equal (setting->ag_name, MC_ENABLED_KEY))
- {
- gboolean on = g_str_equal (value, "true");
-
- _sso_account_enable (ag_account, NULL, on);
- done = TRUE;
- goto done;
- }
- else
- {
- save_setting (ag_account, setting, value);
- done = TRUE;
- }
-
- if (done)
- ag_account_store (ag_account, NULL, NULL);
-
- }
-
- done:
- toggle_mute ();
-
- if (ag_account)
- g_object_unref (ag_account);
-
- clear_setting_data (setting);
-
- return done;
-}
-
-gboolean
-libaccounts_delete (const gchar *mc_account)
-{
- gboolean done = FALSE;
- AgAccount *ag_account = get_ag_account (mc_account);
-
- toggle_mute ();
-
- if(ag_account != NULL)
- {
- ag_account_delete (ag_account);
- ag_account_store (ag_account, NULL, NULL);
- g_object_unref (ag_account);
- done = TRUE;
- }
-
- toggle_mute ();
-
- return done;
-}
-
-gboolean
-libaccounts_exists (const gchar *mc_account)
-{
- gboolean exists = FALSE;
- AgAccount *ag_account = get_ag_account (mc_account);
-
- toggle_mute ();
-
- if (ag_account != NULL)
- {
- exists = TRUE;
- g_object_unref (ag_account);
- }
-
- toggle_mute ();
-
- return exists;
-}
-
-GStrv
-libaccounts_list (void)
-{
- AgManager *ag_manager = get_ag_manager ();
- GList *ag_ids = ag_manager_list_by_service_type (ag_manager, "IM");
- guint len = g_list_length (ag_ids);
- GStrv rval = NULL;
- GList *id;
- guint i = 0;
- Setting *setting = setting_data (MC_IDENTITY_KEY, SETTING_AG);
-
- if (len == 0)
- goto done;
-
- rval = g_new (gchar *, len + 1);
- rval[len] = NULL;
-
- for (id = ag_ids; id && i < len; id = g_list_next (id))
- {
- GValue value = G_VALUE_INIT;
- AgAccountId uid = GPOINTER_TO_UINT (id->data);
- AgAccount *ag_account = ag_manager_get_account (ag_manager, uid);
- AgSettingSource source = AG_SETTING_SOURCE_NONE;
-
- if (ag_account)
- {
- if (setting->global)
- ag_account_select_service (ag_account, NULL);
- else
- _ag_account_select_default_im_service (ag_account);
-
- source = ag_account_get_value (ag_account, setting->ag_name, &value);
- }
-
- if (source != AG_SETTING_SOURCE_NONE)
- {
- rval[i++] = _gvalue_to_string (&value);
- g_value_unset (&value);
- }
- else
- {
- GValue cmanager = G_VALUE_INIT;
- GValue protocol = G_VALUE_INIT;
- GValue account = G_VALUE_INIT;
- const gchar *acct = NULL;
- const gchar *cman = NULL;
- const gchar *proto = NULL;
-
- g_value_init (&cmanager, G_TYPE_STRING);
- g_value_init (&protocol, G_TYPE_STRING);
- g_value_init (&account, G_TYPE_STRING);
-
- _ag_account_select_default_im_service (ag_account);
-
- ag_account_get_value (ag_account, MC_CMANAGER_KEY, &cmanager);
- cman = g_value_get_string (&cmanager);
-
- ag_account_get_value (ag_account, MC_PROTOCOL_KEY, &protocol);
- proto = g_value_get_string (&protocol);
-
- ag_account_select_service (ag_account, NULL);
- ag_account_get_value (ag_account, AG_ACCOUNT_KEY, &account);
- acct = g_value_get_string (&account);
-
- rval[i++] = g_strdup_printf ("unnamed account #%u (%s/%s/%s)",
- uid, cman, proto, acct);
-
- g_value_unset (&cmanager);
- g_value_unset (&protocol);
- g_value_unset (&account);
- }
- }
-
- done:
- g_list_free (ag_ids);
- clear_setting_data (setting);
-
- return rval;
-}
diff --git a/tests/account-store-libaccounts.h b/tests/account-store-libaccounts.h
deleted file mode 100644
index 8e88f696..00000000
--- a/tests/account-store-libaccounts.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * MC account storage backend inspector, libaccounts backend
- *
- * Copyright © 2010 Nokia Corporation
- * Copyright © 2010 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 <glib-object.h>
-
-#ifndef _ACCOUNT_STORE_LIBACCOUNTS_H_
-#define _ACCOUNT_STORE_LIBACCOUNTS_H_
-
-G_BEGIN_DECLS
-
-gchar * libaccounts_get (const gchar *mc_account,
- const gchar *key);
-
-gboolean libaccounts_set (const gchar *mc_account,
- const gchar *key,
- const gchar *value);
-
-gboolean libaccounts_delete (const gchar *mc_account);
-
-gboolean libaccounts_exists (const gchar *mc_account);
-
-GStrv libaccounts_list (void);
-
-G_END_DECLS
-
-#endif
diff --git a/tests/account-store.c b/tests/account-store.c
index fd5cc4a8..419d178a 100644
--- a/tests/account-store.c
+++ b/tests/account-store.c
@@ -41,10 +41,6 @@
" KEY := <manager | protocol | DisplayName | param-<PARAMETER>>\n" \
" VALUE := <STRING>\n\n"
-#if ENABLE_LIBACCOUNTS_SSO
-#include "account-store-libaccounts.h"
-#endif
-
typedef struct {
const gchar *name;
gchar * (*get) (const gchar *account, const gchar *key);
@@ -78,15 +74,6 @@ const Backend backends[] = {
variant_exists,
variant_list },
-#if ENABLE_LIBACCOUNTS_SSO
- { "libaccounts",
- libaccounts_get,
- libaccounts_set,
- libaccounts_delete,
- libaccounts_exists,
- libaccounts_list },
-#endif
-
{ NULL }
};
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index 81e896b1..ac2e88d0 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -19,6 +19,7 @@ TWISTED_BASIC_TESTS = \
account-manager/recover-from-disconnect.py \
account-manager/req-conn-fails.py \
account-manager/request-online.py \
+ account-manager/restricted-storage.py \
account-manager/service.py \
account-manager/update-parameters.py \
account-requests/cancel.py \
@@ -29,7 +30,6 @@ TWISTED_BASIC_TESTS = \
dispatcher/already-has-channel.py \
dispatcher/approver-fails.py \
dispatcher/bypass-approval.py \
- dispatcher/bypass-observers.py \
dispatcher/cancel.py \
dispatcher/capture-bundle.py \
dispatcher/cdo-claim.py \
@@ -142,13 +142,6 @@ nobase_nodist_twistedtests_DATA = \
$(NULL)
endif
-
-if HAVE_MCE
-HAVE_MCE_PYBOOL = True
-else
-HAVE_MCE_PYBOOL = False
-endif
-
if HAVE_NM
HAVE_NM_PYBOOL = True
else
@@ -157,7 +150,6 @@ endif
config.py: Makefile
$(AM_V_GEN) { \
- echo "HAVE_MCE = $(HAVE_MCE_PYBOOL)"; \
echo "HAVE_NM = $(HAVE_NM_PYBOOL)"; \
} > $@
diff --git a/tests/twisted/account-manager/backend-makes-changes.py b/tests/twisted/account-manager/backend-makes-changes.py
index 0d367f90..b1d69df1 100644
--- a/tests/twisted/account-manager/backend-makes-changes.py
+++ b/tests/twisted/account-manager/backend-makes-changes.py
@@ -47,7 +47,8 @@ def test(q, bus, mc, fake_accounts_service=None, **kwargs):
{'account': 'ezio@firenze.fic',
'password': 'nothing is true'},
{},
- {'account': 0, 'password': cs.PARAM_SECRET}]),
+ {'account': 0, 'password': cs.PARAM_SECRET},
+ 0]),
EventPattern('dbus-signal',
path=cs.AM_PATH,
signal='AccountUsabilityChanged',
diff --git a/tests/twisted/account-manager/restricted-storage.py b/tests/twisted/account-manager/restricted-storage.py
new file mode 100644
index 00000000..d2be50fc
--- /dev/null
+++ b/tests/twisted/account-manager/restricted-storage.py
@@ -0,0 +1,185 @@
+# Copyright (C) 2009 Nokia Corporation
+# Copyright (C) 2009-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
+
+import dbus
+import dbus.service
+
+from servicetest import EventPattern, call_async, assertEquals
+from mctest import (exec_test, SimulatedConnection,
+ SimulatedConnectionManager, Account)
+import constants as cs
+
+def test(q, bus, mc, fake_accounts_service=None, **kwargs):
+ simulated_cm = SimulatedConnectionManager(q, bus)
+
+ for enabled in (True, False):
+ for online in (True, False):
+ account_tail = ('fakecm/fakeprotocol/ezio_2efirenze_40fic'
+ + (enabled and '_enabled' or '_disabled')
+ + (online and '_online' or '_offline'))
+ account_path = cs.ACCOUNT_PATH_PREFIX + account_tail
+
+ try_to_connect = [
+ EventPattern('dbus-method-call', method='RequestConnection',
+ destination=cs.tp_name_prefix + '.ConnectionManager.fakecm',
+ path=cs.tp_path_prefix + '/ConnectionManager/fakecm',
+ interface=cs.tp_name_prefix + '.ConnectionManager',
+ predicate=lambda e:
+ e.args[1]['account'] == account_tail,
+ handled=False)
+ ]
+
+ if enabled and online:
+ also_expected = try_to_connect[:]
+ else:
+ also_expected = []
+ q.forbid_events(try_to_connect)
+
+ args = (
+ {
+ 'Enabled': enabled,
+ 'ConnectAutomatically': online,
+ 'manager': 'fakecm',
+ 'protocol': 'fakeprotocol',
+ 'AutomaticPresence':
+ dbus.Struct((dbus.UInt32(cs.PRESENCE_HIDDEN),
+ 'hidden', 'press X to blend'),
+ signature='uss'),
+ },
+ {
+ 'Enabled': 0,
+ 'ConnectAutomatically': 0,
+ 'manager': 0,
+ 'protocol': 0,
+ 'AutomaticPresence': 0,
+ },
+ {
+ 'account': account_tail,
+ 'password': 'nothing is true'
+ },
+ {}, # untyped parameters
+ {
+ 'account': 0,
+ 'password': cs.PARAM_SECRET
+ },
+ cs.StorageRestrictionFlags.CANNOT_SET_PRESENCE |
+ cs.StorageRestrictionFlags.CANNOT_SET_ENABLED,
+ )
+
+ fake_accounts_service.create_account(account_tail, *args)
+
+ events = q.expect_many(
+ EventPattern('dbus-signal',
+ path=cs.TEST_DBUS_ACCOUNT_SERVICE_PATH,
+ signal='AccountCreated',
+ args=[account_tail] + list(args)),
+ EventPattern('dbus-signal',
+ path=cs.AM_PATH,
+ signal='AccountUsabilityChanged',
+ args=[account_path, True]),
+ *also_expected)
+ account = Account(bus, account_path)
+
+ if enabled and online:
+ conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol',
+ account_tail.replace('/', '_'), 'ezio',
+ has_presence=True)
+ q.dbus_return(events[-1].message, conn.bus_name,
+ conn.object_path, signature='so')
+ q.expect('dbus-method-call', method='SetPresence',
+ # the fake CM doesn't support 'hidden' by default
+ args=['busy', 'press X to blend'])
+
+ requested_presence = (dbus.UInt32(cs.PRESENCE_HIDDEN), 'hidden',
+ 'press X to blend')
+ else:
+ requested_presence = (dbus.UInt32(cs.PRESENCE_OFFLINE),
+ 'offline', '')
+
+ call_async(q, account.Properties, 'Get', cs.ACCOUNT,
+ 'RequestedPresence')
+ q.expect('dbus-return', method='Get', value=(requested_presence,))
+
+ # changes that are not really changes are fine
+ call_async(q, account.Properties, 'Set', cs.ACCOUNT,
+ 'Enabled', enabled)
+ q.expect('dbus-return', method='Set')
+ call_async(q, account.Properties, 'Set', cs.ACCOUNT,
+ 'ConnectAutomatically', online)
+ q.expect('dbus-return', method='Set')
+
+ # changes that actually change the restrictive properties
+ # are not allowed
+ call_async(q, account.Properties, 'Set', cs.ACCOUNT,
+ 'RequestedPresence',
+ ((dbus.UInt32(cs.PRESENCE_AVAILABLE), 'available',
+ 'highly conspicuous')))
+ q.expect('dbus-error', method='Set')
+ call_async(q, account.Properties, 'Set', cs.ACCOUNT,
+ 'AutomaticPresence',
+ ((dbus.UInt32(cs.PRESENCE_AVAILABLE), 'available',
+ 'highly conspicuous')))
+ q.expect('dbus-error', method='Set')
+ call_async(q, account.Properties, 'Set', cs.ACCOUNT,
+ 'Enabled', not enabled)
+ q.expect('dbus-error', method='Set')
+ call_async(q, account.Properties, 'Set', cs.ACCOUNT,
+ 'ConnectAutomatically', not online)
+ q.expect('dbus-error', method='Set')
+
+ call_async(q, account, 'Remove')
+ q.expect('dbus-error', method='Remove')
+
+ # ... but the backend can still change them
+ if enabled and online:
+ q.forbid_events(try_to_connect)
+ fake_accounts_service.update_attributes(account_tail,
+ {
+ 'Enabled': False,
+ 'ConnectAutomatically': False,
+ })
+ q.expect('dbus-method-call', method='Disconnect')
+ q.unforbid_events(try_to_connect)
+ else:
+ q.unforbid_events(try_to_connect)
+ fake_accounts_service.update_attributes(account_tail,
+ {
+ 'Enabled': True,
+ 'ConnectAutomatically': True,
+ })
+
+ events = q.expect_many(*try_to_connect)
+ conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol',
+ account_tail.replace('/', '_'), 'ezio',
+ has_presence=True)
+ q.dbus_return(events[-1].message, conn.bus_name,
+ conn.object_path, signature='so')
+
+ # we are connected: deleting the account should
+ # disconnect us
+ fake_accounts_service.delete_account(account_tail)
+ q.expect_many(
+ EventPattern('dbus-signal', signal='AccountRemoved',
+ args=[account_path]),
+ EventPattern('dbus-signal', signal='Removed',
+ path=account_path),
+ EventPattern('dbus-method-call', method='Disconnect'),
+ )
+
+if __name__ == '__main__':
+ exec_test(test, {}, pass_kwargs=True)
diff --git a/tests/twisted/account-manager/update-parameters.py b/tests/twisted/account-manager/update-parameters.py
index 4fc3d3a0..a030a01f 100644
--- a/tests/twisted/account-manager/update-parameters.py
+++ b/tests/twisted/account-manager/update-parameters.py
@@ -252,13 +252,11 @@ def test(q, bus, mc, **kwargs):
assertEquals(r'\\',
kwargs['fake_accounts_service'].accounts
[account.object_path[len(cs.ACCOUNT_PATH_PREFIX):]]
- [2] # parameters of known type
- ['account'])
+ .params['account'])
assertEquals(None,
kwargs['fake_accounts_service'].accounts
[account.object_path[len(cs.ACCOUNT_PATH_PREFIX):]]
- [3] # parameters of unknown type
- .get('account', None))
+ .untyped_params.get('account', None))
if __name__ == '__main__':
exec_test(test, {}, pass_kwargs=True)
diff --git a/tests/twisted/account-storage/libaccounts-sso-storage.py b/tests/twisted/account-storage/libaccounts-sso-storage.py
deleted file mode 100644
index 68637eb7..00000000
--- a/tests/twisted/account-storage/libaccounts-sso-storage.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2009-2010 Nokia Corporation
-# Copyright (C) 2009-2010 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
-
-raise AssertionError('Disabled for 5.6 branch')
-
-import time
-import os
-import os.path
-import signal
-import sys
-
-import dbus
-import dbus.service
-
-from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \
- call_async
-from mctest import exec_test, create_fakecm_account, get_account_manager, \
- get_fakecm_account
-import constants as cs
-
-if ('ACCOUNTS' not in os.environ or not os.environ['ACCOUNTS']):
- print "Not testing accounts-sso storage"
- sys.exit(0)
-
-def account_store(op, backend, key=None, value=None):
- cmd = [ '../account-store', op, backend,
- 'colltest42@googlemail.com' ]
- if key:
- cmd.append(key)
- if value:
- cmd.append(value)
-
- lines = os.popen(' '.join(cmd)).read()
- ret = []
- for line in lines.split('\n'):
- if line.startswith('** '):
- continue
-
- if line:
- ret.append(line)
-
- if len(ret) > 0:
- return ret[0]
- else:
- return None
-
-def prepare_accounts_db(ctl_dir):
- os.system('cp %s/../tools/example-accounts.db %s/accounts.db' % (ctl_dir, ctl_dir))
- os.system('cp %s/../tools/accounts-sso-example.service %s/google-talk.service' % (ctl_dir, ctl_dir))
-
-def test(q, bus, mc):
- account_manager, properties, interfaces = connect_to_mc(q, bus, mc)
-
- va = properties.get('UsableAccounts')
- assert va == [], va
-
- ia = properties.get('UnusableAccounts')
- assert len(ia) == 1
-
- account_path = ia[0]
- print repr(account_path)
-
- account = get_fakecm_account(bus, mc, account_path)
- account_iface = dbus.Interface(account, cs.ACCOUNT)
- account_props = dbus.Interface(account, cs.PROPERTIES_IFACE)
-
- # FIXME at this point MC crashes
- properties = account_props.GetAll(cs.ACCOUNT)
-
-
-if __name__ == '__main__':
- ctl_dir = os.environ['ACCOUNTS']
- prepare_accounts_db(ctl_dir)
- exec_test(test, {}, timeout=10, use_fake_accounts_service=False)
diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py
index d7105294..8a73f129 100644
--- a/tests/twisted/constants.py
+++ b/tests/twisted/constants.py
@@ -590,3 +590,9 @@ TEST_DBUS_ACCOUNT_SERVICE_IFACE = TEST_DBUS_ACCOUNT_SERVICE
TEST_DBUS_ACCOUNT_PLUGIN_PATH = TESTSLASH + "DBusAccountPlugin"
TEST_DBUS_ACCOUNT_PLUGIN_IFACE = TESTDOT + "DBusAccountPlugin"
+
+class StorageRestrictionFlags(object):
+ CANNOT_SET_PARAMETERS = 1
+ CANNOT_SET_ENABLED = 2
+ CANNOT_SET_PRESENCE = 4
+ CANNOT_SET_SERVICE = 8
diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c
index 8924bd95..5b4af4a6 100644
--- a/tests/twisted/dbus-account-plugin.c
+++ b/tests/twisted/dbus-account-plugin.c
@@ -55,6 +55,7 @@ typedef struct {
/* set of strings */
GHashTable *uncommitted_parameters;
enum { UNCOMMITTED_CREATION, UNCOMMITTED_DELETION } flags;
+ TpStorageRestrictionFlags restrictions;
} Account;
static void
@@ -157,7 +158,7 @@ ensure_account (TestDBusAccountPlugin *self,
if (account == NULL)
{
- account = g_slice_new (Account);
+ account = g_slice_new0 (Account);
account->path = g_strdup_printf ("%s%s", TP_ACCOUNT_OBJECT_PATH_BASE,
account_name);
@@ -267,7 +268,8 @@ test_dbus_account_plugin_add_account (TestDBusAccountPlugin *self,
GVariant *attribute_flags,
GVariant *parameters,
GVariant *untyped_parameters,
- GVariant *param_flags)
+ GVariant *param_flags,
+ TpStorageRestrictionFlags restrictions)
{
GVariantIter iter;
const gchar *k;
@@ -306,6 +308,8 @@ test_dbus_account_plugin_add_account (TestDBusAccountPlugin *self,
g_hash_table_insert (account->parameter_flags, g_strdup (k),
GUINT_TO_POINTER (u));
+ account->restrictions = restrictions;
+
return account;
}
@@ -320,10 +324,12 @@ test_dbus_account_plugin_process_account_creation (TestDBusAccountPlugin *self,
GVariant *untyped_params;
GVariant *attr_flags;
GVariant *param_flags;
+ guint32 restrictions;
- g_variant_get (args, "(&s@a{sv}@a{su}@a{sv}@a{ss}@a{su})",
+ g_variant_get (args, "(&s@a{sv}@a{su}@a{sv}@a{ss}@a{su}u)",
&account_name, &attrs, &attr_flags,
- &params, &untyped_params, &param_flags);
+ &params, &untyped_params, &param_flags,
+ &restrictions);
DEBUG ("%s", account_name);
account = lookup_account (self, account_name);
@@ -339,7 +345,7 @@ test_dbus_account_plugin_process_account_creation (TestDBusAccountPlugin *self,
* a lot of rubbish */
account = test_dbus_account_plugin_add_account (self,
account_name, attrs, attr_flags,
- params, untyped_params, param_flags);
+ params, untyped_params, param_flags, restrictions);
mcp_account_storage_emit_created (
MCP_ACCOUNT_STORAGE (self), account_name);
@@ -686,8 +692,8 @@ account_created_cb (GDBusConnection *bus,
TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data);
const gchar *account_name;
- g_variant_get (tuple, "(&s@a{sv}@a{su}@a{sv}@a{ss}@a{su})",
- &account_name, NULL, NULL, NULL, NULL, NULL);
+ g_variant_get (tuple, "(&s@a{sv}@a{su}@a{sv}@a{ss}@a{su}u)",
+ &account_name, NULL, NULL, NULL, NULL, NULL, NULL);
DEBUG ("%s", account_name);
g_queue_push_tail (&self->events, event_new (EVENT_CREATION, tuple));
@@ -765,6 +771,7 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage,
GVariantIter account_iter;
const gchar *account_name;
GList *ret = NULL;
+ guint32 restrictions;
DEBUG ("called");
@@ -823,7 +830,7 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage,
TEST_DBUS_ACCOUNT_SERVICE_IFACE,
"GetAccounts",
NULL, /* no parameters */
- G_VARIANT_TYPE ("(a{s(a{sv}a{su}a{sv}a{ss}a{su})})"),
+ G_VARIANT_TYPE ("(a{s(a{sv}a{su}a{sv}a{ss}a{su}u)})"),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL, /* no cancellable */
@@ -846,13 +853,13 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage,
g_variant_iter_init (&account_iter, accounts);
while (g_variant_iter_loop (&account_iter,
- "{s(@a{sv}@a{su}@a{sv}@a{ss}@a{su})}", &account_name,
+ "{s(@a{sv}@a{su}@a{sv}@a{ss}@a{su}u)}", &account_name,
&attributes, &attribute_flags,
- &parameters, &untyped_parameters, &param_flags))
+ &parameters, &untyped_parameters, &param_flags, &restrictions))
{
test_dbus_account_plugin_add_account (self, account_name,
attributes, attribute_flags, parameters, untyped_parameters,
- param_flags);
+ param_flags, restrictions);
ret = g_list_prepend (ret, g_strdup (account_name));
}
@@ -1570,8 +1577,7 @@ test_dbus_account_plugin_get_restrictions (const McpAccountStorage *storage,
if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION))
return 0;
- /* FIXME: actually enforce this restriction */
- return TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_SERVICE;
+ return account->restrictions;
}
static gboolean
diff --git a/tests/twisted/dispatcher/bypass-observers.py b/tests/twisted/dispatcher/bypass-observers.py
deleted file mode 100644
index 1aeb318f..00000000
--- a/tests/twisted/dispatcher/bypass-observers.py
+++ /dev/null
@@ -1,291 +0,0 @@
-# Copyright (C) 2009-2010 Nokia Corporation
-# Copyright (C) 2009-2010 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
-
-import dbus
-"""Regression test for dispatching an incoming Text channel with bypassed
-observers.
-"""
-
-import dbus
-import dbus.service
-
-from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \
- call_async, sync_dbus, assertEquals, assertLength, assertContains
-from mctest import exec_test, SimulatedConnection, SimulatedClient, \
- create_fakecm_account, enable_fakecm_account, SimulatedChannel, \
- expect_client_setup
-import constants as cs
-
-text_fixed_properties = dbus.Dictionary({
- cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
- }, signature='sv')
-contact_text_fixed_properties = dbus.Dictionary({
- cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT,
- cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
- }, signature='sv')
-secret_fixed_properties = dbus.Dictionary({
- cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT,
- cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT,
- 'com.example.Secrecy.Secret': True,
- }, signature='sv')
-
-def announce_common(q, bus, empathy, kopete, account, conn, cd_props,
- secret=False):
- if secret:
- jid = 'friar.lawrence'
- else:
- jid = 'juliet'
-
- channel_properties = dbus.Dictionary(contact_text_fixed_properties,
- signature='sv')
- channel_properties[cs.CHANNEL + '.TargetID'] = jid
- channel_properties[cs.CHANNEL + '.TargetHandle'] = \
- conn.ensure_handle(cs.HT_CONTACT, jid)
- channel_properties[cs.CHANNEL + '.InitiatorID'] = jid
- channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \
- conn.ensure_handle(cs.HT_CONTACT, jid)
- channel_properties[cs.CHANNEL + '.Requested'] = False
- channel_properties[cs.CHANNEL + '.Interfaces'] = dbus.Array(signature='s')
-
- if secret:
- channel_properties['com.example.Secrecy.Secret'] = True
-
- chan = SimulatedChannel(conn, channel_properties)
- chan.announce()
-
- # A channel dispatch operation is created
-
- e = q.expect('dbus-signal',
- path=cs.CD_PATH,
- interface=cs.CD_IFACE_OP_LIST,
- signal='NewDispatchOperation')
-
- cdo_path = e.args[0]
- cdo_properties = e.args[1]
-
- assertEquals(cdo_properties[cs.CDO + '.Account'], account.object_path)
- assertEquals(cdo_properties[cs.CDO + '.Connection'], conn.object_path)
- assertContains(cs.CDO + '.Interfaces', cdo_properties)
-
- handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:]
-
- if secret:
- # The handler with BypassApproval is first
- assertEquals(cs.tp_name_prefix + '.Client.Kopete.Bypasser',
- handlers[0])
- else:
- handlers.sort()
- assertEquals([cs.tp_name_prefix + '.Client.Empathy',
- cs.tp_name_prefix + '.Client.Kopete'], handlers)
-
- assertContains(cs.CD_IFACE_OP_LIST, cd_props.Get(cs.CD, 'Interfaces'))
-
- assertEquals([(cdo_path, cdo_properties)],
- cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations'))
-
- cdo = bus.get_object(cs.CD, cdo_path)
- cdo_iface = dbus.Interface(cdo, cs.CDO)
-
- # Both Observers are told about the new channel
-
- if secret:
- observe_events = []
- else:
- e, k = q.expect_many(
- EventPattern('dbus-method-call',
- path=empathy.object_path,
- interface=cs.OBSERVER, method='ObserveChannels',
- handled=False),
- EventPattern('dbus-method-call',
- path=kopete.object_path,
- interface=cs.OBSERVER, method='ObserveChannels',
- handled=False),
- )
- assertEquals(account.object_path, e.args[0])
- assertEquals(conn.object_path, e.args[1])
- assertEquals(cdo_path, e.args[3])
- assertEquals([], e.args[4]) # no requests satisfied
- channels = e.args[2]
- assertLength(1, channels)
- assertEquals(chan.object_path, channels[0][0])
- assertEquals(channel_properties, channels[0][1])
-
- assertEquals(k.args, e.args)
- observe_events = [e, k]
-
- return cdo_iface, chan, channel_properties, observe_events
-
-def expect_and_exercise_approval(q, bus, chan, channel_properties,
- empathy, kopete, cdo_iface, cd_props):
- # The Approvers are next
-
- e, k = q.expect_many(
- EventPattern('dbus-method-call',
- path=empathy.object_path,
- interface=cs.APPROVER, method='AddDispatchOperation',
- handled=False),
- EventPattern('dbus-method-call',
- path=kopete.object_path,
- interface=cs.APPROVER, method='AddDispatchOperation',
- handled=False),
- )
-
- assertEquals([(chan.object_path, channel_properties)], e.args[0])
- assertEquals(k.args, e.args)
-
- # Both Approvers indicate that they are ready to proceed
- q.dbus_return(e.message, signature='')
- q.dbus_return(k.message, signature='')
-
- # Both Approvers now have a flashing icon or something, trying to get the
- # user's attention
-
- # The user responds to Kopete first
- call_async(q, cdo_iface, 'HandleWith',
- cs.tp_name_prefix + '.Client.Kopete')
-
- # Kopete is asked to handle the channels
- e = q.expect('dbus-method-call',
- path=kopete.object_path,
- interface=cs.HANDLER, method='HandleChannels',
- handled=False)
-
- # Kopete accepts the channels
- q.dbus_return(e.message, signature='')
-
- q.expect_many(
- EventPattern('dbus-return', method='HandleWith'),
- EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'),
- EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST,
- signal='DispatchOperationFinished'),
- )
-
- # Now there are no more active channel dispatch operations
- assertEquals([], cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations'))
-
-
-def test(q, bus, mc):
- params = dbus.Dictionary({"account": "someguy@example.com",
- "password": "secrecy"}, signature='sv')
- simulated_cm, account = create_fakecm_account(q, bus, mc, params)
- conn = enable_fakecm_account(q, bus, mc, account, params)
-
- # Two clients want to observe, approve and handle channels. Additionally,
- # Kopete recognises a "Secret" flag on certain incoming channels, and
- # wants to bypass approval and observers for them. Also, Empathy is a
- # respawnable observer, which wants to get notified of existing channels
- # if it gets restarted.
- empathy = SimulatedClient(q, bus, 'Empathy',
- observe=[text_fixed_properties], approve=[text_fixed_properties],
- handle=[text_fixed_properties], bypass_approval=False,
- wants_recovery=True)
- kopete = SimulatedClient(q, bus, 'Kopete',
- observe=[contact_text_fixed_properties],
- approve=[contact_text_fixed_properties],
- handle=[contact_text_fixed_properties], bypass_approval=False)
- bypass = SimulatedClient(q, bus, 'Kopete.Bypasser',
- observe=[], approve=[],
- handle=[secret_fixed_properties],
- bypass_approval=True, bypass_observers=True)
-
- # wait for MC to download the properties
- expect_client_setup(q, [empathy, kopete, bypass])
-
- # subscribe to the OperationList interface (MC assumes that until this
- # property has been retrieved once, nobody cares)
-
- cd = bus.get_object(cs.CD, cs.CD_PATH)
- cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE)
- assertEquals([], cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations'))
-
- # First, a non-secret channel is created
-
- cdo_iface, chan, channel_properties, observe_events = announce_common(q,
- bus, empathy, kopete, account, conn, cd_props, False)
-
- # Both Observers indicate that they are ready to proceed
- for e in observe_events:
- q.dbus_return(e.message, signature='')
-
- expect_and_exercise_approval(q, bus, chan, channel_properties,
- empathy, kopete, cdo_iface, cd_props)
-
- nonsecret_chan = chan
-
- # Now a channel that bypasses approval and observers comes in.
- # During this process, we should never be asked to approve or
- # observe anything.
-
- approval = [
- EventPattern('dbus-method-call', method='AddDispatchOperation'),
- ]
-
- q.forbid_events(approval)
-
- cdo_iface, chan, channel_properties, observe_events = announce_common(q,
- bus, empathy, kopete, account, conn, cd_props, True)
-
- # Both Observers indicate that they are ready to proceed
- for e in observe_events:
- q.dbus_return(e.message, signature='')
-
- # Kopete's BypassApproval part is asked to handle the channels
- e = q.expect('dbus-method-call',
- path=bypass.object_path,
- interface=cs.HANDLER, method='HandleChannels',
- handled=False)
- # Kopete accepts the channels
- q.dbus_return(e.message, signature='')
-
- q.unforbid_events(approval)
-
- # Empathy, the observer, crashes
- empathy.release_name()
-
- e = q.expect('dbus-signal',
- signal='NameOwnerChanged',
- predicate=(lambda e:
- e.args[0] == empathy.bus_name and e.args[2] == ''),
- )
- empathy_unique_name = e.args[1]
-
- bus.flush()
-
- # Empathy gets restarted
- empathy.reacquire_name()
-
- e = q.expect('dbus-signal',
- signal='NameOwnerChanged',
- predicate=(lambda e:
- e.args[0] == empathy.bus_name and e.args[1] == ''),
- )
- empathy_unique_name = e.args[2]
-
- # Empathy is told to observe only the non-secret channel
- e = q.expect('dbus-method-call',
- path=empathy.object_path,
- interface=cs.OBSERVER, method='ObserveChannels',
- handled=False)
-
- channels = e.args[2]
- assertLength(1, channels)
- assertEquals(nonsecret_chan.object_path, channels[0][0])
-
-if __name__ == '__main__':
- exec_test(test, {})
-
diff --git a/tests/twisted/fakeaccountsservice.py b/tests/twisted/fakeaccountsservice.py
index 3c10a156..d8c87a0b 100644
--- a/tests/twisted/fakeaccountsservice.py
+++ b/tests/twisted/fakeaccountsservice.py
@@ -25,12 +25,27 @@ from servicetest import (Event, EventPattern)
import constants as cs
-# indices into the tuple of dicts representing an account
-ATTRS = 0
-ATTR_FLAGS = 1
-PARAMS = 2
-UNTYPED_PARAMS = 3
-PARAM_FLAGS = 4
+class FakeAccount(object):
+
+ def __init__(self):
+ self.attrs = dbus.Dictionary({}, signature='sv')
+ self.attr_flags = dbus.Dictionary({}, signature='su')
+ self.params = dbus.Dictionary({}, signature='sv')
+ self.untyped_params = dbus.Dictionary({}, signature='ss')
+ self.param_flags = dbus.Dictionary({}, signature='su')
+ self.restrictions = 0
+
+ SIGNATURE = 'a{sv}a{su}a{sv}a{ss}a{su}u'
+
+ def to_dbus(self):
+ return (
+ self.attrs,
+ self.attr_flags,
+ self.params,
+ self.untyped_params,
+ self.param_flags,
+ dbus.UInt32(self.restrictions),
+ )
class FakeAccountsService(object):
def __init__(self, q, bus):
@@ -68,25 +83,28 @@ class FakeAccountsService(object):
method='UpdateParameters')
def create_account(self, account, attrs={}, attr_flags={}, params={},
- untyped_params={}, param_flags={}):
+ untyped_params={}, param_flags={}, restrictions=0):
+
if account in self.accounts:
raise KeyError('Account %s already exists' % account)
- self.accounts[account] = ({}, {}, {}, {}, {})
- self.accounts[account][ATTRS].update(attrs)
+
+ self.accounts[account] = FakeAccount()
+ self.accounts[account].restrictions = restrictions
+ self.accounts[account].attrs.update(attrs)
for attr in attrs:
- self.accounts[account][ATTR_FLAGS][attr] = dbus.UInt32(0)
- self.accounts[account][ATTR_FLAGS].update(attr_flags)
- self.accounts[account][PARAMS].update(params)
+ self.accounts[account].attr_flags[attr] = dbus.UInt32(0)
+ self.accounts[account].attr_flags.update(attr_flags)
+ self.accounts[account].params.update(params)
for param in params:
- self.accounts[account][PARAM_FLAGS][param] = dbus.UInt32(0)
- self.accounts[account][UNTYPED_PARAMS].update(untyped_params)
+ self.accounts[account].param_flags[param] = dbus.UInt32(0)
+ self.accounts[account].untyped_params.update(untyped_params)
for param in untyped_params:
- self.accounts[account][PARAM_FLAGS][param] = dbus.UInt32(0)
- self.accounts[account][PARAM_FLAGS].update(param_flags)
+ self.accounts[account].param_flags[param] = dbus.UInt32(0)
+ self.accounts[account].param_flags.update(param_flags)
self.q.dbus_emit(self.object_path, cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE,
'AccountCreated',
- account, *self.accounts[account],
- signature='sa{sv}a{su}a{sv}a{ss}a{su}')
+ account, *(self.accounts[account].to_dbus()),
+ signature='s' + FakeAccount.SIGNATURE)
def CreateAccount(self, e):
try:
@@ -111,28 +129,31 @@ class FakeAccountsService(object):
self.q.dbus_return(e.message, signature='')
def GetAccounts(self, e):
- self.q.dbus_return(e.message, self.accounts,
- signature='a{s(a{sv}a{su}a{sv}a{ss}a{su})}')
+ accounts = {}
+ for a in self.accounts:
+ accounts[a] = self.accounts[a].to_dbus()
+ self.q.dbus_return(e.message, accounts,
+ signature='a{s(' + FakeAccount.SIGNATURE + ')}')
def update_attributes(self, account, changed={}, flags={}, deleted=[]):
if account not in self.accounts:
self.create_account(account)
for (attribute, value) in changed.items():
- self.accounts[account][ATTRS][attribute] = value
- self.accounts[account][ATTR_FLAGS][attribute] = flags.get(
+ self.accounts[account].attrs[attribute] = value
+ self.accounts[account].attr_flags[attribute] = flags.get(
attribute, dbus.UInt32(0))
for attribute in deleted:
- if attribute in self.accounts[account][ATTRS]:
- del self.accounts[account][ATTRS][attribute]
- if attribute in self.accounts[account][ATTR_FLAGS]:
- del self.accounts[account][ATTR_FLAGS][attribute]
+ if attribute in self.accounts[account].attrs:
+ del self.accounts[account].attrs[attribute]
+ if attribute in self.accounts[account].attr_flags:
+ del self.accounts[account].attr_flags[attribute]
self.q.dbus_emit(self.object_path, cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE,
'AttributesChanged',
account, changed,
- dict([(a, self.accounts[account][ATTR_FLAGS][a])
+ dict([(a, self.accounts[account].attr_flags[a])
for a in changed]),
deleted, signature='sa{sv}a{su}as')
@@ -150,31 +171,31 @@ class FakeAccountsService(object):
self.create_account(account)
for (param, value) in changed.items():
- self.accounts[account][PARAMS][param] = value
- if param in self.accounts[account][UNTYPED_PARAMS]:
- del self.accounts[account][UNTYPED_PARAMS][param]
- self.accounts[account][PARAM_FLAGS][param] = flags.get(
+ self.accounts[account].params[param] = value
+ if param in self.accounts[account].untyped_params:
+ del self.accounts[account].untyped_params[param]
+ self.accounts[account].param_flags[param] = flags.get(
param, dbus.UInt32(0))
for (param, value) in untyped.items():
- self.accounts[account][UNTYPED_PARAMS][param] = value
- if param in self.accounts[account][PARAMS]:
- del self.accounts[account][PARAMS][param]
- self.accounts[account][PARAM_FLAGS][param] = flags.get(
+ self.accounts[account].untyped_params[param] = value
+ if param in self.accounts[account].params:
+ del self.accounts[account].params[param]
+ self.accounts[account].param_flags[param] = flags.get(
param, dbus.UInt32(0))
for param in deleted:
- if param in self.accounts[account][PARAMS]:
- del self.accounts[account][PARAMS][param]
- if param in self.accounts[account][UNTYPED_PARAMS]:
- del self.accounts[account][UNTYPED_PARAMS][param]
- if param in self.accounts[account][PARAM_FLAGS]:
- del self.accounts[account][PARAM_FLAGS][param]
+ if param in self.accounts[account].params:
+ del self.accounts[account].params[param]
+ if param in self.accounts[account].untyped_params:
+ del self.accounts[account].untyped_params[param]
+ if param in self.accounts[account].param_flags:
+ del self.accounts[account].param_flags[param]
self.q.dbus_emit(self.object_path, cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE,
'ParametersChanged',
account, changed, untyped,
- dict([(p, self.accounts[account][PARAM_FLAGS][p])
+ dict([(p, self.accounts[account].param_flags[p])
for p in (set(changed.keys()) | set(untyped.keys()))]),
deleted,
signature='sa{sv}a{ss}a{su}as')
diff --git a/tests/twisted/mctest.py b/tests/twisted/mctest.py
index 75217642..3bfd66f6 100644
--- a/tests/twisted/mctest.py
+++ b/tests/twisted/mctest.py
@@ -715,7 +715,7 @@ class SimulatedClient(object):
observe=[], approve=[], handle=[],
cap_tokens=[], bypass_approval=False, wants_recovery=False,
request_notification=True, implement_get_interfaces=True,
- is_handler=None, bypass_observers=False, delay_approvers=False):
+ is_handler=None, delay_approvers=False):
self.q = q
self.bus = bus
self.bus_name = '.'.join([cs.tp_name_prefix, 'Client', clientname])
@@ -725,7 +725,6 @@ class SimulatedClient(object):
self.approve = aasv(approve)
self.handle = aasv(handle)
self.bypass_approval = bool(bypass_approval)
- self.bypass_observers = bool(bypass_observers)
self.delay_approvers = bool(delay_approvers)
self.wants_recovery = bool(wants_recovery)
self.request_notification = bool(request_notification)
@@ -841,7 +840,6 @@ class SimulatedClient(object):
self.q.dbus_return(e.message, {
'HandlerChannelFilter': self.handle,
'BypassApproval': self.bypass_approval,
- 'BypassObservers': self.bypass_observers,
'HandledChannels': self.handled_channels,
'Capabilities': self.cap_tokens,
},
@@ -865,11 +863,6 @@ class SimulatedClient(object):
self.q.dbus_return(e.message, self.bypass_approval, signature='v',
bus=self.bus)
- def Get_BypassApproval(self, e):
- assert self.handle
- self.q.dbus_return(e.message, self.bypass_observers, signature='v',
- bus=self.bus)
-
def Get_Recover(self, e):
assert self.handle
self.q.dbus_return(e.message, self.recover, signature='v',
diff --git a/tests/twisted/run-test.sh.in b/tests/twisted/run-test.sh.in
index 8b06c712..d9dfcec2 100644
--- a/tests/twisted/run-test.sh.in
+++ b/tests/twisted/run-test.sh.in
@@ -59,9 +59,6 @@ MC_DEBUG=all
export MC_DEBUG
G_DEBUG=fatal-criticals
export G_DEBUG
-# for ENABLE_LIBACCOUNTS_SSO
-AG_DEBUG=all
-export AG_DEBUG
GIO_EXTRA_MODULES="${plugins}"
export GIO_EXTRA_MODULES
@@ -107,12 +104,6 @@ for i in $list ; do
XDG_CACHE_DIR="${tmp}/cache"
export XDG_CACHE_DIR
- # for ENABLE_LIBACCOUNTS_SSO
- ACCOUNTS="${tmp}/libaccounts-accounts"
- export ACCOUNTS
- AG_SERVICES="${tmp}/libaccounts-services"
- export AG_SERVICES
-
CHECK_TWISTED_VERBOSE=1
export CHECK_TWISTED_VERBOSE