From 4db6783e78972a35a1f66ed0311cf8080a1b63e1 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Fri, 8 Nov 2013 13:17:10 -0500 Subject: Remove all notion of secret parameter We now depend on SASLAuthentication for handling secret, and MC does not have gnome-keyring anymore. [Adjusted to apply before other storage API changes -smcv] Bug: https://bugs.freedesktop.org/show_bug.cgi?id=71384 Signed-off-by: Simon McVittie --- mission-control-plugins/account-storage.c | 3 +- mission-control-plugins/account.c | 59 ------------------ mission-control-plugins/account.h | 8 --- mission-control-plugins/implementation.h | 8 --- mission-control-plugins/mission-control-plugins.h | 1 - src/mcd-account.c | 16 +---- src/mcd-account.h | 3 - src/mcd-storage.c | 73 ++--------------------- src/mcd-storage.h | 3 +- tests/twisted/dbus-account-plugin.c | 21 ------- 10 files changed, 8 insertions(+), 187 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index b51c1264..14f4f6d5 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -395,8 +395,7 @@ mcp_account_storage_priority (const McpAccountStorage *storage) * Before emitting this signal, the plugin must call * either mcp_account_manager_set_attribute(), * mcp_account_manager_set_parameter(), - * or mcp_account_manager_set_value() and (if appropriate) - * mcp_account_manager_parameter_make_secret() + * or mcp_account_manager_set_value() * before returning from this method call. * * Note that mcp_account_manager_set_parameter() does not use the diff --git a/mission-control-plugins/account.c b/mission-control-plugins/account.c index 1744ef6a..493a34c0 100644 --- a/mission-control-plugins/account.c +++ b/mission-control-plugins/account.c @@ -215,65 +215,6 @@ mcp_account_manager_get_value (const McpAccountManager *mcpa, return iface->get_value (mcpa, account, key); } -/** - * mcp_account_manager_parameter_is_secret: - * @mcpa: an #McpAccountManager instance - * @account: the unique name of an account - * @key: the constant string "param-", plus a parameter name like - * "account" or "password" - * - * Determine whether a given account parameter is secret. - * Generally this is determined by MC and passed down to plugins, - * but any #McpAccountStorage plugin may decide a parameter is - * secret, in which case the return value for this call will - * indicate that fact too. - * - * For historical reasons, this function only operates on parameters, - * but requires its argument to be prefixed with "param-". - * - * Returns: %TRUE for secret settings, %FALSE otherwise - */ -gboolean -mcp_account_manager_parameter_is_secret (const McpAccountManager *mcpa, - const gchar *account, - const gchar *key) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_val_if_fail (iface != NULL, FALSE); - g_return_val_if_fail (iface->is_secret != NULL, FALSE); - - return iface->is_secret (mcpa, account, key); -} - -/** - * mcp_account_manager_parameter_make_secret: - * @mcpa: an #McpAccountManager instance - * @account: the unique name of an account - * @key: the constant string "param-", plus a parameter name like - * "account" or "password" - * - * Flag an account setting as secret for the lifetime of this - * #McpAccountManager. For instance, this should be called if - * @key has been retrieved from gnome-keyring. - * - * For historical reasons, this function only operates on parameters, - * but requires its argument to be prefixed with "param-". - */ -void -mcp_account_manager_parameter_make_secret (const McpAccountManager *mcpa, - const gchar *account, - const gchar *key) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_if_fail (iface != NULL); - g_return_if_fail (iface->make_secret != NULL); - - g_debug ("%s.%s should be secret", account, key); - iface->make_secret (mcpa, account, key); -} - /** * mcp_account_manager_get_unique_name: * @mcpa: an #McpAccountManager instance diff --git a/mission-control-plugins/account.h b/mission-control-plugins/account.h index 4015457b..c283ef99 100644 --- a/mission-control-plugins/account.h +++ b/mission-control-plugins/account.h @@ -66,14 +66,6 @@ gchar * mcp_account_manager_get_value (const McpAccountManager *mcpa, const gchar *account, const gchar *key); -gboolean mcp_account_manager_parameter_is_secret (const McpAccountManager *mcpa, - const gchar *account, - const gchar *key); - -void mcp_account_manager_parameter_make_secret (const McpAccountManager *mcpa, - const gchar *account, - const gchar *key); - gchar * mcp_account_manager_get_unique_name (McpAccountManager *mcpa, const gchar *manager, const gchar *protocol, diff --git a/mission-control-plugins/implementation.h b/mission-control-plugins/implementation.h index 2ad28938..9cc04b4e 100644 --- a/mission-control-plugins/implementation.h +++ b/mission-control-plugins/implementation.h @@ -86,14 +86,6 @@ struct _McpAccountManagerIface { const gchar *acct, const gchar *key); - gboolean (*is_secret) (const McpAccountManager *ma, - const gchar *acct, - const gchar *key); - - void (* make_secret) (const McpAccountManager *ma, - const gchar *acct, - const gchar *key); - gchar * (* unique_name) (const McpAccountManager *ma, const gchar *manager, const gchar *protocol, diff --git a/mission-control-plugins/mission-control-plugins.h b/mission-control-plugins/mission-control-plugins.h index 13d87e6f..806f472a 100644 --- a/mission-control-plugins/mission-control-plugins.h +++ b/mission-control-plugins/mission-control-plugins.h @@ -27,7 +27,6 @@ typedef enum { MCP_PARAMETER_FLAG_NONE = 0, - MCP_PARAMETER_FLAG_SECRET = TP_CONN_MGR_PARAM_FLAG_SECRET } McpParameterFlags; typedef enum { diff --git a/src/mcd-account.c b/src/mcd-account.c index 7b51afb8..752e9266 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -378,9 +378,8 @@ _mcd_account_set_parameter (McdAccount *account, const gchar *name, McdAccountPrivate *priv = account->priv; McdStorage *storage = priv->storage; const gchar *account_name = mcd_account_get_unique_name (account); - gboolean secret = mcd_account_parameter_is_secret (account, name); - mcd_storage_set_parameter (storage, account_name, name, value, secret); + mcd_storage_set_parameter (storage, account_name, name, value); } static GType mc_param_type (const TpConnectionManagerParam *param); @@ -5156,19 +5155,6 @@ _mcd_account_needs_dispatch (McdAccount *self) return self->priv->always_dispatch; } -gboolean -mcd_account_parameter_is_secret (McdAccount *self, const gchar *name) -{ - McdAccountPrivate *priv = self->priv; - const TpConnectionManagerParam *param; - - param = mcd_manager_get_protocol_param (priv->manager, - priv->protocol_name, name); - - return (param != NULL && - tp_connection_manager_param_is_secret (param)); -} - void _mcd_account_set_changing_presence (McdAccount *self, gboolean value) { diff --git a/src/mcd-account.h b/src/mcd-account.h index 59d8d9e3..3aad723f 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -129,9 +129,6 @@ McdConnection *mcd_account_get_connection (McdAccount *account); gboolean mcd_account_check_request (McdAccount *account, GHashTable *request, GError **error); -gboolean mcd_account_parameter_is_secret (McdAccount *self, - const gchar *name); - void mcd_account_altered_by_plugin (McdAccount *account, const gchar *name); gchar * mcd_account_dup_display_name (McdAccount *self); diff --git a/src/mcd-storage.c b/src/mcd-storage.c index f82cb797..6cc603b4 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -72,9 +72,6 @@ typedef struct { * e.g. { 'account': 'fred@example.com', 'password': 'foo' } * keys of @parameters and @escaped_parameters are disjoint */ GHashTable *escaped_parameters; - /* set of owned strings - * e.g. { 'password': 'password' } */ - GHashTable *secrets; } McdStorageAccount; static void @@ -85,7 +82,6 @@ mcd_storage_account_free (gpointer p) g_hash_table_unref (sa->attributes); g_hash_table_unref (sa->parameters); g_hash_table_unref (sa->escaped_parameters); - g_hash_table_unref (sa->secrets); g_slice_free (McdStorageAccount, sa); } @@ -222,8 +218,6 @@ ensure_account (McdStorage *self, g_free, (GDestroyNotify) g_variant_unref); sa->escaped_parameters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - sa->secrets = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); g_hash_table_insert (self->accounts, g_strdup (account), sa); } @@ -430,12 +424,6 @@ mcpa_set_parameter (const McpAccountManager *ma, if (value != NULL) g_hash_table_insert (sa->parameters, g_strdup (parameter), g_variant_ref_sink (value)); - - if (flags & MCP_PARAMETER_FLAG_SECRET) - { - DEBUG ("flagging %s parameter %s as secret", account, parameter); - g_hash_table_add (sa->secrets, g_strdup (parameter)); - } } static void @@ -519,47 +507,6 @@ list_keys (const McpAccountManager *ma, return (GStrv) g_ptr_array_free (ret, FALSE); } -static gboolean -is_secret (const McpAccountManager *ma, - const gchar *account, - const gchar *key) -{ - McdStorage *self = MCD_STORAGE (ma); - McdStorageAccount *sa = lookup_account (self, account); - - if (sa == NULL || !g_str_has_prefix (key, "param-")) - return FALSE; - - return g_hash_table_contains (sa->secrets, key + 6); -} - -static void -mcd_storage_make_secret (McdStorage *self, - const gchar *account, - const gchar *key) -{ - McdStorageAccount *sa; - - g_return_if_fail (MCD_IS_STORAGE (self)); - g_return_if_fail (account != NULL); - g_return_if_fail (key != NULL); - - if (!g_str_has_prefix (key, "param-")) - return; - - DEBUG ("flagging %s parameter %s as secret", account, key + 6); - sa = ensure_account (self, account); - g_hash_table_add (sa->secrets, g_strdup (key + 6)); -} - -static void -make_secret (const McpAccountManager *ma, - const gchar *account, - const gchar *key) -{ - mcd_storage_make_secret (MCD_STORAGE (ma), account, key); -} - static gchar * unique_name (const McpAccountManager *ma, const gchar *manager, @@ -1547,17 +1494,13 @@ update_storage (McdStorage *self, const gchar *account, const gchar *key, GVariant *variant, - const gchar *escaped, - gboolean secret) + const gchar *escaped) { GList *store; gboolean done = FALSE; gboolean parameter = g_str_has_prefix (key, "param-"); McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - if (secret) - mcd_storage_make_secret (self, account, key); - /* we're deleting, which is unconditional, no need to check if anyone * * claims this setting for themselves */ if (escaped == NULL) @@ -1582,8 +1525,7 @@ update_storage (McdStorage *self, } else if (variant != NULL && parameter && mcp_account_storage_set_parameter (plugin, ma, account, key + 6, - variant, - secret ? MCP_PARAMETER_FLAG_SECRET : MCP_PARAMETER_FLAG_NONE)) + variant, MCP_PARAMETER_FLAG_NONE)) { done = TRUE; DEBUG ("MCP:%s -> store parameter %s.%s", pn, account, key); @@ -1700,7 +1642,7 @@ mcd_storage_set_attribute (McdStorage *self, if (value != NULL) escaped = mcd_keyfile_escape_value (value); - update_storage (self, account, attribute, new_v, escaped, FALSE); + update_storage (self, account, attribute, new_v, escaped); g_free (escaped); updated = TRUE; } @@ -1715,8 +1657,6 @@ mcd_storage_set_attribute (McdStorage *self, * @account: the unique name of an account * @parameter: the name of the parameter, e.g. "account" * @value: the value to be stored (or %NULL to erase it) - * @secret: whether the value is confidential (might get stored in the - * keyring, for example) * * Copies and stores the supplied @value (or removes it if %NULL) in the * internal cache. @@ -1731,8 +1671,7 @@ gboolean mcd_storage_set_parameter (McdStorage *self, const gchar *account, const gchar *parameter, - const GValue *value, - gboolean secret) + const GValue *value) { GVariant *old_v; GVariant *new_v = NULL; @@ -1775,7 +1714,7 @@ mcd_storage_set_parameter (McdStorage *self, g_variant_ref (new_v)); g_snprintf (key, sizeof (key), "param-%s", parameter); - update_storage (self, account, key, new_v, new_escaped, secret); + update_storage (self, account, key, new_v, new_escaped); return TRUE; } @@ -2279,8 +2218,6 @@ plugin_iface_init (McpAccountManagerIface *iface, iface->set_value = set_value; iface->set_attribute = mcpa_set_attribute; iface->set_parameter = mcpa_set_parameter; - iface->is_secret = is_secret; - iface->make_secret = make_secret; iface->unique_name = unique_name; iface->identify_account_async = identify_account_async; iface->identify_account_finish = identify_account_finish; diff --git a/src/mcd-storage.h b/src/mcd-storage.h index e4408451..930b04b1 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -88,8 +88,7 @@ gboolean mcd_storage_set_attribute (McdStorage *storage, gboolean mcd_storage_set_parameter (McdStorage *storage, const gchar *account, const gchar *parameter, - const GValue *value, - gboolean secret); + const GValue *value); gchar *mcd_storage_create_account (McdStorage *storage, const gchar *provider, diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index a8a2e4df..c81bce48 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -1006,18 +1006,10 @@ test_dbus_account_plugin_get (const McpAccountStorage *storage, while (g_hash_table_iter_next (&iter, &k, &v)) { gchar *param_foo; - McpParameterFlags flags; param_foo = g_strdup_printf ("param-%s", (const gchar *) k); mcp_account_manager_set_value (am, account_name, param_foo, v); - flags = GPOINTER_TO_UINT (g_hash_table_lookup ( - account->parameter_flags, k)); - - if (flags & MCP_PARAMETER_FLAG_SECRET) - mcp_account_manager_parameter_make_secret (am, account_name, - param_foo); - g_free (param_foo); } @@ -1026,7 +1018,6 @@ test_dbus_account_plugin_get (const McpAccountStorage *storage, while (g_hash_table_iter_next (&iter, &k, &v)) { gchar *param_foo; - guint32 flags; gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, v); @@ -1034,13 +1025,6 @@ test_dbus_account_plugin_get (const McpAccountStorage *storage, mcp_account_manager_set_value (am, account_name, param_foo, escaped); g_free (escaped); - flags = GPOINTER_TO_UINT (g_hash_table_lookup (account->parameter_flags, - k)); - - if (flags & MCP_PARAMETER_FLAG_SECRET) - mcp_account_manager_parameter_make_secret (am, account_name, - param_foo); - g_free (param_foo); } @@ -1053,17 +1037,12 @@ test_dbus_account_plugin_get (const McpAccountStorage *storage, { GVariant *v = g_hash_table_lookup (account->parameters, key + 6); const gchar *s = g_hash_table_lookup (account->untyped_parameters, key + 6); - guint32 flags = GPOINTER_TO_UINT ( - g_hash_table_lookup (account->parameter_flags, key + 6)); g_dbus_connection_emit_signal (self->bus, NULL, TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, "GetParameter", g_variant_new_parsed ("(%o, %s)", account->path, key + 6), NULL); - if (flags & MCP_PARAMETER_FLAG_SECRET) - mcp_account_manager_parameter_make_secret (am, account_name, key); - if (v != NULL) { gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, -- cgit v1.2.3 From 21ab80884868a065772297d31f8ce8ba0d30bb7b Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 12 Nov 2013 15:51:44 +0000 Subject: McpAccountStorage: merge commit and commit_one into one function Based on part of a patch by Xavier Claessens. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=71384 Signed-off-by: Simon McVittie --- mission-control-plugins/account-storage.c | 77 ++++--------------------------- mission-control-plugins/account-storage.h | 8 ---- src/mcd-account-manager-default.c | 2 +- src/mcd-storage.c | 4 +- tests/twisted/dbus-account-plugin.c | 16 +++---- tests/twisted/mcp-account-diversion.c | 6 ++- 6 files changed, 24 insertions(+), 89 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 14f4f6d5..8f5609ce 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -60,7 +60,6 @@ * iface->set = foo_plugin_get; * iface->delete = foo_plugin_delete; * iface->commit = foo_plugin_commit; - * iface->commit_one = foo_plugin_commit_one; * iface->list = foo_plugin_list; * iface->ready = foo_plugin_ready; * iface->get_identifier = foo_plugin_get_identifier; @@ -316,7 +315,6 @@ mcp_account_storage_get_type (void) * @commit: implementation of mcp_account_storage_commit() * @list: implementation of mcp_account_storage_list() * @ready: implementation of mcp_account_storage_ready() - * @commit_one: implementation of mcp_account_storage_commit_one() * @get_identifier: implementation of mcp_account_storage_get_identifier() * @get_additional_info: implementation of * mcp_account_storage_get_additional_info() @@ -453,7 +451,7 @@ mcp_account_storage_get (const McpAccountStorage *storage, * * The plugin is not expected to write to its long term storage * at this point. It can expect Mission Control to call either - * mcp_account_storage_commit() or mcp_account_storage_commit_one() + * mcp_account_storage_commit() with either @account or %NULL * after a short delay. * * Plugins that implement mcp_storage_set_attribute() and @@ -686,6 +684,8 @@ mcp_account_storage_delete (const McpAccountStorage *storage, * McpAccountStorageCommitFunc: * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance + * @account: (allow-none): the unique suffix of an account's object path, + * or %NULL to commit all accounts * * An implementation of mcp_account_storage_commit(). * @@ -696,6 +696,8 @@ mcp_account_storage_delete (const McpAccountStorage *storage, * mcp_account_storage_commit: * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance + * @account: (allow-none): the unique suffix of an account's object path, + * or %NULL if all accounts are to be committed * * The plugin is expected to write its cache to long term storage, * deleting, adding or updating entries in said storage as needed. @@ -704,74 +706,12 @@ mcp_account_storage_delete (const McpAccountStorage *storage, * not required to have finished its commit operation when it returns, * merely to have started the operation. * - * If the @commit_one method is implemented, it will be called preferentially - * if only one account is to be committed. If the @commit_one method is - * implemented but @commit is not, @commit_one will be called with - * @account_name = %NULL to commit all accounts. - * * Returns: %TRUE if the commit process was started (but not necessarily * completed) successfully; %FALSE if there was a problem that was immediately * obvious. */ gboolean mcp_account_storage_commit (const McpAccountStorage *storage, - const McpAccountManager *am) -{ - McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - - SDEBUG (storage, "committing all accounts"); - g_return_val_if_fail (iface != NULL, FALSE); - - if (iface->commit != NULL) - { - return iface->commit (storage, am); - } - else if (iface->commit_one != NULL) - { - return iface->commit_one (storage, am, NULL); - } - else - { - SDEBUG (storage, - "neither commit nor commit_one is implemented; cannot save accounts"); - return FALSE; - } -} - -/** - * McpAccountStorageCommitOneFunc: - * @storage: an #McpAccountStorage instance - * @am: an #McpAccountManager instance - * @account: (allow-none): the unique suffix of an account's object path, - * or %NULL - * - * An implementation of mcp_account_storage_commit_one(). - * - * Returns: %TRUE if the commit process was started successfully - */ - -/** - * mcp_account_storage_commit_one: - * @storage: an #McpAccountStorage instance - * @am: an #McpAccountManager instance - * @account: (allow-none): the unique suffix of an account's object path, - * or %NULL if all accounts are to be committed and - * mcp_account_storage_commit() is unimplemented - * - * The same as mcp_account_storage_commit(), but only commit the given - * account. This is optional to implement; the default implementation - * is to call @commit. - * - * If both mcp_account_storage_commit_one() and mcp_account_storage_commit() - * are implemented, Mission Control will never pass @account = %NULL to - * this method. - * - * Returns: %TRUE if the commit process was started (but not necessarily - * completed) successfully; %FALSE if there was a problem that was immediately - * obvious. - */ -gboolean -mcp_account_storage_commit_one (const McpAccountStorage *storage, const McpAccountManager *am, const gchar *account) { @@ -780,11 +720,10 @@ mcp_account_storage_commit_one (const McpAccountStorage *storage, SDEBUG (storage, "called for %s", account ? account : ""); g_return_val_if_fail (iface != NULL, FALSE); - if (iface->commit_one != NULL) - return iface->commit_one (storage, am, account); + if (iface->commit != NULL) + return iface->commit (storage, am, account); else - /* Fall back to plain ->commit() */ - return mcp_account_storage_commit (storage, am); + return FALSE; } /** diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 5c111025..ecc4e267 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -86,9 +86,6 @@ typedef GList * (*McpAccountStorageListFunc) ( const McpAccountStorage *storage, const McpAccountManager *am); typedef gboolean (*McpAccountStorageCommitFunc) ( - const McpAccountStorage *storage, - const McpAccountManager *am); -typedef gboolean (*McpAccountStorageCommitOneFunc) ( const McpAccountStorage *storage, const McpAccountManager *am, const gchar *account); @@ -121,7 +118,6 @@ struct _McpAccountStorageIface McpAccountStorageCommitFunc commit; McpAccountStorageListFunc list; McpAccountStorageReadyFunc ready; - McpAccountStorageCommitOneFunc commit_one; McpAccountStorageGetIdentifierFunc get_identifier; McpAccountStorageGetAdditionalInfoFunc get_additional_info; McpAccountStorageGetRestrictionsFunc get_restrictions; @@ -176,10 +172,6 @@ void mcp_account_storage_ready (const McpAccountStorage *storage, gboolean mcp_account_storage_commit (const McpAccountStorage *storage, - const McpAccountManager *am); - -gboolean -mcp_account_storage_commit_one (const McpAccountStorage *storage, const McpAccountManager *am, const gchar *account); diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 85b5e4e5..0a19e48f 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -1015,7 +1015,7 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->set_parameter = set_parameter; iface->create = _create; iface->delete = _delete; - iface->commit_one = _commit; + iface->commit = _commit; iface->list = _list; } diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 6cc603b4..59322175 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -2144,12 +2144,12 @@ mcd_storage_commit (McdStorage *self, const gchar *account) if (account != NULL) { DEBUG ("flushing plugin %s %s to long term storage", pname, account); - mcp_account_storage_commit_one (plugin, ma, account); + mcp_account_storage_commit (plugin, ma, account); } else { DEBUG ("flushing plugin %s to long term storage", pname); - mcp_account_storage_commit (plugin, ma); + mcp_account_storage_commit (plugin, ma, NULL); } } } diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index c81bce48..0e94b9b3 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -1174,7 +1174,7 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, } static gboolean -test_dbus_account_plugin_commit (const McpAccountStorage *storage, +test_dbus_account_plugin_commit_all (const McpAccountStorage *storage, const McpAccountManager *am) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); @@ -1194,7 +1194,7 @@ test_dbus_account_plugin_commit (const McpAccountStorage *storage, while (g_hash_table_iter_next (&iter, &k, NULL)) { - if (!mcp_account_storage_commit_one (storage, am, k)) + if (!mcp_account_storage_commit (storage, am, k)) { g_warning ("declined to commit account %s", (const gchar *) k); } @@ -1334,12 +1334,12 @@ update_parameters_cb (GObject *source_object, } static gboolean -test_dbus_account_plugin_commit_one (const McpAccountStorage *storage, +test_dbus_account_plugin_commit (const McpAccountStorage *storage, const McpAccountManager *am, const gchar *account_name) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); - Account *account = lookup_account (self, account_name); + Account *account; GHashTableIter iter; gpointer k; GVariantBuilder a_sv_builder; @@ -1349,9 +1349,10 @@ test_dbus_account_plugin_commit_one (const McpAccountStorage *storage, DEBUG ("%s", account_name); - /* MC does not call @commit_one with parameter %NULL (meaning "all accounts") - * if we also implement commit(), which, as it happens, we do */ - g_return_val_if_fail (account_name != NULL, FALSE); + if (account_name == NULL) + return test_dbus_account_plugin_commit_all (storage, am); + + account = lookup_account (self, account_name); if (!self->active || account == NULL) return FALSE; @@ -1591,7 +1592,6 @@ account_storage_iface_init (McpAccountStorageIface *iface) iface->ready = test_dbus_account_plugin_ready; iface->delete = test_dbus_account_plugin_delete; iface->commit = test_dbus_account_plugin_commit; - iface->commit_one = test_dbus_account_plugin_commit_one; iface->get_identifier = test_dbus_account_plugin_get_identifier; iface->get_additional_info = test_dbus_account_plugin_get_additional_info; iface->get_restrictions = test_dbus_account_plugin_get_restrictions; diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index 923f51b4..e36b1ac5 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -207,13 +207,17 @@ _delete (const McpAccountStorage *self, static gboolean _commit (const McpAccountStorage *self, - const McpAccountManager *am) + const McpAccountManager *am, + const gchar *account_name G_GNUC_UNUSED) { gsize n; gchar *data; AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); gboolean rval = FALSE; + /* This simple implementation ignores account_name and commits everything: + * we're writing out the whole keyfile anyway */ + if (!adp->save) return TRUE; -- cgit v1.2.3 From 65e376653dfea9d1b3712f8429b657f9d4338386 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 12 Nov 2013 16:00:31 +0000 Subject: Remove mcp_account_storage_set() _set_attribute() and _set_parameter() are now mandatory for writable storage plugins. Note that most of the keyfile escaping code is still needed to help plugins to read their old keyfile values. [adjusted to apply earlier in the branch; left in the code that detects whether mcd_storage_set_parameter() is a no-op for an escaped parameter; took out mcp_account_storage_emit_created documentation fix -smcv] Bug: https://bugs.freedesktop.org/show_bug.cgi?id=71384 Signed-off-by: Simon McVittie --- mission-control-plugins/account-storage.c | 76 ++----------------------------- mission-control-plugins/account-storage.h | 13 ------ src/mcd-account-manager-default.c | 11 ----- src/mcd-storage.c | 28 +++--------- tests/twisted/dbus-account-plugin.c | 13 ------ tests/twisted/mcp-account-diversion.c | 48 ++++++++++++++++--- 6 files changed, 52 insertions(+), 137 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 8f5609ce..83189564 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -57,7 +57,6 @@ * iface->provider = "org.freedesktop.Telepathy.MissionControl5.FooStorage"; * * iface->get = foo_plugin_get; - * iface->set = foo_plugin_get; * iface->delete = foo_plugin_delete; * iface->commit = foo_plugin_commit; * iface->list = foo_plugin_list; @@ -111,16 +110,6 @@ enum static guint signals[NO_SIGNAL] = { 0 }; -static gboolean -default_set (const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account, - const gchar *key, - const gchar *val) -{ - return FALSE; -} - static gboolean default_set_attribute (McpAccountStorage *storage, McpAccountManager *am, @@ -164,7 +153,6 @@ class_init (gpointer klass, McpAccountStorageIface *iface = klass; iface->owns = default_owns; - iface->set = default_set; iface->set_attribute = default_set_attribute; iface->set_parameter = default_set_parameter; @@ -422,59 +410,6 @@ mcp_account_storage_get (const McpAccountStorage *storage, return iface->get (storage, am, account, key); } -/** - * McpAccountStorageSetFunc: - * @storage: an #McpAccountStorage instance - * @am: an #McpAccountManager instance - * @account: the unique name of the account - * @key: the setting whose value we wish to store: either an attribute - * like "DisplayName", or "param-" plus a parameter like "account" - * @val: a non-%NULL value for @key - * - * An implementation of mcp_account_storage_set(). - * - * Returns: %TRUE if @storage is responsible for @account - */ - -/** - * mcp_account_storage_set: - * @storage: an #McpAccountStorage instance - * @am: an #McpAccountManager instance - * @account: the unique name of the account - * @key: the non-%NULL setting whose value we wish to store: either an - * attribute like "DisplayName", or "param-" plus a parameter like "account" - * @value: a value to associate with @key, escaped as if for a #GKeyFile - * - * The plugin is expected to either quickly and synchronously - * update its internal cache of values with @value, or to - * decline to store the setting. - * - * The plugin is not expected to write to its long term storage - * at this point. It can expect Mission Control to call either - * mcp_account_storage_commit() with either @account or %NULL - * after a short delay. - * - * Plugins that implement mcp_storage_set_attribute() and - * mcp_account_storage_set_parameter() can just return %FALSE here. - * There is a default implementation, which just returns %FALSE. - * - * Returns: %TRUE if the attribute was claimed, %FALSE otherwise - */ -gboolean -mcp_account_storage_set (const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account, - const gchar *key, - const gchar *value) -{ - McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - - SDEBUG (storage, ""); - g_return_val_if_fail (iface != NULL, FALSE); - - return iface->set (storage, am, account, key, value); -} - /** * mcp_account_storage_set_attribute: * @storage: an #McpAccountStorage instance @@ -493,9 +428,8 @@ mcp_account_storage_set (const McpAccountStorage *storage, * The plugin is not expected to write to its long term storage * at this point. * - * There is a default implementation, which just returns %FALSE. - * Mission Control will call mcp_account_storage_set() instead, - * using a keyfile-escaped version of @value. + * There is a default implementation, which just returns %FALSE for read-only + * storage plugins. * * Returns: %TRUE if the attribute was claimed, %FALSE otherwise * @@ -537,10 +471,8 @@ mcp_account_storage_set_attribute (McpAccountStorage *storage, * The plugin is not expected to write to its long term storage * at this point. * - * There is a default implementation, which just returns %FALSE. - * Mission Control will call mcp_account_storage_set() instead, - * using "param-" + @parameter as key and a keyfile-escaped version - * of @value as value. + * There is a default implementation, which just returns %FALSE for read-only + * storage plugins. * * Returns: %TRUE if the parameter was claimed, %FALSE otherwise * diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index ecc4e267..198e8353 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -64,12 +64,6 @@ typedef gboolean (*McpAccountStorageGetFunc) ( const McpAccountManager *am, const gchar *account, const gchar *key); -typedef gboolean (*McpAccountStorageSetFunc) ( - const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account, - const gchar *key, - const gchar *val); typedef gchar * (*McpAccountStorageCreate) ( const McpAccountStorage *storage, const McpAccountManager *am, @@ -112,7 +106,6 @@ struct _McpAccountStorageIface const gchar *desc; const gchar *provider; - McpAccountStorageSetFunc set; McpAccountStorageGetFunc get; McpAccountStorageDeleteFunc delete; McpAccountStorageCommitFunc commit; @@ -149,12 +142,6 @@ gboolean mcp_account_storage_get (const McpAccountStorage *storage, const gchar *account, const gchar *key); -gboolean mcp_account_storage_set (const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account, - const gchar *key, - const gchar *value); - gchar * mcp_account_storage_create (const McpAccountStorage *storage, const McpAccountManager *am, const gchar *manager, diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 0a19e48f..e37ea89b 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -214,16 +214,6 @@ set_attribute (McpAccountStorage *self, return TRUE; } -static gboolean -_set (const McpAccountStorage *self, - const McpAccountManager *am, - const gchar *account, - const gchar *key, - const gchar *val) -{ - return FALSE; -} - static gboolean get_parameter (const McpAccountStorage *self, const McpAccountManager *am, @@ -1010,7 +1000,6 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->priority = PLUGIN_PRIORITY; iface->get = _get; - iface->set = _set; iface->set_attribute = set_attribute; iface->set_parameter = set_parameter; iface->create = _create; diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 59322175..5caafbc5 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1493,8 +1493,7 @@ static void update_storage (McdStorage *self, const gchar *account, const gchar *key, - GVariant *variant, - const gchar *escaped) + GVariant *variant) { GList *store; gboolean done = FALSE; @@ -1503,7 +1502,7 @@ update_storage (McdStorage *self, /* we're deleting, which is unconditional, no need to check if anyone * * claims this setting for themselves */ - if (escaped == NULL) + if (variant == NULL) done = TRUE; for (store = stores; store != NULL; store = g_list_next (store)) @@ -1511,31 +1510,25 @@ update_storage (McdStorage *self, McpAccountStorage *plugin = store->data; const gchar *pn = mcp_account_storage_name (plugin); - if (done) + if (done) /* in particular, if variant == NULL */ { DEBUG ("MCP:%s -> delete %s.%s", pn, account, key); mcp_account_storage_delete (plugin, ma, account, key); } - else if (variant != NULL && !parameter && + else if (!parameter && mcp_account_storage_set_attribute (plugin, ma, account, key, variant, MCP_ATTRIBUTE_FLAG_NONE)) { done = TRUE; DEBUG ("MCP:%s -> store attribute %s.%s", pn, account, key); } - else if (variant != NULL && parameter && + else if (parameter && mcp_account_storage_set_parameter (plugin, ma, account, key + 6, variant, MCP_PARAMETER_FLAG_NONE)) { done = TRUE; DEBUG ("MCP:%s -> store parameter %s.%s", pn, account, key); } - else - { - done = mcp_account_storage_set (plugin, ma, account, key, escaped); - DEBUG ("MCP:%s -> %s %s.%s", - pn, done ? "store" : "ignore", account, key); - } } } @@ -1628,8 +1621,6 @@ mcd_storage_set_attribute (McdStorage *self, if (!mcd_nullable_variant_equal (old_v, new_v)) { - gchar *escaped = NULL; - /* First put it in the attributes hash table. (Watch out, this might * invalidate old_v.) */ if (new_v == NULL) @@ -1638,12 +1629,7 @@ mcd_storage_set_attribute (McdStorage *self, g_hash_table_insert (sa->attributes, g_strdup (attribute), g_variant_ref (new_v)); - /* OK now we have to escape it in a stupid way for plugins */ - if (value != NULL) - escaped = mcd_keyfile_escape_value (value); - - update_storage (self, account, attribute, new_v, escaped); - g_free (escaped); + update_storage (self, account, attribute, new_v); updated = TRUE; } @@ -1714,7 +1700,7 @@ mcd_storage_set_parameter (McdStorage *self, g_variant_ref (new_v)); g_snprintf (key, sizeof (key), "param-%s", parameter); - update_storage (self, account, key, new_v, new_escaped); + update_storage (self, account, key, new_v); return TRUE; } diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 0e94b9b3..016417a1 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -1086,18 +1086,6 @@ test_dbus_account_plugin_get (const McpAccountStorage *storage, return TRUE; } -static gboolean -test_dbus_account_plugin_set (const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account_name, - const gchar *key, - const gchar *value) -{ - /* Now that we implement set_attribute and set_parameter, this no longer - * needs a real implementation. */ - return FALSE; -} - static gboolean test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, McpAccountManager *am, @@ -1585,7 +1573,6 @@ account_storage_iface_init (McpAccountStorageIface *iface) iface->priority = MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_NORMAL + 100; iface->get = test_dbus_account_plugin_get; - iface->set = test_dbus_account_plugin_set; iface->set_attribute = test_dbus_account_plugin_set_attribute; iface->set_parameter = test_dbus_account_plugin_set_parameter; iface->list = test_dbus_account_plugin_list; diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index e36b1ac5..44fd4e3a 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -112,23 +112,56 @@ _create_config (void) } static gboolean -_set (const McpAccountStorage *self, - const McpAccountManager *am, - const gchar *account, - const gchar *key, - const gchar *val) +_set (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + const gchar *key, + GVariant *val, + McpParameterFlags flags) { AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + gchar *val_str; if (g_str_has_prefix (account, DONT_DIVERT)) return FALSE; adp->save = TRUE; - g_key_file_set_value (adp->keyfile, account, key, val); + + val_str = mcp_account_manager_escape_variant_for_keyfile (am, val); + g_key_file_set_value (adp->keyfile, account, key, val_str); + g_free (val_str); return TRUE; } +static gboolean +_set_attribute (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + const gchar *attribute, + GVariant *val, + McpAttributeFlags flags) +{ + return _set (self, am, account, attribute, val, flags); +} + +static gboolean +_set_parameter (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + const gchar *parameter, + GVariant *val, + McpParameterFlags flags) +{ + gchar *param = g_strdup_printf ("param-%s", parameter); + gboolean ret; + + ret = _set (self, am, account, param, val, flags); + g_free (param); + + return ret; +} + static gboolean _get (const McpAccountStorage *self, const McpAccountManager *am, @@ -268,7 +301,8 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->priority = PLUGIN_PRIORITY; iface->get = _get; - iface->set = _set; + iface->set_attribute = _set_attribute; + iface->set_parameter = _set_parameter; iface->delete = _delete; iface->commit = _commit; iface->list = _list; -- cgit v1.2.3 From 8675bf5caaf33593e0e1b5c6cf30ff3133879fa2 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 12 Nov 2013 16:00:49 +0000 Subject: mcp_account_storage_emit_created: fix doc-comment Originally part of a commit by Xavier Claessens. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 83189564..d2ac20cc 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -909,7 +909,7 @@ mcp_account_storage_provider (const McpAccountStorage *storage) } /** - * mcp_account_storage_emit_create: + * mcp_account_storage_emit_created: * @storage: an #McpAccountStorage instance * @account: the unique name of the created account * -- cgit v1.2.3 From 20b3a72a9a34b6c5eb095a24dc94d39f0bcf40ea Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 12 Nov 2013 18:13:24 +0000 Subject: McpAccountStorage: have a default implementation for every method Based on a patch by Xavier Claessens. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 161 +++++++++++++++++++++++------- 1 file changed, 123 insertions(+), 38 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index d2ac20cc..5ad31b6c 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -110,6 +110,82 @@ enum static guint signals[NO_SIGNAL] = { 0 }; +static gboolean +default_get (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *account, + const gchar *key) +{ + return FALSE; +} + +static gboolean +default_delete (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *account, + const gchar *key) +{ + return FALSE; +} + +static gboolean +default_commit (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *account) +{ + return FALSE; +} + +static gchar * +default_create (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *manager, + const gchar *protocol, + const gchar *identification, + GError **error) +{ + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, + "This storage does not implement the create() function"); + return NULL; +} + +static GList * +default_list (const McpAccountStorage *storage, + const McpAccountManager *am) +{ + return NULL; +} + +static void +default_ready (const McpAccountStorage *storage, + const McpAccountManager *am) +{ + /* do nothing */ +} + +static void +default_get_identifier (const McpAccountStorage *storage, + const gchar *account, + GValue *identifier) +{ + g_value_init (identifier, G_TYPE_STRING); + g_value_set_string (identifier, account); +} + +static GHashTable * +default_get_additional_info (const McpAccountStorage *storage, + const gchar *account) +{ + return g_hash_table_new (g_str_hash, g_str_equal); +} + +static TpStorageRestrictionFlags +default_get_restrictions (const McpAccountStorage *storage, + const gchar *account) +{ + return 0; +} + static gboolean default_set_attribute (McpAccountStorage *storage, McpAccountManager *am, @@ -152,6 +228,15 @@ class_init (gpointer klass, GType type = G_TYPE_FROM_CLASS (klass); McpAccountStorageIface *iface = klass; + iface->get = default_get; + iface->create = default_create; + iface->delete = default_delete; + iface->commit = default_commit; + iface->list = default_list; + iface->ready = default_ready; + iface->get_identifier = default_get_identifier; + iface->get_additional_info = default_get_additional_info; + iface->get_restrictions = default_get_restrictions; iface->owns = default_owns; iface->set_attribute = default_set_attribute; iface->set_parameter = default_set_parameter; @@ -393,6 +478,9 @@ mcp_account_storage_priority (const McpAccountStorage *storage) * %TRUE if any attributes or parameters were found, or %FALSE if it * was not responsible for @account. * + * The default implementation just returns %FALSE, and should always be + * overridden. + * * Returns: %TRUE if @storage is responsible for @account */ gboolean @@ -532,6 +620,9 @@ mcp_account_storage_set_parameter (McpAccountStorage *storage, * #McpAccountStorage::created signal should not be emitted for this account, * not even when mcp_account_storage_commit() will be called. * + * The default implementation just returns %NULL, and is appropriate for + * read-only storage. + * * Returns: (transfer full): the newly allocated account name, which should * be freed once the caller is done with it, or %NULL if that couldn't * be done. @@ -547,13 +638,7 @@ mcp_account_storage_create (const McpAccountStorage *storage, McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); g_return_val_if_fail (iface != NULL, NULL); - - if (iface->create == NULL) - { - g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, - "This storage does not implement create function"); - return NULL; - } + g_return_val_if_fail (iface->create != NULL, NULL); return iface->create (storage, am, manager, protocol, identification, error); } @@ -593,6 +678,9 @@ mcp_account_storage_create (const McpAccountStorage *storage, * The plugin is not expected to update its long term storage at * this point. * + * The default implementation just returns %FALSE, and is appropriate for + * read-only storage. + * * Returns: %TRUE if the setting or settings are not * the plugin's cache after this operation, %FALSE otherwise. * This is very unlikely to ever be %FALSE, as a plugin is always @@ -608,6 +696,7 @@ mcp_account_storage_delete (const McpAccountStorage *storage, SDEBUG (storage, ""); g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (iface->delete != NULL, FALSE); return iface->delete (storage, am, account, key); } @@ -638,6 +727,9 @@ mcp_account_storage_delete (const McpAccountStorage *storage, * not required to have finished its commit operation when it returns, * merely to have started the operation. * + * The default implementation just returns %FALSE, and is appropriate for + * read-only storage. + * * Returns: %TRUE if the commit process was started (but not necessarily * completed) successfully; %FALSE if there was a problem that was immediately * obvious. @@ -651,11 +743,9 @@ mcp_account_storage_commit (const McpAccountStorage *storage, SDEBUG (storage, "called for %s", account ? account : ""); g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (iface->commit != NULL, FALSE); - if (iface->commit != NULL) - return iface->commit (storage, am, account); - else - return FALSE; + return iface->commit (storage, am, account); } /** @@ -679,6 +769,8 @@ mcp_account_storage_commit (const McpAccountStorage *storage, * This method is called only at initialisation time, before the dbus name * has been claimed, and is the only one permitted to block. * + * The default implementation returns %NULL, i.e. an empty list. + * * Returns: (element-type utf8) (transfer full): a list of account names that * the plugin has settings for. The account names should be freed with * g_free(), and the list with g_list_free(), when the caller is done with @@ -692,6 +784,7 @@ mcp_account_storage_list (const McpAccountStorage *storage, SDEBUG (storage, ""); g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (iface->list != NULL, NULL); return iface->list (storage, am); } @@ -712,6 +805,10 @@ mcp_account_storage_list (const McpAccountStorage *storage, * Informs the plugin that it is now permitted to create new accounts, * ie it can now fire its "created", "altered-one", "toggled" and "deleted" * signals. + * + * The default implementation does nothing. It should be overridden by + * any plugin that will emit "created", "altered-one", "toggled" and/or + * "deleted". */ void mcp_account_storage_ready (const McpAccountStorage *storage, @@ -720,12 +817,9 @@ mcp_account_storage_ready (const McpAccountStorage *storage, McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); g_return_if_fail (iface != NULL); + g_return_if_fail (iface->ready != NULL); - /* plugins that can't create accounts from external sources don't * - * need to implement this method, as they can never fire the async * - * account change signals: */ - if (iface->ready != NULL) - iface->ready (storage, am); + iface->ready (storage, am); } /** @@ -748,6 +842,8 @@ mcp_account_storage_ready (const McpAccountStorage *storage, * Get the storage-specific identifier for this account. The type is variant, * hence the GValue. * + * The default implementation returns @account as a %G_TYPE_STRING. + * * This method will only be called for the storage plugin that "owns" * the account. */ @@ -760,18 +856,11 @@ mcp_account_storage_get_identifier (const McpAccountStorage *storage, SDEBUG (storage, ""); g_return_if_fail (iface != NULL); + g_return_if_fail (iface->get_identifier != NULL); g_return_if_fail (identifier != NULL); g_return_if_fail (!G_IS_VALUE (identifier)); - if (iface->get_identifier == NULL) - { - g_value_init (identifier, G_TYPE_STRING); - g_value_set_string (identifier, account); - } - else - { - iface->get_identifier (storage, account, identifier); - } + iface->get_identifier (storage, account, identifier); } /** @@ -796,26 +885,22 @@ mcp_account_storage_get_identifier (const McpAccountStorage *storage, * This method will only be called for the storage plugin that "owns" * the account. * + * The default implementation returns an empty map. + * * Returns: (transfer container) (element-type utf8 GObject.Value): additional - * storage-specific information + * storage-specific information, which must not be %NULL */ GHashTable * mcp_account_storage_get_additional_info (const McpAccountStorage *storage, const gchar *account) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - GHashTable *ret = NULL; SDEBUG (storage, ""); g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (iface->get_additional_info != NULL, FALSE); - if (iface->get_additional_info != NULL) - ret = iface->get_additional_info (storage, account); - - if (ret == NULL) - ret = g_hash_table_new (g_str_hash, g_str_equal); - - return ret; + return iface->get_additional_info (storage, account); } /** @@ -836,6 +921,8 @@ mcp_account_storage_get_additional_info (const McpAccountStorage *storage, * This method will only be called for the storage plugin that "owns" * the account. * + * The default implementation returns 0, i.e. no restrictions. + * * Returns: a bitmask of %TpStorageRestrictionFlags with the restrictions to * account storage. */ @@ -846,11 +933,9 @@ mcp_account_storage_get_restrictions (const McpAccountStorage *storage, McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); g_return_val_if_fail (iface != NULL, 0); + g_return_val_if_fail (iface->get_restrictions != NULL, 0); - if (iface->get_restrictions == NULL) - return 0; - else - return iface->get_restrictions (storage, account); + return iface->get_restrictions (storage, account); } /** -- cgit v1.2.3 From 2dc61bd97a4e1d1862df5b45b0f28dfb1d8b2a2c Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 12 Nov 2013 19:30:17 +0000 Subject: Remove unused code [adjusted to apply at a different position in the branch -smcv] Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account.c | 109 ------------------------------- mission-control-plugins/account.h | 19 ------ mission-control-plugins/implementation.h | 16 ----- src/mcd-storage.c | 76 --------------------- 4 files changed, 220 deletions(-) diff --git a/mission-control-plugins/account.c b/mission-control-plugins/account.c index 493a34c0..c9859d70 100644 --- a/mission-control-plugins/account.c +++ b/mission-control-plugins/account.c @@ -190,31 +190,6 @@ mcp_account_manager_list_keys (const McpAccountManager *mcpa, return iface->list_keys (mcpa, account); } -/** - * mcp_account_manager_get_value: - * @mcpa: an #McpAccountManager instance - * @account: the unique name of an account - * @key: the setting whose value we wish to fetch: either an attribute - * like "DisplayName", or "param-" plus a parameter like "account" - * - * Fetch a copy of the current value of an account setting held by - * the account manager. - * - * Returns: (transfer full): the value of @key - */ -gchar * -mcp_account_manager_get_value (const McpAccountManager *mcpa, - const gchar *account, - const gchar *key) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_val_if_fail (iface != NULL, NULL); - g_return_val_if_fail (iface->set_value != NULL, NULL); - - return iface->get_value (mcpa, account, key); -} - /** * mcp_account_manager_get_unique_name: * @mcpa: an #McpAccountManager instance @@ -291,34 +266,6 @@ mcp_account_manager_identify_account_finish (McpAccountManager *mcpa, return iface->identify_account_finish (mcpa, res, error); } -/** - * mcp_account_manager_escape_value_from_keyfile: - * @mcpa: a #McpAccountManager - * @value: a value with a supported #GType - * - * Escape @value so it could be passed to g_key_file_set_value(). - * For instance, escaping the boolean value TRUE returns "true", - * and escaping the string value containing one space returns "\s". - * - * It is a programming error to use an unsupported type. - * The supported types are currently %G_TYPE_STRING, %G_TYPE_BOOLEAN, - * %G_TYPE_INT, %G_TYPE_UINT, %G_TYPE_INT64, %G_TYPE_UINT64, %G_TYPE_UCHAR, - * %G_TYPE_STRV, %DBUS_TYPE_G_OBJECT_PATH and %TP_ARRAY_TYPE_OBJECT_PATH_LIST. - * - * Returns: the escaped form of @value - */ -gchar * -mcp_account_manager_escape_value_for_keyfile (const McpAccountManager *mcpa, - const GValue *value) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_val_if_fail (iface != NULL, NULL); - g_return_val_if_fail (iface->escape_value_for_keyfile != NULL, NULL); - - return iface->escape_value_for_keyfile (mcpa, value); -} - /** * mcp_account_manager_escape_variant_for_keyfile: * @mcpa: a #McpAccountManager @@ -348,59 +295,3 @@ mcp_account_manager_escape_variant_for_keyfile (const McpAccountManager *mcpa, return iface->escape_variant_for_keyfile (mcpa, variant); } - -/** - * mcp_account_manager_unescape_value_from_keyfile: - * @mcpa: a #McpAccountManager - * @escaped: an escaped string as returned by g_key_file_get_value() - * @value: a value to populate, with a supported #GType - * @error: used to raise an error if %FALSE is returned - * - * Attempt to interpret @escaped as a value of @value's type. - * If successful, put it in @value and return %TRUE. - * - * It is a programming error to try to escape an unsupported type. - * The supported types are currently %G_TYPE_STRING, %G_TYPE_BOOLEAN, - * %G_TYPE_INT, %G_TYPE_UINT, %G_TYPE_INT64, %G_TYPE_UINT64, %G_TYPE_UCHAR, - * %G_TYPE_STRV, %DBUS_TYPE_G_OBJECT_PATH and %TP_ARRAY_TYPE_OBJECT_PATH_LIST. - * - * Returns: %TRUE if @value was filled in - */ -gboolean -mcp_account_manager_unescape_value_from_keyfile (const McpAccountManager *mcpa, - const gchar *escaped, - GValue *value, - GError **error) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_val_if_fail (iface != NULL, FALSE); - g_return_val_if_fail (iface->unescape_value_from_keyfile != NULL, FALSE); - - return iface->unescape_value_from_keyfile (mcpa, escaped, value, error); -} - -/** - * mcp_account_manager_init_value_for_attribute: - * @mcpa: a #McpAccountManager - * @value: a zero-filled value to initialize - * @attribute: a supported Mission Control attribute - * - * If @attribute is a known Mission Control attribute, initialize @value - * with an appropriate type for @attribute and return %TRUE. Otherwise, - * return %FALSE. - * - * Returns: %TRUE if @value was initialized - */ -gboolean -mcp_account_manager_init_value_for_attribute (const McpAccountManager *mcpa, - GValue *value, - const gchar *attribute) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_val_if_fail (iface != NULL, FALSE); - g_return_val_if_fail (iface->init_value_for_attribute != NULL, FALSE); - - return iface->init_value_for_attribute (mcpa, value, attribute); -} diff --git a/mission-control-plugins/account.h b/mission-control-plugins/account.h index c283ef99..4356b3c0 100644 --- a/mission-control-plugins/account.h +++ b/mission-control-plugins/account.h @@ -62,10 +62,6 @@ void mcp_account_manager_set_parameter (const McpAccountManager *mcpa, GVariant *value, McpParameterFlags flags); -gchar * mcp_account_manager_get_value (const McpAccountManager *mcpa, - const gchar *account, - const gchar *key); - gchar * mcp_account_manager_get_unique_name (McpAccountManager *mcpa, const gchar *manager, const gchar *protocol, @@ -74,25 +70,10 @@ gchar * mcp_account_manager_get_unique_name (McpAccountManager *mcpa, GStrv mcp_account_manager_list_keys (const McpAccountManager *mcpa, const gchar *account); -gchar *mcp_account_manager_escape_value_for_keyfile ( - const McpAccountManager *mcpa, - const GValue *value); - gchar *mcp_account_manager_escape_variant_for_keyfile ( const McpAccountManager *mcpa, GVariant *variant); -gboolean mcp_account_manager_unescape_value_from_keyfile ( - const McpAccountManager *mcpa, - const gchar *escaped, - GValue *value, - GError **error); - -gboolean mcp_account_manager_init_value_for_attribute ( - const McpAccountManager *mcpa, - GValue *value, - const gchar *attribute); - void mcp_account_manager_identify_account_async (McpAccountManager *mcpa, const gchar *manager, const gchar *protocol, diff --git a/mission-control-plugins/implementation.h b/mission-control-plugins/implementation.h index 9cc04b4e..9d44b3bb 100644 --- a/mission-control-plugins/implementation.h +++ b/mission-control-plugins/implementation.h @@ -82,10 +82,6 @@ struct _McpAccountManagerIface { const gchar *key, const gchar *value); - gchar * (*get_value) (const McpAccountManager *ma, - const gchar *acct, - const gchar *key); - gchar * (* unique_name) (const McpAccountManager *ma, const gchar *manager, const gchar *protocol, @@ -94,18 +90,6 @@ struct _McpAccountManagerIface { GStrv (* list_keys) (const McpAccountManager *ma, const gchar *acct); - gchar * (* escape_value_for_keyfile) (const McpAccountManager *mcpa, - const GValue *value); - - gboolean (* unescape_value_from_keyfile) (const McpAccountManager *mcpa, - const gchar *escaped, - GValue *value, - GError **error); - - gboolean (* init_value_for_attribute) (const McpAccountManager *mcpa, - GValue *value, - const gchar *attribute); - gchar * (* escape_variant_for_keyfile) (const McpAccountManager *mcpa, GVariant *variant); diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 5caafbc5..47822a86 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -224,54 +224,6 @@ ensure_account (McdStorage *self, return sa; } -static gchar * -get_value (const McpAccountManager *ma, - const gchar *account, - const gchar *key) -{ - McdStorage *self = MCD_STORAGE (ma); - McdStorageAccount *sa = lookup_account (self, account); - GVariant *variant; - gchar *ret; - - if (sa == NULL) - return NULL; - - if (g_str_has_prefix (key, "param-")) - { - variant = g_hash_table_lookup (sa->parameters, key + 6); - - if (variant != NULL) - { - ret = mcd_keyfile_escape_variant (variant); - g_variant_unref (variant); - return ret; - } - else - { - /* OK, we don't have it as a variant. How about the keyfile-escaped - * version? */ - return g_strdup (g_hash_table_lookup (sa->escaped_parameters, - key + 6)); - } - } - else - { - variant = g_hash_table_lookup (sa->attributes, key); - - if (variant != NULL) - { - ret = mcd_keyfile_escape_variant (variant); - g_variant_unref (variant); - return ret; - } - else - { - return NULL; - } - } -} - static struct { const gchar *type; const gchar *name; @@ -379,14 +331,6 @@ mcd_storage_init_value_for_attribute (GValue *value, return FALSE; } -static gboolean -mcpa_init_value_for_attribute (const McpAccountManager *mcpa, - GValue *value, - const gchar *attribute) -{ - return mcd_storage_init_value_for_attribute (value, attribute); -} - static void mcpa_set_attribute (const McpAccountManager *ma, const gchar *account, @@ -993,15 +937,6 @@ mcd_storage_get_parameter (McdStorage *self, return mcd_keyfile_unescape_value (escaped, value, error); } -static gboolean -mcpa_unescape_value_from_keyfile (const McpAccountManager *unused G_GNUC_UNUSED, - const gchar *escaped, - GValue *value, - GError **error) -{ - return mcd_keyfile_unescape_value (escaped, value, error); -} - /* * @escaped: a keyfile-escaped string * @value: a #GValue initialized with a supported #GType @@ -1709,13 +1644,6 @@ mcd_storage_set_parameter (McdStorage *self, return updated; } -static gchar * -mcpa_escape_value_for_keyfile (const McpAccountManager *unused G_GNUC_UNUSED, - const GValue *value) -{ - return mcd_keyfile_escape_value (value); -} - /* * @value: a populated #GValue of a supported #GType * @@ -2200,7 +2128,6 @@ plugin_iface_init (McpAccountManagerIface *iface, { DEBUG (); - iface->get_value = get_value; iface->set_value = set_value; iface->set_attribute = mcpa_set_attribute; iface->set_parameter = mcpa_set_parameter; @@ -2208,10 +2135,7 @@ plugin_iface_init (McpAccountManagerIface *iface, iface->identify_account_async = identify_account_async; iface->identify_account_finish = identify_account_finish; iface->list_keys = list_keys; - iface->escape_value_for_keyfile = mcpa_escape_value_for_keyfile; iface->escape_variant_for_keyfile = mcpa_escape_variant_for_keyfile; - iface->unescape_value_from_keyfile = mcpa_unescape_value_from_keyfile; - iface->init_value_for_attribute = mcpa_init_value_for_attribute; } gboolean -- cgit v1.2.3 From 8e91d6b414c669f6397c7b7e5ba53b61aa30dbfd Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 12 Nov 2013 19:36:56 +0000 Subject: mcp_account_manager_list_keys: remove This is unused, and plugins don't have any good reason to call it. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account.c | 23 ----------------------- mission-control-plugins/account.h | 3 --- mission-control-plugins/implementation.h | 3 --- src/mcd-storage.c | 29 ----------------------------- 4 files changed, 58 deletions(-) diff --git a/mission-control-plugins/account.c b/mission-control-plugins/account.c index c9859d70..fecd3d8d 100644 --- a/mission-control-plugins/account.c +++ b/mission-control-plugins/account.c @@ -167,29 +167,6 @@ mcp_account_manager_set_parameter (const McpAccountManager *mcpa, iface->set_parameter (mcpa, account, parameter, value, flags); } -/** - * mcp_account_manage_list_keys: - * @mcpa: a #McpAccountManager instance - * @account: the unique name of an account - * - * - * - * Returns: (transfer full): a list of all keys (attributes and - * "param-"-prefixed parameters) stored for @account by any plugin - */ -GStrv -mcp_account_manager_list_keys (const McpAccountManager *mcpa, - const gchar *account) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_val_if_fail (iface != NULL, NULL); - g_return_val_if_fail (iface->list_keys != NULL, NULL); - g_return_val_if_fail (account != NULL, NULL); - - return iface->list_keys (mcpa, account); -} - /** * mcp_account_manager_get_unique_name: * @mcpa: an #McpAccountManager instance diff --git a/mission-control-plugins/account.h b/mission-control-plugins/account.h index 4356b3c0..788813f1 100644 --- a/mission-control-plugins/account.h +++ b/mission-control-plugins/account.h @@ -67,9 +67,6 @@ gchar * mcp_account_manager_get_unique_name (McpAccountManager *mcpa, const gchar *protocol, const gchar *identification); -GStrv mcp_account_manager_list_keys (const McpAccountManager *mcpa, - const gchar *account); - gchar *mcp_account_manager_escape_variant_for_keyfile ( const McpAccountManager *mcpa, GVariant *variant); diff --git a/mission-control-plugins/implementation.h b/mission-control-plugins/implementation.h index 9d44b3bb..7d951464 100644 --- a/mission-control-plugins/implementation.h +++ b/mission-control-plugins/implementation.h @@ -87,9 +87,6 @@ struct _McpAccountManagerIface { const gchar *protocol, const gchar *identification); - GStrv (* list_keys) (const McpAccountManager *ma, - const gchar *acct); - gchar * (* escape_variant_for_keyfile) (const McpAccountManager *mcpa, GVariant *variant); diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 47822a86..b8f5ffca 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -423,34 +423,6 @@ set_value (const McpAccountManager *ma, } } -static GStrv -list_keys (const McpAccountManager *ma, - const gchar * account) -{ - McdStorage *self = MCD_STORAGE (ma); - GPtrArray *ret = g_ptr_array_new (); - McdStorageAccount *sa = lookup_account (self, account); - - if (sa != NULL) - { - GHashTableIter iter; - gpointer k; - - g_hash_table_iter_init (&iter, sa->attributes); - - while (g_hash_table_iter_next (&iter, &k, NULL)) - g_ptr_array_add (ret, g_strdup (k)); - - g_hash_table_iter_init (&iter, sa->parameters); - - while (g_hash_table_iter_next (&iter, &k, NULL)) - g_ptr_array_add (ret, g_strdup_printf ("param-%s", (gchar *) k)); - } - - g_ptr_array_add (ret, NULL); - return (GStrv) g_ptr_array_free (ret, FALSE); -} - static gchar * unique_name (const McpAccountManager *ma, const gchar *manager, @@ -2134,7 +2106,6 @@ plugin_iface_init (McpAccountManagerIface *iface, iface->unique_name = unique_name; iface->identify_account_async = identify_account_async; iface->identify_account_finish = identify_account_finish; - iface->list_keys = list_keys; iface->escape_variant_for_keyfile = mcpa_escape_variant_for_keyfile; } -- cgit v1.2.3 From 189f9a9e131bb113a88300228eb4cea5b135c9d9 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 14:39:04 +0000 Subject: mcd_storage_dup_attributes: remove Nothing calls it, and getting rid of it is a step towards having McdStorage just be a "view". Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 33 --------------------------------- src/mcd-storage.h | 4 ---- 2 files changed, 37 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index b8f5ffca..b3a4bc96 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -687,39 +687,6 @@ mcd_storage_dup_accounts (McdStorage *self, return (GStrv) g_ptr_array_free (ret, FALSE); } -/* - * mcd_storage_dup_attributes: - * @storage: An object implementing the #McdStorage interface - * @account: unique name of the account - * @n: place for the number of attributes to be written to (or %NULL) - * - * Returns: a newly allocated GStrv containing the names of all the - * attributes or parameters currently stored for @account. Must be - * freed by the caller with g_strfreev(). - */ -GStrv -mcd_storage_dup_attributes (McdStorage *self, - const gchar *account, - gsize *n) -{ - GPtrArray *ret = g_ptr_array_new (); - McdStorageAccount *sa = lookup_account (self, account); - - if (sa != NULL) - { - GHashTableIter iter; - gpointer k; - - g_hash_table_iter_init (&iter, sa->attributes); - - while (g_hash_table_iter_next (&iter, &k, NULL)) - g_ptr_array_add (ret, g_strdup (k)); - } - - g_ptr_array_add (ret, NULL); - return (GStrv) g_ptr_array_free (ret, FALSE); -} - /* * mcd_storage_get_plugin: * @storage: An object implementing the #McdStorage interface diff --git a/src/mcd-storage.h b/src/mcd-storage.h index 930b04b1..5f608af1 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -66,10 +66,6 @@ void mcd_storage_load (McdStorage *storage); GStrv mcd_storage_dup_accounts (McdStorage *storage, gsize *n); -GStrv mcd_storage_dup_attributes (McdStorage *storage, - const gchar *account, - gsize *n); - gboolean mcd_storage_set_string (McdStorage *storage, const gchar *account, const gchar *attribute, -- cgit v1.2.3 From c1dfbed74b450b059bf9cac20a5b485c1656a66d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 15:56:34 +0000 Subject: mcd_account_delete: be primarily responsible for emitting Removed We still don't get here if disposed early, though. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/mcd-account.c b/src/mcd-account.c index 752e9266..e5763a48 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -762,18 +762,15 @@ mcd_account_delete (McdAccount *account, mcd_storage_commit (priv->storage, name); - if (callback != NULL) - callback (account, NULL, user_data); - - /* If the account was not removed via the DBus Account interface code * - * path and something is holding a ref to it so it does not get disposed, * - * then this signal may not get fired, so we make sure it _does_ here */ if (!priv->removed) { - DEBUG ("Forcing Account.Removed for %s", name); + DEBUG ("emitting Account.Removed for %s", name); priv->removed = TRUE; tp_svc_account_emit_removed (account); } + + if (callback != NULL) + callback (account, NULL, user_data); } void @@ -2438,11 +2435,8 @@ account_remove_delete_cb (McdAccount *account, const GError *error, return; } - if (!data->self->priv->removed) - { - data->self->priv->removed = TRUE; - tp_svc_account_emit_removed (data->self); - } + /* mcd_account_delete() is meant to have deleted it */ + g_warn_if_fail (data->self->priv->removed); tp_svc_account_return_from_remove (data->context); @@ -3502,6 +3496,9 @@ _mcd_account_dispose (GObject *object) if (!self->priv->removed) { + /* this can happen in certain account-creation error paths, + * as far as I can see */ + DEBUG ("Account never emitted Removed, emitting it now"); self->priv->removed = TRUE; tp_svc_account_emit_removed (self); } -- cgit v1.2.3 From 609bbcfa2ef5615839aafcc8b20734edb16dead6 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 17:06:31 +0000 Subject: mcd_account_delete: convert into mcd_account_delete_async Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 49 ++++++++++++++++++++++++++++++------------- src/mcd-account.c | 53 +++++++++++++++++++++++++++++++---------------- src/mcd-account.h | 14 ++++++------- 3 files changed, 77 insertions(+), 39 deletions(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 81afa31d..86e2d8b6 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -381,11 +381,27 @@ reconnect_cb (GObject *plugin, const gchar *name, gpointer data) } static void -_mcd_account_delete_cb (McdAccount *account, const GError *error, gpointer data) +mcd_account_delete_debug_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) { - /* no need to do anything other than release the account ref, which * - * should be the last ref we hold by the time this rolls arouns: */ - g_object_unref (account); + McdAccount *account = MCD_ACCOUNT (source); + GError *error = NULL; + + if (mcd_account_delete_finish (account, res, &error)) + { + DEBUG ("successfully deleted account %s (%s)", + mcd_account_get_unique_name (account), + (const gchar *) user_data); + } + else + { + WARNING ("could not delete account %s (%s): %s #%d: %s", + mcd_account_get_unique_name (account), + (const gchar *) user_data, + g_quark_to_string (error->domain), error->code, error->message); + g_clear_error (&error); + } } /* a backend plugin notified us that an account was vaporised: remove it */ @@ -409,9 +425,11 @@ 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_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE, - _mcd_account_delete_cb, NULL); + mcd_account_delete_async (account, + MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE, + mcd_account_delete_debug_cb, + "in response to McpAccountStorage::deleted"); + g_object_unref (account); } } @@ -722,8 +740,10 @@ complete_account_creation_finish (McdAccount *account, if (!cad->ok) { - mcd_account_delete (account, MCD_DBUS_PROP_SET_FLAG_NONE, - NULL, NULL); + mcd_account_delete_async (account, + MCD_DBUS_PROP_SET_FLAG_NONE, + mcd_account_delete_debug_cb, + "while recovering from failure to create"); tp_clear_object (&account); } @@ -1176,12 +1196,13 @@ migrate_ctx_free (MigrateCtx *ctx) static void -migrate_delete_account_cb (McdAccount *account, - const GError *error, - gpointer user_data) +migrate_delete_account_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) { MigrateCtx *ctx = user_data; + mcd_account_delete_debug_cb (source, res, "after migrating it"); migrate_ctx_free (ctx); } @@ -1205,8 +1226,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, MCD_DBUS_PROP_SET_FLAG_NONE, - migrate_delete_account_cb, ctx); + mcd_account_delete_async (ctx->account, MCD_DBUS_PROP_SET_FLAG_NONE, + migrate_delete_account_cb, ctx); } static void diff --git a/src/mcd-account.c b/src/mcd-account.c index e5763a48..c1cae82b 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -674,16 +674,19 @@ static TpStorageRestrictionFlags mcd_account_get_storage_restrictions ( McdAccount *account); void -mcd_account_delete (McdAccount *account, - McdDBusPropSetFlags flags, - McdAccountDeleteCb callback, - gpointer user_data) +mcd_account_delete_async (McdAccount *account, + McdDBusPropSetFlags flags, + GAsyncReadyCallback callback, + gpointer user_data) { McdAccountPrivate *priv = account->priv; gchar *data_dir_str; GError *error = NULL; const gchar *name = mcd_account_get_unique_name (account); TpConnectionManager *cm = mcd_account_get_cm (account); + GTask *task; + + task = g_task_new (account, NULL, callback, user_data); /* 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 @@ -694,16 +697,18 @@ mcd_account_delete (McdAccount *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, + g_task_return_new_error (task, 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); + g_object_unref (task); return; } - /* if the CM implements CM.I.AccountStorage, we need to tell the CM - * to forget any account credentials it knows */ + /* If the CM implements CM.I.AccountStorage, we need to tell the CM + * to forget any account credentials it knows. + * + * FIXME: put this in the main flow rather than doing it async and + * throwing away its result? */ if (tp_proxy_has_interface_by_id (cm, MC_IFACE_QUARK_CONNECTION_MANAGER_INTERFACE_ACCOUNT_STORAGE)) { @@ -728,8 +733,8 @@ mcd_account_delete (McdAccount *account, flags, &error)) { g_warning ("could not disable account %s (%s)", name, error->message); - callback (account, error, user_data); - g_error_free (error); + g_task_return_error (task, error); + g_object_unref (task); return; } @@ -769,8 +774,18 @@ mcd_account_delete (McdAccount *account, tp_svc_account_emit_removed (account); } - if (callback != NULL) - callback (account, NULL, user_data); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +gboolean +mcd_account_delete_finish (McdAccount *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, self), NULL); + + return g_task_propagate_boolean (G_TASK (result), error); } void @@ -2424,14 +2439,17 @@ typedef struct } RemoveMethodData; static void -account_remove_delete_cb (McdAccount *account, const GError *error, +account_remove_delete_cb (GObject *source, + GAsyncResult *res, gpointer user_data) { RemoveMethodData *data = (RemoveMethodData *) user_data; + GError *error = NULL; - if (error != NULL) + if (!mcd_account_delete_finish (MCD_ACCOUNT (source), res, &error)) { dbus_g_method_return_error (data->context, (GError *) error); + g_error_free (error); return; } @@ -2439,7 +2457,6 @@ account_remove_delete_cb (McdAccount *account, const GError *error, g_warn_if_fail (data->self->priv->removed); tp_svc_account_return_from_remove (data->context); - g_slice_free (RemoveMethodData, data); } @@ -2454,8 +2471,8 @@ account_remove (TpSvcAccount *svc, DBusGMethodInvocation *context) data->context = context; DEBUG ("called"); - mcd_account_delete (self, MCD_DBUS_PROP_SET_FLAG_NONE, - account_remove_delete_cb, data); + mcd_account_delete_async (self, MCD_DBUS_PROP_SET_FLAG_NONE, + account_remove_delete_cb, data); } /* diff --git a/src/mcd-account.h b/src/mcd-account.h index 3aad723f..edb8da0e 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -61,9 +61,6 @@ GQuark mcd_account_error_quark (void); typedef void (*McdAccountLoadCb) (McdAccount *account, const GError *error, gpointer user_data); -typedef void (*McdAccountDeleteCb) (McdAccount *account, - const GError *error, - gpointer user_data); struct _McdAccountClass { @@ -85,10 +82,13 @@ McdAccount *mcd_account_new (McdAccountManager *account_manager, const gchar *name, McdConnectivityMonitor *minotaur); -void mcd_account_delete (McdAccount *account, - McdDBusPropSetFlags flags, - McdAccountDeleteCb callback, - gpointer user_data); +void mcd_account_delete_async (McdAccount *account, + McdDBusPropSetFlags flags, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mcd_account_delete_finish (McdAccount *account, + GAsyncResult *result, + GError **error); const gchar *mcd_account_get_unique_name (McdAccount *account); const gchar *mcd_account_get_object_path (McdAccount *account); -- cgit v1.2.3 From a3521e21d9534bb169c4d5361537656af3b06376 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 29 Jan 2014 15:01:01 +0000 Subject: fixup! --- src/mcd-account.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mcd-account.c b/src/mcd-account.c index c1cae82b..6c08d8ea 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -783,7 +783,7 @@ mcd_account_delete_finish (McdAccount *self, GAsyncResult *result, GError **error) { - g_return_val_if_fail (g_task_is_valid (result, self), NULL); + g_return_val_if_fail (g_task_is_valid (result, self), FALSE); return g_task_propagate_boolean (G_TASK (result), error); } -- cgit v1.2.3 From b69fcaca8a6c6d60c1106178d1285ef29466c189 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 17:07:46 +0000 Subject: mc-debug-server: don't exit when disconnected from system bus The session bus is our fake system bus, too. We exit when libdbus tells us we have disconnected, and ignore both the possible ways in which GDBus can kill us, in order to get coverage stats. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- tests/twisted/mc-debug-server.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/twisted/mc-debug-server.c b/tests/twisted/mc-debug-server.c index 48f02484..917a5d34 100644 --- a/tests/twisted/mc-debug-server.c +++ b/tests/twisted/mc-debug-server.c @@ -154,6 +154,7 @@ main (int argc, char **argv) { GError *error = NULL; GDBusConnection *gdbus = NULL; + GDBusConnection *gdbus_system = NULL; DBusConnection *connection = NULL; int ret = 1; GMainLoop *teardown_loop; @@ -185,6 +186,18 @@ main (int argc, char **argv) g_dbus_connection_set_exit_on_close (gdbus, FALSE); + gdbus_system = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + + if (gdbus_system == NULL) + { + g_warning ("%s", error->message); + g_error_free (error); + error = NULL; + goto out; + } + + g_dbus_connection_set_exit_on_close (gdbus_system, FALSE); + bus_daemon = tp_dbus_daemon_dup (&error); if (bus_daemon == NULL) @@ -238,6 +251,7 @@ out: } tp_clear_object (&gdbus); + tp_clear_object (&gdbus_system); tp_clear_object (&bus_daemon); dbus_shutdown (); -- cgit v1.2.3 From 657b61379825143b83465c840e1fa70a66d3989f Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 17:40:19 +0000 Subject: McdStorage: adjust IdentifyAccount error behaviour We were ignoring failures if they were NotImplemented or ServiceUnknown, but thinking about it more, we should probably ignore "most" errors here: the only errors that should abort the account-creation attempt are those that indicate that the intended parameters are unusable, namely InvalidArgument and InvalidHandle (in its secondary role as "invalid identifier-that-corresponds-to-a-handle"). Also add more debug messages here. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index b3a4bc96..37d6700f 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -469,17 +469,26 @@ identify_account_cb (TpProxy *proxy, { if (error == NULL) { + DEBUG ("identified account: %s", identification); g_task_return_pointer (task, g_strdup (identification), g_free); } - else if (g_error_matches (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED) || - g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN)) + else if (g_error_matches (error, TP_ERROR, TP_ERROR_INVALID_HANDLE) || + g_error_matches (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT)) { - g_task_return_pointer (task, g_strdup (g_task_get_task_data (task)), - g_free); + /* The connection manager didn't like our account parameters. + * Give up now. */ + DEBUG ("failed to identify account: %s #%d: %s", + g_quark_to_string (error->domain), error->code, error->message); + g_task_return_error (task, g_error_copy (error)); } else { - g_task_return_error (task, g_error_copy (error)); + /* We weren't able to identify the account, but carry on and hope + * for the best... */ + DEBUG ("ignoring failure to identify account: %s #%d: %s", + g_quark_to_string (error->domain), error->code, error->message); + g_task_return_pointer (task, g_strdup (g_task_get_task_data (task)), + g_free); } } -- cgit v1.2.3 From 48dff5c37b468eaa927120093a6d872cba0265d7 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 17:42:09 +0000 Subject: Add some missing test coverage: IdentifyAccount failing hard Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- tests/twisted/account-manager/bad-cm.py | 11 +++++++++- tests/twisted/mctest.py | 38 +++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/tests/twisted/account-manager/bad-cm.py b/tests/twisted/account-manager/bad-cm.py index 74277b46..008ac605 100644 --- a/tests/twisted/account-manager/bad-cm.py +++ b/tests/twisted/account-manager/bad-cm.py @@ -22,11 +22,12 @@ import dbus from servicetest import call_async, assertEquals, assertContains -from mctest import exec_test, AccountManager +from mctest import (exec_test, SimulatedConnectionManager, AccountManager) import constants as cs def test(q, bus, mc): am = AccountManager(bus) + simulated_cm = SimulatedConnectionManager(q, bus) def call_create(cm='fakecm', protocol='fakeprotocol', parameters=None): if parameters is None: @@ -74,5 +75,13 @@ def test(q, bus, mc): assertEquals(cs.INVALID_ARGUMENT, e.name) assertContains("password", e.message) + # Create an account that will fail IdentifyAccount + call_create(parameters={ "account": "", + "password": "ohai", + }) + e = q.expect('dbus-error', method='CreateAccount') + assertEquals(cs.INVALID_HANDLE, e.name) + assertContains("Invalid account name", e.message) + if __name__ == '__main__': exec_test(test, {}) diff --git a/tests/twisted/mctest.py b/tests/twisted/mctest.py index 35ccec97..2229525b 100644 --- a/tests/twisted/mctest.py +++ b/tests/twisted/mctest.py @@ -1018,12 +1018,11 @@ class SimulatedConnectionManager(object): for protocol_name in protocol_names: assert '-' not in protocol_name - q.add_dbus_method_impl(self.IdentifyAccount, - path=self.object_path + '/' + protocol_name, - interface=cs.PROTOCOL, method='IdentifyAccount') - q.add_dbus_method_impl(self.NormalizeContact, - path=self.object_path + '/' + protocol_name, - interface=cs.PROTOCOL, method='NormalizeContact') + + q.add_dbus_method_impl(self.IdentifyAccount, + interface=cs.PROTOCOL, method='IdentifyAccount') + q.add_dbus_method_impl(self.NormalizeContact, + interface=cs.PROTOCOL, method='NormalizeContact') def release_name(self): del self._bus_name_ref @@ -1132,11 +1131,32 @@ class SimulatedConnectionManager(object): }, signature='a{sv}', bus=self.bus) def IdentifyAccount(self, e): + if e.path.startswith(self.object_path + '/'): + protocol = e.path[len(self.object_path + '/'):] + + if protocol not in self.protocol_names: + self.q.dbus_raise(e.message, cs.DBUS_ERROR_UNKNOWN_METHOD, + 'Not my protocol') + return + else: + self.q.dbus_raise(e.message, cs.DBUS_ERROR_UNKNOWN_METHOD, + 'Not even my object path') + return + + if protocol in ('serializable', 'defaults') and 's' in e.args[0]: + ret = e.args[0]['s'].lower() + if ret: + self.q.dbus_return(e.message, ret, signature='s') + return + if 'account' in e.args[0]: ret = e.args[0]['account'].lower() - else: - ret = 'account' - self.q.dbus_return(e.message, ret, signature='s') + if ret: + self.q.dbus_return(e.message, ret, signature='s') + return + + self.q.dbus_raise(e.message, cs.INVALID_HANDLE, + 'Invalid account name %r' % e.args[0].get('account')) def NormalizeContact(self, e): self.q.dbus_return(e.message, e.args[0].lower(), signature='s') -- cgit v1.2.3 From cae73ae1d7634b761f5121298359b6f45ebfbe25 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 17:45:30 +0000 Subject: McdAccountManager: don't double-delete accounts from storage McdAccount (via mcd_account_delete_async) is responsible for deleting itself from storage if necessary. McdAccountManager shouldn't second-guess it. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 86e2d8b6..3f4427d7 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -597,7 +597,6 @@ static void on_account_removed (McdAccount *account, McdAccountManager *account_manager) { McdAccountManagerPrivate *priv = account_manager->priv; - McdStorage *storage = priv->storage; const gchar *name, *object_path; object_path = mcd_account_get_object_path (account); @@ -607,10 +606,6 @@ on_account_removed (McdAccount *account, McdAccountManager *account_manager) name = mcd_account_get_unique_name (account); g_hash_table_remove (priv->accounts, name); - - mcd_storage_delete_account (storage, name); - mcd_account_manager_write_conf_async (account_manager, account, NULL, - NULL); } static inline void -- cgit v1.2.3 From b1681efb1e541072bd23d70d2a25e2a521f2d271 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 19:36:44 +0000 Subject: Call set_attribute, set_parameter to delete them It really doesn't make a great deal of sense to use the same callback to delete individual keys, and to delete accounts. McdAccountManagerDefault already dealt with that case, but the two test plugins didn't. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 6 ++-- src/mcd-account-manager-default.c | 23 +------------ src/mcd-storage.c | 19 +++-------- tests/twisted/dbus-account-plugin.c | 54 +++++++++++++++++-------------- tests/twisted/mcp-account-diversion.c | 39 +++++++++++++--------- 5 files changed, 63 insertions(+), 78 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 5ad31b6c..53b00be0 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -504,7 +504,8 @@ mcp_account_storage_get (const McpAccountStorage *storage, * @am: an #McpAccountManager instance * @account: the unique name of the account * @attribute: the name of an attribute, e.g. "DisplayName" - * @value: a value to associate with @attribute + * @value: (allow-none): a value to associate with @attribute, + * or %NULL to delete * @flags: flags influencing how the attribute is to be stored * * Store an attribute. @@ -547,7 +548,8 @@ mcp_account_storage_set_attribute (McpAccountStorage *storage, * @account: the unique name of the account * @parameter: the name of a parameter, e.g. "account" (note that there * is no "param-" prefix here) - * @value: a value to associate with @parameter + * @value: (allow-none): a value to associate with @parameter, + * or %NULL to delete * @flags: flags influencing how the parameter is to be stored * * Store a parameter. diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index e37ea89b..07f22319 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -374,28 +374,7 @@ _delete (const McpAccountStorage *self, } else { - if (g_str_has_prefix (key, "param-")) - { - if (g_hash_table_remove (sa->parameters, key + 6)) - amd->save = TRUE; - - if (g_hash_table_remove (sa->untyped_parameters, key + 6)) - amd->save = TRUE; - } - else - { - if (g_hash_table_remove (sa->attributes, key)) - amd->save = TRUE; - } - - /* if that was the last attribute or parameter, the account is gone - * too */ - if (g_hash_table_size (sa->attributes) == 0 && - g_hash_table_size (sa->untyped_parameters) == 0 && - g_hash_table_size (sa->parameters) == 0) - { - sa->pending_deletion = TRUE; - } + g_assert_not_reached (); } return TRUE; diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 37d6700f..dbc04c30 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1379,38 +1379,29 @@ update_storage (McdStorage *self, GVariant *variant) { GList *store; - gboolean done = FALSE; gboolean parameter = g_str_has_prefix (key, "param-"); McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - /* we're deleting, which is unconditional, no need to check if anyone * - * claims this setting for themselves */ - if (variant == NULL) - done = TRUE; - for (store = stores; store != NULL; store = g_list_next (store)) { McpAccountStorage *plugin = store->data; const gchar *pn = mcp_account_storage_name (plugin); - if (done) /* in particular, if variant == NULL */ - { - DEBUG ("MCP:%s -> delete %s.%s", pn, account, key); - mcp_account_storage_delete (plugin, ma, account, key); - } - else if (!parameter && + if (!parameter && mcp_account_storage_set_attribute (plugin, ma, account, key, variant, MCP_ATTRIBUTE_FLAG_NONE)) { - done = TRUE; DEBUG ("MCP:%s -> store attribute %s.%s", pn, account, key); + /* set it to NULL in all lower-priority stores */ + variant = NULL; } else if (parameter && mcp_account_storage_set_parameter (plugin, ma, account, key + 6, variant, MCP_PARAMETER_FLAG_NONE)) { - done = TRUE; DEBUG ("MCP:%s -> store parameter %s.%s", pn, account, key); + /* set it to NULL in all lower-priority stores */ + variant = NULL; } } } diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 016417a1..3ea5df9d 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -940,28 +940,9 @@ test_dbus_account_plugin_delete (const McpAccountStorage *storage, "DeferringDelete", g_variant_new_parsed ("(%o,)", account->path), NULL); } - else if (g_str_has_prefix (key, "param-")) - { - g_hash_table_remove (account->parameters, key + 6); - g_hash_table_remove (account->untyped_parameters, key + 6); - g_hash_table_remove (account->parameter_flags, key + 6); - g_hash_table_add (account->uncommitted_parameters, g_strdup (key + 6)); - - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "DeferringDeleteParameter", - g_variant_new_parsed ("(%o, %s)", account->path, key + 6), NULL); - } else { - g_hash_table_remove (account->attributes, key); - g_hash_table_remove (account->attribute_flags, key); - g_hash_table_add (account->uncommitted_attributes, g_strdup (key)); - - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "DeferringDeleteAttribute", - g_variant_new_parsed ("(%o, %s)", account->path, key), NULL); + g_assert_not_reached (); } return TRUE; @@ -1099,8 +1080,6 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, g_return_val_if_fail (account_name != NULL, FALSE); g_return_val_if_fail (attribute != NULL, FALSE); - /* for deletions, MC would call delete() instead */ - g_return_val_if_fail (value != NULL, FALSE); DEBUG ("%s of %s", attribute, account_name); @@ -1108,6 +1087,20 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, (account->flags & UNCOMMITTED_DELETION)) return FALSE; + if (value == NULL) + { + g_hash_table_remove (account->attributes, attribute); + g_hash_table_remove (account->attribute_flags, attribute); + g_hash_table_add (account->uncommitted_attributes, g_strdup (attribute)); + + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "DeferringDeleteAttribute", + g_variant_new_parsed ("(%o, %s)", account->path, attribute), NULL); + + return TRUE; + } + g_hash_table_insert (account->attributes, g_strdup (attribute), g_variant_ref (value)); g_hash_table_insert (account->attribute_flags, g_strdup (attribute), @@ -1136,8 +1129,6 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, g_return_val_if_fail (account_name != NULL, FALSE); g_return_val_if_fail (parameter != NULL, FALSE); - /* for deletions, MC would call delete() instead */ - g_return_val_if_fail (value != NULL, FALSE); DEBUG ("%s of %s", parameter, account_name); @@ -1145,6 +1136,21 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, (account->flags & UNCOMMITTED_DELETION)) return FALSE; + if (value == NULL) + { + g_hash_table_remove (account->parameters, parameter); + g_hash_table_remove (account->untyped_parameters, parameter); + g_hash_table_remove (account->parameter_flags, parameter); + g_hash_table_add (account->uncommitted_parameters, g_strdup (parameter)); + + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "DeferringDeleteParameter", + g_variant_new_parsed ("(%o, %s)", account->path, parameter), NULL); + + return TRUE; + } + g_hash_table_remove (account->untyped_parameters, parameter); g_hash_table_insert (account->parameters, g_strdup (parameter), g_variant_ref (value)); diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index 44fd4e3a..9639fafb 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -125,11 +125,29 @@ _set (McpAccountStorage *self, if (g_str_has_prefix (account, DONT_DIVERT)) return FALSE; - adp->save = TRUE; + if (val == NULL) + { + gsize n; + GStrv keys; + + if (g_key_file_remove_key (adp->keyfile, account, key, NULL)) + adp->save = TRUE; + + keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL); - val_str = mcp_account_manager_escape_variant_for_keyfile (am, val); - g_key_file_set_value (adp->keyfile, account, key, val_str); - g_free (val_str); + if (keys == NULL || n == 0) + g_key_file_remove_group (adp->keyfile, account, NULL); + + g_strfreev (keys); + } + else + { + adp->save = TRUE; + + val_str = mcp_account_manager_escape_variant_for_keyfile (am, val); + g_key_file_set_value (adp->keyfile, account, key, val_str); + g_free (val_str); + } return TRUE; } @@ -220,18 +238,7 @@ _delete (const McpAccountStorage *self, } else { - gsize n; - GStrv keys; - - if (g_key_file_remove_key (adp->keyfile, account, key, NULL)) - adp->save = TRUE; - - keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL); - - if (keys == NULL || n == 0) - g_key_file_remove_group (adp->keyfile, account, NULL); - - g_strfreev (keys); + g_assert_not_reached (); } return TRUE; -- cgit v1.2.3 From 561206632852eb2cea78ec60dfeb10a88a53cd63 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 19:44:46 +0000 Subject: Make account deletion async (sort of), and imply a selective commit This means we don't need to commit separately after each deletion, and means account plugins don't have to have the concept of flagging an account for "delete this later" - much rejoicing. It also has the incidental benefit that we no longer use the C++ reserved word 'delete' in a header file. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 97 ++++++++++-------- mission-control-plugins/account-storage.h | 19 +++- src/mcd-account-manager-default.c | 159 ++++++++++++++---------------- src/mcd-account.c | 2 - src/mcd-storage.c | 28 +++++- tests/twisted/dbus-account-plugin.c | 145 ++++++++++++++------------- tests/twisted/mcp-account-diversion.c | 41 +++++--- 7 files changed, 275 insertions(+), 216 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 53b00be0..b87909c3 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -119,13 +119,24 @@ default_get (const McpAccountStorage *storage, return FALSE; } -static gboolean -default_delete (const McpAccountStorage *storage, - const McpAccountManager *am, +static void +default_delete_async (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account, - const gchar *key) + GAsyncReadyCallback callback, + gpointer user_data) { - return FALSE; + g_task_report_new_error (storage, callback, user_data, + default_delete_async, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, + "This storage plugin cannot delete accounts"); +} + +static gboolean +default_delete_finish (McpAccountStorage *storage, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); } static gboolean @@ -230,7 +241,8 @@ class_init (gpointer klass, iface->get = default_get; iface->create = default_create; - iface->delete = default_delete; + iface->delete_async = default_delete_async; + iface->delete_finish = default_delete_finish; iface->commit = default_commit; iface->list = default_list; iface->ready = default_ready; @@ -646,61 +658,62 @@ mcp_account_storage_create (const McpAccountStorage *storage, } /** - * McpAccountStorageDeleteFunc: + * mcp_account_storage_delete_async: * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance * @account: the unique name of the account - * @key: (allow-none): the setting whose value we wish to store - either an - * attribute like "DisplayName", or "param-" plus a parameter like - * "account" - or %NULL to delete the entire account + * @callback: called on success or failure + * @user_data: data for @callback * - * An implementation of mcp_account_storage_delete(). + * Delete the account @account, and commit the change, + * emitting #McpAccountStorage::deleted afterwards. * - * Returns: %TRUE if the setting or settings are not - * the plugin's cache after this operation, %FALSE otherwise. + * Unlike the 'delete' virtual method in earlier MC versions, this + * function is expected to commit the change to long-term storage, + * is expected to emit #McpAccountStorage::deleted, and is + * not called for the deletion of individual attributes or parameters. + * + * The default implementation just returns failure (asynchronously), + * and is appropriate for read-only storage. */ +void +mcp_account_storage_delete_async (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + GAsyncReadyCallback callback, + gpointer user_data) +{ + McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + + SDEBUG (storage, ""); + g_return_if_fail (iface != NULL); + g_return_if_fail (iface->delete_async != NULL); + + iface->delete_async (storage, am, account, callback, user_data); +} /** - * mcp_account_storage_delete: + * mcp_account_storage_delete_finish: * @storage: an #McpAccountStorage instance - * @am: an #McpAccountManager instance - * @account: the unique name of the account - * @key: (allow-none): the setting whose value we wish to store - either an - * attribute like "DisplayName", or "param-" plus a parameter like - * "account" - or %NULL to delete the entire account - * - * The plugin is expected to remove the setting for @key from its - * internal cache and to remember that its state has changed, so - * that it can delete said setting from its long term storage if - * its long term storage method makes this necessary. + * @res: the result of mcp_account_storage_delete_async() + * @error: used to raise an error if %FALSE is returned * - * If @key is %NULL, the plugin should forget all its settings for - * @account,and remember to delete the entire account from its storage later. + * Process the result of mcp_account_storage_delete_async(). * - * The plugin is not expected to update its long term storage at - * this point. - * - * The default implementation just returns %FALSE, and is appropriate for - * read-only storage. - * - * Returns: %TRUE if the setting or settings are not - * the plugin's cache after this operation, %FALSE otherwise. - * This is very unlikely to ever be %FALSE, as a plugin is always - * expected to be able to manipulate its own cache. + * Returns: %TRUE on success, %FALSE if the account could not be deleted */ gboolean -mcp_account_storage_delete (const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account, - const gchar *key) +mcp_account_storage_delete_finish (McpAccountStorage *storage, + GAsyncResult *result, + GError **error) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); SDEBUG (storage, ""); g_return_val_if_fail (iface != NULL, FALSE); - g_return_val_if_fail (iface->delete != NULL, FALSE); + g_return_val_if_fail (iface->delete_finish != NULL, FALSE); - return iface->delete (storage, am, account, key); + return iface->delete_finish (storage, result, error); } /** diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 198e8353..ff3633e2 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -107,7 +107,14 @@ struct _McpAccountStorageIface const gchar *provider; McpAccountStorageGetFunc get; - McpAccountStorageDeleteFunc delete; + void (*delete_async) (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*delete_finish) (McpAccountStorage *storage, + GAsyncResult *res, + GError **error); McpAccountStorageCommitFunc commit; McpAccountStorageListFunc list; McpAccountStorageReadyFunc ready; @@ -149,10 +156,14 @@ gchar * mcp_account_storage_create (const McpAccountStorage *storage, const gchar *identification, GError **error); -gboolean mcp_account_storage_delete (const McpAccountStorage *storage, - const McpAccountManager *am, +void mcp_account_storage_delete_async (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account, - const gchar *key); + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mcp_account_storage_delete_finish (McpAccountStorage *storage, + GAsyncResult *result, + GError **error); void mcp_account_storage_ready (const McpAccountStorage *storage, const McpAccountManager *am); diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 07f22319..f87aee73 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -47,8 +47,6 @@ typedef struct { /* owned string, parameter (without "param-") => owned string, value * parameters of unknwn type to be stored in the variant-file */ GHashTable *untyped_parameters; - /* TRUE if the entire account is pending deletion */ - gboolean pending_deletion; /* TRUE if the account doesn't really exist, but is here to stop us * loading it from a lower-priority file */ gboolean absent; @@ -79,7 +77,6 @@ ensure_stored_account (McdAccountManagerDefault *self, g_hash_table_insert (self->accounts, g_strdup (account), sa); } - sa->pending_deletion = FALSE; sa->absent = FALSE; return sa; } @@ -346,38 +343,96 @@ _create (const McpAccountStorage *self, return unique_name; } -static gboolean -_delete (const McpAccountStorage *self, - const McpAccountManager *am, - const gchar *account, - const gchar *key) +static void +delete_async (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + GAsyncReadyCallback callback, + gpointer user_data) { McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); McdDefaultStoredAccount *sa = lookup_stored_account (amd, account); + GTask *task; + gchar *filename = NULL; + const gchar * const *iter; + + task = g_task_new (amd, NULL, callback, user_data); if (sa == NULL || sa->absent) { /* Apparently we never had this account anyway. The plugin API * considers this to be "success". */ - return TRUE; + g_task_return_boolean (task, TRUE); + goto finally; } - if (key == NULL) + filename = account_file_in (g_get_user_data_dir (), account); + + DEBUG ("Deleting account %s from %s", account, filename); + + if (g_unlink (filename) != 0) { - amd->save = TRUE; + int e = errno; - /* flag the whole account as purged */ - sa->pending_deletion = TRUE; - g_hash_table_remove_all (sa->attributes); - g_hash_table_remove_all (sa->parameters); - g_hash_table_remove_all (sa->untyped_parameters); + /* ENOENT is OK, anything else is more upsetting */ + if (e != ENOENT) + { + WARNING ("Unable to delete %s: %s", filename, + g_strerror (e)); + g_task_return_new_error (task, G_IO_ERROR, g_io_error_from_errno (e), + "Unable to delete %s: %s", filename, g_strerror (e)); + goto finally; + } } - else + + for (iter = g_get_system_data_dirs (); + iter != NULL && *iter != NULL; + iter++) { - g_assert_not_reached (); + gchar *other = account_file_in (*iter, account); + gboolean other_exists = g_file_test (other, G_FILE_TEST_EXISTS); + + g_free (other); + + if (other_exists) + { + GError *error = NULL; + + /* There is a lower-priority file that would provide this + * account. We can't delete a file from XDG_DATA_DIRS which + * are conceptually read-only, but we can mask it with an + * empty file (prior art: systemd) */ + if (!g_file_set_contents (filename, "", 0, &error)) + { + g_prefix_error (&error, + "Unable to save empty account file to %s: ", filename); + WARNING ("%s", error->message); + g_task_return_error (task, error); + g_free (filename); + goto finally; + } + + break; + } } - return TRUE; + /* clean up the mess */ + g_hash_table_remove (amd->accounts, account); + mcp_account_storage_emit_deleted (self, account); + + g_task_return_boolean (task, TRUE); + +finally: + g_free (filename); + g_object_unref (task); +} + +static gboolean +delete_finish (McpAccountStorage *storage, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); } static gboolean @@ -397,58 +452,6 @@ am_default_commit_one (McdAccountManagerDefault *self, filename = account_file_in (g_get_user_data_dir (), account_name); - if (sa->pending_deletion) - { - const gchar * const *iter; - - DEBUG ("Deleting account %s from %s", account_name, filename); - - if (g_unlink (filename) != 0) - { - int e = errno; - - /* ENOENT is OK, anything else is more upsetting */ - if (e != ENOENT) - { - WARNING ("Unable to delete %s: %s", filename, - g_strerror (e)); - g_free (filename); - return FALSE; - } - } - - for (iter = g_get_system_data_dirs (); - iter != NULL && *iter != NULL; - iter++) - { - gchar *other = account_file_in (*iter, account_name); - gboolean other_exists = g_file_test (other, G_FILE_TEST_EXISTS); - - g_free (other); - - if (other_exists) - { - /* There is a lower-priority file that would provide this - * account. We can't delete a file from XDG_DATA_DIRS which - * are conceptually read-only, but we can mask it with an - * empty file (prior art: systemd) */ - if (!g_file_set_contents (filename, "", 0, &error)) - { - WARNING ("Unable to save empty account file to %s: %s", - filename, error->message); - g_clear_error (&error); - g_free (filename); - return FALSE; - } - - break; - } - } - - g_free (filename); - return TRUE; - } - DEBUG ("Saving account %s to %s", account_name, filename); g_variant_builder_init (&attrs_builder, G_VARIANT_TYPE_VARDICT); @@ -544,17 +547,6 @@ _commit (const McpAccountStorage *self, amd->save = FALSE; } - g_hash_table_iter_init (&outer, amd->accounts); - - /* forget about any entirely removed accounts */ - while (g_hash_table_iter_next (&outer, NULL, &sa_p)) - { - McdDefaultStoredAccount *sa = sa_p; - - if (sa->pending_deletion) - g_hash_table_iter_remove (&outer); - } - return all_succeeded; } @@ -982,7 +974,8 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->set_attribute = set_attribute; iface->set_parameter = set_parameter; iface->create = _create; - iface->delete = _delete; + iface->delete_async = delete_async; + iface->delete_finish = delete_finish; iface->commit = _commit; iface->list = _list; diff --git a/src/mcd-account.c b/src/mcd-account.c index 6c08d8ea..e70eaadf 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -765,8 +765,6 @@ mcd_account_delete_async (McdAccount *account, g_free (data_dir_str); } - mcd_storage_commit (priv->storage, name); - if (!priv->removed) { DEBUG ("emitting Account.Removed for %s", name); diff --git a/src/mcd-storage.c b/src/mcd-storage.c index dbc04c30..25194b38 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1942,6 +1942,28 @@ mcd_storage_create_account (McdStorage *self, return NULL; } +static void +delete_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + + if (mcp_account_storage_delete_finish (MCP_ACCOUNT_STORAGE (source), + res, &error)) + { + DEBUG ("deleted account %s", (const gchar *) user_data); + } + else + { + DEBUG ("could not delete account %s (but no way to signal that): " + "%s #%d: %s", (const gchar *) user_data, + g_quark_to_string (error->domain), error->code, error->message); + g_error_free (error); + } + + g_free (user_data); +} /* * mcd_storage_delete_account: @@ -1969,7 +1991,11 @@ mcd_storage_delete_account (McdStorage *self, { McpAccountStorage *plugin = store->data; - mcp_account_storage_delete (plugin, ma, account, NULL); + /* FIXME: when we know which plugin owns the account, we can stop + * ignoring the error (if any), and make this method async + * in order to pass the error up to McdAccount */ + mcp_account_storage_delete_async (plugin, ma, account, + delete_cb, g_strdup (account)); } } diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 3ea5df9d..01410a1b 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -54,7 +54,7 @@ typedef struct { GHashTable *parameter_flags; /* set of strings */ GHashTable *uncommitted_parameters; - enum { UNCOMMITTED_CREATION, UNCOMMITTED_DELETION } flags; + enum { UNCOMMITTED_CREATION = 1 } flags; TpStorageRestrictionFlags restrictions; } Account; @@ -183,7 +183,6 @@ ensure_account (TestDBusAccountPlugin *self, g_hash_table_insert (self->accounts, g_strdup (account_name), account); } - account->flags &= ~UNCOMMITTED_DELETION; return account; } @@ -211,18 +210,14 @@ service_vanished_cb (GDBusConnection *bus, { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (user_data); GHashTableIter iter; - gpointer k, v; + gpointer k; self->active = FALSE; g_hash_table_iter_init (&iter, self->accounts); - while (g_hash_table_iter_next (&iter, &k, &v)) + while (g_hash_table_iter_next (&iter, &k, NULL)) { - Account *account = v; - - if ((account->flags & UNCOMMITTED_DELETION) == 0) - mcp_account_storage_emit_deleted (MCP_ACCOUNT_STORAGE (self), k); - + mcp_account_storage_emit_deleted (MCP_ACCOUNT_STORAGE (self), k); g_hash_table_iter_remove (&iter); } @@ -908,44 +903,64 @@ test_dbus_account_plugin_create (const McpAccountStorage *storage, return name; } -static gboolean -test_dbus_account_plugin_delete (const McpAccountStorage *storage, - const McpAccountManager *am, +static void delete_account_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data); + +static void +test_dbus_account_plugin_delete_async (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account_name, - const gchar *key) + GAsyncReadyCallback callback, + gpointer user_data) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); + GTask *task = g_task_new (self, NULL, callback, user_data); + + g_task_set_task_data (task, g_strdup (user_data), g_free); DEBUG ("called"); if (account == NULL || !self->active) - return FALSE; - - if (key == NULL) { - account->flags |= UNCOMMITTED_DELETION; - g_hash_table_remove_all (account->attributes); - g_hash_table_remove_all (account->parameters); - g_hash_table_remove_all (account->untyped_parameters); - g_hash_table_remove_all (account->attribute_flags); - g_hash_table_remove_all (account->parameter_flags); + /* We were asked to delete an account we don't have. It's + * a bit like success. */ + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } - account->flags &= ~UNCOMMITTED_CREATION; - g_hash_table_remove_all (account->uncommitted_attributes); - g_hash_table_remove_all (account->uncommitted_parameters); + /* deletion used to be delayed, so the regression tests will expect this + * to happen - leave them unmodified for now */ + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "DeferringDelete", g_variant_new_parsed ("(%o,)", account->path), + NULL); + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "CommittingOne", g_variant_new_parsed ("(%o,)", account->path), NULL); - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "DeferringDelete", g_variant_new_parsed ("(%o,)", account->path), - NULL); - } - else - { - g_assert_not_reached (); - } + g_dbus_connection_call (self->bus, + TEST_DBUS_ACCOUNT_SERVICE, + TEST_DBUS_ACCOUNT_SERVICE_PATH, + TEST_DBUS_ACCOUNT_SERVICE_IFACE, + "DeleteAccount", + g_variant_new_parsed ("(%s,)", account_name), + G_VARIANT_TYPE_UNIT, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* no cancellable */ + delete_account_cb, + task); +} - return TRUE; +static gboolean +test_dbus_account_plugin_delete_finish (McpAccountStorage *storage, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); } static gboolean @@ -957,7 +972,7 @@ test_dbus_account_plugin_get (const McpAccountStorage *storage, TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) + if (!self->active || account == NULL) return FALSE; if (key == NULL) @@ -1083,8 +1098,7 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, DEBUG ("%s of %s", attribute, account_name); - if (!self->active || account == NULL || - (account->flags & UNCOMMITTED_DELETION)) + if (!self->active || account == NULL) return FALSE; if (value == NULL) @@ -1132,8 +1146,7 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, DEBUG ("%s of %s", parameter, account_name); - if (!self->active || account == NULL || - (account->flags & UNCOMMITTED_DELETION)) + if (!self->active || account == NULL) return FALSE; if (value == NULL) @@ -1202,27 +1215,31 @@ delete_account_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { - AsyncData *ad = user_data; + GTask *task = user_data; GVariant *tuple; GError *error = NULL; + TestDBusAccountPlugin *self = g_task_get_source_object (task); + const gchar *account_name = g_task_get_task_data (task); - tuple = g_dbus_connection_call_finish (ad->self->bus, res, &error); + tuple = g_dbus_connection_call_finish (self->bus, res, &error); if (tuple != NULL) { - g_hash_table_remove (ad->self->accounts, ad->account_name); + /* we'll emit ::deleted when we see the signal, which probably + * already happened */ + g_hash_table_remove (self->accounts, account_name); g_variant_unref (tuple); + g_task_return_boolean (task, TRUE); } else { - g_warning ("Unable to delete account %s: %s", ad->account_name, - error->message); - g_clear_error (&error); - /* FIXME: we could roll back the deletion by claiming that - * the service re-created the account? */ + g_prefix_error (&error, "Unable to delete account %s: ", + account_name); + g_warning ("%s", error->message); + g_task_return_error (task, error); } - async_data_free (ad); + g_object_unref (task); } static void @@ -1355,25 +1372,6 @@ test_dbus_account_plugin_commit (const McpAccountStorage *storage, TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, "CommittingOne", g_variant_new_parsed ("(%o,)", account->path), NULL); - if (account->flags & UNCOMMITTED_DELETION) - { - g_dbus_connection_call (self->bus, - TEST_DBUS_ACCOUNT_SERVICE, - TEST_DBUS_ACCOUNT_SERVICE_PATH, - TEST_DBUS_ACCOUNT_SERVICE_IFACE, - "DeleteAccount", - g_variant_new_parsed ("(%s,)", account_name), - G_VARIANT_TYPE_UNIT, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, /* no cancellable */ - delete_account_cb, - async_data_new (self, account_name)); - - /* this doesn't mean we succeeded: it means we tried */ - return TRUE; - } - if (account->flags & UNCOMMITTED_CREATION) { g_dbus_connection_call (self->bus, @@ -1509,7 +1507,7 @@ test_dbus_account_plugin_get_identifier (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) + if (!self->active || account == NULL) return; /* Our "library-specific unique identifier" is just the object-path @@ -1528,7 +1526,7 @@ test_dbus_account_plugin_get_additional_info (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) + if (!self->active || account == NULL) return NULL; ret = g_hash_table_new_full (g_str_hash, g_str_equal, @@ -1548,7 +1546,7 @@ test_dbus_account_plugin_get_restrictions (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) + if (!self->active || account == NULL) return 0; return account->restrictions; @@ -1564,7 +1562,7 @@ test_dbus_account_plugin_owns (McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL || (account->flags & UNCOMMITTED_DELETION)) + if (!self->active || account == NULL) return FALSE; return TRUE; @@ -1583,7 +1581,8 @@ account_storage_iface_init (McpAccountStorageIface *iface) iface->set_parameter = test_dbus_account_plugin_set_parameter; iface->list = test_dbus_account_plugin_list; iface->ready = test_dbus_account_plugin_ready; - iface->delete = test_dbus_account_plugin_delete; + iface->delete_async = test_dbus_account_plugin_delete_async; + iface->delete_finish = test_dbus_account_plugin_delete_finish; iface->commit = test_dbus_account_plugin_commit; iface->get_identifier = test_dbus_account_plugin_get_identifier; iface->get_additional_info = test_dbus_account_plugin_get_additional_info; diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index 9639fafb..8e210d62 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -223,27 +223,45 @@ _get (const McpAccountStorage *self, return TRUE; } -static gboolean -_delete (const McpAccountStorage *self, - const McpAccountManager *am, - const gchar *account, - const gchar *key) +static gboolean _commit (const McpAccountStorage *self, + const McpAccountManager *am, + const gchar *account_name); + +static void +delete_async (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + GAsyncReadyCallback callback, + gpointer user_data) { AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + GTask *task = g_task_new (adp, NULL, callback, user_data); - if (key == NULL) + if (g_key_file_remove_group (adp->keyfile, account, NULL)) + adp->save = TRUE; + + if (_commit (self, am, account)) { - if (g_key_file_remove_group (adp->keyfile, account, NULL)) - adp->save = TRUE; + mcp_account_storage_emit_deleted (self, account); + g_task_return_boolean (task, TRUE); } else { - g_assert_not_reached (); + g_task_return_new_error (task, TP_ERROR, TP_ERROR_NOT_AVAILABLE, + "_commit()'s error handling is not good enough to know why " + "I couldn't commit the deletion of %s", account); } - return TRUE; + g_object_unref (task); } +static gboolean +delete_finish (McpAccountStorage *storage, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} static gboolean _commit (const McpAccountStorage *self, @@ -310,7 +328,8 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->get = _get; iface->set_attribute = _set_attribute; iface->set_parameter = _set_parameter; - iface->delete = _delete; + iface->delete_async = delete_async; + iface->delete_finish = delete_finish; iface->commit = _commit; iface->list = _list; } -- cgit v1.2.3 From d06943578e345689f2d040dcc12cf314f64157b9 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 14:51:47 +0000 Subject: Make mcp_account_storage_create() mandatory This means we can (finally) track which plugin "owns" which account in a reliable way. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 4 + src/mcd-account-manager-default.c | 4 +- src/mcd-account-manager.c | 5 +- src/mcd-storage.c | 148 +++++++++++++++++------------- src/mcd-storage.h | 3 +- tests/twisted/mcp-account-diversion.c | 30 ++++++ 6 files changed, 127 insertions(+), 67 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index b87909c3..b64e9987 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -637,6 +637,10 @@ mcp_account_storage_set_parameter (McpAccountStorage *storage, * The default implementation just returns %NULL, and is appropriate for * read-only storage. * + * Since Mission Control 5.17, all storage plugins in which new accounts + * can be created by Mission Control must implement this method. + * Previously, it was not mandatory. + * * Returns: (transfer full): the newly allocated account name, which should * be freed once the caller is done with it, or %NULL if that couldn't * be done. diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index f87aee73..642a67b8 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -331,15 +331,15 @@ _create (const McpAccountStorage *self, const gchar *identification, GError **error) { + McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); gchar *unique_name; - /* See comment in plugin-account.c::_storage_create_account() before changing - * this implementation, it's more subtle than it looks */ unique_name = mcp_account_manager_get_unique_name (MCP_ACCOUNT_MANAGER (am), manager, protocol, identification); g_return_val_if_fail (unique_name != NULL, NULL); + ensure_stored_account (amd, unique_name); return unique_name; } diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 3f4427d7..7ba5d3af 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -277,9 +277,10 @@ created_cb (GObject *storage_plugin_obj, McdMaster *master = mcd_master_get_default (); McdManager *cm = NULL; const gchar *cm_name = NULL; + GError *error = NULL; /* actually fetch the data into our cache from the plugin: */ - if (mcd_storage_add_account_from_plugin (storage, plugin, name)) + if (mcd_storage_add_account_from_plugin (storage, plugin, name, &error)) { account = mcd_account_new (am, name, priv->minotaur); g_assert (MCD_IS_ACCOUNT (account)); @@ -292,7 +293,7 @@ created_cb (GObject *storage_plugin_obj, } else { - /* that function already warned about it */ + WARNING ("%s", error->message); goto finish; } diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 25194b38..020c037e 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -72,6 +72,8 @@ typedef struct { * e.g. { 'account': 'fred@example.com', 'password': 'foo' } * keys of @parameters and @escaped_parameters are disjoint */ GHashTable *escaped_parameters; + /* reffed */ + McpAccountStorage *plugin; } McdStorageAccount; static void @@ -82,6 +84,7 @@ mcd_storage_account_free (gpointer p) g_hash_table_unref (sa->attributes); g_hash_table_unref (sa->parameters); g_hash_table_unref (sa->escaped_parameters); + g_object_unref (sa->plugin); g_slice_free (McdStorageAccount, sa); } @@ -204,22 +207,19 @@ lookup_account (McdStorage *self, } static McdStorageAccount * -ensure_account (McdStorage *self, +mcd_storage_account_new (McpAccountStorage *plugin, const gchar *account) { - McdStorageAccount *sa = lookup_account (self, account); + McdStorageAccount *sa; - if (sa == NULL) - { - sa = g_slice_new (McdStorageAccount); - sa->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_variant_unref); - sa->parameters = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_variant_unref); - sa->escaped_parameters = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - g_hash_table_insert (self->accounts, g_strdup (account), sa); - } + sa = g_slice_new (McdStorageAccount); + sa->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_variant_unref); + sa->parameters = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_variant_unref); + sa->escaped_parameters = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); + sa->plugin = g_object_ref (plugin); return sa; } @@ -339,7 +339,9 @@ mcpa_set_attribute (const McpAccountManager *ma, McpAttributeFlags flags) { McdStorage *self = MCD_STORAGE (ma); - McdStorageAccount *sa = ensure_account (self, account); + McdStorageAccount *sa = lookup_account (self, account); + + g_return_if_fail (sa != NULL); if (value != NULL) { @@ -360,7 +362,9 @@ mcpa_set_parameter (const McpAccountManager *ma, McpParameterFlags flags) { McdStorage *self = MCD_STORAGE (ma); - McdStorageAccount *sa = ensure_account (self, account); + McdStorageAccount *sa = lookup_account (self, account); + + g_return_if_fail (sa != NULL); g_hash_table_remove (sa->parameters, parameter); g_hash_table_remove (sa->escaped_parameters, parameter); @@ -377,7 +381,9 @@ set_value (const McpAccountManager *ma, const gchar *value) { McdStorage *self = MCD_STORAGE (ma); - McdStorageAccount *sa = ensure_account (self, account); + McdStorageAccount *sa = lookup_account (self, account); + + g_return_if_fail (sa != NULL); if (g_str_has_prefix (key, "param-")) { @@ -638,10 +644,10 @@ mcd_storage_load (McdStorage *self) sort_and_cache_plugins (); - store = g_list_last (stores); + store = stores; - /* fetch accounts stored in plugins, in reverse priority so higher prio * - * plugins can overwrite lower prio ones' account data */ + /* fetch accounts stored in plugins, highest priority first, so that + * low priority plugins can be overidden by high priority */ while (store != NULL) { GList *account; @@ -653,16 +659,24 @@ mcd_storage_load (McdStorage *self) DEBUG ("listing from plugin %s [prio: %d]", pname, prio); for (account = stored; account != NULL; account = g_list_next (account)) { + GError *error = NULL; gchar *name = account->data; DEBUG ("fetching %s from plugin %s [prio: %d]", name, pname, prio); - mcd_storage_add_account_from_plugin (self, plugin, name); + + if (!mcd_storage_add_account_from_plugin (self, plugin, name, + &error)) + { + DEBUG ("%s", error->message); + g_clear_error (&error); + } + g_free (name); } /* already freed the contents, just need to free the list itself */ g_list_free (stored); - store = g_list_previous (store); + store = store->next; } } @@ -1484,7 +1498,8 @@ mcd_storage_set_attribute (McdStorage *self, g_return_val_if_fail (attribute != NULL, FALSE); g_return_val_if_fail (!g_str_has_prefix (attribute, "param-"), FALSE); - sa = ensure_account (self, account); + sa = lookup_account (self, account); + g_return_val_if_fail (sa != NULL, FALSE); if (value != NULL) new_v = g_variant_ref_sink (dbus_g_value_build_g_variant (value)); @@ -1544,7 +1559,8 @@ mcd_storage_set_parameter (McdStorage *self, g_return_val_if_fail (account != NULL, FALSE); g_return_val_if_fail (parameter != NULL, FALSE); - sa = ensure_account (self, account); + sa = lookup_account (self, account); + g_return_val_if_fail (sa != NULL, FALSE); if (value != NULL) { @@ -1858,6 +1874,7 @@ mcd_storage_create_account (McdStorage *self, { GList *store; McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + gchar *ret; g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); g_return_val_if_fail (!tp_str_empty (manager), NULL); @@ -1872,8 +1889,18 @@ mcd_storage_create_account (McdStorage *self, if (!tp_strdiff (mcp_account_storage_provider (plugin), provider)) { - return mcp_account_storage_create (plugin, ma, manager, + ret = mcp_account_storage_create (plugin, ma, manager, protocol, identification, error); + if (mcd_storage_add_account_from_plugin (self, plugin, ret, + error)) + { + return ret; + } + else + { + g_free (ret); + return NULL; + } } } @@ -1885,50 +1912,27 @@ mcd_storage_create_account (McdStorage *self, /* No provider specified, let's pick the first plugin able to create this * account in priority order. - * - * FIXME: This is rather subtle, and relies on the fact that accounts - * aren't always strongly tied to a single plugin. - * - * For plugins that only store their accounts set up specifically - * through them (like the libaccounts/SSO pseudo-plugin, - * McdAccountManagerSSO), create() will fail as unimplemented, - * and we'll fall through to the next plugin. Eventually we'll - * reach the default keyfile+gnome-keyring plugin, or another - * plugin that accepts arbitrary accounts. When set() is called, - * the libaccounts/SSO plugin will reject that too, and again, - * we'll fall through to a plugin that accepts arbitrary - * accounts. - * - * Plugins that will accept arbitrary accounts being created - * via D-Bus (like the default keyfile+gnome-keyring plugin, - * and the account-diversion plugin in tests/twisted) - * should, in principle, implement create() to be successful. - * If they do, their create() will succeed, and later, so will - * their set(). - * - * We can't necessarily rely on all such plugins implementing - * create(), because it isn't a mandatory part of the plugin - * API (it was added later). However, as it happens, the - * default plugin returns successfully from create() without - * really doing anything. When we iterate through the accounts again - * to call set(), higher-priority plugins are given a second - * chance to intercept that; so we end up with create() in - * the default plugin being followed by set() from the - * higher-priority plugin. In theory that's bad because it - * splits the account across two plugins, but in practice - * it isn't a problem because the default plugin's create() - * doesn't really do anything anyway. */ for (store = stores; store != NULL; store = g_list_next (store)) { McpAccountStorage *plugin = store->data; - gchar *ret; ret = mcp_account_storage_create (plugin, ma, manager, protocol, identification, error); if (ret != NULL) - return ret; + { + if (mcd_storage_add_account_from_plugin (self, plugin, ret, + error)) + { + return ret; + } + else + { + g_free (ret); + return NULL; + } + } g_clear_error (error); } @@ -2105,13 +2109,33 @@ plugin_iface_init (McpAccountManagerIface *iface, gboolean mcd_storage_add_account_from_plugin (McdStorage *self, McpAccountStorage *plugin, - const gchar *account) + const gchar *account, + GError **error) { + McdStorageAccount *sa = lookup_account (self, account); + + if (sa != NULL) + { + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, + "account %s already exists in plugin '%s', cannot create " + "for plugin '%s'", + account, + mcp_account_storage_name (sa->plugin), + mcp_account_storage_name (plugin)); + return FALSE; + } + + g_hash_table_insert (self->accounts, g_strdup (account), + mcd_storage_account_new (plugin, account)); + if (!mcp_account_storage_get (plugin, MCP_ACCOUNT_MANAGER (self), account, NULL)) { - g_warning ("plugin %s disowned account %s", - mcp_account_storage_name (plugin), account); + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, + "plugin '%s' denied any knowledge of account %s", + mcp_account_storage_name (plugin), + account); + g_hash_table_remove (self->accounts, account); return FALSE; } diff --git a/src/mcd-storage.h b/src/mcd-storage.h index 5f608af1..604af269 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -128,7 +128,8 @@ G_GNUC_INTERNAL void _mcd_storage_store_connections (McdStorage *storage); gboolean mcd_storage_add_account_from_plugin (McdStorage *storage, McpAccountStorage *plugin, - const gchar *account); + const gchar *account, + GError **error); GVariant *mcd_keyfile_get_variant (GKeyFile *keyfile, const gchar *group, diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index 8e210d62..e99c6144 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -317,6 +317,35 @@ _list (const McpAccountStorage *self, return rval; } +static gchar * +create (const McpAccountStorage *self, + const McpAccountManager *am, + const gchar *manager, + const gchar *protocol, + const gchar *identification, + GError **error) +{ + gchar *unique_name; + + unique_name = mcp_account_manager_get_unique_name (MCP_ACCOUNT_MANAGER (am), + manager, protocol, + identification); + + g_return_val_if_fail (unique_name != NULL, NULL); + + if (g_str_has_prefix (unique_name, DONT_DIVERT)) + { + g_free (unique_name); + return NULL; + } + + /* No need to actually create anything: we'll happily return values + * from get(., ., ., NULL) regardless of whether we have that account + * in our list */ + + return unique_name; +} + static void account_storage_iface_init (McpAccountStorageIface *iface, gpointer unused G_GNUC_UNUSED) @@ -332,6 +361,7 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->delete_finish = delete_finish; iface->commit = _commit; iface->list = _list; + iface->create = create; } -- cgit v1.2.3 From cb5879dda2daedee866f1f516c952c33e4728560 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 13 Nov 2013 20:21:49 +0000 Subject: McdStorage: remove "owns" method We now know whose account it is, without having to do this. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 45 ------------------------------- mission-control-plugins/account-storage.h | 7 ----- src/mcd-storage.c | 15 +++-------- tests/twisted/dbus-account-plugin.c | 17 ------------ 4 files changed, 4 insertions(+), 80 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index b64e9987..098e336f 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -65,7 +65,6 @@ * iface->get_additional_info = foo_plugin_get_additional_info; * iface->get_restrictions = foo_plugin_get_restrictions; * iface->create = foo_plugin_create; - * iface->owns = foo_plugin_owns; * iface->set_attribute = foo_plugin_set_attribute; * iface->set_parameter = foo_plugin_set_parameter; * } @@ -219,19 +218,6 @@ default_set_parameter (McpAccountStorage *storage, return FALSE; } -static gboolean -default_owns (McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account) -{ - /* This has the side-effect of pushing the "manager" key back into @am, - * but that should be a no-op in practice: we always call this - * method in priority order and stop at the first one that says "yes", - * and @am's idea of what "manager" is should have come from that same - * plugin anyway. */ - return mcp_account_storage_get (storage, am, account, "manager"); -} - static void class_init (gpointer klass, gpointer data) @@ -249,7 +235,6 @@ class_init (gpointer klass, iface->get_identifier = default_get_identifier; iface->get_additional_info = default_get_additional_info; iface->get_restrictions = default_get_restrictions; - iface->owns = default_owns; iface->set_attribute = default_set_attribute; iface->set_parameter = default_set_parameter; @@ -1086,33 +1071,3 @@ mcp_account_storage_emit_reconnect (McpAccountStorage *storage, { g_signal_emit (storage, signals[RECONNECT], 0, account); } - -/** - * mcp_account_storage_owns: - * @storage: an #McpAccountStorage instance - * @am: an #McpAccountManager instance - * @account: the unique name (object-path tail) of an account - * - * Check whether @account is stored in @storage. The highest-priority - * plugin for which this function returns %TRUE is considered to be - * responsible for @account. - * - * There is a default implementation, which calls mcp_account_storage_get() - * for the well-known key "manager". - * - * Returns: %TRUE if @account is stored in @storage - * - * Since: 5.15.0 - */ -gboolean -mcp_account_storage_owns (McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account) -{ - McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - - g_return_val_if_fail (iface != NULL, FALSE); - g_return_val_if_fail (iface->owns != NULL, FALSE); - - return iface->owns (storage, am, account); -} diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index ff3633e2..44f7bd63 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -124,9 +124,6 @@ struct _McpAccountStorageIface McpAccountStorageCreate create; /* Since 5.15.0 */ - gboolean (*owns) (McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account); gboolean (*set_attribute) (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -193,10 +190,6 @@ const gchar *mcp_account_storage_name (const McpAccountStorage *storage); const gchar *mcp_account_storage_description (const McpAccountStorage *storage); const gchar *mcp_account_storage_provider (const McpAccountStorage *storage); -gboolean mcp_account_storage_owns (McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account); - gboolean mcp_account_storage_set_attribute (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 020c037e..92a2eef9 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -727,22 +727,15 @@ McpAccountStorage * mcd_storage_get_plugin (McdStorage *self, const gchar *account) { - GList *store = stores; - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - McpAccountStorage *owner = NULL; + McdStorageAccount *sa; g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); g_return_val_if_fail (account != NULL, NULL); - for (; store != NULL && owner == NULL; store = g_list_next (store)) - { - McpAccountStorage *plugin = store->data; - - if (mcp_account_storage_owns (plugin, ma, account)) - owner = plugin; - } + sa = lookup_account (self, account); + g_return_val_if_fail (account != NULL, NULL); - return owner; + return sa->plugin; } /* diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 01410a1b..733fbefd 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -1552,22 +1552,6 @@ test_dbus_account_plugin_get_restrictions (const McpAccountStorage *storage, return account->restrictions; } -static gboolean -test_dbus_account_plugin_owns (McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account_name) -{ - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); - Account *account = lookup_account (self, account_name); - - DEBUG ("%s", account_name); - - if (!self->active || account == NULL) - return FALSE; - - return TRUE; -} - static void account_storage_iface_init (McpAccountStorageIface *iface) { @@ -1588,5 +1572,4 @@ account_storage_iface_init (McpAccountStorageIface *iface) iface->get_additional_info = test_dbus_account_plugin_get_additional_info; iface->get_restrictions = test_dbus_account_plugin_get_restrictions; iface->create = test_dbus_account_plugin_create; - iface->owns = test_dbus_account_plugin_owns; } -- cgit v1.2.3 From 927db6c1644e8cc5843f0c7ff0a39b4f5736d152 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 15:26:18 +0000 Subject: mcp_account_storage_set_*: return whether anything changed The plugins are better-placed to do this than McdStorage: they know their own storage format, after all. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 23 ++++--- mission-control-plugins/account-storage.h | 16 +++-- src/mcd-account-manager-default.c | 94 +++++++++++++++++++++------ src/mcd-storage.c | 104 +++++++++++++----------------- tests/twisted/dbus-account-plugin.c | 39 +++++++++-- tests/twisted/mcp-account-diversion.c | 33 +++++++--- 6 files changed, 204 insertions(+), 105 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 098e336f..ca9c7fa8 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -196,7 +196,7 @@ default_get_restrictions (const McpAccountStorage *storage, return 0; } -static gboolean +static McpAccountStorageSetResult default_set_attribute (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -204,10 +204,10 @@ default_set_attribute (McpAccountStorage *storage, GVariant *value, McpAttributeFlags flags) { - return FALSE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; } -static gboolean +static McpAccountStorageSetResult default_set_parameter (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -215,7 +215,7 @@ default_set_parameter (McpAccountStorage *storage, GVariant *value, McpParameterFlags flags) { - return FALSE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; } static void @@ -521,7 +521,7 @@ mcp_account_storage_get (const McpAccountStorage *storage, * * Since: 5.15.0 */ -gboolean +McpAccountStorageSetResult mcp_account_storage_set_attribute (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -532,8 +532,10 @@ mcp_account_storage_set_attribute (McpAccountStorage *storage, McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); SDEBUG (storage, ""); - g_return_val_if_fail (iface != NULL, FALSE); - g_return_val_if_fail (iface->set_attribute != NULL, FALSE); + g_return_val_if_fail (iface != NULL, + MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + g_return_val_if_fail (iface->set_attribute != NULL, + MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); return iface->set_attribute (storage, am, account, attribute, value, flags); } @@ -565,7 +567,7 @@ mcp_account_storage_set_attribute (McpAccountStorage *storage, * * Since: 5.15.0 */ -gboolean +McpAccountStorageSetResult mcp_account_storage_set_parameter (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -577,7 +579,10 @@ mcp_account_storage_set_parameter (McpAccountStorage *storage, SDEBUG (storage, ""); g_return_val_if_fail (iface != NULL, FALSE); - g_return_val_if_fail (iface->set_parameter != NULL, FALSE); + g_return_val_if_fail (iface != NULL, + MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + g_return_val_if_fail (iface->set_parameter != NULL, + MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); return iface->set_parameter (storage, am, account, parameter, value, flags); } diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 44f7bd63..3a8766e3 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -32,6 +32,12 @@ G_BEGIN_DECLS #define MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_NORMAL 100 #define MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_KEYRING 10000 +typedef enum { + MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED = 0, + MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED, + MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED +} McpAccountStorageSetResult; + /* API for plugins to implement */ typedef struct _McpAccountStorage McpAccountStorage; typedef struct _McpAccountStorageIface McpAccountStorageIface; @@ -124,13 +130,13 @@ struct _McpAccountStorageIface McpAccountStorageCreate create; /* Since 5.15.0 */ - gboolean (*set_attribute) (McpAccountStorage *storage, + McpAccountStorageSetResult (*set_attribute) (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, const gchar *attribute, GVariant *val, McpAttributeFlags flags); - gboolean (*set_parameter) (McpAccountStorage *storage, + McpAccountStorageSetResult (*set_parameter) (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, const gchar *parameter, @@ -190,13 +196,15 @@ const gchar *mcp_account_storage_name (const McpAccountStorage *storage); const gchar *mcp_account_storage_description (const McpAccountStorage *storage); const gchar *mcp_account_storage_provider (const McpAccountStorage *storage); -gboolean mcp_account_storage_set_attribute (McpAccountStorage *storage, +McpAccountStorageSetResult mcp_account_storage_set_attribute ( + McpAccountStorage *storage, McpAccountManager *am, const gchar *account, const gchar *attribute, GVariant *value, McpAttributeFlags flags); -gboolean mcp_account_storage_set_parameter (McpAccountStorage *storage, +McpAccountStorageSetResult mcp_account_storage_set_parameter ( + McpAccountStorage *storage, McpAccountManager *am, const gchar *account, const gchar *parameter, diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 642a67b8..d6860ec3 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -163,7 +163,7 @@ mcd_account_manager_default_class_init (McdAccountManagerDefaultClass *cls) DEBUG ("mcd_account_manager_default_class_init"); } -static gboolean +static McpAccountStorageSetResult set_parameter (McpAccountStorage *self, McpAccountManager *am, const gchar *account, @@ -174,22 +174,61 @@ set_parameter (McpAccountStorage *self, McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); McdDefaultStoredAccount *sa; - sa = ensure_stored_account (amd, account); - amd->save = TRUE; + if (val == NULL) + { + gboolean changed = FALSE; - /* remove it from all sets, then re-add it to the right one if - * non-null */ - g_hash_table_remove (sa->parameters, parameter); - g_hash_table_remove (sa->untyped_parameters, parameter); + sa = lookup_stored_account (amd, account); - if (val != NULL) - g_hash_table_insert (sa->parameters, g_strdup (parameter), - g_variant_ref (val)); + if (sa == NULL) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; - return TRUE; + changed = g_hash_table_remove (sa->parameters, parameter); + /* deliberately not ||= - if we removed it from parameters, we + * still want to remove it from untyped_parameters if it was there */ + changed |= g_hash_table_remove (sa->untyped_parameters, parameter); + + if (!changed) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + } + else + { + GVariant *old; + + sa = ensure_stored_account (amd, account); + old = g_hash_table_lookup (sa->parameters, parameter); + + if (old == NULL) + { + /* it might still be in untyped_parameters? */ + const gchar *escaped = g_hash_table_lookup (sa->untyped_parameters, + parameter); + gchar *new = mcp_account_manager_escape_variant_for_keyfile ( + am, val); + + if (!tp_strdiff (escaped, new)) + { + g_free (new); + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + } + + g_free (new); + } + else if (g_variant_equal (old, val)) + { + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + } + + g_hash_table_remove (sa->untyped_parameters, parameter); + g_hash_table_insert (sa->parameters, g_strdup (parameter), + g_variant_ref (val)); + } + + amd->save = TRUE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } -static gboolean +static McpAccountStorageSetResult set_attribute (McpAccountStorage *self, McpAccountManager *am, const gchar *account, @@ -198,17 +237,34 @@ set_attribute (McpAccountStorage *self, McpAttributeFlags flags) { McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); - McdDefaultStoredAccount *sa = ensure_stored_account (amd, account); + McdDefaultStoredAccount *sa; - amd->save = TRUE; + if (val == NULL) + { + sa = lookup_stored_account (amd, account); + + if (sa == NULL) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; - if (val != NULL) - g_hash_table_insert (sa->attributes, g_strdup (attribute), - g_variant_ref (val)); + if (!g_hash_table_remove (sa->attributes, attribute)) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + } else - g_hash_table_remove (sa->attributes, attribute); + { + GVariant *old; - return TRUE; + sa = ensure_stored_account (amd, account); + old = g_hash_table_lookup (sa->attributes, attribute); + + if (old != NULL && g_variant_equal (old, val)) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + + g_hash_table_insert (sa->attributes, g_strdup (attribute), + g_variant_ref (val)); + } + + amd->save = TRUE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } static gboolean diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 92a2eef9..65ed69d7 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1379,38 +1379,56 @@ mcd_storage_get_integer (McdStorage *self, return g_value_get_int (&tmp); } -static void +static gboolean update_storage (McdStorage *self, const gchar *account, + gboolean parameter, const gchar *key, GVariant *variant) { GList *store; - gboolean parameter = g_str_has_prefix (key, "param-"); McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + gboolean updated = FALSE; for (store = stores; store != NULL; store = g_list_next (store)) { McpAccountStorage *plugin = store->data; const gchar *pn = mcp_account_storage_name (plugin); + McpAccountStorageSetResult res; - if (!parameter && - mcp_account_storage_set_attribute (plugin, ma, account, key, variant, - MCP_ATTRIBUTE_FLAG_NONE)) - { - DEBUG ("MCP:%s -> store attribute %s.%s", pn, account, key); - /* set it to NULL in all lower-priority stores */ - variant = NULL; - } - else if (parameter && - mcp_account_storage_set_parameter (plugin, ma, account, key + 6, - variant, MCP_PARAMETER_FLAG_NONE)) + if (parameter) + res = mcp_account_storage_set_parameter (plugin, ma, account, + key, variant, MCP_PARAMETER_FLAG_NONE); + else + res = mcp_account_storage_set_attribute (plugin, ma, account, + key, variant, MCP_ATTRIBUTE_FLAG_NONE); + + switch (res) { - DEBUG ("MCP:%s -> store parameter %s.%s", pn, account, key); - /* set it to NULL in all lower-priority stores */ - variant = NULL; + case MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED: + DEBUG ("MCP:%s -> store %s %s.%s", pn, + parameter ? "parameter" : "attribute", account, key); + updated = TRUE; + /* set it to NULL in all lower-priority stores */ + variant = NULL; + break; + + case MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED: + DEBUG ("MCP:%s -> failed to store %s %s.%s", + pn, parameter ? "parameter" : "attribute", account, key); + break; + + case MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED: + DEBUG ("MCP:%s -> no change to %s %s.%s", + pn, parameter ? "parameter" : "attribute", account, key); + break; + + default: + g_warn_if_reached (); } } + + return updated; } /* @@ -1482,7 +1500,6 @@ mcd_storage_set_attribute (McdStorage *self, const GValue *value) { McdStorageAccount *sa; - GVariant *old_v; GVariant *new_v; gboolean updated = FALSE; @@ -1499,21 +1516,13 @@ mcd_storage_set_attribute (McdStorage *self, else new_v = NULL; - old_v = g_hash_table_lookup (sa->attributes, attribute); - - if (!mcd_nullable_variant_equal (old_v, new_v)) - { - /* First put it in the attributes hash table. (Watch out, this might - * invalidate old_v.) */ - if (new_v == NULL) - g_hash_table_remove (sa->attributes, attribute); - else - g_hash_table_insert (sa->attributes, g_strdup (attribute), - g_variant_ref (new_v)); + if (new_v != NULL) + g_hash_table_insert (sa->attributes, g_strdup (attribute), + g_variant_ref (new_v)); + else + g_hash_table_remove (sa->attributes, attribute); - update_storage (self, account, attribute, new_v); - updated = TRUE; - } + updated = update_storage (self, account, FALSE, attribute, new_v); tp_clear_pointer (&new_v, g_variant_unref); return updated; @@ -1541,10 +1550,7 @@ mcd_storage_set_parameter (McdStorage *self, const gchar *parameter, const GValue *value) { - GVariant *old_v; GVariant *new_v = NULL; - const gchar *old_escaped; - gchar *new_escaped = NULL; McdStorageAccount *sa; gboolean updated = FALSE; @@ -1557,37 +1563,19 @@ mcd_storage_set_parameter (McdStorage *self, if (value != NULL) { - new_escaped = mcd_keyfile_escape_value (value); new_v = g_variant_ref_sink (dbus_g_value_build_g_variant (value)); } - old_v = g_hash_table_lookup (sa->parameters, parameter); - old_escaped = g_hash_table_lookup (sa->escaped_parameters, parameter); + g_hash_table_remove (sa->escaped_parameters, parameter); - if (old_v != NULL) - updated = !mcd_nullable_variant_equal (old_v, new_v); - else if (old_escaped != NULL) - updated = tp_strdiff (old_escaped, new_escaped); + if (new_v != NULL) + g_hash_table_insert (sa->parameters, g_strdup (parameter), + g_variant_ref (new_v)); else - updated = (value != NULL); - - if (updated) - { - gchar key[MAX_KEY_LENGTH]; - - g_hash_table_remove (sa->parameters, parameter); - g_hash_table_remove (sa->escaped_parameters, parameter); + g_hash_table_remove (sa->parameters, parameter); - if (new_v != NULL) - g_hash_table_insert (sa->parameters, g_strdup (parameter), - g_variant_ref (new_v)); - - g_snprintf (key, sizeof (key), "param-%s", parameter); - update_storage (self, account, key, new_v); - return TRUE; - } + updated = update_storage (self, account, TRUE, parameter, new_v); - g_free (new_escaped); tp_clear_pointer (&new_v, g_variant_unref); return updated; } diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 733fbefd..e43d40e5 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -1082,7 +1082,7 @@ test_dbus_account_plugin_get (const McpAccountStorage *storage, return TRUE; } -static gboolean +static McpAccountStorageSetResult test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, McpAccountManager *am, const gchar *account_name, @@ -1092,6 +1092,8 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); + GVariant *old; + guint old_flags; g_return_val_if_fail (account_name != NULL, FALSE); g_return_val_if_fail (attribute != NULL, FALSE); @@ -1099,10 +1101,13 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, DEBUG ("%s of %s", attribute, account_name); if (!self->active || account == NULL) - return FALSE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; if (value == NULL) { + if (!g_hash_table_contains (account->attributes, attribute)) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + g_hash_table_remove (account->attributes, attribute); g_hash_table_remove (account->attribute_flags, attribute); g_hash_table_add (account->uncommitted_attributes, g_strdup (attribute)); @@ -1112,9 +1117,16 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, "DeferringDeleteAttribute", g_variant_new_parsed ("(%o, %s)", account->path, attribute), NULL); - return TRUE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } + old = g_hash_table_lookup (account->attributes, attribute); + old_flags = GPOINTER_TO_UINT (g_hash_table_lookup ( + account->attribute_flags, attribute)); + + if (old != NULL && g_variant_equal (old, value) && old_flags == flags) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + g_hash_table_insert (account->attributes, g_strdup (attribute), g_variant_ref (value)); g_hash_table_insert (account->attribute_flags, g_strdup (attribute), @@ -1127,10 +1139,10 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, g_variant_new_parsed ("(%o, %s, %v)", account->path, attribute, value), NULL); - return TRUE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } -static gboolean +static McpAccountStorageSetResult test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, McpAccountManager *am, const gchar *account_name, @@ -1140,6 +1152,8 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); + GVariant *old; + guint old_flags; g_return_val_if_fail (account_name != NULL, FALSE); g_return_val_if_fail (parameter != NULL, FALSE); @@ -1147,10 +1161,14 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, DEBUG ("%s of %s", parameter, account_name); if (!self->active || account == NULL) - return FALSE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; if (value == NULL) { + if (!g_hash_table_contains (account->parameters, parameter) && + !g_hash_table_contains (account->untyped_parameters, parameter)) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + g_hash_table_remove (account->parameters, parameter); g_hash_table_remove (account->untyped_parameters, parameter); g_hash_table_remove (account->parameter_flags, parameter); @@ -1164,6 +1182,13 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, return TRUE; } + old = g_hash_table_lookup (account->parameters, parameter); + old_flags = GPOINTER_TO_UINT (g_hash_table_lookup ( + account->parameter_flags, parameter)); + + if (old != NULL && g_variant_equal (old, value) && old_flags == flags) + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; + g_hash_table_remove (account->untyped_parameters, parameter); g_hash_table_insert (account->parameters, g_strdup (parameter), g_variant_ref (value)); @@ -1177,7 +1202,7 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, g_variant_new_parsed ("(%o, %s, %v)", account->path, parameter, value), NULL); - return TRUE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } static gboolean diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index e99c6144..7bba5d8f 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -111,7 +111,7 @@ _create_config (void) DEBUG ("created %s", file); } -static gboolean +static McpAccountStorageSetResult _set (McpAccountStorage *self, McpAccountManager *am, const gchar *account, @@ -121,9 +121,10 @@ _set (McpAccountStorage *self, { AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); gchar *val_str; + gboolean changed; if (g_str_has_prefix (account, DONT_DIVERT)) - return FALSE; + return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; if (val == NULL) { @@ -131,7 +132,10 @@ _set (McpAccountStorage *self, GStrv keys; if (g_key_file_remove_key (adp->keyfile, account, key, NULL)) - adp->save = TRUE; + { + adp->save = TRUE; + changed = TRUE; + } keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL); @@ -142,17 +146,30 @@ _set (McpAccountStorage *self, } else { - adp->save = TRUE; + gchar *old; val_str = mcp_account_manager_escape_variant_for_keyfile (am, val); - g_key_file_set_value (adp->keyfile, account, key, val_str); + + old = g_key_file_get_value (adp->keyfile, account, key, NULL); + + if (tp_strdiff (old, val_str)) + { + g_key_file_set_value (adp->keyfile, account, key, val_str); + adp->save = TRUE; + changed = TRUE; + } + g_free (val_str); + g_free (old); } - return TRUE; + if (changed) + return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; + else + return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; } -static gboolean +static McpAccountStorageSetResult _set_attribute (McpAccountStorage *self, McpAccountManager *am, const gchar *account, @@ -163,7 +180,7 @@ _set_attribute (McpAccountStorage *self, return _set (self, am, account, attribute, val, flags); } -static gboolean +static McpAccountStorageSetResult _set_parameter (McpAccountStorage *self, McpAccountManager *am, const gchar *account, -- cgit v1.2.3 From fcfe2c59cba3a8de7e4fe43b05723992cff25661 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 16:12:17 +0000 Subject: Thread expected GVariant types through to mcd_storage_get_* We're going to need this soon, in order to advise plugins how best to unescape the value. The result is still a GValue, for now. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-addressing.c | 4 +-- src/mcd-account-manager-default.c | 4 +-- src/mcd-account-manager.c | 8 ++++-- src/mcd-account.c | 60 ++++++++++++++++++++++++++++++--------- src/mcd-account.h | 1 + src/mcd-storage.c | 31 +++++++++++++------- src/mcd-storage.h | 7 +++-- 7 files changed, 82 insertions(+), 33 deletions(-) diff --git a/src/mcd-account-addressing.c b/src/mcd-account-addressing.c index ec3d8f5e..c9740c78 100644 --- a/src/mcd-account-addressing.c +++ b/src/mcd-account-addressing.c @@ -48,7 +48,7 @@ addressing_set_uri_scheme_association (TpSvcAccountInterfaceAddressing *iface, g_value_init (&value, G_TYPE_STRV); if (mcd_storage_get_attribute (storage, account, MC_ACCOUNTS_KEY_URI_SCHEMES, - &value, NULL)) + G_VARIANT_TYPE_STRING_ARRAY, &value, NULL)) { schemes = g_value_get_boxed (&value); old_association = tp_strv_contains ((const gchar * const *) schemes, @@ -109,7 +109,7 @@ addressing_get_uri_schemes (TpSvcDBusProperties *iface, g_value_init (value, G_TYPE_STRV); if (!mcd_storage_get_attribute (storage, account, MC_ACCOUNTS_KEY_URI_SCHEMES, - value, NULL)) + G_VARIANT_TYPE_STRING_ARRAY, value, NULL)) { g_value_set_boxed (value, NULL); } diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index d6860ec3..24e2232b 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -666,7 +666,7 @@ am_default_load_keyfile (McdAccountManagerDefault *self, } else { - const gchar *type = mcd_storage_get_attribute_type (key); + const GVariantType *type = mcd_storage_get_attribute_type (key); GVariant *variant = NULL; if (type == NULL) @@ -678,7 +678,7 @@ am_default_load_keyfile (McdAccountManagerDefault *self, else { variant = mcd_keyfile_get_variant (keyfile, - account, key, G_VARIANT_TYPE (type), &error); + account, key, type, &error); } if (variant == NULL) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 7ba5d3af..0939015c 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -1250,7 +1250,9 @@ migrate_butterfly_haze_ready (McdManager *manager, /* Parameters; the only mandatory one is 'account' */ if (!mcd_account_get_parameter_of_known_type (ctx->account, - "account", G_TYPE_STRING, + "account", + G_VARIANT_TYPE_STRING, + G_TYPE_STRING, &v, NULL)) { _mcd_account_set_enabled (ctx->account, FALSE, TRUE, @@ -1264,7 +1266,9 @@ migrate_butterfly_haze_ready (McdManager *manager, /* If MC is storing the password, let's copy that too, so Empathy * can migrate it somewhere better. */ if (mcd_account_get_parameter_of_known_type (ctx->account, - "password", G_TYPE_STRING, + "password", + G_VARIANT_TYPE_STRING, + G_TYPE_STRING, &password_v, NULL)) { g_hash_table_insert (parameters, "password", &password_v); diff --git a/src/mcd-account.c b/src/mcd-account.c index e70eaadf..1a75adcb 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -382,7 +382,8 @@ _mcd_account_set_parameter (McdAccount *account, const gchar *name, mcd_storage_set_parameter (storage, account_name, name, value); } -static GType mc_param_type (const TpConnectionManagerParam *param); +static GType mc_param_type (const TpConnectionManagerParam *param, + const GVariantType **variant_type_out); /** * mcd_account_get_parameter: @@ -405,18 +406,22 @@ mcd_account_get_parameter (McdAccount *account, const gchar *name, McdAccountPrivate *priv = account->priv; const TpConnectionManagerParam *param; GType type; + const GVariantType *variant_type; + gboolean ret; param = mcd_manager_get_protocol_param (priv->manager, priv->protocol_name, name); - type = mc_param_type (param); + type = mc_param_type (param, &variant_type); - return mcd_account_get_parameter_of_known_type (account, name, - type, parameter, error); + ret = mcd_account_get_parameter_of_known_type (account, name, + variant_type, type, parameter, error); + return ret; } gboolean mcd_account_get_parameter_of_known_type (McdAccount *account, const gchar *name, + const GVariantType *variant_type, GType type, GValue *parameter, GError **error) @@ -427,7 +432,8 @@ mcd_account_get_parameter_of_known_type (McdAccount *account, g_value_init (&tmp, type); - if (mcd_storage_get_parameter (storage, account_name, name, &tmp, error)) + if (mcd_storage_get_parameter (storage, account_name, name, variant_type, + &tmp, error)) { if (parameter != NULL) { @@ -1090,7 +1096,8 @@ mcd_account_get_string_val (McdAccount *account, const gchar *key, g_value_init (value, G_TYPE_STRING); - if (!mcd_storage_get_attribute (priv->storage, name, key, value, NULL)) + if (!mcd_storage_get_attribute (priv->storage, name, key, + G_VARIANT_TYPE_STRING, value, NULL)) { g_value_set_static_string (value, NULL); } @@ -2375,10 +2382,13 @@ properties_iface_init (TpSvcDBusPropertiesClass *iface, gpointer iface_data) } static GType -mc_param_type (const TpConnectionManagerParam *param) +mc_param_type (const TpConnectionManagerParam *param, + const GVariantType **variant_type_out) { const gchar *dbus_signature; + *variant_type_out = NULL; + if (G_UNLIKELY (param == NULL)) return G_TYPE_INVALID; @@ -2390,37 +2400,49 @@ mc_param_type (const TpConnectionManagerParam *param) switch (dbus_signature[0]) { case DBUS_TYPE_STRING: + *variant_type_out = G_VARIANT_TYPE_STRING; return G_TYPE_STRING; case DBUS_TYPE_BYTE: + *variant_type_out = G_VARIANT_TYPE_BYTE; return G_TYPE_UCHAR; case DBUS_TYPE_INT16: case DBUS_TYPE_INT32: + *variant_type_out = G_VARIANT_TYPE_INT32; return G_TYPE_INT; case DBUS_TYPE_UINT16: case DBUS_TYPE_UINT32: + *variant_type_out = G_VARIANT_TYPE_UINT32; return G_TYPE_UINT; case DBUS_TYPE_BOOLEAN: + *variant_type_out = G_VARIANT_TYPE_BOOLEAN; return G_TYPE_BOOLEAN; case DBUS_TYPE_DOUBLE: + *variant_type_out = G_VARIANT_TYPE_DOUBLE; return G_TYPE_DOUBLE; case DBUS_TYPE_OBJECT_PATH: + *variant_type_out = G_VARIANT_TYPE_OBJECT_PATH; return DBUS_TYPE_G_OBJECT_PATH; case DBUS_TYPE_INT64: + *variant_type_out = G_VARIANT_TYPE_INT64; return G_TYPE_INT64; case DBUS_TYPE_UINT64: + *variant_type_out = G_VARIANT_TYPE_UINT64; return G_TYPE_UINT64; case DBUS_TYPE_ARRAY: if (dbus_signature[1] == DBUS_TYPE_STRING) + { + *variant_type_out = G_VARIANT_TYPE_STRING_ARRAY; return G_TYPE_STRV; + } /* other array types are not supported: * fall through the default case */ default: @@ -2497,11 +2519,13 @@ mcd_account_altered_by_plugin (McdAccount *account, const McdDBusProp *prop = NULL; GValue value = G_VALUE_INIT; GError *error = NULL; + const GVariantType *variant_type = NULL; DEBUG ("%s", name); if (tp_strdiff (name, "Parameters") && - !mcd_storage_init_value_for_attribute (&value, name)) + !mcd_storage_init_value_for_attribute (&value, name, + &variant_type)) { WARNING ("plugin wants to alter %s but I don't know what " "type that ought to be", name); @@ -2514,7 +2538,8 @@ mcd_account_altered_by_plugin (McdAccount *account, } else if (!mcd_storage_get_attribute (account->priv->storage, account->priv->unique_name, - name, &value, &error)) + name, variant_type, &value, + &error)) { WARNING ("cannot get new value of %s: %s", name, error->message); g_error_free (error); @@ -2703,6 +2728,7 @@ check_one_parameter_update (McdAccount *account, const TpConnectionManagerParam *param = tp_protocol_get_param (protocol, name); GType type; + const GVariantType *variant_type; if (param == NULL) { @@ -2712,15 +2738,18 @@ check_one_parameter_update (McdAccount *account, return FALSE; } - type = mc_param_type (param); + type = mc_param_type (param, &variant_type); if (G_VALUE_TYPE (new_value) != type) { /* FIXME: use D-Bus type names, not GType names. */ g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "parameter '%s' must be of type %s, not %s", + "parameter '%s' must be of type %s ('%.*s'), not %s", tp_connection_manager_param_get_name (param), - g_type_name (type), G_VALUE_TYPE_NAME (new_value)); + g_type_name (type), + (int) g_variant_type_get_string_length (variant_type), + g_variant_type_peek_string (variant_type), + G_VALUE_TYPE_NAME (new_value)); return FALSE; } @@ -3305,7 +3334,8 @@ mcd_account_setup (McdAccount *account) g_free (priv->auto_presence_message); if (mcd_storage_get_attribute (storage, name, - MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE, &value, + MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE, + G_VARIANT_TYPE ("(uss)"), &value, NULL)) { GValueArray *va = g_value_get_boxed (&value); @@ -3377,7 +3407,9 @@ mcd_account_setup (McdAccount *account) g_ptr_array_unref (priv->supersedes); if (mcd_storage_get_attribute (storage, name, - MC_ACCOUNTS_KEY_SUPERSEDES, &value, NULL)) + MC_ACCOUNTS_KEY_SUPERSEDES, + G_VARIANT_TYPE_OBJECT_PATH_ARRAY, + &value, NULL)) { priv->supersedes = g_value_dup_boxed (&value); } diff --git a/src/mcd-account.h b/src/mcd-account.h index edb8da0e..6dce6496 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -139,6 +139,7 @@ gboolean mcd_account_get_parameter (McdAccount *account, const gchar *name, gboolean mcd_account_get_parameter_of_known_type (McdAccount *account, const gchar *name, + const GVariantType *variant_type, GType type, GValue *parameter, GError **error); diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 65ed69d7..b09473df 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -264,7 +264,7 @@ static struct { { NULL, NULL } }; -const gchar * +const GVariantType * mcd_storage_get_attribute_type (const gchar *attribute) { guint i; @@ -272,7 +272,7 @@ mcd_storage_get_attribute_type (const gchar *attribute) for (i = 0; known_attributes[i].type != NULL; i++) { if (!tp_strdiff (attribute, known_attributes[i].name)) - return known_attributes[i].type; + return G_VARIANT_TYPE (known_attributes[i].type); } return NULL; @@ -280,14 +280,18 @@ mcd_storage_get_attribute_type (const gchar *attribute) gboolean mcd_storage_init_value_for_attribute (GValue *value, - const gchar *attribute) + const gchar *attribute, + const GVariantType **variant_type) { - const gchar *s = mcd_storage_get_attribute_type (attribute); + const GVariantType *s = mcd_storage_get_attribute_type (attribute); if (s == NULL) return FALSE; - switch (s[0]) + if (variant_type != NULL) + *variant_type = s; + + switch (g_variant_type_peek_string (s)[0]) { case 's': g_value_init (value, G_TYPE_STRING); @@ -304,7 +308,7 @@ mcd_storage_init_value_for_attribute (GValue *value, case 'a': { - switch (s[1]) + switch (g_variant_type_peek_string (s)[1]) { case 'o': g_value_init (value, TP_ARRAY_TYPE_OBJECT_PATH_LIST); @@ -319,7 +323,7 @@ mcd_storage_init_value_for_attribute (GValue *value, case '(': { - if (!tp_strdiff (s, "(uss)")) + if (g_variant_type_equal (s, G_VARIANT_TYPE ("(uss)"))) { g_value_init (value, TP_STRUCT_TYPE_SIMPLE_PRESENCE); return TRUE; @@ -401,7 +405,7 @@ set_value (const McpAccountManager *ma, GValue tmp = G_VALUE_INIT; GError *error = NULL; - if (!mcd_storage_init_value_for_attribute (&tmp, key)) + if (!mcd_storage_init_value_for_attribute (&tmp, key, NULL)) { g_warning ("Not sure what the type of '%s' is, assuming string", key); @@ -762,7 +766,8 @@ mcd_storage_dup_string (McdStorage *self, g_value_init (&tmp, G_TYPE_STRING); - if (!mcd_storage_get_attribute (self, account, attribute, &tmp, NULL)) + if (!mcd_storage_get_attribute (self, account, attribute, + G_VARIANT_TYPE_STRING, &tmp, NULL)) return NULL; ret = g_value_dup_string (&tmp); @@ -809,6 +814,7 @@ gboolean mcd_storage_get_attribute (McdStorage *self, const gchar *account, const gchar *attribute, + const GVariantType *type, GValue *value, GError **error) { @@ -853,6 +859,7 @@ gboolean mcd_storage_get_parameter (McdStorage *self, const gchar *account, const gchar *parameter, + const GVariantType *type, GValue *value, GError **error) { @@ -1345,7 +1352,8 @@ mcd_storage_get_boolean (McdStorage *self, g_value_init (&tmp, G_TYPE_BOOLEAN); - if (!mcd_storage_get_attribute (self, account, attribute, &tmp, NULL)) + if (!mcd_storage_get_attribute (self, account, attribute, + G_VARIANT_TYPE_BOOLEAN, &tmp, NULL)) return FALSE; return g_value_get_boolean (&tmp); @@ -1373,7 +1381,8 @@ mcd_storage_get_integer (McdStorage *self, g_value_init (&tmp, G_TYPE_INT); - if (!mcd_storage_get_attribute (self, account, attribute, &tmp, NULL)) + if (!mcd_storage_get_attribute (self, account, attribute, + G_VARIANT_TYPE_INT32, &tmp, NULL)) return FALSE; return g_value_get_int (&tmp); diff --git a/src/mcd-storage.h b/src/mcd-storage.h index 604af269..be0d0aa4 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -104,12 +104,14 @@ gchar *mcd_storage_dup_string (McdStorage *storage, gboolean mcd_storage_get_attribute (McdStorage *storage, const gchar *account, const gchar *attribute, + const GVariantType *type, GValue *value, GError **error); gboolean mcd_storage_get_parameter (McdStorage *storage, const gchar *account, const gchar *parameter, + const GVariantType *type, GValue *value, GError **error); @@ -155,9 +157,10 @@ gboolean mcd_keyfile_unescape_value (const gchar *escaped, GValue *value, GError **error); -const gchar *mcd_storage_get_attribute_type (const gchar *attribute); +const GVariantType *mcd_storage_get_attribute_type (const gchar *attribute); gboolean mcd_storage_init_value_for_attribute (GValue *value, - const gchar *attribute); + const gchar *attribute, + const GVariantType **variant_type); G_END_DECLS -- cgit v1.2.3 From ea1ebe93295eb140212a9b6885d7d2d9a613e6d1 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 16:14:35 +0000 Subject: mcp_account_manager_unescape_variant_from_keyfile: add I want to push responsibility for unescaping into storage plugins. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account.c | 29 +++++++++++++++++++++++++++++ mission-control-plugins/account.h | 6 ++++++ mission-control-plugins/implementation.h | 4 ++++ src/mcd-storage.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/mission-control-plugins/account.c b/mission-control-plugins/account.c index fecd3d8d..a6ca95ac 100644 --- a/mission-control-plugins/account.c +++ b/mission-control-plugins/account.c @@ -272,3 +272,32 @@ mcp_account_manager_escape_variant_for_keyfile (const McpAccountManager *mcpa, return iface->escape_variant_for_keyfile (mcpa, variant); } + +/** + * mcp_account_manager_unescape_variant_from_keyfile: + * @mcpa: a #McpAccountManager + * @escaped: a string that could have come from g_key_file_get_value() + * @type: the type of the variant to which to unescape + * + * Unescape @escaped as if it had appeared in a #GKeyFile, with syntax + * appropriate for @type. + * + * It is a programming error to use an unsupported type. + * + * Returns: (transfer full): the unescaped form of @escaped + * (*not* a floating reference) + */ +GVariant * +mcp_account_manager_unescape_variant_from_keyfile ( + const McpAccountManager *mcpa, + const gchar *escaped, + const GVariantType *type, + GError **error) +{ + McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); + + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (iface->unescape_variant_from_keyfile != NULL, NULL); + + return iface->unescape_variant_from_keyfile (mcpa, escaped, type, error); +} diff --git a/mission-control-plugins/account.h b/mission-control-plugins/account.h index 788813f1..78e58d0d 100644 --- a/mission-control-plugins/account.h +++ b/mission-control-plugins/account.h @@ -71,6 +71,12 @@ gchar *mcp_account_manager_escape_variant_for_keyfile ( const McpAccountManager *mcpa, GVariant *variant); +GVariant *mcp_account_manager_unescape_variant_from_keyfile ( + const McpAccountManager *mcpa, + const gchar *escaped, + const GVariantType *type, + GError **error); + void mcp_account_manager_identify_account_async (McpAccountManager *mcpa, const gchar *manager, const gchar *protocol, diff --git a/mission-control-plugins/implementation.h b/mission-control-plugins/implementation.h index 7d951464..7db25f5c 100644 --- a/mission-control-plugins/implementation.h +++ b/mission-control-plugins/implementation.h @@ -89,6 +89,10 @@ struct _McpAccountManagerIface { gchar * (* escape_variant_for_keyfile) (const McpAccountManager *mcpa, GVariant *variant); + GVariant *(* unescape_variant_from_keyfile) (const McpAccountManager *mcpa, + const gchar *escaped, + const GVariantType *type, + GError **error); void (* set_attribute) (const McpAccountManager *mcpa, const gchar *account, diff --git a/src/mcd-storage.c b/src/mcd-storage.c index b09473df..af63dfb8 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -2081,6 +2081,37 @@ mcd_storage_ready (McdStorage *self) } } +static GVariant * +mcd_keyfile_unescape_variant (const gchar *escaped, + const GVariantType *type, + GError **error) +{ + GKeyFile *keyfile; + GVariant *ret; + + g_return_val_if_fail (escaped != NULL, NULL); + g_return_val_if_fail (type != NULL, NULL); + + keyfile = g_key_file_new (); + g_key_file_set_value (keyfile, "g", "k", escaped); + ret = mcd_keyfile_get_variant (keyfile, "g", "k", type, error); + g_key_file_free (keyfile); + + if (ret != NULL) + g_variant_ref_sink (ret); + + return ret; +} + +static GVariant * +mcpa_unescape_variant_from_keyfile (const McpAccountManager *mcpa, + const gchar *escaped, + const GVariantType *type, + GError **error) +{ + return mcd_keyfile_unescape_variant (escaped, type, error); +} + static void plugin_iface_init (McpAccountManagerIface *iface, gpointer unused G_GNUC_UNUSED) @@ -2094,6 +2125,7 @@ plugin_iface_init (McpAccountManagerIface *iface, iface->identify_account_async = identify_account_async; iface->identify_account_finish = identify_account_finish; iface->escape_variant_for_keyfile = mcpa_escape_variant_for_keyfile; + iface->unescape_variant_from_keyfile = mcpa_unescape_variant_from_keyfile; } gboolean -- cgit v1.2.3 From 93b822857d1898caed819baad7680a10a23e0486 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 16:29:02 +0000 Subject: dbus-account-plugin: update internal cache correctly The backend-makes-changes test replaces an typed parameter with an untyped parameter. We correctly signalled the change to MC, but didn't update the internal cache; the rather strange way in which MC receives attributes/parameters masked this bug. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- tests/twisted/dbus-account-plugin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index e43d40e5..7eaccc37 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -581,6 +581,7 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, (stored == NULL || !g_variant_equal (value, stored))) { + g_hash_table_remove (account->parameters, param); g_hash_table_insert (account->untyped_parameters, g_strdup (param), g_strdup (escaped)); key = g_strdup_printf ("param-%s", param); -- cgit v1.2.3 From 03c99601d7a76fbc49ed376cd9c30ca631bc085f Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 16:20:21 +0000 Subject: mcp_account_storage_get: replace with get_attribute, get_parameter The old API in which plugins poked new values into the McdStorage was non-obvious, and also fundamentally incompatible with the idea that each account is owned by at most one plugin: if an account in a high-priority plugin is masked by one in a low-priority plugin, the McdStorage can't prevent the low-priority plugin from changing its effective attribute and parameter values. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 149 +++++++++++------ mission-control-plugins/account-storage.h | 36 ++-- mission-control-plugins/account.c | 94 ----------- mission-control-plugins/account.h | 17 -- mission-control-plugins/implementation.h | 17 -- src/mcd-account-manager-default.c | 130 +++++---------- src/mcd-storage.c | 263 +++++------------------------- src/mcd-storage.h | 2 +- tests/twisted/dbus-account-plugin.c | 163 +++++++----------- tests/twisted/mcp-account-diversion.c | 71 ++++---- 10 files changed, 300 insertions(+), 642 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index ca9c7fa8..6ce8c725 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -56,7 +56,6 @@ * iface->desc = "The FOO storage backend"; * iface->provider = "org.freedesktop.Telepathy.MissionControl5.FooStorage"; * - * iface->get = foo_plugin_get; * iface->delete = foo_plugin_delete; * iface->commit = foo_plugin_commit; * iface->list = foo_plugin_list; @@ -65,6 +64,8 @@ * iface->get_additional_info = foo_plugin_get_additional_info; * iface->get_restrictions = foo_plugin_get_restrictions; * iface->create = foo_plugin_create; + * iface->get_attribute = foo_plugin_get_attribute; + * iface->get_parameter = foo_plugin_get_parameter; * iface->set_attribute = foo_plugin_set_attribute; * iface->set_parameter = foo_plugin_set_parameter; * } @@ -109,15 +110,6 @@ enum static guint signals[NO_SIGNAL] = { 0 }; -static gboolean -default_get (const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account, - const gchar *key) -{ - return FALSE; -} - static void default_delete_async (McpAccountStorage *storage, McpAccountManager *am, @@ -196,6 +188,28 @@ default_get_restrictions (const McpAccountStorage *storage, return 0; } +static GVariant * +default_get_attribute (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags) +{ + return NULL; +} + +static GVariant * +default_get_parameter (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags) +{ + return NULL; +} + static McpAccountStorageSetResult default_set_attribute (McpAccountStorage *storage, McpAccountManager *am, @@ -225,7 +239,6 @@ class_init (gpointer klass, GType type = G_TYPE_FROM_CLASS (klass); McpAccountStorageIface *iface = klass; - iface->get = default_get; iface->create = default_create; iface->delete_async = default_delete_async; iface->delete_finish = default_delete_finish; @@ -235,6 +248,8 @@ class_init (gpointer klass, iface->get_identifier = default_get_identifier; iface->get_additional_info = default_get_additional_info; iface->get_restrictions = default_get_restrictions; + iface->get_attribute = default_get_attribute; + iface->get_parameter = default_get_parameter; iface->set_attribute = default_set_attribute; iface->set_parameter = default_set_parameter; @@ -262,20 +277,20 @@ class_init (gpointer klass, /** * McpAccountStorage::altered-one * @account: the unique name of the altered account - * @name: the name of the altered property (its key) + * @name: either an attribute name such as DisplayName, + * or "param-" plus a parameter name, e.g. "param-require-encryption" * * Emitted if an external entity alters an account * in the backend that the emitting plugin handles. * - * Before emitting this signal, the plugin must call - * either mcp_account_manager_set_attribute(), - * either mcp_account_manager_set_parameter() or - * mcp_account_manager_set_value() to push the new value - * into the account manager. + * Before emitting this signal, the plugin must update its + * internal cache (if any) so that mcp_account_storage_get_attribute() + * or mcp_account_storage_get_parameter() will return the new value + * when queried. * - * Note that mcp_account_manager_set_parameter() does not use the - * "param-" prefix, but this signal and mcp_account_manager_set_value() - * both do. + * Note that mcp_account_manager_get_parameter() and + * mcp_account_manager_set_parameter() do not use the + * "param-" prefix, but this signal does. * * Should not be fired until mcp_account_storage_ready() has been called */ @@ -308,8 +323,11 @@ class_init (gpointer klass, * Emitted if an external entity enables/disables an account * in the backend the emitting plugin handles. This is similar to * emitting #McpAccountStorage::altered-one for the attribute - * "Enabled", except that the plugin is not required to call - * a function like mcp_account_manager_set_value() first. + * "Enabled". + * + * Before emitting this signal, the plugin must update its + * internal cache (if any) so that mcp_account_storage_get_attribute() + * will return the new value for Enabled when queried. * * Should not be fired until mcp_account_storage_ready() has been called * @@ -439,60 +457,83 @@ mcp_account_storage_priority (const McpAccountStorage *storage) } /** - * McpAccountStorageGetFunc: - * @storage: the account storage plugin - * @am: object used to call back into the account manager + * mcp_account_storage_get_attribute: + * @storage: an #McpAccountStorage instance + * @am: an #McpAccountManager instance * @account: the unique name of the account - * @key: the setting whose value we wish to fetch: either an attribute - * like "DisplayName", or "param-" plus a parameter like "account" + * @attribute: the name of an attribute, e.g. "DisplayName" + * @type: the expected type of @attribute, as a hint for + * legacy account storage plugins that do not store attributes' types + * @flags: (allow-none) (out): used to return attribute flags + * + * Retrieve an attribute. * - * An implementation of mcp_account_storage_get(). + * There is a default implementation, which just returns %NULL. + * All account storage plugins must override this method. * - * Returns: %TRUE if @storage is responsible for @account + * The returned variant does not necessarily have to match @type: + * Mission Control will coerce it to an appropriate type if required. In + * particular, plugins that store strongly-typed attributes may return + * the stored type, not the expected type, if they differ. + * + * Returns: (transfer full): the value of the attribute, or %NULL if it + * is not present */ +GVariant * +mcp_account_storage_get_attribute (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags) +{ + McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + + SDEBUG (storage, ""); + g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (iface->get_attribute != NULL, FALSE); + + return iface->get_attribute (storage, am, account, attribute, type, flags); +} /** - * mcp_account_storage_get: + * mcp_account_storage_get_parameter: * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance * @account: the unique name of the account - * @key: the setting whose value we wish to fetch: either an attribute - * like "DisplayName", or "param-" plus a parameter like "account" - * - * Get a value from the plugin's in-memory cache. - * Before emitting this signal, the plugin must call - * either mcp_account_manager_set_attribute(), - * mcp_account_manager_set_parameter(), - * or mcp_account_manager_set_value() - * before returning from this method call. + * @parameter: the name of a parameter, e.g. "require-encryption" + * @type: the expected type of @parameter, as a hint for + * legacy account storage plugins that do not store parameters' types + * @flags: (allow-none) (out): used to return parameter flags * - * Note that mcp_account_manager_set_parameter() does not use the - * "param-" prefix, even if called from this function. + * Retrieve a parameter. * - * If @key is %NULL the plugin should iterate through all attributes and - * parameters, and push each of them into @am, as if this method had - * been called once for each attribute or parameter. It must then return - * %TRUE if any attributes or parameters were found, or %FALSE if it - * was not responsible for @account. + * There is a default implementation, which just returns %NULL. + * All account storage plugins must override this method. * - * The default implementation just returns %FALSE, and should always be - * overridden. + * The returned variant does not necessarily have to match @type: + * Mission Control will coerce it to an appropriate type if required. In + * particular, plugins that store strongly-typed parameters may return + * the stored type, not the expected type, if they differ. * - * Returns: %TRUE if @storage is responsible for @account + * Returns: (transfer full): the value of the parameter, or %NULL if it + * is not present */ -gboolean -mcp_account_storage_get (const McpAccountStorage *storage, +GVariant * +mcp_account_storage_get_parameter (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, - const gchar *key) + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); SDEBUG (storage, ""); g_return_val_if_fail (iface != NULL, FALSE); - g_return_val_if_fail (iface->get != NULL, FALSE); + g_return_val_if_fail (iface->get_parameter != NULL, FALSE); - return iface->get (storage, am, account, key); + return iface->get_parameter (storage, am, account, parameter, type, flags); } /** diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 3a8766e3..42898a5f 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -65,11 +65,6 @@ struct _McpAccountStorage { }; GType mcp_account_storage_get_type (void); /* Virtual method implementation signatures */ -typedef gboolean (*McpAccountStorageGetFunc) ( - const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account, - const gchar *key); typedef gchar * (*McpAccountStorageCreate) ( const McpAccountStorage *storage, const McpAccountManager *am, @@ -112,7 +107,6 @@ struct _McpAccountStorageIface const gchar *desc; const gchar *provider; - McpAccountStorageGetFunc get; void (*delete_async) (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -130,6 +124,18 @@ struct _McpAccountStorageIface McpAccountStorageCreate create; /* Since 5.15.0 */ + GVariant *(*get_attribute) (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags); + GVariant *(*get_parameter) (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags); McpAccountStorageSetResult (*set_attribute) (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -147,11 +153,6 @@ struct _McpAccountStorageIface /* virtual methods */ gint mcp_account_storage_priority (const McpAccountStorage *storage); -gboolean mcp_account_storage_get (const McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account, - const gchar *key); - gchar * mcp_account_storage_create (const McpAccountStorage *storage, const McpAccountManager *am, const gchar *manager, @@ -196,6 +197,19 @@ const gchar *mcp_account_storage_name (const McpAccountStorage *storage); const gchar *mcp_account_storage_description (const McpAccountStorage *storage); const gchar *mcp_account_storage_provider (const McpAccountStorage *storage); +GVariant *mcp_account_storage_get_attribute (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags); +GVariant *mcp_account_storage_get_parameter (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account, + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags); + McpAccountStorageSetResult mcp_account_storage_set_attribute ( McpAccountStorage *storage, McpAccountManager *am, diff --git a/mission-control-plugins/account.c b/mission-control-plugins/account.c index a6ca95ac..2c194616 100644 --- a/mission-control-plugins/account.c +++ b/mission-control-plugins/account.c @@ -73,100 +73,6 @@ mcp_account_manager_get_type (void) return type; } -/** - * mcp_account_manager_set_value: - * @mcpa: an #McpAccountManager instance - * @account: the unique name of an account - * @key: the setting whose value we wish to change: either an attribute - * like "DisplayName", or "param-" plus a parameter like "account" - * @value: the new value, escaped as if for a #GKeyFile, or %NULL to delete - * the setting/parameter - * - * Inform Mission Control that @key has changed its value to @value. - * - * This function may either be called from mcp_account_storage_get(), - * or just before emitting #McpAccountStorage::altered-one. - * - * New plugins should call mcp_account_manager_set_attribute() or - * mcp_account_manager_set_parameter() instead. - */ -void -mcp_account_manager_set_value (const McpAccountManager *mcpa, - const gchar *account, - const gchar *key, - const gchar *value) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_if_fail (iface != NULL); - g_return_if_fail (iface->set_value != NULL); - - iface->set_value (mcpa, account, key, value); -} - -/** - * mcp_account_manager_set_attribute: - * @mcpa: an #McpAccountManager instance - * @account: the unique name of an account - * @attribute: the name of an attribute, such as "DisplayName" - * @value: (allow-none): the new value, or %NULL to delete the attribute - * @flags: flags for the new value (only used if @value is non-%NULL) - * - * Inform Mission Control that @attribute has changed its value to @value. - * - * If @value is a floating reference, Mission Control will take ownership - * of it, much like g_variant_builder_add_value(). - * - * This function may either be called from mcp_account_storage_get(), - * or just before emitting #McpAccountStorage::altered-one. - */ -void -mcp_account_manager_set_attribute (const McpAccountManager *mcpa, - const gchar *account, - const gchar *attribute, - GVariant *value, - McpAttributeFlags flags) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_if_fail (iface != NULL); - g_return_if_fail (iface->set_attribute != NULL); - - iface->set_attribute (mcpa, account, attribute, value, flags); -} - -/** - * mcp_account_manager_set_parameter: - * @mcpa: an #McpAccountManager instance - * @account: the unique name of an account - * @parameter: the name of a parameter, such as "account", without - * the "param-" prefix - * @value: (allow-none): the new value, or %NULL to delete the parameter - * @flags: flags for the new value (only used if @value is non-%NULL) - * - * Inform Mission Control that @parameter has changed its value to @value. - * - * If @value is a floating reference, Mission Control will take ownership - * of it, much like g_variant_builder_add_value(). - * - * This function may either be called from mcp_account_storage_get(), - * or just before emitting #McpAccountStorage::altered-one. - */ -void -mcp_account_manager_set_parameter (const McpAccountManager *mcpa, - const gchar *account, - const gchar *parameter, - GVariant *value, - McpParameterFlags flags) -{ - McpAccountManagerIface *iface = MCP_ACCOUNT_MANAGER_GET_IFACE (mcpa); - - g_return_if_fail (iface != NULL); - g_return_if_fail (iface->set_parameter != NULL); - - iface->set_parameter (mcpa, account, parameter, value, flags); -} - /** * mcp_account_manager_get_unique_name: * @mcpa: an #McpAccountManager instance diff --git a/mission-control-plugins/account.h b/mission-control-plugins/account.h index 78e58d0d..2a46c3ab 100644 --- a/mission-control-plugins/account.h +++ b/mission-control-plugins/account.h @@ -45,23 +45,6 @@ typedef struct _McpAccountManagerIface McpAccountManagerIface; GType mcp_account_manager_get_type (void) G_GNUC_CONST; -void mcp_account_manager_set_value (const McpAccountManager *mcpa, - const gchar *account, - const gchar *key, - const gchar *value); - -void mcp_account_manager_set_attribute (const McpAccountManager *mcpa, - const gchar *account, - const gchar *attribute, - GVariant *value, - McpAttributeFlags flags); - -void mcp_account_manager_set_parameter (const McpAccountManager *mcpa, - const gchar *account, - const gchar *parameter, - GVariant *value, - McpParameterFlags flags); - gchar * mcp_account_manager_get_unique_name (McpAccountManager *mcpa, const gchar *manager, const gchar *protocol, diff --git a/mission-control-plugins/implementation.h b/mission-control-plugins/implementation.h index 7db25f5c..59096f93 100644 --- a/mission-control-plugins/implementation.h +++ b/mission-control-plugins/implementation.h @@ -77,11 +77,6 @@ struct _McpDispatchOperationIface { struct _McpAccountManagerIface { GTypeInterface parent; - void (*set_value) (const McpAccountManager *ma, - const gchar *acct, - const gchar *key, - const gchar *value); - gchar * (* unique_name) (const McpAccountManager *ma, const gchar *manager, const gchar *protocol, @@ -94,18 +89,6 @@ struct _McpAccountManagerIface { const GVariantType *type, GError **error); - void (* set_attribute) (const McpAccountManager *mcpa, - const gchar *account, - const gchar *attribute, - GVariant *value, - McpAttributeFlags flags); - - void (* set_parameter) (const McpAccountManager *mcpa, - const gchar *account, - const gchar *parameter, - GVariant *value, - McpParameterFlags flags); - void (* identify_account_async) (McpAccountManager *mcpa, const gchar *manager, const gchar *protocol, diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 24e2232b..bac90ad3 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -52,6 +52,12 @@ typedef struct { gboolean absent; } McdDefaultStoredAccount; +static GVariant * +variant_ref0 (GVariant *v) +{ + return (v == NULL ? NULL : g_variant_ref (v)); +} + static McdDefaultStoredAccount * lookup_stored_account (McdAccountManagerDefault *self, const gchar *account) @@ -267,116 +273,59 @@ set_attribute (McpAccountStorage *self, return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } -static gboolean -get_parameter (const McpAccountStorage *self, - const McpAccountManager *am, +static GVariant * +get_attribute (McpAccountStorage *self, + McpAccountManager *am, const gchar *account, - const gchar *prefixed, - const gchar *parameter) + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags) { McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); McdDefaultStoredAccount *sa = lookup_stored_account (amd, account); - if (parameter != NULL) - { - gchar *v = NULL; - GVariant *variant = NULL; - - if (sa == NULL || sa->absent) - return FALSE; - - variant = g_hash_table_lookup (sa->parameters, parameter); - - if (variant != NULL) - { - mcp_account_manager_set_parameter (am, account, parameter, - variant, MCP_PARAMETER_FLAG_NONE); - return TRUE; - } + if (flags != NULL) + *flags = 0; - v = g_hash_table_lookup (sa->untyped_parameters, parameter); - - if (v == NULL) - return FALSE; - - mcp_account_manager_set_value (am, account, prefixed, v); - } - else - { - g_assert_not_reached (); - } + if (sa == NULL || sa->absent) + return FALSE; - return TRUE; + /* ignore @type, we store every attribute with its type anyway; MC will + * coerce values to an appropriate type if needed */ + return variant_ref0 (g_hash_table_lookup (sa->attributes, attribute)); } -static gboolean -_get (const McpAccountStorage *self, - const McpAccountManager *am, +static GVariant * +get_parameter (McpAccountStorage *self, + McpAccountManager *am, const gchar *account, - const gchar *key) + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags) { McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); McdDefaultStoredAccount *sa = lookup_stored_account (amd, account); + GVariant *variant; + gchar *str; + + if (flags != NULL) + *flags = 0; if (sa == NULL || sa->absent) return FALSE; - if (key != NULL) - { - GVariant *v = NULL; + variant = g_hash_table_lookup (sa->parameters, parameter); - if (g_str_has_prefix (key, "param-")) - { - return get_parameter (self, am, account, key, key + 6); - } + if (variant != NULL) + return g_variant_ref (variant); - v = g_hash_table_lookup (sa->attributes, key); - - if (v == NULL) - return FALSE; - - mcp_account_manager_set_attribute (am, account, key, v, - MCP_ATTRIBUTE_FLAG_NONE); - } - else - { - GHashTableIter iter; - gpointer k, v; - - g_hash_table_iter_init (&iter, sa->attributes); - - while (g_hash_table_iter_next (&iter, &k, &v)) - { - if (v != NULL) - mcp_account_manager_set_attribute (am, account, k, - v, MCP_ATTRIBUTE_FLAG_NONE); - } + str = g_hash_table_lookup (sa->untyped_parameters, parameter); - g_hash_table_iter_init (&iter, sa->parameters); - - while (g_hash_table_iter_next (&iter, &k, &v)) - { - if (v != NULL) - mcp_account_manager_set_parameter (am, account, k, v, - MCP_PARAMETER_FLAG_NONE); - } - - g_hash_table_iter_init (&iter, sa->untyped_parameters); - - while (g_hash_table_iter_next (&iter, &k, &v)) - { - if (v != NULL) - { - gchar *prefixed = g_strdup_printf ("param-%s", - (const gchar *) k); - - mcp_account_manager_set_value (am, account, prefixed, v); - g_free (prefixed); - } - } - } + if (str == NULL) + return NULL; - return TRUE; + return mcp_account_manager_unescape_variant_from_keyfile (am, + str, type, NULL); } static gchar * @@ -1026,7 +975,8 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->desc = PLUGIN_DESCRIPTION; iface->priority = PLUGIN_PRIORITY; - iface->get = _get; + iface->get_attribute = get_attribute; + iface->get_parameter = get_parameter; iface->set_attribute = set_attribute; iface->set_parameter = set_parameter; iface->create = _create; diff --git a/src/mcd-storage.c b/src/mcd-storage.c index af63dfb8..dffc498f 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -61,38 +61,11 @@ G_DEFINE_TYPE_WITH_CODE (McdStorage, mcd_storage, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (MCP_TYPE_ACCOUNT_MANAGER, plugin_iface_init)) -typedef struct { - /* owned string => GVariant - * e.g. { 'DisplayName': <'Frederick Bloggs'> } */ - GHashTable *attributes; - /* owned string => owned GVariant - * e.g. { 'account': <'fred@example.com'>, 'password': <'foo'> } */ - GHashTable *parameters; - /* owned string => owned string escaped as if for a keyfile - * e.g. { 'account': 'fred@example.com', 'password': 'foo' } - * keys of @parameters and @escaped_parameters are disjoint */ - GHashTable *escaped_parameters; - /* reffed */ - McpAccountStorage *plugin; -} McdStorageAccount; - -static void -mcd_storage_account_free (gpointer p) -{ - McdStorageAccount *sa = p; - - g_hash_table_unref (sa->attributes); - g_hash_table_unref (sa->parameters); - g_hash_table_unref (sa->escaped_parameters); - g_object_unref (sa->plugin); - g_slice_free (McdStorageAccount, sa); -} - static void mcd_storage_init (McdStorage *self) { self->accounts = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, mcd_storage_account_free); + g_free, g_object_unref); } static void @@ -199,31 +172,6 @@ mcd_keyfile_escape_variant (GVariant *variant) return ret; } -static McdStorageAccount * -lookup_account (McdStorage *self, - const gchar *account) -{ - return g_hash_table_lookup (self->accounts, account); -} - -static McdStorageAccount * -mcd_storage_account_new (McpAccountStorage *plugin, - const gchar *account) -{ - McdStorageAccount *sa; - - sa = g_slice_new (McdStorageAccount); - sa->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_variant_unref); - sa->parameters = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_variant_unref); - sa->escaped_parameters = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - sa->plugin = g_object_ref (plugin); - - return sa; -} - static struct { const gchar *type; const gchar *name; @@ -335,104 +283,6 @@ mcd_storage_init_value_for_attribute (GValue *value, return FALSE; } -static void -mcpa_set_attribute (const McpAccountManager *ma, - const gchar *account, - const gchar *attribute, - GVariant *value, - McpAttributeFlags flags) -{ - McdStorage *self = MCD_STORAGE (ma); - McdStorageAccount *sa = lookup_account (self, account); - - g_return_if_fail (sa != NULL); - - if (value != NULL) - { - g_hash_table_insert (sa->attributes, g_strdup (attribute), - g_variant_ref_sink (value)); - } - else - { - g_hash_table_remove (sa->attributes, attribute); - } -} - -static void -mcpa_set_parameter (const McpAccountManager *ma, - const gchar *account, - const gchar *parameter, - GVariant *value, - McpParameterFlags flags) -{ - McdStorage *self = MCD_STORAGE (ma); - McdStorageAccount *sa = lookup_account (self, account); - - g_return_if_fail (sa != NULL); - - g_hash_table_remove (sa->parameters, parameter); - g_hash_table_remove (sa->escaped_parameters, parameter); - - if (value != NULL) - g_hash_table_insert (sa->parameters, g_strdup (parameter), - g_variant_ref_sink (value)); -} - -static void -set_value (const McpAccountManager *ma, - const gchar *account, - const gchar *key, - const gchar *value) -{ - McdStorage *self = MCD_STORAGE (ma); - McdStorageAccount *sa = lookup_account (self, account); - - g_return_if_fail (sa != NULL); - - if (g_str_has_prefix (key, "param-")) - { - g_hash_table_remove (sa->parameters, key + 6); - g_hash_table_remove (sa->escaped_parameters, key + 6); - - if (value != NULL) - g_hash_table_insert (sa->escaped_parameters, g_strdup (key + 6), - g_strdup (value)); - } - else - { - if (value != NULL) - { - GValue tmp = G_VALUE_INIT; - GError *error = NULL; - - if (!mcd_storage_init_value_for_attribute (&tmp, key, NULL)) - { - g_warning ("Not sure what the type of '%s' is, assuming string", - key); - g_value_init (&tmp, G_TYPE_STRING); - } - - if (mcd_keyfile_unescape_value (value, &tmp, &error)) - { - g_hash_table_insert (sa->attributes, g_strdup (key), - g_variant_ref_sink (dbus_g_value_build_g_variant (&tmp))); - g_value_unset (&tmp); - } - else - { - g_warning ("Could not decode attribute '%s':'%s' from plugin: %s", - key, value, error->message); - g_error_free (error); - g_hash_table_remove (sa->attributes, key); - } - } - else - { - g_hash_table_remove (sa->attributes, key); - } - } -} - static gchar * unique_name (const McpAccountManager *ma, const gchar *manager, @@ -698,16 +548,13 @@ mcd_storage_dup_accounts (McdStorage *self, { GPtrArray *ret = g_ptr_array_new (); GHashTableIter iter; - gpointer k, v; + gpointer k; g_hash_table_iter_init (&iter, self->accounts); - while (g_hash_table_iter_next (&iter, &k, &v)) + while (g_hash_table_iter_next (&iter, &k, NULL)) { - McdStorageAccount *sa = v; - - if (g_hash_table_size (sa->attributes) > 0) - g_ptr_array_add (ret, g_strdup (k)); + g_ptr_array_add (ret, g_strdup (k)); } g_ptr_array_add (ret, NULL); @@ -731,15 +578,15 @@ McpAccountStorage * mcd_storage_get_plugin (McdStorage *self, const gchar *account) { - McdStorageAccount *sa; + McpAccountStorage *plugin; g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); g_return_val_if_fail (account != NULL, NULL); - sa = lookup_account (self, account); - g_return_val_if_fail (account != NULL, NULL); + plugin = g_hash_table_lookup (self->accounts, account); + g_return_val_if_fail (plugin != NULL, NULL); - return sa->plugin; + return plugin; } /* @@ -818,33 +665,38 @@ mcd_storage_get_attribute (McdStorage *self, GValue *value, GError **error) { - McdStorageAccount *sa; + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + McpAccountStorage *plugin; GVariant *variant; + gboolean ret; g_return_val_if_fail (MCD_IS_STORAGE (self), FALSE); g_return_val_if_fail (account != NULL, FALSE); g_return_val_if_fail (attribute != NULL, FALSE); g_return_val_if_fail (!g_str_has_prefix (attribute, "param-"), FALSE); - sa = lookup_account (self, account); + plugin = g_hash_table_lookup (self->accounts, account); - if (sa == NULL) + if (plugin == NULL) { g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Account %s does not exist", account); return FALSE; } - variant = g_hash_table_lookup (sa->attributes, attribute); + variant = mcp_account_storage_get_attribute (plugin, ma, account, + attribute, type, NULL); if (variant == NULL) { g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "Setting '%s' not stored by account %s", attribute, account); + "Account %s has no attribute '%s'", account, attribute); return FALSE; } - return mcd_storage_coerce_variant_to_value (variant, value, error); + ret = mcd_storage_coerce_variant_to_value (variant, value, error); + g_variant_unref (variant); + return ret; } /* @@ -863,40 +715,38 @@ mcd_storage_get_parameter (McdStorage *self, GValue *value, GError **error) { - McdStorageAccount *sa; - const gchar *escaped; + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + McpAccountStorage *plugin; GVariant *variant; + gboolean ret; g_return_val_if_fail (MCD_IS_STORAGE (self), FALSE); g_return_val_if_fail (account != NULL, FALSE); g_return_val_if_fail (parameter != NULL, FALSE); + g_return_val_if_fail (!g_str_has_prefix (parameter, "param-"), FALSE); - sa = lookup_account (self, account); + plugin = g_hash_table_lookup (self->accounts, account); - if (sa == NULL) + if (plugin == NULL) { g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Account %s does not exist", account); return FALSE; } - variant = g_hash_table_lookup (sa->parameters, parameter); + variant = mcp_account_storage_get_parameter (plugin, ma, account, + parameter, type, NULL); - if (variant != NULL) - return mcd_storage_coerce_variant_to_value (variant, value, error); - - /* OK, we don't have it as a variant. How about the keyfile-escaped - * version? */ - escaped = g_hash_table_lookup (sa->escaped_parameters, parameter); - - if (escaped == NULL) + if (variant == NULL) { g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "Parameter '%s' not stored by account %s", parameter, account); + "Account %s has no parameter '%s'", account, parameter); return FALSE; } - return mcd_keyfile_unescape_value (escaped, value, error); + ret = mcd_storage_coerce_variant_to_value (variant, value, error); + g_variant_unref (variant); + return ret; } /* @@ -1508,29 +1358,23 @@ mcd_storage_set_attribute (McdStorage *self, const gchar *attribute, const GValue *value) { - McdStorageAccount *sa; GVariant *new_v; gboolean updated = FALSE; + McpAccountStorage *plugin; g_return_val_if_fail (MCD_IS_STORAGE (self), FALSE); g_return_val_if_fail (account != NULL, FALSE); g_return_val_if_fail (attribute != NULL, FALSE); g_return_val_if_fail (!g_str_has_prefix (attribute, "param-"), FALSE); - sa = lookup_account (self, account); - g_return_val_if_fail (sa != NULL, FALSE); + plugin = g_hash_table_lookup (self->accounts, account); + g_return_val_if_fail (plugin != NULL, FALSE); if (value != NULL) new_v = g_variant_ref_sink (dbus_g_value_build_g_variant (value)); else new_v = NULL; - if (new_v != NULL) - g_hash_table_insert (sa->attributes, g_strdup (attribute), - g_variant_ref (new_v)); - else - g_hash_table_remove (sa->attributes, attribute); - updated = update_storage (self, account, FALSE, attribute, new_v); tp_clear_pointer (&new_v, g_variant_unref); @@ -1560,29 +1404,21 @@ mcd_storage_set_parameter (McdStorage *self, const GValue *value) { GVariant *new_v = NULL; - McdStorageAccount *sa; gboolean updated = FALSE; + McpAccountStorage *plugin; g_return_val_if_fail (MCD_IS_STORAGE (self), FALSE); g_return_val_if_fail (account != NULL, FALSE); g_return_val_if_fail (parameter != NULL, FALSE); - sa = lookup_account (self, account); - g_return_val_if_fail (sa != NULL, FALSE); + plugin = g_hash_table_lookup (self->accounts, account); + g_return_val_if_fail (plugin != NULL, FALSE); if (value != NULL) { new_v = g_variant_ref_sink (dbus_g_value_build_g_variant (value)); } - g_hash_table_remove (sa->escaped_parameters, parameter); - - if (new_v != NULL) - g_hash_table_insert (sa->parameters, g_strdup (parameter), - g_variant_ref (new_v)); - else - g_hash_table_remove (sa->parameters, parameter); - updated = update_storage (self, account, TRUE, parameter, new_v); tp_clear_pointer (&new_v, g_variant_unref); @@ -2118,9 +1954,6 @@ plugin_iface_init (McpAccountManagerIface *iface, { DEBUG (); - iface->set_value = set_value; - iface->set_attribute = mcpa_set_attribute; - iface->set_parameter = mcpa_set_parameter; iface->unique_name = unique_name; iface->identify_account_async = identify_account_async; iface->identify_account_finish = identify_account_finish; @@ -2134,32 +1967,20 @@ mcd_storage_add_account_from_plugin (McdStorage *self, const gchar *account, GError **error) { - McdStorageAccount *sa = lookup_account (self, account); + McpAccountStorage *other = g_hash_table_lookup (self->accounts, account); - if (sa != NULL) + if (other != NULL) { g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "account %s already exists in plugin '%s', cannot create " "for plugin '%s'", account, - mcp_account_storage_name (sa->plugin), + mcp_account_storage_name (other), mcp_account_storage_name (plugin)); return FALSE; } g_hash_table_insert (self->accounts, g_strdup (account), - mcd_storage_account_new (plugin, account)); - - if (!mcp_account_storage_get (plugin, MCP_ACCOUNT_MANAGER (self), - account, NULL)) - { - g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, - "plugin '%s' denied any knowledge of account %s", - mcp_account_storage_name (plugin), - account); - g_hash_table_remove (self->accounts, account); - return FALSE; - } - + g_object_ref (plugin)); return TRUE; } diff --git a/src/mcd-storage.h b/src/mcd-storage.h index be0d0aa4..d78b595ba 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -30,7 +30,7 @@ G_BEGIN_DECLS typedef struct { GObject parent; TpDBusDaemon *dbusd; - /* owned string => owned McdStorageAccount */ + /* owned string => owned McpAccountStorage */ GHashTable *accounts; } McdStorage; diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 7eaccc37..9e0025ae 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -443,8 +443,6 @@ test_dbus_account_plugin_process_attributes (TestDBusAccountPlugin *self, g_hash_table_insert (account->attributes, g_strdup (attr), g_variant_ref (value)); - mcp_account_manager_set_attribute (self->feedback, - account_name, attr, value, flags); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, attr); @@ -468,8 +466,6 @@ test_dbus_account_plugin_process_attributes (TestDBusAccountPlugin *self, DEBUG ("%s deleted", attr); g_hash_table_remove (account->attributes, attr); - mcp_account_manager_set_attribute (self->feedback, - account_name, attr, NULL, 0); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, attr); @@ -552,8 +548,6 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, g_hash_table_insert (account->parameters, g_strdup (param), g_variant_ref (value)); key = g_strdup_printf ("param-%s", param); - mcp_account_manager_set_parameter (self->feedback, - account_name, param, value, flags); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, key); g_free (key); @@ -585,8 +579,6 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, g_hash_table_insert (account->untyped_parameters, g_strdup (param), g_strdup (escaped)); key = g_strdup_printf ("param-%s", param); - mcp_account_manager_set_value (self->feedback, - account_name, key, escaped); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, key); g_free (key); @@ -616,8 +608,6 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, g_hash_table_remove (account->untyped_parameters, param); key = g_strdup_printf ("param-%s", param); - mcp_account_manager_set_parameter (self->feedback, - account_name, param, NULL, 0); mcp_account_storage_emit_altered_one ( MCP_ACCOUNT_STORAGE (self), account_name, key); g_free (key); @@ -964,123 +954,81 @@ test_dbus_account_plugin_delete_finish (McpAccountStorage *storage, return g_task_propagate_boolean (G_TASK (res), error); } -static gboolean -test_dbus_account_plugin_get (const McpAccountStorage *storage, - const McpAccountManager *am, +static GVariant * +test_dbus_account_plugin_get_attribute (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account_name, - const gchar *key) + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); + GVariant *v; - if (!self->active || account == NULL) - return FALSE; - - if (key == NULL) - { - GHashTableIter iter; - gpointer k, v; - - /* get everything */ - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "GetAllKeys", - g_variant_new_parsed ("(%o,)", account->path), NULL); - - g_hash_table_iter_init (&iter, account->attributes); + if (flags != NULL) + *flags = 0; - while (g_hash_table_iter_next (&iter, &k, &v)) - { - gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, - v); - - mcp_account_manager_set_value (am, account_name, k, escaped); - g_free (escaped); - } + if (!self->active || account == NULL) + return NULL; - g_hash_table_iter_init (&iter, account->untyped_parameters); + v = g_hash_table_lookup (account->attributes, attribute); - while (g_hash_table_iter_next (&iter, &k, &v)) - { - gchar *param_foo; + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "GetAttribute", + g_variant_new_parsed ("(%o, %s)", account->path, attribute), NULL); - param_foo = g_strdup_printf ("param-%s", (const gchar *) k); - mcp_account_manager_set_value (am, account_name, param_foo, v); + if (v != NULL) + { + return g_variant_ref (v); + } + else + { + return NULL; + } +} - g_free (param_foo); - } +static GVariant * +test_dbus_account_plugin_get_parameter (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name, + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags) +{ + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); + Account *account = lookup_account (self, account_name); + GVariant *v; + const gchar *s; - g_hash_table_iter_init (&iter, account->parameters); + if (flags != NULL) + *flags = 0; - while (g_hash_table_iter_next (&iter, &k, &v)) - { - gchar *param_foo; - gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, - v); + if (!self->active || account == NULL) + return NULL; - param_foo = g_strdup_printf ("param-%s", (const gchar *) k); - mcp_account_manager_set_value (am, account_name, param_foo, escaped); - g_free (escaped); + g_dbus_connection_emit_signal (self->bus, NULL, + TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, + "GetParameter", + g_variant_new_parsed ("(%o, %s)", account->path, parameter), NULL); - g_free (param_foo); - } + v = g_hash_table_lookup (account->parameters, parameter); + s = g_hash_table_lookup (account->untyped_parameters, parameter); - return TRUE; + if (v != NULL) + { + return g_variant_ref (v); } - - /* get one parameter */ - - if (g_str_has_prefix (key, "param-")) + else if (s != NULL) { - GVariant *v = g_hash_table_lookup (account->parameters, key + 6); - const gchar *s = g_hash_table_lookup (account->untyped_parameters, key + 6); - - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "GetParameter", - g_variant_new_parsed ("(%o, %s)", account->path, key + 6), NULL); - - if (v != NULL) - { - gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, - v); - - mcp_account_manager_set_value (am, account_name, key, escaped); - g_free (escaped); - } - else if (s != NULL) - { - mcp_account_manager_set_value (am, account_name, key, s); - } - else - { - return FALSE; - } + return mcp_account_manager_unescape_variant_from_keyfile (am, + s, type, NULL); } else { - GVariant *v = g_hash_table_lookup (account->attributes, key); - - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "GetAttribute", - g_variant_new_parsed ("(%o, %s)", account->path, key), NULL); - - if (v != NULL) - { - gchar *escaped = mcp_account_manager_escape_variant_for_keyfile (am, - v); - - mcp_account_manager_set_value (am, account_name, key, escaped); - g_free (escaped); - } - else - { - return FALSE; - } + return NULL; } - - return TRUE; } static McpAccountStorageSetResult @@ -1586,7 +1534,8 @@ account_storage_iface_init (McpAccountStorageIface *iface) /* this should be higher priority than the diverted-keyfile one */ iface->priority = MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_NORMAL + 100; - iface->get = test_dbus_account_plugin_get; + iface->get_attribute = test_dbus_account_plugin_get_attribute; + iface->get_parameter = test_dbus_account_plugin_get_parameter; iface->set_attribute = test_dbus_account_plugin_set_attribute; iface->set_parameter = test_dbus_account_plugin_set_parameter; iface->list = test_dbus_account_plugin_list; diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index 7bba5d8f..11c7caa9 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -197,47 +197,57 @@ _set_parameter (McpAccountStorage *self, return ret; } -static gboolean -_get (const McpAccountStorage *self, - const McpAccountManager *am, +static GVariant * +_get_attribute (McpAccountStorage *self, + McpAccountManager *am, const gchar *account, - const gchar *key) + const gchar *attribute, + const GVariantType *type, + McpAttributeFlags *flags) { AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + gchar *v; + GVariant *ret; - if (key != NULL) - { - gchar *v = g_key_file_get_value (adp->keyfile, account, key, NULL); + if (flags != NULL) + *flags = 0; - if (v == NULL) - return FALSE; + v = g_key_file_get_value (adp->keyfile, account, attribute, NULL); - mcp_account_manager_set_value (am, account, key, v); - g_free (v); - } - else - { - gsize i; - gsize n; - GStrv keys = g_key_file_get_keys (adp->keyfile, account, &n, NULL); + if (v == NULL) + return NULL; - if (keys == NULL) - n = 0; + ret = mcp_account_manager_unescape_variant_from_keyfile (am, v, type, NULL); + g_free (v); + return ret; +} - for (i = 0; i < n; i++) - { - gchar *v = g_key_file_get_value (adp->keyfile, account, keys[i], NULL); +static GVariant * +_get_parameter (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account, + const gchar *parameter, + const GVariantType *type, + McpParameterFlags *flags) +{ + AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); + gchar *key; + gchar *v; + GVariant *ret; - if (v != NULL) - mcp_account_manager_set_value (am, account, keys[i], v); + if (flags != NULL) + *flags = 0; - g_free (v); - } + key = g_strdup_printf ("param-%s", parameter); + v = g_key_file_get_value (adp->keyfile, account, key, NULL); + g_free (key); - g_strfreev (keys); - } + if (v == NULL) + return NULL; - return TRUE; + ret = mcp_account_manager_unescape_variant_from_keyfile (am, v, type, NULL); + g_free (v); + return ret; } static gboolean _commit (const McpAccountStorage *self, @@ -371,7 +381,8 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->desc = PLUGIN_DESCRIPTION; iface->priority = PLUGIN_PRIORITY; - iface->get = _get; + iface->get_attribute = _get_attribute; + iface->get_parameter = _get_parameter; iface->set_attribute = _set_attribute; iface->set_parameter = _set_parameter; iface->delete_async = delete_async; -- cgit v1.2.3 From 1e1ba5f4fef9ee83411d55e376f0f5fec0a6e892 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 16:51:37 +0000 Subject: McdStorage: when acting on one account, only store it in its plugin Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 68 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index dffc498f..07d07f3d 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1245,13 +1245,14 @@ update_storage (McdStorage *self, const gchar *key, GVariant *variant) { - GList *store; McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); gboolean updated = FALSE; + McpAccountStorage *plugin; - for (store = stores; store != NULL; store = g_list_next (store)) + plugin = g_hash_table_lookup (self->accounts, account); + + if (plugin != NULL) { - McpAccountStorage *plugin = store->data; const gchar *pn = mcp_account_storage_name (plugin); McpAccountStorageSetResult res; @@ -1268,8 +1269,6 @@ update_storage (McdStorage *self, DEBUG ("MCP:%s -> store %s %s.%s", pn, parameter ? "parameter" : "attribute", account, key); updated = TRUE; - /* set it to NULL in all lower-priority stores */ - variant = NULL; break; case MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED: @@ -1286,6 +1285,10 @@ update_storage (McdStorage *self, g_warn_if_reached (); } } + else + { + g_assert_not_reached (); + } return updated; } @@ -1809,24 +1812,29 @@ void mcd_storage_delete_account (McdStorage *self, const gchar *account) { - GList *store; McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + McpAccountStorage *plugin; g_return_if_fail (MCD_IS_STORAGE (self)); g_return_if_fail (account != NULL); - g_hash_table_remove (self->accounts, account); + plugin = g_hash_table_lookup (self->accounts, account); - for (store = stores; store != NULL; store = g_list_next (store)) + if (plugin == NULL) { - McpAccountStorage *plugin = store->data; - - /* FIXME: when we know which plugin owns the account, we can stop - * ignoring the error (if any), and make this method async - * in order to pass the error up to McdAccount */ - mcp_account_storage_delete_async (plugin, ma, account, - delete_cb, g_strdup (account)); + /* we wanted no account, we got no account, I call that success! */ + return; } + + g_object_ref (plugin); + g_hash_table_remove (self->accounts, account); + + /* FIXME: stop ignoring the error (if any), and make this method async + * in order to pass the error up to McdAccount */ + mcp_account_storage_delete_async (plugin, ma, account, + delete_cb, g_strdup (account)); + + g_object_unref (plugin); } /* @@ -1842,24 +1850,30 @@ mcd_storage_commit (McdStorage *self, const gchar *account) { GList *store; McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + McpAccountStorage *plugin; + const gchar *pname; g_return_if_fail (MCD_IS_STORAGE (self)); + if (account != NULL) + { + plugin = g_hash_table_lookup (self->accounts, account); + g_return_val_if_fail (plugin != NULL, FALSE); + + pname = mcp_account_storage_name (plugin); + + DEBUG ("flushing plugin %s %s to long term storage", pname, account); + mcp_account_storage_commit (plugin, ma, account); + return; + } + for (store = stores; store != NULL; store = g_list_next (store)) { - McpAccountStorage *plugin = store->data; - const gchar *pname = mcp_account_storage_name (plugin); + plugin = store->data; + pname = mcp_account_storage_name (plugin); - if (account != NULL) - { - DEBUG ("flushing plugin %s %s to long term storage", pname, account); - mcp_account_storage_commit (plugin, ma, account); - } - else - { - DEBUG ("flushing plugin %s to long term storage", pname); - mcp_account_storage_commit (plugin, ma, NULL); - } + DEBUG ("flushing plugin %s to long term storage", pname); + mcp_account_storage_commit (plugin, ma, NULL); } } -- cgit v1.2.3 From d19d7d0998c872e9288c864b511c6297651498eb Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 29 Jan 2014 14:34:12 +0000 Subject: McdAccount: have a ref to the storage plugin from construct time onwards This will make the account more self-contained. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 74 +++++++++++++++++++++-------------- src/mcd-account.c | 99 ++++++++++++++--------------------------------- src/mcd-account.h | 5 ++- src/mcd-storage.c | 36 ++++++++--------- src/mcd-storage.h | 3 +- 5 files changed, 98 insertions(+), 119 deletions(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 0939015c..cf9ce6be 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -110,6 +110,7 @@ typedef struct gchar *cm_name; gchar *protocol_name; gchar *display_name; + gchar *provider; GHashTable *parameters; GHashTable *properties; McdGetAccountCb callback; @@ -282,7 +283,7 @@ created_cb (GObject *storage_plugin_obj, /* actually fetch the data into our cache from the plugin: */ if (mcd_storage_add_account_from_plugin (storage, plugin, name, &error)) { - account = mcd_account_new (am, name, priv->minotaur); + account = mcd_account_new (am, name, priv->minotaur, plugin); g_assert (MCD_IS_ACCOUNT (account)); lad = g_slice_new (McdLoadAccountsData); @@ -686,6 +687,7 @@ mcd_create_account_data_free (McdCreateAccountData *cad) if (cad->destroy != NULL) cad->destroy (cad->user_data); + g_free (cad->provider); g_free (cad->cm_name); g_free (cad->protocol_name); g_free (cad->display_name); @@ -831,10 +833,10 @@ identify_account_cb (GObject *source_object, { McdStorage *storage = MCD_STORAGE (source_object); McdCreateAccountData *cad = user_data; - const gchar *provider; gchar *id; gchar *unique_name; McdAccount *account; + McpAccountStorage *plugin; id = mcp_account_manager_identify_account_finish ( MCP_ACCOUNT_MANAGER (storage), result, &cad->error); @@ -846,12 +848,9 @@ identify_account_cb (GObject *source_object, return; } - provider = tp_asv_get_string (cad->properties, - TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER); - - unique_name = mcd_storage_create_account (storage, provider, + unique_name = mcd_storage_create_account (storage, cad->provider, cad->cm_name, cad->protocol_name, - id, &cad->error); + id, &plugin, &cad->error); if (unique_name == NULL) { @@ -874,8 +873,10 @@ identify_account_cb (GObject *source_object, cad->display_name); account = mcd_account_new (cad->account_manager, unique_name, - cad->account_manager->priv->minotaur); + cad->account_manager->priv->minotaur, + plugin); g_free (unique_name); + g_object_unref (plugin); if (G_LIKELY (account)) { @@ -918,18 +919,33 @@ _mcd_account_manager_create_account (McdAccountManager *account_manager, return; } - cad = g_slice_new (McdCreateAccountData); + cad = g_slice_new0 (McdCreateAccountData); cad->account_manager = account_manager; cad->cm_name = g_strdup (manager); cad->protocol_name = g_strdup (protocol); cad->display_name = g_strdup (display_name); cad->parameters = g_hash_table_ref (params); - cad->properties = (properties ? g_hash_table_ref (properties) : NULL); cad->callback = callback; cad->user_data = user_data; cad->destroy = destroy; cad->error = NULL; + if (properties != NULL) + { + cad->properties = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) tp_g_value_slice_free); + + tp_g_hash_table_update (cad->properties, properties, + (GBoxedCopyFunc) g_strdup, + (GBoxedCopyFunc) tp_g_value_slice_dup); + + /* special case: "construct-only" */ + cad->provider = g_strdup (tp_asv_get_string (cad->properties, + TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER)); + g_hash_table_remove (cad->properties, + TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER); + } + g_value_init (&value, TP_HASH_TYPE_STRING_VARIANT_MAP); g_value_set_static_boxed (&value, params); variant_params = dbus_g_value_build_g_variant (&value); @@ -1405,9 +1421,9 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) { McdAccountManagerPrivate *priv = account_manager->priv; McdStorage *storage = priv->storage; - gchar **accounts, **name; + GHashTable *accounts; GHashTableIter iter; - gpointer v; + gpointer k, v; /* for simplicity we don't support re-entrant setup */ g_return_if_fail (priv->setup_lock == 0); @@ -1418,29 +1434,35 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) list_connection_names_cb, NULL, NULL, (GObject *)account_manager); - accounts = mcd_storage_dup_accounts (storage, NULL); + accounts = mcd_storage_get_accounts (storage); + g_hash_table_iter_init (&iter, accounts); - for (name = accounts; *name != NULL; name++) + while (g_hash_table_iter_next (&iter, &k, &v)) { gboolean plausible = FALSE; const gchar *manager = NULL; const gchar *protocol = NULL; + const gchar *account_name = k; + McpAccountStorage *plugin = v; McdAccount *account = mcd_account_manager_lookup_account ( - account_manager, *name); + account_manager, account_name); if (account != NULL) { - /* FIXME: this shouldn't really happen */ - DEBUG ("already have account %p called '%s'; skipping", account, *name); + /* FIXME: can't happen? We shouldn't create any accounts before + * we got here, and there can't be any duplicates in @accounts */ + DEBUG ("already have account %p called '%s'; skipping", + account, account_name); continue; } - account = mcd_account_new (account_manager, *name, priv->minotaur); + account = mcd_account_new (account_manager, account_name, + priv->minotaur, plugin); if (G_UNLIKELY (!account)) { g_warning ("%s: account %s failed to instantiate", G_STRFUNC, - *name); + account_name); continue; } @@ -1455,7 +1477,7 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) const gchar *dbg_protocol = (protocol == NULL) ? "(nil)" : protocol; g_warning ("%s: account %s has implausible manager/protocol: %s/%s", - G_STRFUNC, *name, dbg_manager, dbg_protocol); + G_STRFUNC, account_name, dbg_manager, dbg_protocol); g_object_unref (account); continue; } @@ -1466,7 +1488,8 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) g_object_ref (account_manager)); g_object_unref (account); } - g_strfreev (accounts); + + g_hash_table_unref (accounts); uncork_storage_plugins (account_manager); @@ -1753,15 +1776,8 @@ mcd_account_manager_write_conf_async (McdAccountManager *account_manager, } else { - GStrv groups; - gsize n_accounts = 0; - - groups = mcd_storage_dup_accounts (storage, &n_accounts); - DEBUG ("updating all %" G_GSIZE_FORMAT " accounts", n_accounts); - + DEBUG ("updating all accounts"); mcd_storage_commit (storage, NULL); - - g_strfreev (groups); } if (callback != NULL) diff --git a/src/mcd-account.c b/src/mcd-account.c index 1a75adcb..1b997bd0 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -181,6 +181,7 @@ enum PROP_DBUS_DAEMON, PROP_CONNECTIVITY_MONITOR, PROP_STORAGE, + PROP_STORAGE_PLUGIN, PROP_NAME, }; @@ -2092,58 +2093,16 @@ get_supersedes (TpSvcDBusProperties *svc, g_value_set_boxed (value, self->priv->supersedes); } -static McpAccountStorage * -get_storage_plugin (McdAccount *account) -{ - McdAccountPrivate *priv = account->priv; - const gchar *account_name = mcd_account_get_unique_name (account); - - if (priv->storage_plugin != NULL) - return priv->storage_plugin; - - priv->storage_plugin = mcd_storage_get_plugin (priv->storage, account_name); - - if (priv->storage_plugin != NULL) - g_object_ref (priv->storage_plugin); - - return priv->storage_plugin; -} - static void get_storage_provider (TpSvcDBusProperties *self, const gchar *name, GValue *value) { McdAccount *account = MCD_ACCOUNT (self); - McpAccountStorage *storage_plugin = get_storage_plugin (account); g_value_init (value, G_TYPE_STRING); - if (storage_plugin != NULL) - g_value_set_string (value, mcp_account_storage_provider (storage_plugin)); - else - g_value_set_static_string (value, ""); -} - -static gboolean -set_storage_provider (TpSvcDBusProperties *self, - const gchar *name, - const GValue *value, - McdDBusPropSetFlags flags, - GError **error) -{ - McdAccount *account = MCD_ACCOUNT (self); - McpAccountStorage *storage_plugin = get_storage_plugin (account); - const gchar *current_provider = mcp_account_storage_provider (storage_plugin); - - if (!G_VALUE_HOLDS_STRING (value) || - tp_strdiff (g_value_get_string (value), current_provider)) - { - g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "Cannot change provider, it is defined at account creation only"); - return FALSE; - } - - return TRUE; + g_value_set_string (value, + mcp_account_storage_provider (account->priv->storage_plugin)); } static void @@ -2152,22 +2111,13 @@ get_storage_identifier (TpSvcDBusProperties *self, { McdAccount *account = MCD_ACCOUNT (self); - McpAccountStorage *storage_plugin = get_storage_plugin (account); GValue identifier = G_VALUE_INIT; g_value_init (value, G_TYPE_VALUE); - if (storage_plugin != NULL) - { - mcp_account_storage_get_identifier ( - storage_plugin, account->priv->unique_name, &identifier); - } - else - { - g_value_init (&identifier, G_TYPE_UINT); - - g_value_set_uint (&identifier, 0); - } + mcp_account_storage_get_identifier ( + account->priv->storage_plugin, account->priv->unique_name, + &identifier); g_value_set_boxed (value, &identifier); @@ -2180,15 +2130,11 @@ get_storage_specific_info (TpSvcDBusProperties *self, { GHashTable *storage_specific_info; McdAccount *account = MCD_ACCOUNT (self); - McpAccountStorage *storage_plugin = get_storage_plugin (account); g_value_init (value, TP_HASH_TYPE_STRING_VARIANT_MAP); - if (storage_plugin != NULL) - storage_specific_info = mcp_account_storage_get_additional_info ( - storage_plugin, account->priv->unique_name); - else - storage_specific_info = g_hash_table_new (g_str_hash, g_str_equal); + storage_specific_info = mcp_account_storage_get_additional_info ( + account->priv->storage_plugin, account->priv->unique_name); g_value_take_boxed (value, storage_specific_info); } @@ -2196,11 +2142,7 @@ get_storage_specific_info (TpSvcDBusProperties *self, 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, + return mcp_account_storage_get_restrictions (self->priv->storage_plugin, self->priv->unique_name); } @@ -2244,7 +2186,7 @@ static const McdDBusProp account_avatar_properties[] = { }; static const McdDBusProp account_storage_properties[] = { - { "StorageProvider", set_storage_provider, get_storage_provider }, + { "StorageProvider", NULL, get_storage_provider }, { "StorageIdentifier", NULL, get_storage_identifier }, { "StorageSpecificInformation", NULL, get_storage_specific_info }, { "StorageRestrictions", NULL, get_storage_restrictions }, @@ -3457,6 +3399,11 @@ set_property (GObject *obj, guint prop_id, priv->storage = g_value_dup_object (val); break; + case PROP_STORAGE_PLUGIN: + g_assert (priv->storage_plugin == NULL); + priv->storage_plugin = g_value_dup_object (val); + break; + case PROP_DBUS_DAEMON: g_assert (priv->dbus_daemon == NULL); priv->dbus_daemon = g_value_dup_object (val); @@ -3720,6 +3667,12 @@ mcd_account_class_init (McdAccountClass * klass) "storage", MCD_TYPE_STORAGE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property + (object_class, PROP_STORAGE_PLUGIN, + g_param_spec_object ("storage-plugin", "storage-plugin", + "Storage plugin", MCP_TYPE_ACCOUNT_STORAGE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_NAME, g_param_spec_string ("name", "Unique name", "Unique name", @@ -3796,7 +3749,8 @@ mcd_account_init (McdAccount *account) McdAccount * mcd_account_new (McdAccountManager *account_manager, const gchar *name, - McdConnectivityMonitor *connectivity) + McdConnectivityMonitor *connectivity, + McpAccountStorage *storage_plugin) { gpointer *obj; McdStorage *storage = mcd_account_manager_get_storage (account_manager); @@ -3804,6 +3758,7 @@ mcd_account_new (McdAccountManager *account_manager, obj = g_object_new (MCD_TYPE_ACCOUNT, "storage", storage, + "storage-plugin", storage_plugin, "dbus-daemon", dbus, "connectivity-monitor", connectivity, "name", name, @@ -3817,6 +3772,12 @@ _mcd_account_get_storage (McdAccount *account) return account->priv->storage; } +McpAccountStorage * +mcd_account_get_storage_plugin (McdAccount *account) +{ + return account->priv->storage_plugin; +} + /* * mcd_account_is_valid: * @account: the #McdAccount. diff --git a/src/mcd-account.h b/src/mcd-account.h index 6dce6496..a0b29afb 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -80,7 +80,8 @@ GType mcd_account_get_type (void); McdAccount *mcd_account_new (McdAccountManager *account_manager, const gchar *name, - McdConnectivityMonitor *minotaur); + McdConnectivityMonitor *minotaur, + McpAccountStorage *storage_plugin); void mcd_account_delete_async (McdAccount *account, McdDBusPropSetFlags flags, @@ -159,6 +160,8 @@ void mcd_account_connection_proceed (McdAccount *account, gboolean success); void mcd_account_connection_proceed_with_reason (McdAccount *account, gboolean success, TpConnectionStatusReason reason); +McpAccountStorage *mcd_account_get_storage_plugin (McdAccount *account); + G_END_DECLS #endif diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 07d07f3d..978c12db 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -535,30 +535,17 @@ mcd_storage_load (McdStorage *self) } /* - * mcd_storage_dup_accounts: + * mcd_storage_get_accounts: * @storage: An object implementing the #McdStorage interface * @n: place for the number of accounts to be written to (or %NULL) * - * Returns: a newly allocated GStrv containing the unique account names, - * which must be freed by the caller with g_strfreev(). + * Returns: (transfer container) (element-type utf8 Mcp.AccountStorage): a + * map from account object path tail to plugin */ -GStrv -mcd_storage_dup_accounts (McdStorage *self, - gsize *n) +GHashTable * +mcd_storage_get_accounts (McdStorage *self) { - GPtrArray *ret = g_ptr_array_new (); - GHashTableIter iter; - gpointer k; - - g_hash_table_iter_init (&iter, self->accounts); - - while (g_hash_table_iter_next (&iter, &k, NULL)) - { - g_ptr_array_add (ret, g_strdup (k)); - } - - g_ptr_array_add (ret, NULL); - return (GStrv) g_ptr_array_free (ret, FALSE); + return g_hash_table_ref (self->accounts); } /* @@ -1684,6 +1671,7 @@ mcd_keyfile_set_variant (GKeyFile *keyfile, * @manager: the name of the manager * @protocol: the name of the protocol * @identification: the result of IdentifyAccount + * @plugin_out: (out) (transfer full): the plugin we used * @error: a #GError to fill when returning %NULL * * Create a new account in storage. This should not store any @@ -1699,12 +1687,16 @@ mcd_storage_create_account (McdStorage *self, const gchar *manager, const gchar *protocol, const gchar *identification, + McpAccountStorage **plugin_out, GError **error) { GList *store; McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); gchar *ret; + if (plugin_out != NULL) + *plugin_out = NULL; + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); g_return_val_if_fail (!tp_str_empty (manager), NULL); g_return_val_if_fail (!tp_str_empty (protocol), NULL); @@ -1723,6 +1715,9 @@ mcd_storage_create_account (McdStorage *self, if (mcd_storage_add_account_from_plugin (self, plugin, ret, error)) { + if (plugin_out != NULL) + *plugin_out = g_object_ref (plugin); + return ret; } else @@ -1754,6 +1749,9 @@ mcd_storage_create_account (McdStorage *self, if (mcd_storage_add_account_from_plugin (self, plugin, ret, error)) { + if (plugin_out != NULL) + *plugin_out = g_object_ref (plugin); + return ret; } else diff --git a/src/mcd-storage.h b/src/mcd-storage.h index d78b595ba..c2624a40 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -64,7 +64,7 @@ void mcd_storage_connect_signal (const gchar *signal, void mcd_storage_load (McdStorage *storage); -GStrv mcd_storage_dup_accounts (McdStorage *storage, gsize *n); +GHashTable *mcd_storage_get_accounts (McdStorage *storage); gboolean mcd_storage_set_string (McdStorage *storage, const gchar *account, @@ -91,6 +91,7 @@ gchar *mcd_storage_create_account (McdStorage *storage, const gchar *manager, const gchar *protocol, const gchar *identification, + McpAccountStorage **plugin_out, GError **error); void mcd_storage_delete_account (McdStorage *storage, const gchar *account); -- cgit v1.2.3 From 5633f3ae27a762444bb7a487abfd1f4b2aeacbaf Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 29 Jan 2014 18:28:53 +0000 Subject: fixup! --- src/mcd-storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 978c12db..d43a8875 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1856,7 +1856,7 @@ mcd_storage_commit (McdStorage *self, const gchar *account) if (account != NULL) { plugin = g_hash_table_lookup (self->accounts, account); - g_return_val_if_fail (plugin != NULL, FALSE); + g_return_if_fail (plugin != NULL); pname = mcp_account_storage_name (plugin); -- cgit v1.2.3 From 5ec39a1c88cf74a1e81d65de66f084ff8d467e48 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 18:01:33 +0000 Subject: McdAccountManager: ignore altered-one, deleted, toggled from wrong plugin Now that the account knows its own storage plugin, this is pretty easy. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index cf9ce6be..54320c0a 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -177,7 +177,7 @@ async_altered_one_manager_cb (McdManager *cm, static void -altered_one_cb (GObject *storage, +altered_one_cb (McpAccountStorage *storage, const gchar *account_name, const gchar *key, gpointer data) @@ -187,6 +187,7 @@ altered_one_cb (GObject *storage, McdAccount *account = NULL; McdManager *cm = NULL; const gchar *cm_name = NULL; + McpAccountStorage *its_plugin; account = mcd_account_manager_lookup_account (am, account_name); @@ -196,6 +197,18 @@ altered_one_cb (GObject *storage, return; } + its_plugin = mcd_account_get_storage_plugin (account); + + if (storage != its_plugin) + { + DEBUG ("Ignoring altered-one from plugin %s because account %s " + "belongs to %s", + mcp_account_storage_name (storage), + account_name, + mcp_account_storage_name (its_plugin)); + return; + } + /* in theory, the CM is already ready by this point, but make sure: */ cm_name = mcd_account_get_manager_name (account); @@ -335,6 +348,7 @@ toggled_cb (GObject *plugin, const gchar *name, gboolean on, gpointer data) McdAccountManager *manager = MCD_ACCOUNT_MANAGER (data); McdAccount *account = NULL; GError *error = NULL; + McpAccountStorage *its_plugin; account = mcd_account_manager_lookup_account (manager, name); @@ -348,6 +362,18 @@ toggled_cb (GObject *plugin, const gchar *name, gboolean on, gpointer data) return; } + its_plugin = mcd_account_get_storage_plugin (account); + + if (storage_plugin != its_plugin) + { + DEBUG ("Ignoring toggled signal from plugin %s because account %s " + "belongs to %s", + mcp_account_storage_name (storage_plugin), + name, + mcp_account_storage_name (its_plugin)); + return; + } + _mcd_account_set_enabled (account, on, FALSE, MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE, &error); @@ -422,6 +448,18 @@ deleted_cb (GObject *plugin, const gchar *name, gpointer data) if (account != NULL) { const gchar * object_path = mcd_account_get_object_path (account); + McpAccountStorage *its_plugin = mcd_account_get_storage_plugin ( + account); + + if (storage_plugin != its_plugin) + { + DEBUG ("Ignoring altered-one from plugin %s because account %s " + "belongs to %s", + mcp_account_storage_name (storage_plugin), + name, + mcp_account_storage_name (its_plugin)); + return; + } g_object_ref (account); /* this unhooks the account's signal handlers */ -- cgit v1.2.3 From b95223939c82dbe7cd194a018e674c719f39de12 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:01:34 +0000 Subject: McpAccountStorage: overriding get_* and list is mandatory Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 39 ++++--------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 6ce8c725..625801d8 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -151,13 +151,6 @@ default_create (const McpAccountStorage *storage, return NULL; } -static GList * -default_list (const McpAccountStorage *storage, - const McpAccountManager *am) -{ - return NULL; -} - static void default_ready (const McpAccountStorage *storage, const McpAccountManager *am) @@ -188,28 +181,6 @@ default_get_restrictions (const McpAccountStorage *storage, return 0; } -static GVariant * -default_get_attribute (McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account, - const gchar *attribute, - const GVariantType *type, - McpAttributeFlags *flags) -{ - return NULL; -} - -static GVariant * -default_get_parameter (McpAccountStorage *storage, - McpAccountManager *am, - const gchar *account, - const gchar *parameter, - const GVariantType *type, - McpParameterFlags *flags) -{ - return NULL; -} - static McpAccountStorageSetResult default_set_attribute (McpAccountStorage *storage, McpAccountManager *am, @@ -243,13 +214,10 @@ class_init (gpointer klass, iface->delete_async = default_delete_async; iface->delete_finish = default_delete_finish; iface->commit = default_commit; - iface->list = default_list; iface->ready = default_ready; iface->get_identifier = default_get_identifier; iface->get_additional_info = default_get_additional_info; iface->get_restrictions = default_get_restrictions; - iface->get_attribute = default_get_attribute; - iface->get_parameter = default_get_parameter; iface->set_attribute = default_set_attribute; iface->set_parameter = default_set_parameter; @@ -468,7 +436,7 @@ mcp_account_storage_priority (const McpAccountStorage *storage) * * Retrieve an attribute. * - * There is a default implementation, which just returns %NULL. + * There is no default implementation. * All account storage plugins must override this method. * * The returned variant does not necessarily have to match @type: @@ -508,7 +476,7 @@ mcp_account_storage_get_attribute (McpAccountStorage *storage, * * Retrieve a parameter. * - * There is a default implementation, which just returns %NULL. + * There is no default implementation. * All account storage plugins must override this method. * * The returned variant does not necessarily have to match @type: @@ -819,7 +787,8 @@ mcp_account_storage_commit (const McpAccountStorage *storage, * This method is called only at initialisation time, before the dbus name * has been claimed, and is the only one permitted to block. * - * The default implementation returns %NULL, i.e. an empty list. + * There is no default implementation. All implementations of this interface + * must override this method. * * Returns: (element-type utf8) (transfer full): a list of account names that * the plugin has settings for. The account names should be freed with -- cgit v1.2.3 From 5aa409ec88b30dbadaba799cff44d3ddd978a94e Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:02:13 +0000 Subject: McpAccountStorage: override neither or both of delete_async, delete_finish Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 625801d8..678891ab 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -678,6 +678,9 @@ mcp_account_storage_create (const McpAccountStorage *storage, * * The default implementation just returns failure (asynchronously), * and is appropriate for read-only storage. + * + * Implementations that override delete_async must also override + * delete_finish. */ void mcp_account_storage_delete_async (McpAccountStorage *storage, -- cgit v1.2.3 From 812378a1064b35a54adb9dc992fe55ef7c5ddae5 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:12:53 +0000 Subject: McpAccountStorage: update documentation for delete_async Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 678891ab..a50b1bb2 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -56,7 +56,8 @@ * iface->desc = "The FOO storage backend"; * iface->provider = "org.freedesktop.Telepathy.MissionControl5.FooStorage"; * - * iface->delete = foo_plugin_delete; + * iface->delete_async = foo_plugin_delete_async; + * iface->delete_finish = foo_plugin_delete_finish; * iface->commit = foo_plugin_commit; * iface->list = foo_plugin_list; * iface->ready = foo_plugin_ready; -- cgit v1.2.3 From 4a56a04f6860d7d66f25398c410a1c6435c9dca7 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:13:36 +0000 Subject: mcp_account_storage_delete_async: be cancellable, at least in theory Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 3 +++ mission-control-plugins/account-storage.h | 2 ++ src/mcd-account-manager-default.c | 3 ++- src/mcd-storage.c | 2 +- tests/twisted/dbus-account-plugin.c | 3 ++- tests/twisted/mcp-account-diversion.c | 3 ++- 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index a50b1bb2..8d10ad6a 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -115,6 +115,7 @@ static void default_delete_async (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { @@ -666,6 +667,7 @@ mcp_account_storage_create (const McpAccountStorage *storage, * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance * @account: the unique name of the account + * @cancellable: (allow-none): optionally used to (try to) cancel the operation * @callback: called on success or failure * @user_data: data for @callback * @@ -687,6 +689,7 @@ void mcp_account_storage_delete_async (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 42898a5f..1a30b5ed 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -110,6 +110,7 @@ struct _McpAccountStorageIface void (*delete_async) (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); gboolean (*delete_finish) (McpAccountStorage *storage, @@ -163,6 +164,7 @@ gchar * mcp_account_storage_create (const McpAccountStorage *storage, void mcp_account_storage_delete_async (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); gboolean mcp_account_storage_delete_finish (McpAccountStorage *storage, diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index bac90ad3..db0ede9a 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -352,6 +352,7 @@ static void delete_async (McpAccountStorage *self, McpAccountManager *am, const gchar *account, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { @@ -361,7 +362,7 @@ delete_async (McpAccountStorage *self, gchar *filename = NULL; const gchar * const *iter; - task = g_task_new (amd, NULL, callback, user_data); + task = g_task_new (amd, cancellable, callback, user_data); if (sa == NULL || sa->absent) { diff --git a/src/mcd-storage.c b/src/mcd-storage.c index d43a8875..0ded3492 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1829,7 +1829,7 @@ mcd_storage_delete_account (McdStorage *self, /* FIXME: stop ignoring the error (if any), and make this method async * in order to pass the error up to McdAccount */ - mcp_account_storage_delete_async (plugin, ma, account, + mcp_account_storage_delete_async (plugin, ma, account, NULL, delete_cb, g_strdup (account)); g_object_unref (plugin); diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 9e0025ae..ea35c148 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -902,12 +902,13 @@ static void test_dbus_account_plugin_delete_async (McpAccountStorage *storage, McpAccountManager *am, const gchar *account_name, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); Account *account = lookup_account (self, account_name); - GTask *task = g_task_new (self, NULL, callback, user_data); + GTask *task = g_task_new (self, cancellable, callback, user_data); g_task_set_task_data (task, g_strdup (user_data), g_free); diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index 11c7caa9..bcb8930c 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -258,11 +258,12 @@ static void delete_async (McpAccountStorage *self, McpAccountManager *am, const gchar *account, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (self); - GTask *task = g_task_new (adp, NULL, callback, user_data); + GTask *task = g_task_new (adp, cancellable, callback, user_data); if (g_key_file_remove_group (adp->keyfile, account, NULL)) adp->save = TRUE; -- cgit v1.2.3 From 026cbb87190680f53a9a3382ed65f6e31cd9a4e5 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 29 Jan 2014 18:33:55 +0000 Subject: fixup! --- mission-control-plugins/account-storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 8d10ad6a..6a49d738 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -699,7 +699,7 @@ mcp_account_storage_delete_async (McpAccountStorage *storage, g_return_if_fail (iface != NULL); g_return_if_fail (iface->delete_async != NULL); - iface->delete_async (storage, am, account, callback, user_data); + iface->delete_async (storage, am, account, cancellable, callback, user_data); } /** -- cgit v1.2.3 From f97f287ae9ad702a9300720b441c6cfc3915878a Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:14:16 +0000 Subject: McpAccountStorage: more, and more informative, debug messages Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 34 ++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 6a49d738..338003c0 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -459,7 +459,10 @@ mcp_account_storage_get_attribute (McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - SDEBUG (storage, ""); + SDEBUG (storage, "%s.%s (type '%.*s')", account, attribute, + (int) g_variant_type_get_string_length (type), + g_variant_type_peek_string (type)); + g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (iface->get_attribute != NULL, FALSE); @@ -499,7 +502,10 @@ mcp_account_storage_get_parameter (McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - SDEBUG (storage, ""); + SDEBUG (storage, "%s.%s (type '%.*s')", account, parameter, + (int) g_variant_type_get_string_length (type), + g_variant_type_peek_string (type)); + g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (iface->get_parameter != NULL, FALSE); @@ -542,7 +548,9 @@ mcp_account_storage_set_attribute (McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - SDEBUG (storage, ""); + SDEBUG (storage, "%s.%s (type '%s')", account, attribute, + value == NULL ? "null" : g_variant_get_type_string (value)); + g_return_val_if_fail (iface != NULL, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); g_return_val_if_fail (iface->set_attribute != NULL, @@ -588,7 +596,9 @@ mcp_account_storage_set_parameter (McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - SDEBUG (storage, ""); + SDEBUG (storage, "%s.%s (type '%s')", account, parameter, + value == NULL ? "null" : g_variant_get_type_string (value)); + g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (iface != NULL, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); @@ -656,6 +666,8 @@ mcp_account_storage_create (const McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + SDEBUG (storage, "%s/%s \"%s\"", manager, protocol, identification); + g_return_val_if_fail (iface != NULL, NULL); g_return_val_if_fail (iface->create != NULL, NULL); @@ -695,7 +707,8 @@ mcp_account_storage_delete_async (McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - SDEBUG (storage, ""); + SDEBUG (storage, "%s", account); + g_return_if_fail (iface != NULL); g_return_if_fail (iface->delete_async != NULL); @@ -842,6 +855,7 @@ mcp_account_storage_ready (const McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + SDEBUG (storage, ""); g_return_if_fail (iface != NULL); g_return_if_fail (iface->ready != NULL); @@ -880,7 +894,7 @@ mcp_account_storage_get_identifier (const McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - SDEBUG (storage, ""); + SDEBUG (storage, "%s", account); g_return_if_fail (iface != NULL); g_return_if_fail (iface->get_identifier != NULL); g_return_if_fail (identifier != NULL); @@ -922,7 +936,7 @@ mcp_account_storage_get_additional_info (const McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - SDEBUG (storage, ""); + SDEBUG (storage, "%s", account); g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (iface->get_additional_info != NULL, FALSE); @@ -958,6 +972,7 @@ mcp_account_storage_get_restrictions (const McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + SDEBUG (storage, "%s", account); g_return_val_if_fail (iface != NULL, 0); g_return_val_if_fail (iface->get_restrictions != NULL, 0); @@ -1030,6 +1045,7 @@ void mcp_account_storage_emit_created (McpAccountStorage *storage, const gchar *account) { + SDEBUG (storage, "%s", account); g_signal_emit (storage, signals[CREATED], 0, account); } @@ -1047,6 +1063,7 @@ mcp_account_storage_emit_altered_one (McpAccountStorage *storage, const gchar *account, const gchar *key) { + SDEBUG (storage, "%s", account); g_signal_emit (storage, signals[ALTERED_ONE], 0, account, key); } @@ -1061,6 +1078,7 @@ void mcp_account_storage_emit_deleted (McpAccountStorage *storage, const gchar *account) { + SDEBUG (storage, "%s", account); g_signal_emit (storage, signals[DELETED], 0, account); } @@ -1077,6 +1095,7 @@ mcp_account_storage_emit_toggled (McpAccountStorage *storage, const gchar *account, gboolean enabled) { + SDEBUG (storage, "%s: Enabled=%s", account, enabled ? "True" : "False"); g_signal_emit (storage, signals[TOGGLED], 0, account, enabled); } @@ -1091,5 +1110,6 @@ void mcp_account_storage_emit_reconnect (McpAccountStorage *storage, const gchar *account) { + SDEBUG (storage, "%s", account); g_signal_emit (storage, signals[RECONNECT], 0, account); } -- cgit v1.2.3 From a58ba5a870d89f236ce529d2257e6a477ba4e876 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:14:45 +0000 Subject: mc-debug-server: don't try to cope gracefully with a bad D-Bus connection We know the regression tests are going to provide fake system and session buses. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- tests/twisted/mc-debug-server.c | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/tests/twisted/mc-debug-server.c b/tests/twisted/mc-debug-server.c index 917a5d34..559f3f58 100644 --- a/tests/twisted/mc-debug-server.c +++ b/tests/twisted/mc-debug-server.c @@ -175,38 +175,18 @@ main (int argc, char **argv) G_LOG_FATAL_MASK | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); gdbus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - - if (gdbus == NULL) - { - g_warning ("%s", error->message); - g_error_free (error); - error = NULL; - goto out; - } - + g_assert_no_error (error); + g_assert (gdbus != NULL); g_dbus_connection_set_exit_on_close (gdbus, FALSE); gdbus_system = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - - if (gdbus_system == NULL) - { - g_warning ("%s", error->message); - g_error_free (error); - error = NULL; - goto out; - } - + g_assert_no_error (error); + g_assert (gdbus_system != NULL); g_dbus_connection_set_exit_on_close (gdbus_system, FALSE); bus_daemon = tp_dbus_daemon_dup (&error); - - if (bus_daemon == NULL) - { - g_warning ("%s", error->message); - g_error_free (error); - error = NULL; - goto out; - } + g_assert_no_error (error); + g_assert (bus_daemon != NULL); /* It appears that dbus-glib registers a filter that wrongly returns * DBUS_HANDLER_RESULT_HANDLED for signals, so for *our* filter to have any @@ -243,8 +223,6 @@ main (int argc, char **argv) g_main_loop_run (teardown_loop); -out: - if (connection != NULL) { dbus_connection_flush (connection); -- cgit v1.2.3 From fb880af29636b7540116b865a122fa0757dd6ced Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:16:43 +0000 Subject: created_cb: don't leak error Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 54320c0a..2af47c0d 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -308,6 +308,7 @@ created_cb (GObject *storage_plugin_obj, else { WARNING ("%s", error->message); + g_clear_error (&error); goto finish; } -- cgit v1.2.3 From 443a396b555635313f12163b0351f81fc63576ad Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:17:24 +0000 Subject: mcd_storage_load: convert while loop into for loop Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 0ded3492..35eaed5f 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -498,11 +498,9 @@ mcd_storage_load (McdStorage *self) sort_and_cache_plugins (); - store = stores; - /* fetch accounts stored in plugins, highest priority first, so that * low priority plugins can be overidden by high priority */ - while (store != NULL) + for (store = stores; store != NULL; store = store->next) { GList *account; McpAccountStorage *plugin = store->data; @@ -530,7 +528,6 @@ mcd_storage_load (McdStorage *self) /* already freed the contents, just need to free the list itself */ g_list_free (stored); - store = store->next; } } -- cgit v1.2.3 From eabc50ba0c875f356adc2fc6f4008721309005ec Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:20:29 +0000 Subject: mcd_storage_get_accounts: use (transfer none) Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 2 -- src/mcd-storage.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 2af47c0d..6a7b8163 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -1528,8 +1528,6 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) g_object_unref (account); } - g_hash_table_unref (accounts); - uncork_storage_plugins (account_manager); migrate_accounts (account_manager); diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 35eaed5f..77fd7b24 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -536,13 +536,13 @@ mcd_storage_load (McdStorage *self) * @storage: An object implementing the #McdStorage interface * @n: place for the number of accounts to be written to (or %NULL) * - * Returns: (transfer container) (element-type utf8 Mcp.AccountStorage): a + * Returns: (transfer none) (element-type utf8 Mcp.AccountStorage): a * map from account object path tail to plugin */ GHashTable * mcd_storage_get_accounts (McdStorage *self) { - return g_hash_table_ref (self->accounts); + return self->accounts; } /* -- cgit v1.2.3 From 3559e8dc58f847d58da2aa35ca4b7a18af8b93e1 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:20:44 +0000 Subject: update_storage: re-indent Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 60 +++++++++++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 77fd7b24..11dab99d 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1232,46 +1232,40 @@ update_storage (McdStorage *self, McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); gboolean updated = FALSE; McpAccountStorage *plugin; + const gchar *pn; + McpAccountStorageSetResult res; plugin = g_hash_table_lookup (self->accounts, account); + g_return_val_if_fail (plugin != NULL, FALSE); + pn = mcp_account_storage_name (plugin); - if (plugin != NULL) - { - const gchar *pn = mcp_account_storage_name (plugin); - McpAccountStorageSetResult res; - - if (parameter) - res = mcp_account_storage_set_parameter (plugin, ma, account, - key, variant, MCP_PARAMETER_FLAG_NONE); - else - res = mcp_account_storage_set_attribute (plugin, ma, account, - key, variant, MCP_ATTRIBUTE_FLAG_NONE); + if (parameter) + res = mcp_account_storage_set_parameter (plugin, ma, account, + key, variant, MCP_PARAMETER_FLAG_NONE); + else + res = mcp_account_storage_set_attribute (plugin, ma, account, + key, variant, MCP_ATTRIBUTE_FLAG_NONE); - switch (res) - { - case MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED: - DEBUG ("MCP:%s -> store %s %s.%s", pn, - parameter ? "parameter" : "attribute", account, key); - updated = TRUE; - break; + switch (res) + { + case MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED: + DEBUG ("MCP:%s -> store %s %s.%s", pn, + parameter ? "parameter" : "attribute", account, key); + updated = TRUE; + break; - case MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED: - DEBUG ("MCP:%s -> failed to store %s %s.%s", - pn, parameter ? "parameter" : "attribute", account, key); - break; + case MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED: + DEBUG ("MCP:%s -> failed to store %s %s.%s", + pn, parameter ? "parameter" : "attribute", account, key); + break; - case MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED: - DEBUG ("MCP:%s -> no change to %s %s.%s", - pn, parameter ? "parameter" : "attribute", account, key); - break; + case MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED: + DEBUG ("MCP:%s -> no change to %s %s.%s", + pn, parameter ? "parameter" : "attribute", account, key); + break; - default: - g_warn_if_reached (); - } - } - else - { - g_assert_not_reached (); + default: + g_warn_if_reached (); } return updated; -- cgit v1.2.3 From 2333321be2b6550a462d9cf92a1700d77d682734 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:21:45 +0000 Subject: McdStorage: delete_cb: improve clarity with a temporary variable Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 11dab99d..0f965571 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1770,16 +1770,17 @@ delete_cb (GObject *source, gpointer user_data) { GError *error = NULL; + const gchar *account_name = user_data; if (mcp_account_storage_delete_finish (MCP_ACCOUNT_STORAGE (source), res, &error)) { - DEBUG ("deleted account %s", (const gchar *) user_data); + DEBUG ("deleted account %s", account_name); } else { DEBUG ("could not delete account %s (but no way to signal that): " - "%s #%d: %s", (const gchar *) user_data, + "%s #%d: %s", account_name, g_quark_to_string (error->domain), error->code, error->message); g_error_free (error); } -- cgit v1.2.3 From 85b98a82332a55925b2bcc2f26bee530ee244dd7 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:22:28 +0000 Subject: mcpa_unescape_variant_from_keyfile: inline implementation Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 0f965571..66fbd826 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1922,7 +1922,8 @@ mcd_storage_ready (McdStorage *self) } static GVariant * -mcd_keyfile_unescape_variant (const gchar *escaped, +mcpa_unescape_variant_from_keyfile (const McpAccountManager *mcpa, + const gchar *escaped, const GVariantType *type, GError **error) { @@ -1943,15 +1944,6 @@ mcd_keyfile_unescape_variant (const gchar *escaped, return ret; } -static GVariant * -mcpa_unescape_variant_from_keyfile (const McpAccountManager *mcpa, - const gchar *escaped, - const GVariantType *type, - GError **error) -{ - return mcd_keyfile_unescape_variant (escaped, type, error); -} - static void plugin_iface_init (McpAccountManagerIface *iface, gpointer unused G_GNUC_UNUSED) -- cgit v1.2.3 From 1bdae99f8cd780caa7fdf3aa7f72ac7c853ef2a6 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:38:54 +0000 Subject: dbus-account-plugin: fail tests if fake accounts service misbehaves Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- tests/twisted/dbus-account-plugin.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index ea35c148..493df5aa 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -27,6 +27,8 @@ #include #define DEBUG(format, ...) g_debug ("%s: " format, G_STRFUNC, ##__VA_ARGS__) +#define CRITICAL(format, ...) \ + g_critical ("%s: " format, G_STRFUNC, ##__VA_ARGS__) #define TESTDOT "org.freedesktop.Telepathy.Test." #define TESTSLASH "/org/freedesktop/Telepathy/Test/" @@ -371,7 +373,7 @@ test_dbus_account_plugin_process_account_deletion (TestDBusAccountPlugin *self, if (account == NULL) { - g_warning ("accounts service deleted %s but we don't " + CRITICAL ("accounts service deleted %s but we don't " "have any record of that account", account_name); } else @@ -409,7 +411,7 @@ test_dbus_account_plugin_process_attributes (TestDBusAccountPlugin *self, if (account == NULL) { - g_warning ("accounts service altered %s but we don't " + CRITICAL ("accounts service altered %s but we don't " "have any record of that account", account_name); } else @@ -516,7 +518,7 @@ test_dbus_account_plugin_process_parameters (TestDBusAccountPlugin *self, if (account == NULL) { - g_warning ("accounts service altered %s but we don't " + CRITICAL ("accounts service altered %s but we don't " "have any record of that account", account_name); } else -- cgit v1.2.3 From eb7dc4a25c602de15f87fc63f56610ba5a7a05f8 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 13:40:52 +0000 Subject: dbus-account-plugin: fail tests on various invalid method calls Methods that act on a single account should always be called on an account that exists (if it doesn't, where did you get its name from?), so treat it as an error if they are called with a nonexistent account. commit() has a dual role here: the method that takes a non-NULL account (which acts on a single account, as described), and the method that takes a NULL account name (which is OK to call at any time, to commit all of our 0-or-more accounts). While we are not active, we don't claim to have any accounts at all, so treat it as an error if any method is called with a non-NULL account name while inactive. I've temporarily made an exception for delete_async(), although that exception is removed in a later patch on this branch. It's less bad if delete_async() is called on an account that doesn't exist, because if you do, the desired state ("account X doesn't exist") has already been reached. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- tests/twisted/dbus-account-plugin.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 493df5aa..455095fa 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -972,8 +972,8 @@ test_dbus_account_plugin_get_attribute (McpAccountStorage *storage, if (flags != NULL) *flags = 0; - if (!self->active || account == NULL) - return NULL; + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); v = g_hash_table_lookup (account->attributes, attribute); @@ -1008,8 +1008,8 @@ test_dbus_account_plugin_get_parameter (McpAccountStorage *storage, if (flags != NULL) *flags = 0; - if (!self->active || account == NULL) - return NULL; + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); g_dbus_connection_emit_signal (self->bus, NULL, TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, @@ -1052,8 +1052,8 @@ test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, DEBUG ("%s of %s", attribute, account_name); - if (!self->active || account == NULL) - return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; + g_return_val_if_fail (self->active, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + g_return_val_if_fail (account != NULL, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); if (value == NULL) { @@ -1112,8 +1112,8 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, DEBUG ("%s of %s", parameter, account_name); - if (!self->active || account == NULL) - return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; + g_return_val_if_fail (self->active, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + g_return_val_if_fail (account != NULL, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); if (value == NULL) { @@ -1342,8 +1342,8 @@ test_dbus_account_plugin_commit (const McpAccountStorage *storage, account = lookup_account (self, account_name); - if (!self->active || account == NULL) - return FALSE; + g_return_val_if_fail (self->active, FALSE); + g_return_val_if_fail (account != NULL, FALSE); g_dbus_connection_emit_signal (self->bus, NULL, TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, @@ -1484,8 +1484,8 @@ test_dbus_account_plugin_get_identifier (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL) - return; + g_return_if_fail (self->active); + g_return_if_fail (account != NULL); /* Our "library-specific unique identifier" is just the object-path * as a string. */ @@ -1503,8 +1503,8 @@ test_dbus_account_plugin_get_additional_info (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL) - return NULL; + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); ret = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) tp_g_value_slice_free); @@ -1523,8 +1523,8 @@ test_dbus_account_plugin_get_restrictions (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (!self->active || account == NULL) - return 0; + g_return_val_if_fail (self->active, 0); + g_return_val_if_fail (account != NULL, 0); return account->restrictions; } -- cgit v1.2.3 From 2257fbc2b95c00719aac0d8707643c05785dda4e Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 15:04:18 +0000 Subject: McdAccountManagerDefault: don't try to save "absent" accounts These are empty account records corresponding to empty files in a high-priority directory, which only exist to "mask" an account of the same name in a lower-priority directory. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager-default.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index db0ede9a..0b9acc64 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -543,6 +543,11 @@ _commit (const McpAccountStorage *self, { if (account == NULL || !tp_strdiff (account, account_p)) { + McdDefaultStoredAccount *sa = sa_p; + + if (sa->absent) + continue; + if (!am_default_commit_one (amd, account_p, sa_p)) all_succeeded = FALSE; } -- cgit v1.2.3 From 296a3ff2d5b0e5a6a2fbc0a577d98629b869e4cb Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 15:00:56 +0000 Subject: McdAccountManagerDefault: track whether saving is needed correctly _commit (self, am, "just/one/account") would reset the global "dirty" flag, even if another account also needed writing out. I don't think this could actually happen in practice, but it seems best to fix it. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager-default.c | 44 ++++++++++++++++++++++++++------------- src/mcd-account-manager-default.h | 1 - 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 0b9acc64..e42d1675 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -50,6 +50,8 @@ typedef struct { /* TRUE if the account doesn't really exist, but is here to stop us * loading it from a lower-priority file */ gboolean absent; + /* TRUE if this account needs saving */ + gboolean dirty; } McdDefaultStoredAccount; static GVariant * @@ -159,7 +161,6 @@ mcd_account_manager_default_init (McdAccountManagerDefault *self) self->directory = account_directory_in (g_get_user_data_dir ()); self->accounts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, stored_account_free); - self->save = FALSE; self->loaded = FALSE; } @@ -230,7 +231,7 @@ set_parameter (McpAccountStorage *self, g_variant_ref (val)); } - amd->save = TRUE; + sa->dirty = TRUE; return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } @@ -269,7 +270,7 @@ set_attribute (McpAccountStorage *self, g_variant_ref (val)); } - amd->save = TRUE; + sa->dirty = TRUE; return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } @@ -456,6 +457,9 @@ am_default_commit_one (McdAccountManagerDefault *self, gboolean ret; GError *error = NULL; + if (!sa->dirty) + return TRUE; + filename = account_file_in (g_get_user_data_dir (), account_name); DEBUG ("Saving account %s to %s", account_name, filename); @@ -498,6 +502,7 @@ am_default_commit_one (McdAccountManagerDefault *self, if (g_file_set_contents (filename, content_text, -1, &error)) { + sa->dirty = FALSE; ret = TRUE; } else @@ -524,9 +529,6 @@ _commit (const McpAccountStorage *self, GHashTableIter outer; gpointer account_p, sa_p; - if (!amd->save) - return TRUE; - DEBUG ("Saving accounts to %s", amd->directory); if (!mcd_ensure_directory (amd->directory, &error)) @@ -553,11 +555,6 @@ _commit (const McpAccountStorage *self, } } - if (all_succeeded) - { - amd->save = FALSE; - } - return all_succeeded; } @@ -605,7 +602,7 @@ am_default_load_keyfile (McdAccountManagerDefault *self, GStrv keys = g_key_file_get_keys (keyfile, account, &m, NULL); /* We're going to need to migrate this account. */ - self->save = TRUE; + sa->dirty = TRUE; for (j = 0; j < m; j++) { @@ -853,6 +850,7 @@ _list (const McpAccountStorage *self, GHashTableIter hash_iter; gchar *migrate_from = NULL; gpointer k, v; + gboolean save = FALSE; if (!amd->loaded) { @@ -928,7 +926,7 @@ _list (const McpAccountStorage *self, if (!am_default_load_keyfile (amd, migrate_from)) tp_clear_pointer (&migrate_from, g_free); amd->loaded = TRUE; - amd->save = TRUE; + save = TRUE; } else { @@ -940,10 +938,26 @@ _list (const McpAccountStorage *self, { DEBUG ("Creating initial account data"); amd->loaded = TRUE; - amd->save = TRUE; + save = TRUE; + } + + if (!save) + { + g_hash_table_iter_init (&hash_iter, amd->accounts); + + while (g_hash_table_iter_next (&hash_iter, NULL, &v)) + { + McdDefaultStoredAccount *sa = v; + + if (sa->dirty) + { + save = TRUE; + break; + } + } } - if (amd->save) + if (save) { DEBUG ("Saving initial or migrated account data"); diff --git a/src/mcd-account-manager-default.h b/src/mcd-account-manager-default.h index e16e062f..fb2cb75e 100644 --- a/src/mcd-account-manager-default.h +++ b/src/mcd-account-manager-default.h @@ -51,7 +51,6 @@ typedef struct { GObject parent; GHashTable *accounts; gchar *directory; - gboolean save; gboolean loaded; } _McdAccountManagerDefault; -- cgit v1.2.3 From ff00f3cfcf3b50ad8fea903434b13f4dac33b793 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 15:20:26 +0000 Subject: McdAccountManagerDefault: don't pass "absent" accounts up to MC They're not really accounts, just gaps where an account could go. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager-default.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index e42d1675..9becfd3b 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -981,7 +981,10 @@ _list (const McpAccountStorage *self, while (g_hash_table_iter_next (&hash_iter, &k, &v)) { - rval = g_list_prepend (rval, g_strdup (k)); + McdDefaultStoredAccount *sa = v; + + if (!sa->absent) + rval = g_list_prepend (rval, g_strdup (k)); } return rval; -- cgit v1.2.3 From 9e890f2ee20791dc87093bb72b1a6a5148d28766 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 15:24:16 +0000 Subject: McdAccountManagerDefault: get/set/commit on a missing account is an error Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager-default.c | 41 ++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 9becfd3b..49f04079 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -181,15 +181,14 @@ set_parameter (McpAccountStorage *self, McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); McdDefaultStoredAccount *sa; + sa = lookup_stored_account (amd, account); + g_return_val_if_fail (sa != NULL, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + g_return_val_if_fail (!sa->absent, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + if (val == NULL) { gboolean changed = FALSE; - sa = lookup_stored_account (amd, account); - - if (sa == NULL) - return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; - changed = g_hash_table_remove (sa->parameters, parameter); /* deliberately not ||= - if we removed it from parameters, we * still want to remove it from untyped_parameters if it was there */ @@ -202,7 +201,6 @@ set_parameter (McpAccountStorage *self, { GVariant *old; - sa = ensure_stored_account (amd, account); old = g_hash_table_lookup (sa->parameters, parameter); if (old == NULL) @@ -246,13 +244,12 @@ set_attribute (McpAccountStorage *self, McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); McdDefaultStoredAccount *sa; + sa = lookup_stored_account (amd, account); + g_return_val_if_fail (sa != NULL, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + g_return_val_if_fail (!sa->absent, MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED); + if (val == NULL) { - sa = lookup_stored_account (amd, account); - - if (sa == NULL) - return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; - if (!g_hash_table_remove (sa->attributes, attribute)) return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; } @@ -260,7 +257,6 @@ set_attribute (McpAccountStorage *self, { GVariant *old; - sa = ensure_stored_account (amd, account); old = g_hash_table_lookup (sa->attributes, attribute); if (old != NULL && g_variant_equal (old, val)) @@ -288,8 +284,8 @@ get_attribute (McpAccountStorage *self, if (flags != NULL) *flags = 0; - if (sa == NULL || sa->absent) - return FALSE; + g_return_val_if_fail (sa != NULL, NULL); + g_return_val_if_fail (!sa->absent, NULL); /* ignore @type, we store every attribute with its type anyway; MC will * coerce values to an appropriate type if needed */ @@ -312,8 +308,8 @@ get_parameter (McpAccountStorage *self, if (flags != NULL) *flags = 0; - if (sa == NULL || sa->absent) - return FALSE; + g_return_val_if_fail (sa != NULL, NULL); + g_return_val_if_fail (!sa->absent, NULL); variant = g_hash_table_lookup (sa->parameters, parameter); @@ -457,6 +453,9 @@ am_default_commit_one (McdAccountManagerDefault *self, gboolean ret; GError *error = NULL; + g_return_val_if_fail (sa != NULL, FALSE); + g_return_val_if_fail (!sa->absent, FALSE); + if (!sa->dirty) return TRUE; @@ -539,6 +538,16 @@ _commit (const McpAccountStorage *self, * give us a chance to commit to the keyring too */ } + if (account != NULL) + { + McdDefaultStoredAccount *sa = lookup_stored_account (amd, account); + + g_return_val_if_fail (sa != NULL, FALSE); + g_return_val_if_fail (!sa->absent, FALSE); + + return am_default_commit_one (amd, account, sa); + } + g_hash_table_iter_init (&outer, amd->accounts); while (g_hash_table_iter_next (&outer, &account_p, &sa_p)) -- cgit v1.2.3 From 2f325de3b7847018071d13dd3d050b02c0832d9d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 15:41:10 +0000 Subject: deleted_cb: correct a debug message Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 6a7b8163..66168243 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -454,7 +454,7 @@ deleted_cb (GObject *plugin, const gchar *name, gpointer data) if (storage_plugin != its_plugin) { - DEBUG ("Ignoring altered-one from plugin %s because account %s " + DEBUG ("Ignoring deleted signal from plugin %s because account %s " "belongs to %s", mcp_account_storage_name (storage_plugin), name, -- cgit v1.2.3 From ec5def2cdb05891f7d233a7039a1a94d2315040c Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 16:21:00 +0000 Subject: McdAccount: don't delete from storage if already deleted Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mcd-account.c b/src/mcd-account.c index 1b997bd0..6253a7ef 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -745,7 +745,8 @@ mcd_account_delete_async (McdAccount *account, return; } - mcd_storage_delete_account (priv->storage, name); + if ((flags & MCD_DBUS_PROP_SET_FLAG_ALREADY_IN_STORAGE) == 0) + mcd_storage_delete_account (priv->storage, name); data_dir_str = get_old_account_data_path (priv); -- cgit v1.2.3 From 50247324010cbe6fb9495db71f1feccbc517cdea Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 16:31:21 +0000 Subject: McdStorage: don't forget accounts until the McpAccountStorage says so We shouldn't remove it from the hash table until the storage plugin says ::deleted: until then, deletion could fail. This will become significant when we start considering deletion of a deleted account to be an error. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 66fbd826..ba8420a6 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1816,15 +1816,11 @@ mcd_storage_delete_account (McdStorage *self, return; } - g_object_ref (plugin); - g_hash_table_remove (self->accounts, account); /* FIXME: stop ignoring the error (if any), and make this method async * in order to pass the error up to McdAccount */ mcp_account_storage_delete_async (plugin, ma, account, NULL, delete_cb, g_strdup (account)); - - g_object_unref (plugin); } /* -- cgit v1.2.3 From 183af896db254c19eedc62ad58d5e2b08297791f Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 16:31:47 +0000 Subject: mcd_storage_delete_account: don't tolerate deletion of unknown accounts We should always know what we're deleting, now. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index ba8420a6..d3bc5dae 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1809,13 +1809,7 @@ mcd_storage_delete_account (McdStorage *self, g_return_if_fail (account != NULL); plugin = g_hash_table_lookup (self->accounts, account); - - if (plugin == NULL) - { - /* we wanted no account, we got no account, I call that success! */ - return; - } - + g_return_if_fail (plugin != NULL); /* FIXME: stop ignoring the error (if any), and make this method async * in order to pass the error up to McdAccount */ -- cgit v1.2.3 From 28f6731e92a596eabea5c4975249d5927428f459 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 16:46:23 +0000 Subject: delete_async: being asked to delete a nonexistent account is an error Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager-default.c | 9 ++------- tests/twisted/dbus-account-plugin.c | 10 ++-------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 49f04079..fed283b1 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -361,13 +361,8 @@ delete_async (McpAccountStorage *self, task = g_task_new (amd, cancellable, callback, user_data); - if (sa == NULL || sa->absent) - { - /* Apparently we never had this account anyway. The plugin API - * considers this to be "success". */ - g_task_return_boolean (task, TRUE); - goto finally; - } + g_return_if_fail (sa != NULL); + g_return_if_fail (!sa->absent); filename = account_file_in (g_get_user_data_dir (), account); diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 455095fa..c7c5dbde 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -916,14 +916,8 @@ test_dbus_account_plugin_delete_async (McpAccountStorage *storage, DEBUG ("called"); - if (account == NULL || !self->active) - { - /* We were asked to delete an account we don't have. It's - * a bit like success. */ - g_task_return_boolean (task, TRUE); - g_object_unref (task); - return; - } + g_return_if_fail (self->active); + g_return_if_fail (account != NULL); /* deletion used to be delayed, so the regression tests will expect this * to happen - leave them unmodified for now */ -- cgit v1.2.3 From 762d3c7746146b7d94b3e3c5df7d78c62e78202f Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 16:49:04 +0000 Subject: McdAccountManager: remove unused timed account storage commit Nothing ever sets write_conf_id nonzero, so this can never be called any more. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 66168243..a71350cc 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -134,8 +134,6 @@ enum PROP_CLIENT_FACTORY }; -static guint write_conf_id = 0; - static void register_dbus_service (McdAccountManager *account_manager); static void release_setup_lock (McdAccountManager *account_manager); static void setup_account_loaded (McdAccount *account, @@ -1132,20 +1130,6 @@ properties_iface_init (TpSvcDBusPropertiesClass *iface, gpointer iface_data) #undef IMPLEMENT } -static gboolean -write_conf (gpointer userdata) -{ - McdStorage *storage = MCD_STORAGE (userdata); - - DEBUG ("called"); - g_source_remove (write_conf_id); - write_conf_id = 0; - - mcd_storage_commit (storage, NULL); - - return TRUE; -} - static void release_setup_lock (McdAccountManager *self) { @@ -1614,12 +1598,6 @@ _mcd_account_manager_finalize (GObject *object) { McdAccountManagerPrivate *priv = MCD_ACCOUNT_MANAGER_PRIV (object); - if (write_conf_id) - { - write_conf (priv->storage); - g_assert (write_conf_id == 0); - } - tp_clear_object (&priv->storage); g_free (priv->account_connections_dir); remove (priv->account_connections_file); -- cgit v1.2.3 From 8e5e39aa29a833be16598b2392539af07808a85d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 17:33:06 +0000 Subject: McdAccountManager: commit accounts one at a time In the process, inline mcd_account_manager_write_conf_async and uncork_storage_plugins into their callers, with considerable simplification because the async API isn't actually used any more. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 79 ++++++++++------------------------------------- src/mcd-account-manager.h | 9 ------ 2 files changed, 17 insertions(+), 71 deletions(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index a71350cc..fa031161 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -782,8 +782,11 @@ complete_account_creation_finish (McdAccount *account, tp_clear_object (&account); } - mcd_account_manager_write_conf_async (account_manager, account, NULL, - NULL); + if (account != NULL) + { + mcd_storage_commit (account_manager->priv->storage, + mcd_account_get_unique_name (account)); + } if (cad->callback != NULL) cad->callback (account_manager, account, cad->error, cad->user_data); @@ -1191,15 +1194,6 @@ setup_account_loaded (McdAccount *account, g_object_unref (self); } -static void -uncork_storage_plugins (McdAccountManager *account_manager) -{ - McdAccountManagerPrivate *priv = MCD_ACCOUNT_MANAGER_PRIV (account_manager); - - mcd_account_manager_write_conf_async (account_manager, NULL, NULL, NULL); - mcd_storage_ready (priv->storage); -} - typedef struct { McdAccountManager *self; @@ -1512,7 +1506,18 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) g_object_unref (account); } - uncork_storage_plugins (account_manager); + /* FIXME: why do we need to commit the accounts at this point? + * It was added to uncork_storage_plugins() in 3d5b5e7a248d + * without explanation */ + g_hash_table_iter_init (&iter, account_manager->priv->accounts); + while (g_hash_table_iter_next (&iter, NULL, &v)) + { + mcd_storage_commit (storage, + mcd_account_get_unique_name (v)); + } + + /* uncork signals from storage plugins */ + mcd_storage_ready (priv->storage); migrate_accounts (account_manager); @@ -1749,56 +1754,6 @@ mcd_account_manager_get_connectivity_monitor (McdAccountManager *self) return self->priv->minotaur; } -/** - * McdAccountManagerWriteConfCb: - * @account_manager: the #McdAccountManager - * @error: a set #GError on failure or %NULL if there was no error - * @user_data: user data - * - * The callback from mcd_account_manager_write_conf_async(). If the config - * writing was successful, @error will be %NULL, otherwise it will be set - * with the appropriate error. - */ - -/** - * mcd_account_manager_write_conf_async: - * @account_manager: the #McdAccountManager - * @account: the account to be written, or %NULL to flush all accounts - * @callback: a callback to be called on write success or failure - * @user_data: data to be passed to @callback - * - * Write the account manager configuration to disk. - */ -void -mcd_account_manager_write_conf_async (McdAccountManager *account_manager, - McdAccount *account, - McdAccountManagerWriteConfCb callback, - gpointer user_data) -{ - McdStorage *storage = NULL; - const gchar *account_name = NULL; - - g_return_if_fail (MCD_IS_ACCOUNT_MANAGER (account_manager)); - - storage = account_manager->priv->storage; - - if (account != NULL) - { - account_name = mcd_account_get_unique_name (account); - - DEBUG ("updating %s", account_name); - mcd_storage_commit (storage, account_name); - } - else - { - DEBUG ("updating all accounts"); - mcd_storage_commit (storage, NULL); - } - - if (callback != NULL) - callback (account_manager, NULL, user_data); -} - GHashTable * _mcd_account_manager_get_accounts (McdAccountManager *account_manager) { diff --git a/src/mcd-account-manager.h b/src/mcd-account-manager.h index 922f4896..f33c2949 100644 --- a/src/mcd-account-manager.h +++ b/src/mcd-account-manager.h @@ -66,15 +66,6 @@ McdAccountManager *mcd_account_manager_new ( TpDBusDaemon *mcd_account_manager_get_dbus_daemon (McdAccountManager *account_manager); -typedef void (McdAccountManagerWriteConfCb) (McdAccountManager *account_manager, - const GError *error, - gpointer user_data); - -void mcd_account_manager_write_conf_async (McdAccountManager *account_manager, - McdAccount *account, - McdAccountManagerWriteConfCb callback, - gpointer user_data); - McdAccount *mcd_account_manager_lookup_account (McdAccountManager *account_manager, const gchar *name); McdAccount *mcd_account_manager_lookup_account_by_path (McdAccountManager *account_manager, -- cgit v1.2.3 From 9624c084d46660721aa0173e23103cd25165a5a5 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 17:33:28 +0000 Subject: mcd_storage_commit: rely on never being called with account == NULL Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-storage.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/src/mcd-storage.c b/src/mcd-storage.c index d3bc5dae..cbca24e2 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1828,33 +1828,21 @@ mcd_storage_delete_account (McdStorage *self, void mcd_storage_commit (McdStorage *self, const gchar *account) { - GList *store; McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); McpAccountStorage *plugin; const gchar *pname; g_return_if_fail (MCD_IS_STORAGE (self)); + g_return_if_fail (account != NULL); - if (account != NULL) - { - plugin = g_hash_table_lookup (self->accounts, account); - g_return_if_fail (plugin != NULL); - - pname = mcp_account_storage_name (plugin); - - DEBUG ("flushing plugin %s %s to long term storage", pname, account); - mcp_account_storage_commit (plugin, ma, account); - return; - } + plugin = g_hash_table_lookup (self->accounts, account); + g_return_if_fail (plugin != NULL); - for (store = stores; store != NULL; store = g_list_next (store)) - { - plugin = store->data; - pname = mcp_account_storage_name (plugin); + pname = mcp_account_storage_name (plugin); - DEBUG ("flushing plugin %s to long term storage", pname); - mcp_account_storage_commit (plugin, ma, NULL); - } + /* FIXME: fd.o #29563: this should be async, really */ + DEBUG ("flushing plugin %s %s to long term storage", pname, account); + mcp_account_storage_commit (plugin, ma, account); } /* -- cgit v1.2.3 From e7ba5a86df4e90ec334a4c8ff9a11f9305458e00 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 15 Nov 2013 17:34:58 +0000 Subject: mcp_account_storage_commit: guarantee that we commit one at a time Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 9 ++-- src/mcd-account-manager-default.c | 68 +++++++++++++------------------ tests/twisted/dbus-account-plugin.c | 33 --------------- tests/twisted/mcp-account-diversion.c | 4 +- 4 files changed, 36 insertions(+), 78 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 338003c0..e30bb51e 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -743,8 +743,7 @@ mcp_account_storage_delete_finish (McpAccountStorage *storage, * McpAccountStorageCommitFunc: * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance - * @account: (allow-none): the unique suffix of an account's object path, - * or %NULL to commit all accounts + * @account: the unique suffix of an account's object path * * An implementation of mcp_account_storage_commit(). * @@ -755,8 +754,7 @@ mcp_account_storage_delete_finish (McpAccountStorage *storage, * mcp_account_storage_commit: * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance - * @account: (allow-none): the unique suffix of an account's object path, - * or %NULL if all accounts are to be committed + * @account: the unique suffix of an account's object path * * The plugin is expected to write its cache to long term storage, * deleting, adding or updating entries in said storage as needed. @@ -768,6 +766,9 @@ mcp_account_storage_delete_finish (McpAccountStorage *storage, * The default implementation just returns %FALSE, and is appropriate for * read-only storage. * + * Mission Control 5.17+ no longer requires plugins to cope with + * account == NULL. + * * Returns: %TRUE if the commit process was started (but not necessarily * completed) successfully; %FALSE if there was a problem that was immediately * obvious. diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index fed283b1..efcb19f4 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -454,6 +454,13 @@ am_default_commit_one (McdAccountManagerDefault *self, if (!sa->dirty) return TRUE; + if (!mcd_ensure_directory (self->directory, &error)) + { + g_warning ("%s", error->message); + g_error_free (error); + return FALSE; + } + filename = account_file_in (g_get_user_data_dir (), account_name); DEBUG ("Saving account %s to %s", account_name, filename); @@ -518,48 +525,14 @@ _commit (const McpAccountStorage *self, const gchar *account) { McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); - gboolean all_succeeded = TRUE; - GError *error = NULL; - GHashTableIter outer; - gpointer account_p, sa_p; - - DEBUG ("Saving accounts to %s", amd->directory); - - if (!mcd_ensure_directory (amd->directory, &error)) - { - g_warning ("%s", error->message); - g_clear_error (&error); - /* fall through anyway: writing to the files will fail, but it does - * give us a chance to commit to the keyring too */ - } - - if (account != NULL) - { - McdDefaultStoredAccount *sa = lookup_stored_account (amd, account); - - g_return_val_if_fail (sa != NULL, FALSE); - g_return_val_if_fail (!sa->absent, FALSE); - - return am_default_commit_one (amd, account, sa); - } - - g_hash_table_iter_init (&outer, amd->accounts); - - while (g_hash_table_iter_next (&outer, &account_p, &sa_p)) - { - if (account == NULL || !tp_strdiff (account, account_p)) - { - McdDefaultStoredAccount *sa = sa_p; + McdDefaultStoredAccount *sa = lookup_stored_account (amd, account); - if (sa->absent) - continue; + g_return_val_if_fail (sa != NULL, FALSE); + g_return_val_if_fail (!sa->absent, FALSE); - if (!am_default_commit_one (amd, account_p, sa_p)) - all_succeeded = FALSE; - } - } + DEBUG ("Saving account %s to %s", account, amd->directory); - return all_succeeded; + return am_default_commit_one (amd, account, sa); } static gboolean @@ -963,9 +936,24 @@ _list (const McpAccountStorage *self, if (save) { + gboolean all_succeeded = TRUE; + DEBUG ("Saving initial or migrated account data"); - if (_commit (self, am, NULL)) + g_hash_table_iter_init (&hash_iter, amd->accounts); + + while (g_hash_table_iter_next (&hash_iter, &k, &v)) + { + McdDefaultStoredAccount *sa = v; + + if (sa->absent) + continue; + + if (!am_default_commit_one (amd, k, v)) + all_succeeded = FALSE; + } + + if (all_succeeded) { if (migrate_from != NULL) { diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index c7c5dbde..2e66179e 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -1151,36 +1151,6 @@ test_dbus_account_plugin_set_parameter (McpAccountStorage *storage, return MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED; } -static gboolean -test_dbus_account_plugin_commit_all (const McpAccountStorage *storage, - const McpAccountManager *am) -{ - TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); - GHashTableIter iter; - gpointer k; - - DEBUG ("called"); - - if (!self->active) - return FALSE; - - g_dbus_connection_emit_signal (self->bus, NULL, - TEST_DBUS_ACCOUNT_PLUGIN_PATH, TEST_DBUS_ACCOUNT_PLUGIN_IFACE, - "CommittingAll", NULL, NULL); - - g_hash_table_iter_init (&iter, self->accounts); - - while (g_hash_table_iter_next (&iter, &k, NULL)) - { - if (!mcp_account_storage_commit (storage, am, k)) - { - g_warning ("declined to commit account %s", (const gchar *) k); - } - } - - return TRUE; -} - static void delete_account_cb (GObject *source_object, GAsyncResult *res, @@ -1331,9 +1301,6 @@ test_dbus_account_plugin_commit (const McpAccountStorage *storage, DEBUG ("%s", account_name); - if (account_name == NULL) - return test_dbus_account_plugin_commit_all (storage, am); - account = lookup_account (self, account_name); g_return_val_if_fail (self->active, FALSE); diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index bcb8930c..02775b4c 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -302,7 +302,9 @@ _commit (const McpAccountStorage *self, gboolean rval = FALSE; /* This simple implementation ignores account_name and commits everything: - * we're writing out the whole keyfile anyway */ + * we're writing out the whole keyfile anyway. If MC is looping over + * accounts, the second and subsequent accounts will find that + * adp->save is false, so there's no write-amplification. */ if (!adp->save) return TRUE; -- cgit v1.2.3 From 097db6919cc185342e6b3fed347ba15dae9d004d Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 20 Nov 2013 16:06:35 -0500 Subject: Remove MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_KEYRING I makes no sense now that MC stopped caring about secrets. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.h | 1 - 1 file changed, 1 deletion(-) diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 1a30b5ed..1e4c5873 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -30,7 +30,6 @@ G_BEGIN_DECLS #define MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_READONLY -1 #define MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_DEFAULT 0 #define MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_NORMAL 100 -#define MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_KEYRING 10000 typedef enum { MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED = 0, -- cgit v1.2.3 From c0b9663101092257873410d92e2c02219d109353 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 20 Nov 2013 17:10:40 -0500 Subject: Be consistent in the constness of arguments in storage virtual methods We usually don't pass const objects Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- mission-control-plugins/account-storage.c | 48 +++++++-------- mission-control-plugins/account-storage.h | 97 +++++++++++++++---------------- src/mcd-account-manager-default.c | 12 ++-- src/mcd-storage.c | 4 +- tests/twisted/dbus-account-plugin.c | 22 +++---- tests/twisted/mcp-account-diversion.c | 16 ++--- 6 files changed, 98 insertions(+), 101 deletions(-) diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index e30bb51e..288df077 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -133,16 +133,16 @@ default_delete_finish (McpAccountStorage *storage, } static gboolean -default_commit (const McpAccountStorage *storage, - const McpAccountManager *am, +default_commit (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account) { return FALSE; } static gchar * -default_create (const McpAccountStorage *storage, - const McpAccountManager *am, +default_create (McpAccountStorage *storage, + McpAccountManager *am, const gchar *manager, const gchar *protocol, const gchar *identification, @@ -154,14 +154,14 @@ default_create (const McpAccountStorage *storage, } static void -default_ready (const McpAccountStorage *storage, - const McpAccountManager *am) +default_ready (McpAccountStorage *storage, + McpAccountManager *am) { /* do nothing */ } static void -default_get_identifier (const McpAccountStorage *storage, +default_get_identifier (McpAccountStorage *storage, const gchar *account, GValue *identifier) { @@ -170,14 +170,14 @@ default_get_identifier (const McpAccountStorage *storage, } static GHashTable * -default_get_additional_info (const McpAccountStorage *storage, +default_get_additional_info (McpAccountStorage *storage, const gchar *account) { return g_hash_table_new (g_str_hash, g_str_equal); } static TpStorageRestrictionFlags -default_get_restrictions (const McpAccountStorage *storage, +default_get_restrictions (McpAccountStorage *storage, const gchar *account) { return 0; @@ -417,7 +417,7 @@ mcp_account_storage_get_type (void) * Returns: the priority of this plugin **/ gint -mcp_account_storage_priority (const McpAccountStorage *storage) +mcp_account_storage_priority (McpAccountStorage *storage) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); @@ -657,8 +657,8 @@ mcp_account_storage_set_parameter (McpAccountStorage *storage, * be done. */ gchar * -mcp_account_storage_create (const McpAccountStorage *storage, - const McpAccountManager *am, +mcp_account_storage_create (McpAccountStorage *storage, + McpAccountManager *am, const gchar *manager, const gchar *protocol, const gchar *identification, @@ -774,8 +774,8 @@ mcp_account_storage_delete_finish (McpAccountStorage *storage, * obvious. */ gboolean -mcp_account_storage_commit (const McpAccountStorage *storage, - const McpAccountManager *am, +mcp_account_storage_commit (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); @@ -817,8 +817,8 @@ mcp_account_storage_commit (const McpAccountStorage *storage, * them. */ GList * -mcp_account_storage_list (const McpAccountStorage *storage, - const McpAccountManager *am) +mcp_account_storage_list (McpAccountStorage *storage, + McpAccountManager *am) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); @@ -851,8 +851,8 @@ mcp_account_storage_list (const McpAccountStorage *storage, * "deleted". */ void -mcp_account_storage_ready (const McpAccountStorage *storage, - const McpAccountManager *am) +mcp_account_storage_ready (McpAccountStorage *storage, + McpAccountManager *am) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); @@ -889,7 +889,7 @@ mcp_account_storage_ready (const McpAccountStorage *storage, * the account. */ void -mcp_account_storage_get_identifier (const McpAccountStorage *storage, +mcp_account_storage_get_identifier (McpAccountStorage *storage, const gchar *account, GValue *identifier) { @@ -932,7 +932,7 @@ mcp_account_storage_get_identifier (const McpAccountStorage *storage, * storage-specific information, which must not be %NULL */ GHashTable * -mcp_account_storage_get_additional_info (const McpAccountStorage *storage, +mcp_account_storage_get_additional_info (McpAccountStorage *storage, const gchar *account) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); @@ -968,7 +968,7 @@ mcp_account_storage_get_additional_info (const McpAccountStorage *storage, * account storage. */ TpStorageRestrictionFlags -mcp_account_storage_get_restrictions (const McpAccountStorage *storage, +mcp_account_storage_get_restrictions (McpAccountStorage *storage, const gchar *account) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); @@ -989,7 +989,7 @@ mcp_account_storage_get_restrictions (const McpAccountStorage *storage, * Returns: the plugin's name (for logging etc) */ const gchar * -mcp_account_storage_name (const McpAccountStorage *storage) +mcp_account_storage_name (McpAccountStorage *storage) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); @@ -1007,7 +1007,7 @@ mcp_account_storage_name (const McpAccountStorage *storage) * Returns: the plugin's description (for logging etc) */ const gchar * -mcp_account_storage_description (const McpAccountStorage *storage) +mcp_account_storage_description (McpAccountStorage *storage) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); @@ -1026,7 +1026,7 @@ mcp_account_storage_description (const McpAccountStorage *storage) * was provided in #McpAccountStorageIface.provider. */ const gchar * -mcp_account_storage_provider (const McpAccountStorage *storage) +mcp_account_storage_provider (McpAccountStorage *storage) { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 1e4c5873..356642f6 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -63,38 +63,15 @@ struct _McpAccountStorage { }; GType mcp_account_storage_get_type (void); -/* Virtual method implementation signatures */ typedef gchar * (*McpAccountStorageCreate) ( - const McpAccountStorage *storage, - const McpAccountManager *am, + McpAccountStorage *storage, + McpAccountManager *am, const gchar *manager, const gchar *protocol, const gchar *identification, GError **error); -typedef gboolean (*McpAccountStorageDeleteFunc) ( - const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account, - const gchar *key); -typedef GList * (*McpAccountStorageListFunc) ( - const McpAccountStorage *storage, - const McpAccountManager *am); -typedef gboolean (*McpAccountStorageCommitFunc) ( - const McpAccountStorage *storage, - const McpAccountManager *am, - const gchar *account); -typedef void (*McpAccountStorageReadyFunc) ( - const McpAccountStorage *storage, - const McpAccountManager *am); -typedef void (*McpAccountStorageGetIdentifierFunc) ( - const McpAccountStorage *storage, - const gchar *account, - GValue *identifier); -typedef GHashTable * (*McpAccountStorageGetAdditionalInfoFunc) ( - const McpAccountStorage *storage, - const gchar *account); typedef TpStorageRestrictionFlags (*McpAccountStorageGetRestrictionsFunc) ( - const McpAccountStorage *storage, + McpAccountStorage *storage, const gchar *account); struct _McpAccountStorageIface @@ -115,15 +92,34 @@ struct _McpAccountStorageIface gboolean (*delete_finish) (McpAccountStorage *storage, GAsyncResult *res, GError **error); - McpAccountStorageCommitFunc commit; - McpAccountStorageListFunc list; - McpAccountStorageReadyFunc ready; - McpAccountStorageGetIdentifierFunc get_identifier; - McpAccountStorageGetAdditionalInfoFunc get_additional_info; - McpAccountStorageGetRestrictionsFunc get_restrictions; - McpAccountStorageCreate create; - - /* Since 5.15.0 */ + + gboolean (*commit) (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account); + + GList * (*list) (McpAccountStorage *storage, + McpAccountManager *am); + + void (*ready) (McpAccountStorage *storage, + McpAccountManager *am); + + void (*get_identifier) (McpAccountStorage *storage, + const gchar *account, + GValue *identifier); + + GHashTable * (*get_additional_info) (McpAccountStorage *storage, + const gchar *account); + + TpStorageRestrictionFlags (*get_restrictions) (McpAccountStorage *storage, + const gchar *account); + + gchar * (*create) (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *manager, + const gchar *protocol, + const gchar *identification, + GError **error); + GVariant *(*get_attribute) (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -136,6 +132,7 @@ struct _McpAccountStorageIface const gchar *parameter, const GVariantType *type, McpParameterFlags *flags); + McpAccountStorageSetResult (*set_attribute) (McpAccountStorage *storage, McpAccountManager *am, const gchar *account, @@ -151,10 +148,10 @@ struct _McpAccountStorageIface }; /* virtual methods */ -gint mcp_account_storage_priority (const McpAccountStorage *storage); +gint mcp_account_storage_priority (McpAccountStorage *storage); -gchar * mcp_account_storage_create (const McpAccountStorage *storage, - const McpAccountManager *am, +gchar * mcp_account_storage_create (McpAccountStorage *storage, + McpAccountManager *am, const gchar *manager, const gchar *protocol, const gchar *identification, @@ -170,33 +167,33 @@ gboolean mcp_account_storage_delete_finish (McpAccountStorage *storage, GAsyncResult *result, GError **error); -void mcp_account_storage_ready (const McpAccountStorage *storage, - const McpAccountManager *am); +void mcp_account_storage_ready (McpAccountStorage *storage, + McpAccountManager *am); gboolean -mcp_account_storage_commit (const McpAccountStorage *storage, - const McpAccountManager *am, +mcp_account_storage_commit (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account); -GList *mcp_account_storage_list (const McpAccountStorage *storage, - const McpAccountManager *am); +GList *mcp_account_storage_list (McpAccountStorage *storage, + McpAccountManager *am); -void mcp_account_storage_get_identifier (const McpAccountStorage *storage, +void mcp_account_storage_get_identifier (McpAccountStorage *storage, const gchar *account, GValue *identifier); GHashTable *mcp_account_storage_get_additional_info ( - const McpAccountStorage *storage, + McpAccountStorage *storage, const gchar *account); TpStorageRestrictionFlags mcp_account_storage_get_restrictions ( - const McpAccountStorage *storage, + McpAccountStorage *storage, const gchar *account); -const gchar *mcp_account_storage_name (const McpAccountStorage *storage); +const gchar *mcp_account_storage_name (McpAccountStorage *storage); -const gchar *mcp_account_storage_description (const McpAccountStorage *storage); -const gchar *mcp_account_storage_provider (const McpAccountStorage *storage); +const gchar *mcp_account_storage_description (McpAccountStorage *storage); +const gchar *mcp_account_storage_provider (McpAccountStorage *storage); GVariant *mcp_account_storage_get_attribute (McpAccountStorage *storage, McpAccountManager *am, diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index efcb19f4..b79b6bba 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -326,8 +326,8 @@ get_parameter (McpAccountStorage *self, } static gchar * -_create (const McpAccountStorage *self, - const McpAccountManager *am, +_create (McpAccountStorage *self, + McpAccountManager *am, const gchar *manager, const gchar *protocol, const gchar *identification, @@ -520,8 +520,8 @@ am_default_commit_one (McdAccountManagerDefault *self, } static gboolean -_commit (const McpAccountStorage *self, - const McpAccountManager *am, +_commit (McpAccountStorage *self, + McpAccountManager *am, const gchar *account) { McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); @@ -819,8 +819,8 @@ am_default_load_directory (McdAccountManagerDefault *self, } static GList * -_list (const McpAccountStorage *self, - const McpAccountManager *am) +_list (McpAccountStorage *self, + McpAccountManager *am) { GList *rval = NULL; McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); diff --git a/src/mcd-storage.c b/src/mcd-storage.c index cbca24e2..828d5a1b 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -409,8 +409,8 @@ identify_account_async (McpAccountManager *mcpa, static gint account_storage_cmp (gconstpointer a, gconstpointer b) { - gint pa = mcp_account_storage_priority (a); - gint pb = mcp_account_storage_priority (b); + gint pa = mcp_account_storage_priority ((McpAccountStorage *) a); + gint pb = mcp_account_storage_priority ((McpAccountStorage *) b); if (pa > pb) return -1; if (pa < pb) return 1; diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index 2e66179e..446a2ad7 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -748,8 +748,8 @@ parameters_changed_cb (GDBusConnection *bus, } static GList * -test_dbus_account_plugin_list (const McpAccountStorage *storage, - const McpAccountManager *am) +test_dbus_account_plugin_list (McpAccountStorage *storage, + McpAccountManager *am) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); GError *error = NULL; @@ -858,8 +858,8 @@ test_dbus_account_plugin_list (const McpAccountStorage *storage, } static void -test_dbus_account_plugin_ready (const McpAccountStorage *storage, - const McpAccountManager *am) +test_dbus_account_plugin_ready (McpAccountStorage *storage, + McpAccountManager *am) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); @@ -873,8 +873,8 @@ test_dbus_account_plugin_ready (const McpAccountStorage *storage, } static gchar * -test_dbus_account_plugin_create (const McpAccountStorage *storage, - const McpAccountManager *am, +test_dbus_account_plugin_create (McpAccountStorage *storage, + McpAccountManager *am, const gchar *manager, const gchar *protocol, const gchar *identifier, @@ -1286,8 +1286,8 @@ update_parameters_cb (GObject *source_object, } static gboolean -test_dbus_account_plugin_commit (const McpAccountStorage *storage, - const McpAccountManager *am, +test_dbus_account_plugin_commit (McpAccountStorage *storage, + McpAccountManager *am, const gchar *account_name) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); @@ -1436,7 +1436,7 @@ test_dbus_account_plugin_commit (const McpAccountStorage *storage, } static void -test_dbus_account_plugin_get_identifier (const McpAccountStorage *storage, +test_dbus_account_plugin_get_identifier (McpAccountStorage *storage, const gchar *account_name, GValue *identifier) { @@ -1455,7 +1455,7 @@ test_dbus_account_plugin_get_identifier (const McpAccountStorage *storage, } static GHashTable * -test_dbus_account_plugin_get_additional_info (const McpAccountStorage *storage, +test_dbus_account_plugin_get_additional_info (McpAccountStorage *storage, const gchar *account_name) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); @@ -1476,7 +1476,7 @@ test_dbus_account_plugin_get_additional_info (const McpAccountStorage *storage, } static guint -test_dbus_account_plugin_get_restrictions (const McpAccountStorage *storage, +test_dbus_account_plugin_get_restrictions (McpAccountStorage *storage, const gchar *account_name) { TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index 02775b4c..466d3ee3 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -250,8 +250,8 @@ _get_parameter (McpAccountStorage *self, return ret; } -static gboolean _commit (const McpAccountStorage *self, - const McpAccountManager *am, +static gboolean _commit (McpAccountStorage *self, + McpAccountManager *am, const gchar *account_name); static void @@ -292,8 +292,8 @@ delete_finish (McpAccountStorage *storage, } static gboolean -_commit (const McpAccountStorage *self, - const McpAccountManager *am, +_commit (McpAccountStorage *self, + McpAccountManager *am, const gchar *account_name G_GNUC_UNUSED) { gsize n; @@ -321,8 +321,8 @@ _commit (const McpAccountStorage *self, } static GList * -_list (const McpAccountStorage *self, - const McpAccountManager *am) +_list (McpAccountStorage *self, + McpAccountManager *am) { gsize i; gsize n; @@ -348,8 +348,8 @@ _list (const McpAccountStorage *self, } static gchar * -create (const McpAccountStorage *self, - const McpAccountManager *am, +create (McpAccountStorage *self, + McpAccountManager *am, const gchar *manager, const gchar *protocol, const gchar *identification, -- cgit v1.2.3 From 37221c0f0955fe6afa33eba483d45e5204700c35 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 27 Jan 2014 17:25:55 +0000 Subject: _mcd_account_manager_setup: simplify a loop As per Xavier's review, we don't need to call mcd_account_get_unique_name(), because account unique names (object path tails) are the keys in this map anyway. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27727 --- src/mcd-account-manager.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index fa031161..5ff7bc9c 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -1510,10 +1510,9 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) * It was added to uncork_storage_plugins() in 3d5b5e7a248d * without explanation */ g_hash_table_iter_init (&iter, account_manager->priv->accounts); - while (g_hash_table_iter_next (&iter, NULL, &v)) + while (g_hash_table_iter_next (&iter, &k, NULL)) { - mcd_storage_commit (storage, - mcd_account_get_unique_name (v)); + mcd_storage_commit (storage, k); } /* uncork signals from storage plugins */ -- cgit v1.2.3 From 8010027de1f36e2151ec7fdb438cbe4144e51383 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 27 Jan 2014 17:38:56 +0000 Subject: Make MCP_API_VERSION less misleading We didn't release this in 5.15, so it'll be the 5.18 API instead. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6a2f35aa..22b7f0a4 100644 --- a/configure.ac +++ b/configure.ac @@ -35,7 +35,7 @@ esac # If API has been removed or changed since last release, change MCP_API (which # is part of the directory name under /usr/include) to the version that # changed it -MCP_API_VERSION=5.15 +MCP_API_VERSION=5.18 AC_SUBST([MCP_API_VERSION]) # If ABI has been removed or changed since last release -- cgit v1.2.3 From c00effb16665ac09f3fa5bb781f2e65b0899f66b Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 27 Jan 2014 17:41:10 +0000 Subject: Define MCP_API_VERSION_5_18, so implementations can use #ifdef --- mission-control-plugins/loader.c | 15 +++++++++++++++ mission-control-plugins/mission-control-plugins.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/mission-control-plugins/loader.c b/mission-control-plugins/loader.c index 640d1d87..a23028b3 100644 --- a/mission-control-plugins/loader.c +++ b/mission-control-plugins/loader.c @@ -61,6 +61,21 @@ static gboolean debugging = FALSE; #define PLUGIN_PREFIX "libmcp-" #endif +/** + * MCP_API_VERSION_5_18: + * + * Defined to allow simple plugin implementations to support both Mission + * Control 5.16 and 5.18 plugin APIs: + * + * |[ + * #ifdef MCP_API_VERSION_5_18 + * ... // implement MC 5.18 API + * #else + * ... // implement MC 5.16 API + * #endif + * ]| + */ + /** * mcp_set_debug: * @debug: whether to log debug output diff --git a/mission-control-plugins/mission-control-plugins.h b/mission-control-plugins/mission-control-plugins.h index 806f472a..aa846f78 100644 --- a/mission-control-plugins/mission-control-plugins.h +++ b/mission-control-plugins/mission-control-plugins.h @@ -25,6 +25,8 @@ #include #include +#define MCP_API_VERSION_5_18 (518) + typedef enum { MCP_PARAMETER_FLAG_NONE = 0, } McpParameterFlags; -- cgit v1.2.3 From 1beafc65f2125df00f89a8e47c7ac67a7be9fb9b Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 27 Jan 2014 20:16:21 +0000 Subject: Add dedicated tests for keyfile-based storage These are impossible to test without restarting Mission Control, because we only read from one such location at a time; so there's no point in trying to bundle them into one test. --- tests/twisted/Makefile.am | 6 +- tests/twisted/account-storage/5-12.py | 29 ++++ tests/twisted/account-storage/5-14.py | 29 ++++ .../account-storage/default-keyring-storage.py | 54 +------- tests/twisted/account-storage/storage_helper.py | 149 +++++++++++++++++++++ 5 files changed, 213 insertions(+), 54 deletions(-) create mode 100644 tests/twisted/account-storage/5-12.py create mode 100644 tests/twisted/account-storage/5-14.py create mode 100644 tests/twisted/account-storage/storage_helper.py diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am index 587d6b0c..1f7dd21c 100644 --- a/tests/twisted/Makefile.am +++ b/tests/twisted/Makefile.am @@ -75,7 +75,10 @@ TWISTED_BASIC_TESTS = \ TWISTED_SPECIAL_BUILD_TESTS = \ account-manager/connectivity.py \ account-storage/default-keyring-storage.py \ - account-storage/diverted-storage.py + account-storage/diverted-storage.py \ + account-storage/5-12.py \ + account-storage/5-14.py \ + $(NULL) # Tests that are usually too slow to run. TWISTED_SLOW_TESTS = \ @@ -105,6 +108,7 @@ TWISTED_OTHER_FILES = \ fakeconnectivity.py \ mctest.py \ servicetest.py \ + account-storage/storage_helper.py \ telepathy/clients/README \ telepathy/clients/AbiWord.client \ telepathy/clients/Logger.client \ diff --git a/tests/twisted/account-storage/5-12.py b/tests/twisted/account-storage/5-12.py new file mode 100644 index 00000000..9075d767 --- /dev/null +++ b/tests/twisted/account-storage/5-12.py @@ -0,0 +1,29 @@ +# Test for a former default account storage backend: +# ~/.mission-control/accounts.cfg, as used in MC 5.0 to 5.13.1 +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 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 + +from storage_helper import test_keyfile +from mctest import exec_test + +def test_5_12(q, bus, mc): + test_keyfile(q, bus, mc, '5.12') + +if __name__ == '__main__': + exec_test(test_5_12, {}, preload_mc=False, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/5-14.py b/tests/twisted/account-storage/5-14.py new file mode 100644 index 00000000..42deb3ec --- /dev/null +++ b/tests/twisted/account-storage/5-14.py @@ -0,0 +1,29 @@ +# Test for a former default account storage backend: +# XDG_DATA_HOME/telepathy/mission-control/accounts.cfg, as used in MC 5.14 +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 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 + +from storage_helper import test_keyfile +from mctest import exec_test + +def test_5_14(q, bus, mc): + test_keyfile(q, bus, mc, '5.14') + +if __name__ == '__main__': + exec_test(test_5_14, {}, preload_mc=False, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/default-keyring-storage.py b/tests/twisted/account-storage/default-keyring-storage.py index 27b45e51..2281387f 100644 --- a/tests/twisted/account-storage/default-keyring-storage.py +++ b/tests/twisted/account-storage/default-keyring-storage.py @@ -32,32 +32,9 @@ from mctest import ( exec_test, create_fakecm_account, get_fakecm_account, connect_to_mc, keyfile_read, tell_mc_to_die, resuscitate_mc ) +from storage_helper import (account_store) import constants as cs -# This doesn't escape its parameters before passing them to the shell, -# so be careful. -def account_store(op, backend, key=None, value=None, - account='fakecm/fakeprotocol/dontdivert_40example_2ecom0'): - cmd = [ '../account-store', op, backend, account ] - 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 test(q, bus, mc): ctl_dir = os.environ['MC_ACCOUNT_DIR'] old_key_file_name = os.path.join(ctl_dir, 'accounts.cfg') @@ -279,35 +256,6 @@ def test(q, bus, mc): pwd = account_store('get', 'variant-file', 'param-password') assertEquals(None, pwd) - # Write out an account configuration in the old keyfile, to test - # migration from there - os.remove(new_variant_file_name) - os.remove(new_variant_file_name.replace('.account', 'masked.account')) - os.remove(new_variant_file_name.replace('.account', 'priority.account')) - os.remove(low_prio_variant_file_name) - os.remove(low_prio_variant_file_name.replace('.account', 'masked.account')) - os.remove(low_prio_variant_file_name.replace('.account', 'priority.account')) - open(old_key_file_name, 'w').write( -r"""# Telepathy accounts -[%s] -manager=fakecm -protocol=fakeprotocol -param-account=dontdivert@example.com -DisplayName=Ye olde account -AutomaticPresence=2;available;; -""" % group) - - account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) - account = get_fakecm_account(bus, mc, account_path) - account_iface = dbus.Interface(account, cs.ACCOUNT) - - # This time it *does* get deleted automatically during MC startup, - # after copying its contents to the new name/format - assert not os.path.exists(old_key_file_name) - assert not os.path.exists(low_prio_variant_file_name) - assertEquals("'Ye olde account'", - account_store('get', 'variant-file', 'DisplayName')) - if __name__ == '__main__': ctl_dir = os.environ['MC_ACCOUNT_DIR'] try: diff --git a/tests/twisted/account-storage/storage_helper.py b/tests/twisted/account-storage/storage_helper.py new file mode 100644 index 00000000..42bfcf1e --- /dev/null +++ b/tests/twisted/account-storage/storage_helper.py @@ -0,0 +1,149 @@ +# Helper code for former default account storage backends +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 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 errno +import os +import os.path + +from servicetest import ( + assertEquals, assertContains, assertLength, + ) +from mctest import ( + exec_test, get_fakecm_account, connect_to_mc, + MC, SimulatedConnectionManager, + ) +import constants as cs + +# This doesn't escape its parameters before passing them to the shell, +# so be careful. +def account_store(op, backend, key=None, value=None, + account='fakecm/fakeprotocol/dontdivert_40example_2ecom0'): + cmd = [ '../account-store', op, backend, account ] + 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 test_keyfile(q, bus, mc, how_old='5.12'): + simulated_cm = SimulatedConnectionManager(q, bus) + + if how_old == '5.12': + # This is not actually ~/.mission-control, but it uses the same + # code paths. + dot_mission_control = os.environ['MC_ACCOUNT_DIR'] + old_key_file_name = os.path.join(dot_mission_control, 'accounts.cfg') + elif how_old == '5.14': + # Same format, different location. + old_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', 'accounts.cfg') + else: + raise AssertionError('Unsupported value for how_old') + + a1_new_variant_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert1_40example_2ecom0.account') + a1_tail = 'fakecm/fakeprotocol/dontdivert1_40example_2ecom0' + + a2_new_variant_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert2_40example_2ecom0.account') + a2_tail = 'fakecm/fakeprotocol/dontdivert2_40example_2ecom0' + + try: + os.makedirs(os.path.dirname(old_key_file_name), 0700) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + open(old_key_file_name, 'w').write( +r"""# Telepathy accounts +[%s] +manager=fakecm +protocol=fakeprotocol +param-account=dontdivert1@example.com +param-password=1 +DisplayName=First among equals +AutomaticPresence=2;available;; + +[%s] +manager=fakecm +protocol=fakeprotocol +param-account=dontdivert2@example.com +param-password=2 +DisplayName=Second to none +AutomaticPresence=2;available;; +""" % (a1_tail, a2_tail)) + + mc = MC(q, bus) + account_manager, properties, interfaces = connect_to_mc(q, bus, mc) + + # During MC startup, it moved the old keyfile's contents into + # variant-based files, and deleted the old keyfile. + assert not os.path.exists(old_key_file_name) + assert os.path.exists(a1_new_variant_file_name) + assert os.path.exists(a2_new_variant_file_name) + assertEquals("'First among equals'", + account_store('get', 'variant-file', 'DisplayName', + account=a1_tail)) + assertEquals("'Second to none'", + account_store('get', 'variant-file', 'DisplayName', + account=a2_tail)) + # MC doesn't currently ensure that parameters are stored with their + # proper types. + assertEquals("keyfile-escaped 'dontdivert1@example.com'", + account_store('get', 'variant-file', 'param-account', + account=a1_tail)) + assertEquals("keyfile-escaped 'dontdivert2@example.com'", + account_store('get', 'variant-file', 'param-account', + account=a2_tail)) + + # Also, MC has both accounts in memory... + assertContains(cs.ACCOUNT_PATH_PREFIX + a1_tail, + properties['ValidAccounts']) + account = get_fakecm_account(bus, mc, cs.ACCOUNT_PATH_PREFIX + a1_tail) + assertEquals('dontdivert1@example.com', + account.Properties.Get(cs.ACCOUNT, 'Parameters')['account']) + assertEquals('First among equals', + account.Properties.Get(cs.ACCOUNT, 'DisplayName')) + + assertContains(cs.ACCOUNT_PATH_PREFIX + a2_tail, + properties['ValidAccounts']) + account = get_fakecm_account(bus, mc, cs.ACCOUNT_PATH_PREFIX + a2_tail) + assertEquals('dontdivert2@example.com', + account.Properties.Get(cs.ACCOUNT, 'Parameters')['account']) + assertEquals('Second to none', + account.Properties.Get(cs.ACCOUNT, 'DisplayName')) + + # ... and no other accounts. + assertLength(2, properties['ValidAccounts']) -- cgit v1.2.3 From 3c32422dfcdcfcd16f106b7a5107cbe35be93e36 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 27 Jan 2014 20:16:33 +0000 Subject: McdAccount: improve debug output for account validity --- src/mcd-account.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/mcd-account.c b/src/mcd-account.c index 6253a7ef..28e3602c 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -315,6 +315,20 @@ mcd_account_loaded (McdAccount *account) g_return_if_fail (!account->priv->loaded); account->priv->loaded = TRUE; + if (account->priv->invalid_reason == NULL) + { + DEBUG ("account %s is now loaded and valid", + account->priv->unique_name); + } + else + { + DEBUG ("account %s is now loaded, but not valid: %s #%d: %s", + account->priv->unique_name, + g_quark_to_string (account->priv->invalid_reason->domain), + account->priv->invalid_reason->code, + account->priv->invalid_reason->message); + } + /* invoke all the callbacks */ g_object_ref (account); @@ -799,10 +813,29 @@ _mcd_account_load (McdAccount *account, McdAccountLoadCb callback, gpointer user_data) { if (account->priv->loaded) + { + if (account->priv->invalid_reason == NULL) + { + DEBUG ("account %s already loaded and valid", + account->priv->unique_name); + } + else + { + DEBUG ("account %s already loaded, but not valid: %s #%d: %s", + account->priv->unique_name, + g_quark_to_string (account->priv->invalid_reason->domain), + account->priv->invalid_reason->code, + account->priv->invalid_reason->message); + } + callback (account, NULL, user_data); + } else + { + DEBUG ("account %s not yet loaded", account->priv->unique_name); _mcd_object_call_when_ready (account, account_ready_quark, (McdReadyCb)callback, user_data); + } } static void -- cgit v1.2.3 From ed7bf646a77630de9e24641d5ca889904132fe85 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 27 Jan 2014 20:58:20 +0000 Subject: Chop up the increasingly inaccurately-named default-keyring-storage test This test hasn't dealt with a keyring for a while, and now only covers "variant files". Split it into two: one deals with creating an account at runtime in the default backend, and one deals with loading files from disk. --- tests/twisted/Makefile.am | 3 +- tests/twisted/account-storage/create-new.py | 136 +++++++++++ .../account-storage/default-keyring-storage.py | 265 --------------------- tests/twisted/account-storage/load-keyfiles.py | 202 ++++++++++++++++ 4 files changed, 340 insertions(+), 266 deletions(-) create mode 100644 tests/twisted/account-storage/create-new.py delete mode 100644 tests/twisted/account-storage/default-keyring-storage.py create mode 100644 tests/twisted/account-storage/load-keyfiles.py diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am index 1f7dd21c..2a96647f 100644 --- a/tests/twisted/Makefile.am +++ b/tests/twisted/Makefile.am @@ -74,10 +74,11 @@ TWISTED_BASIC_TESTS = \ # account-storage/*.py need their own instances. TWISTED_SPECIAL_BUILD_TESTS = \ account-manager/connectivity.py \ - account-storage/default-keyring-storage.py \ account-storage/diverted-storage.py \ account-storage/5-12.py \ account-storage/5-14.py \ + account-storage/create-new.py \ + account-storage/load-keyfiles.py \ $(NULL) # Tests that are usually too slow to run. diff --git a/tests/twisted/account-storage/create-new.py b/tests/twisted/account-storage/create-new.py new file mode 100644 index 00000000..f77624a9 --- /dev/null +++ b/tests/twisted/account-storage/create-new.py @@ -0,0 +1,136 @@ +# Test for "stringified GVariant per account" storage backend introduced in +# Mission Control 5.16, when creating a new account stored in this default +# backend +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 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 time +import os +import os.path +import signal + +import dbus +import dbus.service + +from servicetest import ( + EventPattern, assertEquals, + ) +from mctest import ( + exec_test, create_fakecm_account, connect_to_mc, + ) +from storage_helper import (account_store) +import constants as cs + +def test(q, bus, mc): + ctl_dir = os.environ['MC_ACCOUNT_DIR'] + old_key_file_name = os.path.join(ctl_dir, 'accounts.cfg') + newer_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', 'accounts.cfg') + new_variant_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert_40example_2ecom0.account') + + account_manager, properties, interfaces = connect_to_mc(q, bus, mc) + + assert properties.get('ValidAccounts') == [], \ + properties.get('ValidAccounts') + assert properties.get('InvalidAccounts') == [], \ + properties.get('InvalidAccounts') + + params = dbus.Dictionary({"account": "dontdivert@example.com", + "password": "secrecy", + "snakes": dbus.UInt32(23)}, signature='sv') + (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) + + account_path = account.__dbus_object_path__ + + # Check the account is correctly created + properties = account_manager.GetAll(cs.AM, + dbus_interface=cs.PROPERTIES_IFACE) + assert properties is not None + assert properties.get('ValidAccounts') == [account_path], properties + account_path = properties['ValidAccounts'][0] + assert isinstance(account_path, dbus.ObjectPath), repr(account_path) + assert properties.get('InvalidAccounts') == [], properties + + account_iface = dbus.Interface(account, cs.ACCOUNT) + account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) + + # Alter some miscellaneous r/w properties + + account_props.Set(cs.ACCOUNT, 'DisplayName', 'Work account') + account_props.Set(cs.ACCOUNT, 'Icon', 'im-jabber') + account_props.Set(cs.ACCOUNT, 'Nickname', 'Joe Bloggs') + account_props.Set(cs.ACCOUNT, 'ConnectAutomatically', True) + account_props.Set(cs.ACCOUNT, 'AutomaticPresence', + (dbus.UInt32(cs.PRESENCE_EXTENDED_AWAY), 'xa', + 'never online')) + + # .. let's check the keyfile + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(new_variant_file_name) + assert 'Joe Bloggs' in open(new_variant_file_name).read() + assertEquals("'fakecm'", account_store('get', 'variant-file', 'manager')) + assertEquals("'fakeprotocol'", account_store('get', 'variant-file', + 'protocol')) + assertEquals("'Work account'", account_store('get', 'variant-file', + 'DisplayName')) + assertEquals("'im-jabber'", account_store('get', 'variant-file', + 'Icon')) + assertEquals("'Joe Bloggs'", account_store('get', 'variant-file', + 'Nickname')) + assertEquals('true', account_store('get', 'variant-file', + 'ConnectAutomatically')) + assertEquals("(uint32 4, 'xa', 'never online')", + account_store('get', 'variant-file', 'AutomaticPresence')) + assertEquals("'dontdivert@example.com'", + account_store('get', 'variant-file', 'param-account')) + assertEquals("uint32 23", + account_store('get', 'variant-file', 'param-snakes')) + assertEquals("'secrecy'", + account_store('get', 'variant-file', 'param-password')) + + assertEquals({'password': 'secrecy', 'account': 'dontdivert@example.com', + 'snakes': 23}, account.Properties.Get(cs.ACCOUNT, 'Parameters')) + + # Delete the account + assert account_iface.Remove() is None + account_event, account_manager_event = q.expect_many( + EventPattern('dbus-signal', + path=account_path, + signal='Removed', + interface=cs.ACCOUNT, + args=[] + ), + EventPattern('dbus-signal', + path=cs.AM_PATH, + signal='AccountRemoved', + interface=cs.AM, + args=[account_path] + ), + ) + + # Check the account is correctly deleted + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert not os.path.exists(new_variant_file_name) + +if __name__ == '__main__': + exec_test(test, {}, timeout=10, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/default-keyring-storage.py b/tests/twisted/account-storage/default-keyring-storage.py deleted file mode 100644 index 2281387f..00000000 --- a/tests/twisted/account-storage/default-keyring-storage.py +++ /dev/null @@ -1,265 +0,0 @@ -# Test for default account storage backend. -# -# 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 time -import os -import os.path -import signal - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async, assertEquals, assertContains, assertDoesNotContain -from mctest import ( - exec_test, create_fakecm_account, get_fakecm_account, connect_to_mc, - keyfile_read, tell_mc_to_die, resuscitate_mc - ) -from storage_helper import (account_store) -import constants as cs - -def test(q, bus, mc): - ctl_dir = os.environ['MC_ACCOUNT_DIR'] - old_key_file_name = os.path.join(ctl_dir, 'accounts.cfg') - newer_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], - 'telepathy', 'mission-control', 'accounts.cfg') - new_variant_file_name = os.path.join(os.environ['XDG_DATA_HOME'], - 'telepathy', 'mission-control', - 'fakecm-fakeprotocol-dontdivert_40example_2ecom0.account') - group = 'fakecm/fakeprotocol/dontdivert_40example_2ecom0' - - account_manager, properties, interfaces = connect_to_mc(q, bus, mc) - - assert properties.get('ValidAccounts') == [], \ - properties.get('ValidAccounts') - assert properties.get('InvalidAccounts') == [], \ - properties.get('InvalidAccounts') - - params = dbus.Dictionary({"account": "dontdivert@example.com", - "password": "secrecy", - "snakes": dbus.UInt32(23)}, signature='sv') - (simulated_cm, account) = create_fakecm_account(q, bus, mc, params) - - account_path = account.__dbus_object_path__ - - # Check the account is correctly created - properties = account_manager.GetAll(cs.AM, - dbus_interface=cs.PROPERTIES_IFACE) - assert properties is not None - assert properties.get('ValidAccounts') == [account_path], properties - account_path = properties['ValidAccounts'][0] - assert isinstance(account_path, dbus.ObjectPath), repr(account_path) - assert properties.get('InvalidAccounts') == [], properties - - account_iface = dbus.Interface(account, cs.ACCOUNT) - account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) - - # Alter some miscellaneous r/w properties - - account_props.Set(cs.ACCOUNT, 'DisplayName', 'Work account') - account_props.Set(cs.ACCOUNT, 'Icon', 'im-jabber') - account_props.Set(cs.ACCOUNT, 'Nickname', 'Joe Bloggs') - account_props.Set(cs.ACCOUNT, 'ConnectAutomatically', True) - account_props.Set(cs.ACCOUNT, 'AutomaticPresence', - (dbus.UInt32(cs.PRESENCE_EXTENDED_AWAY), 'xa', - 'never online')) - - tell_mc_to_die(q, bus) - - # .. let's check the keyfile - assert not os.path.exists(old_key_file_name) - assert not os.path.exists(newer_key_file_name) - assert 'Joe Bloggs' in open(new_variant_file_name).read() - assertEquals("'fakecm'", account_store('get', 'variant-file', 'manager')) - assertEquals("'fakeprotocol'", account_store('get', 'variant-file', - 'protocol')) - assertEquals("'Work account'", account_store('get', 'variant-file', - 'DisplayName')) - assertEquals("'im-jabber'", account_store('get', 'variant-file', - 'Icon')) - assertEquals("'Joe Bloggs'", account_store('get', 'variant-file', - 'Nickname')) - assertEquals('true', account_store('get', 'variant-file', - 'ConnectAutomatically')) - assertEquals("(uint32 4, 'xa', 'never online')", - account_store('get', 'variant-file', 'AutomaticPresence')) - assertEquals("'dontdivert@example.com'", - account_store('get', 'variant-file', 'param-account')) - assertEquals("uint32 23", - account_store('get', 'variant-file', 'param-snakes')) - assertEquals("'secrecy'", - account_store('get', 'variant-file', 'param-password')) - - # Reactivate MC - account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) - account = get_fakecm_account(bus, mc, account_path) - account_iface = dbus.Interface(account, cs.ACCOUNT) - - assertEquals({'password': 'secrecy', 'account': 'dontdivert@example.com', - 'snakes': 23}, account.Properties.Get(cs.ACCOUNT, 'Parameters')) - - # Delete the account - assert account_iface.Remove() is None - account_event, account_manager_event = q.expect_many( - EventPattern('dbus-signal', - path=account_path, - signal='Removed', - interface=cs.ACCOUNT, - args=[] - ), - EventPattern('dbus-signal', - path=cs.AM_PATH, - signal='AccountRemoved', - interface=cs.AM, - args=[account_path] - ), - ) - - # Check the account is correctly deleted - assert not os.path.exists(old_key_file_name) - assert not os.path.exists(newer_key_file_name) - assert not os.path.exists(new_variant_file_name) - - # Tell MC to die, again - tell_mc_to_die(q, bus) - - low_prio_variant_file_name = os.path.join( - os.environ['XDG_DATA_DIRS'].split(':')[0], - 'telepathy', 'mission-control', - 'fakecm-fakeprotocol-dontdivert_40example_2ecom0.account') - os.makedirs(os.path.dirname(low_prio_variant_file_name), 0700) - - # This is deliberately a lower-priority location - open(low_prio_variant_file_name, 'w').write( -"""{ -'manager': <'fakecm'>, -'protocol': <'fakeprotocol'>, -'DisplayName': <'New and improved account'>, -'AutomaticPresence': <(uint32 2, 'available', '')>, -'KeyFileParameters': <{ - 'account': 'dontdivert@example.com', - 'password': 'password_in_variant_file', - 'snakes': '42' - }> -} -""") - - # This version of this account will be used - open(new_variant_file_name.replace('.account', 'priority.account'), - 'w').write("""{ -'manager': <'fakecm'>, -'protocol': <'fakeprotocol'>, -'DisplayName': <'Visible'>, -'AutomaticPresence': <(uint32 2, 'available', '')>, -'KeyFileParameters': <{'account': 'dontdivert@example.com', - 'password': 'password_in_variant_file'}> -} -""") - # This one won't, because it's "masked" by the higher-priority one - open(low_prio_variant_file_name.replace('.account', 'priority.account'), - 'w').write("""{ -'manager': <'fakecm'>, -'protocol': <'fakeprotocol'>, -'DisplayName': <'Hidden'>, -'Nickname': <'Hidden'>, -'AutomaticPresence': <(uint32 2, 'available', '')>, -'KeyFileParameters': <{'account': 'dontdivert@example.com', - 'password': 'password_in_variant_file'}> -} -""") - - # This empty file is considered to "mask" the lower-priority one - open(new_variant_file_name.replace('.account', 'masked.account'), - 'w').write('') - open(low_prio_variant_file_name.replace('.account', 'masked.account'), - 'w').write("""{ -'manager': <'fakecm'>, -'protocol': <'fakeprotocol'>, -'AutomaticPresence': <(uint32 2, 'available', '')>, -'KeyFileParameters': <{'account': 'dontdivert@example.com', - 'password': 'password_in_variant_file'}> -} -""") - - account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) - assertContains(account_path, properties['ValidAccounts']) - account = get_fakecm_account(bus, mc, account_path) - account_iface = dbus.Interface(account, cs.ACCOUNT) - - assertEquals(42, - account.Properties.Get(cs.ACCOUNT, 'Parameters')['snakes']) - assertEquals(dbus.UInt32, - type(account.Properties.Get(cs.ACCOUNT, 'Parameters')['snakes'])) - - # Files in lower-priority XDG locations aren't copied until something - # actually changes, and they aren't deleted. - assert not os.path.exists(new_variant_file_name) - assert os.path.exists(low_prio_variant_file_name) - - # Delete the password (only), like Empathy 3.0-3.4 do when migrating - account_iface.UpdateParameters({}, ['password']) - q.expect('dbus-signal', - path=account_path, - signal='AccountPropertyChanged', - interface=cs.ACCOUNT, - predicate=(lambda e: - 'Parameters' in e.args[0]), - ) - - # test that "masking" works - assertDoesNotContain(account_path + "masked", properties['ValidAccounts']) - assertDoesNotContain(account_path + "masked", - properties['InvalidAccounts']) - - # test that priority works - assertContains(account_path + "priority", properties['ValidAccounts']) - priority_account = get_fakecm_account(bus, mc, account_path + "priority") - assertEquals('', priority_account.Properties.Get(cs.ACCOUNT, 'Nickname')) - assertEquals('Visible', - priority_account.Properties.Get(cs.ACCOUNT, 'DisplayName')) - - # test what happens when we delete an account that has a lower-priority - # "other self" - assert priority_account.Remove() is None - - # Tell MC to die yet again - tell_mc_to_die(q, bus) - - # Check the account has copied (not moved! XDG_DATA_DIRS are, - # conceptually, read-only) from the old to the new name - assert not os.path.exists(old_key_file_name) - assert not os.path.exists(newer_key_file_name) - assert os.path.exists(low_prio_variant_file_name) - assert os.path.exists(new_variant_file_name) - assert open(new_variant_file_name.replace('.account', 'masked.account'), - 'r').read() == '' - assert open(new_variant_file_name.replace('.account', 'priority.account'), - 'r').read() == '' - - pwd = account_store('get', 'variant-file', 'param-password') - assertEquals(None, pwd) - -if __name__ == '__main__': - ctl_dir = os.environ['MC_ACCOUNT_DIR'] - try: - os.mkdir(ctl_dir, 0700) - except OSError: - pass - exec_test(test, {}, timeout=10, use_fake_accounts_service=False) diff --git a/tests/twisted/account-storage/load-keyfiles.py b/tests/twisted/account-storage/load-keyfiles.py new file mode 100644 index 00000000..35280db2 --- /dev/null +++ b/tests/twisted/account-storage/load-keyfiles.py @@ -0,0 +1,202 @@ +# Test for "stringified GVariant per account" storage backend introduced in +# Mission Control 5.16, when loading pre-prepared files +# +# Copyright (C) 2009-2010 Nokia Corporation +# Copyright (C) 2009-2014 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 errno +import os +import os.path + +import dbus + +from servicetest import ( + assertEquals, assertContains, assertDoesNotContain, + ) +from mctest import ( + MC, exec_test, get_fakecm_account, connect_to_mc, + SimulatedConnectionManager, + ) +import constants as cs + +def test(q, bus, mc): + simulated_cm = SimulatedConnectionManager(q, bus) + + ctl_dir = os.environ['MC_ACCOUNT_DIR'] + old_key_file_name = os.path.join(ctl_dir, 'accounts.cfg') + newer_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', 'accounts.cfg') + + # We do several scenarios in one MC run, to speed up testing a bit. + scenarios = ('low', 'priority', 'masked') + + variant_file_names = {} + low_prio_variant_file_names = {} + account_paths = {} + tails = {} + + for s in scenarios: + variant_file_names[s] = os.path.join(os.environ['XDG_DATA_HOME'], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert%s_40example_2ecom0.account' + % s) + tails[s] = ('fakecm/fakeprotocol/dontdivert%s_40example_2ecom0' % s) + account_paths[s] = cs.ACCOUNT_PATH_PREFIX + tails[s] + low_prio_variant_file_names[s] = os.path.join( + os.environ['XDG_DATA_DIRS'].split(':')[0], + 'telepathy', 'mission-control', + 'fakecm-fakeprotocol-dontdivert%s_40example_2ecom0.account' % + s) + + try: + os.makedirs(os.path.dirname(variant_file_names[s]), 0700) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + try: + os.makedirs(os.path.dirname(low_prio_variant_file_names[s]), 0700) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + # This is deliberately a lower-priority location + open(low_prio_variant_file_names['low'], 'w').write( +"""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'DisplayName': <'Account in a low-priority location'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{ + 'account': 'dontdivertlow@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + + # This version of this account will be used + open(variant_file_names['priority'], 'w').write("""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'DisplayName': <'Visible'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{'account': 'dontdivertpriority@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + # This one won't, because it's "masked" by the higher-priority one + open(low_prio_variant_file_names['priority'], 'w').write("""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'DisplayName': <'Hidden'>, +'Nickname': <'Hidden'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{'account': 'dontdivertpriority@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + + # This empty file is considered to "mask" the lower-priority one + open(variant_file_names['masked'], 'w').write('') + open(low_prio_variant_file_names['masked'], 'w').write("""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{'account': 'dontdivert@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + + mc = MC(q, bus) + account_manager, properties, interfaces = connect_to_mc(q, bus, mc) + + for s in scenarios: + if s == 'masked': + assertDoesNotContain(account_paths[s], properties['ValidAccounts']) + else: + assertContains(account_paths[s], properties['ValidAccounts']) + + assertDoesNotContain(account_paths[s], properties['InvalidAccounts']) + + accounts = {} + account_ifaces = {} + + for s in scenarios: + if s != 'masked': + accounts[s] = get_fakecm_account(bus, mc, account_paths[s]) + account_ifaces[s] = dbus.Interface(accounts[s], cs.ACCOUNT) + + assertEquals(42, accounts[s].Properties.Get(cs.ACCOUNT, + 'Parameters')['snakes']) + assertEquals(dbus.UInt32, + type(accounts[s].Properties.Get(cs.ACCOUNT, + 'Parameters')['snakes'])) + + # Files in lower-priority XDG locations aren't copied until something + # actually changes, and they aren't deleted. + + if s == 'low': + assert os.path.exists(low_prio_variant_file_names[s]) + + # Delete the password (only), like Empathy 3.0-3.4 do when migrating. + # This results in the higher-priority file being written out. + account_ifaces['low'].UpdateParameters({}, ['password']) + q.expect('dbus-signal', + path=account_paths['low'], + signal='AccountPropertyChanged', + interface=cs.ACCOUNT, + predicate=(lambda e: + 'Parameters' in e.args[0]), + ) + # Check the account has copied (not moved! XDG_DATA_DIRS are, + # conceptually, read-only) 'low' from the old to the new name + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['low']) + assert os.path.exists(variant_file_names['low']) + + # test that priority works + assertContains(account_paths["priority"], properties['ValidAccounts']) + assertEquals('', + accounts['priority'].Properties.Get(cs.ACCOUNT, 'Nickname')) + assertEquals('Visible', + accounts['priority'].Properties.Get(cs.ACCOUNT, 'DisplayName')) + + # test what happens when we delete an account that has a lower-priority + # "other self": it becomes masked + assert accounts['priority'].Remove() is None + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['priority']) + assert os.path.exists(variant_file_names['priority']) + assert open(variant_file_names['priority'], 'r').read() == '' + assertContains('password_in_variant_file', + open(low_prio_variant_file_names['priority'], 'r').read()) + + # The masked account is still masked + assert open(variant_file_names['masked'], 'r').read() == '' + +if __name__ == '__main__': + exec_test(test, {}, preload_mc=False, use_fake_accounts_service=False) -- cgit v1.2.3 From 70272b8fd90c65700bd0f6a8d7a4cc3849d42e21 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 28 Jan 2014 11:26:29 +0000 Subject: Only exercise old avatar storage locations in 5-12 and 5-14 tests Otherwise, it will reduce test coverage while porting to Telepathy 1.0: all the tests dealing with old locations need to be disabled until we implement 0.x -> 1.0 migration. --- tests/twisted/account-manager/auto-connect.py | 9 +++++++-- tests/twisted/account-manager/avatar-refresh.py | 22 +--------------------- tests/twisted/account-storage/storage_helper.py | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/tests/twisted/account-manager/auto-connect.py b/tests/twisted/account-manager/auto-connect.py index 46b13364..28cfb2ab 100644 --- a/tests/twisted/account-manager/auto-connect.py +++ b/tests/twisted/account-manager/auto-connect.py @@ -21,6 +21,7 @@ import dbus """ import os +import os.path import dbus import dbus.service @@ -65,8 +66,12 @@ def preseed(q, bus, fake_accounts_service): 'password': r'\\\\ionstorm\\\\', }) - os.makedirs(accounts_dir + '/' + account_id) - avatar_bin = open(accounts_dir + '/' + account_id + '/avatar.bin', 'w') + avatar_filename = account_id + avatar_filename = avatar_filename.replace('/', '-') + '.avatar' + avatar_filename = (os.environ['XDG_DATA_HOME'] + + '/telepathy/mission-control/' + avatar_filename) + os.makedirs(os.path.dirname(avatar_filename)) + avatar_bin = open(avatar_filename, 'w') avatar_bin.write('Deus Ex') avatar_bin.close() diff --git a/tests/twisted/account-manager/avatar-refresh.py b/tests/twisted/account-manager/avatar-refresh.py index f76d7fb6..d914c439 100644 --- a/tests/twisted/account-manager/avatar-refresh.py +++ b/tests/twisted/account-manager/avatar-refresh.py @@ -90,15 +90,6 @@ class Account(object): avatar_bin = open(avatar_filename, 'w') avatar_bin.write(local_avatar) avatar_bin.close() - elif not avatars_persist: - self.avatar_location = 'old' - # exercise migration from ~/.mission-control in a - # situation where MC should "win" - os.makedirs(accounts_dir + '/' + self.id) - avatar_bin = open( - accounts_dir + '/' + self.id + '/avatar.bin', 'w') - avatar_bin.write(local_avatar) - avatar_bin.close() else: # store it in the normal location self.avatar_location = 'home' @@ -258,18 +249,7 @@ class Account(object): self.test_migration(bus, q, conn, account_proxy) def test_migration(self, bus, q, conn, account_proxy): - if self.avatar_location == 'old': - # The avatar got migrated to the new location. - assert not os.path.exists(os.environ['MC_ACCOUNT_DIR'] + '/' + - self.id + '/avatar.bin') - assert not os.path.exists(os.environ['MC_ACCOUNT_DIR'] + '/fakecm') - avatar_filename = self.id - avatar_filename = avatar_filename.replace('/', '-') + '.avatar' - avatar_filename = (os.environ['XDG_DATA_HOME'] + - '/telepathy/mission-control/' + avatar_filename) - assertEquals(conn.avatar[0], ''.join(open(avatar_filename, - 'r').readlines())) - elif self.avatar_location == 'datadir' and self.winner == 'service': + if self.avatar_location == 'datadir' and self.winner == 'service': # The avatar wasn't deleted from $XDG_DATA_DIRS, but it was # overridden. assert not os.path.exists(os.environ['MC_ACCOUNT_DIR'] + '/' + diff --git a/tests/twisted/account-storage/storage_helper.py b/tests/twisted/account-storage/storage_helper.py index 42bfcf1e..ebbe78e6 100644 --- a/tests/twisted/account-storage/storage_helper.py +++ b/tests/twisted/account-storage/storage_helper.py @@ -22,6 +22,8 @@ import errno import os import os.path +import dbus + from servicetest import ( assertEquals, assertContains, assertLength, ) @@ -63,10 +65,28 @@ def test_keyfile(q, bus, mc, how_old='5.12'): # code paths. dot_mission_control = os.environ['MC_ACCOUNT_DIR'] old_key_file_name = os.path.join(dot_mission_control, 'accounts.cfg') + + os.makedirs(dot_mission_control + + '/fakecm/fakeprotocol/dontdivert1_40example_2ecom0') + avatar_bin = open(dot_mission_control + + '/fakecm/fakeprotocol/dontdivert1_40example_2ecom0/avatar.bin', + 'w') + avatar_bin.write('hello, world') + avatar_bin.close() elif how_old == '5.14': # Same format, different location. old_key_file_name = os.path.join(os.environ['XDG_DATA_HOME'], 'telepathy', 'mission-control', 'accounts.cfg') + + # exercise override of an avatar in XDG_DATA_DIRS + avatar_dir = (os.environ['XDG_DATA_DIRS'].split(':')[0] + + '/telepathy/mission-control') + os.makedirs(avatar_dir) + avatar_bin = open(avatar_dir + + '/fakecm-fakeprotocol-dontdivert1_40example_2ecom0.avatar', + 'w') + avatar_bin.write('hello, world') + avatar_bin.close() else: raise AssertionError('Unsupported value for how_old') @@ -95,6 +115,8 @@ param-account=dontdivert1@example.com param-password=1 DisplayName=First among equals AutomaticPresence=2;available;; +AvatarMime=text/plain +avatar_token=hello, world [%s] manager=fakecm @@ -136,6 +158,9 @@ AutomaticPresence=2;available;; account.Properties.Get(cs.ACCOUNT, 'Parameters')['account']) assertEquals('First among equals', account.Properties.Get(cs.ACCOUNT, 'DisplayName')) + assertEquals((dbus.ByteArray('hello, world'), 'text/plain'), + account.Properties.Get(cs.ACCOUNT_IFACE_AVATAR, 'Avatar', + byte_arrays=True)) assertContains(cs.ACCOUNT_PATH_PREFIX + a2_tail, properties['ValidAccounts']) -- cgit v1.2.3 From 08ade738693e685d7de271792f605ebbc8af03df Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 28 Jan 2014 16:30:07 +0000 Subject: McdAccountManagerDefault: opportunistically save parameters' types --- src/mcd-account-manager-default.c | 23 ++++++----------------- tests/twisted/account-storage/load-keyfiles.py | 8 ++++---- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index b79b6bba..e9f2bf20 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -203,27 +203,16 @@ set_parameter (McpAccountStorage *self, old = g_hash_table_lookup (sa->parameters, parameter); - if (old == NULL) - { - /* it might still be in untyped_parameters? */ - const gchar *escaped = g_hash_table_lookup (sa->untyped_parameters, - parameter); - gchar *new = mcp_account_manager_escape_variant_for_keyfile ( - am, val); - - if (!tp_strdiff (escaped, new)) - { - g_free (new); - return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; - } - - g_free (new); - } - else if (g_variant_equal (old, val)) + if (old != NULL && g_variant_equal (old, val)) { return MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED; } + /* We haven't checked whether it's in untyped_parameters with the + * same value - but if it is, we want to migrate it to parameters + * anyway (in order to record its type), so treat it as having + * actually changed. */ + g_hash_table_remove (sa->untyped_parameters, parameter); g_hash_table_insert (sa->parameters, g_strdup (parameter), g_variant_ref (val)); diff --git a/tests/twisted/account-storage/load-keyfiles.py b/tests/twisted/account-storage/load-keyfiles.py index 35280db2..1f4cd986 100644 --- a/tests/twisted/account-storage/load-keyfiles.py +++ b/tests/twisted/account-storage/load-keyfiles.py @@ -82,10 +82,10 @@ def test(q, bus, mc): 'protocol': <'fakeprotocol'>, 'DisplayName': <'Account in a low-priority location'>, 'AutomaticPresence': <(uint32 2, 'available', '')>, -'KeyFileParameters': <{ - 'account': 'dontdivertlow@example.com', - 'password': 'password_in_variant_file', - 'snakes': '42' +'Parameters': <{ + 'account': <'dontdivertlow@example.com'>, + 'password': <'password_in_variant_file'>, + 'snakes': }> } """) -- cgit v1.2.3 From 775c27341c109cc4067df733ceec6c7728e9c6dd Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 28 Jan 2014 16:34:18 +0000 Subject: Test that we add types to accounts' parameters when set --- tests/twisted/account-storage/load-keyfiles.py | 78 +++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/tests/twisted/account-storage/load-keyfiles.py b/tests/twisted/account-storage/load-keyfiles.py index 1f4cd986..dfba53b4 100644 --- a/tests/twisted/account-storage/load-keyfiles.py +++ b/tests/twisted/account-storage/load-keyfiles.py @@ -32,6 +32,9 @@ from mctest import ( MC, exec_test, get_fakecm_account, connect_to_mc, SimulatedConnectionManager, ) +from storage_helper import ( + account_store, + ) import constants as cs def test(q, bus, mc): @@ -43,7 +46,7 @@ def test(q, bus, mc): 'telepathy', 'mission-control', 'accounts.cfg') # We do several scenarios in one MC run, to speed up testing a bit. - scenarios = ('low', 'priority', 'masked') + scenarios = ('low', 'priority', 'masked', 'migration', 'absentcm') variant_file_names = {} low_prio_variant_file_names = {} @@ -88,6 +91,39 @@ def test(q, bus, mc): 'snakes': }> } +""") + + # This is in a lower-priority location and we don't know the + # parameters' types yet + open(low_prio_variant_file_names['migration'], 'w').write( +"""{ +'manager': <'fakecm'>, +'protocol': <'fakeprotocol'>, +'DisplayName': <'Account in a low-priority location with KeyFileParameters'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{ + 'account': 'dontdivertmigration@example.com', + 'password': 'password_in_variant_file', + 'snakes': '42' + }> +} +""") + + # This is in a lower-priority location, and we don't know the + # parameters' types, and we can't learn them by asking the CM + # because it isn't installed + open(low_prio_variant_file_names['absentcm'], 'w').write( +"""{ +'manager': <'absentcm'>, +'protocol': <'absentprotocol'>, +'DisplayName': <'Account in a low-priority location with absent CM'>, +'AutomaticPresence': <(uint32 2, 'available', '')>, +'KeyFileParameters': <{ + 'account': 'dontdivertabsentcm@example.com', + 'password': 'hello', + 'snakes': '42' + }> +} """) # This version of this account will be used @@ -135,10 +171,13 @@ def test(q, bus, mc): for s in scenarios: if s == 'masked': assertDoesNotContain(account_paths[s], properties['ValidAccounts']) + assertDoesNotContain(account_paths[s], properties['InvalidAccounts']) + elif s == 'absentcm': + assertContains(account_paths[s], properties['InvalidAccounts']) + assertDoesNotContain(account_paths[s], properties['ValidAccounts']) else: assertContains(account_paths[s], properties['ValidAccounts']) - - assertDoesNotContain(account_paths[s], properties['InvalidAccounts']) + assertDoesNotContain(account_paths[s], properties['InvalidAccounts']) accounts = {} account_ifaces = {} @@ -148,6 +187,9 @@ def test(q, bus, mc): accounts[s] = get_fakecm_account(bus, mc, account_paths[s]) account_ifaces[s] = dbus.Interface(accounts[s], cs.ACCOUNT) + if s not in ('masked', 'absentcm'): + # We can't get untyped parameters if we don't know what types + # the CM gives them. assertEquals(42, accounts[s].Properties.Get(cs.ACCOUNT, 'Parameters')['snakes']) assertEquals(dbus.UInt32, @@ -198,5 +240,35 @@ def test(q, bus, mc): # The masked account is still masked assert open(variant_file_names['masked'], 'r').read() == '' + # Teach the one that knows its CM that the 'password' is a string. + # This results in the higher-priority file being written out. + account_ifaces['migration'].UpdateParameters({'password': 'hello'}, []) + q.expect('dbus-signal', + path=account_paths['migration'], + signal='AccountPropertyChanged', + interface=cs.ACCOUNT, + predicate=(lambda e: + 'Parameters' in e.args[0]), + ) + # Check the account has copied (not moved! XDG_DATA_DIRS are, + # conceptually, read-only) 'migration' from the old to the new name + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['migration']) + assert os.path.exists(variant_file_names['migration']) + assertEquals("'hello'", account_store('get', 'variant-file', + 'param-password', account=tails['migration'])) + # Parameters whose types are still unknown are copied too, but their + # types are still unknown + assertEquals("keyfile-escaped '42'", account_store('get', 'variant-file', + 'param-snakes', account=tails['migration'])) + + # 'absentcm' is still only in the low-priority location: we can't + # known the types of its parameters + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['absentcm']) + assert not os.path.exists(variant_file_names['absentcm']) + if __name__ == '__main__': exec_test(test, {}, preload_mc=False, use_fake_accounts_service=False) -- cgit v1.2.3 From 0b2293f16df6259d2f2aab1db1fc126c2edae59e Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 28 Jan 2014 17:36:33 +0000 Subject: McpParameterFlags, McpAttributeFlags: move to the right header --- mission-control-plugins/account-storage.h | 10 ++++++++++ mission-control-plugins/mission-control-plugins.h | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 356642f6..fd6daee1 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -31,6 +31,16 @@ G_BEGIN_DECLS #define MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_DEFAULT 0 #define MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_NORMAL 100 +typedef enum /*< flags >*/ +{ + MCP_PARAMETER_FLAG_NONE = 0 +} McpParameterFlags; + +typedef enum /*< flags >*/ +{ + MCP_ATTRIBUTE_FLAG_NONE = 0 +} McpAttributeFlags; + typedef enum { MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED = 0, MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED, diff --git a/mission-control-plugins/mission-control-plugins.h b/mission-control-plugins/mission-control-plugins.h index aa846f78..186da91d 100644 --- a/mission-control-plugins/mission-control-plugins.h +++ b/mission-control-plugins/mission-control-plugins.h @@ -27,14 +27,6 @@ #define MCP_API_VERSION_5_18 (518) -typedef enum { - MCP_PARAMETER_FLAG_NONE = 0, -} McpParameterFlags; - -typedef enum { - MCP_ATTRIBUTE_FLAG_NONE = 0 -} McpAttributeFlags; - #define _MCP_IN_MISSION_CONTROL_PLUGINS_H #include #include -- cgit v1.2.3