pidgin/pidgin

Parents 2fc55152b79c
Children 271b8dac2b0d
Create a no operation credential provider and fix a number of other issues

* Create a "None" credential provider that allows users to disable credential
storing and only allows them to enter passwords manually.
* Use g_signal_connect_object in PidginCredentialProviderStore.
* Move purple_credential_manager_shutdown after purple_plugins_uninit.
* Set the active credential provider to NULL during shutdown.

Testing Done:
Compiled and ran locally verified that we no long hang on exit if we've opened the preferences window.

Reviewed at https://reviews.imfreedom.org/r/456/
--- a/doc/reference/libpurple/libpurple-docs.xml Sat Jan 30 01:26:47 2021 -0600
+++ b/doc/reference/libpurple/libpurple-docs.xml Sat Jan 30 01:30:00 2021 -0600
@@ -78,6 +78,7 @@
<xi:include href="xml/purpleimconversation.xml" />
<xi:include href="xml/purplekeyvaluepair.xml" />
<xi:include href="xml/purplemarkup.xml" />
+ <xi:include href="xml/purplenoopcredentialprovider.xml" />
<xi:include href="xml/purpleoptions.xml" />
<xi:include href="xml/purplepresence.xml" />
<xi:include href="xml/purpleprotocolattention.xml" />
--- a/libpurple/core.c Sat Jan 30 01:26:47 2021 -0600
+++ b/libpurple/core.c Sat Jan 30 01:30:00 2021 -0600
@@ -36,6 +36,7 @@
#include "plugins.h"
#include "prefs.h"
#include "proxy.h"
+#include "purplecredentialmanager.h"
#include "purplemessage.h"
#include "purpleprivate.h"
#include "savedstatuses.h"
@@ -208,12 +209,17 @@
{
PurpleCoreUiOps *ops;
PurpleCore *core = purple_get_core();
+ PurpleCredentialManager *manager = NULL;
g_return_if_fail(core != NULL);
/* The self destruct sequence has been initiated */
purple_signal_emit(purple_get_core(), "quitting");
+ /* Remove the active provider in the credential manager. */
+ manager = purple_credential_manager_get_default();
+ purple_credential_manager_set_active_provider(manager, NULL, NULL);
+
/* Transmission ends */
purple_connections_disconnect_all();
@@ -231,7 +237,6 @@
purple_statuses_uninit();
purple_accounts_uninit();
purple_keyring_uninit(); /* after accounts */
- purple_credential_manager_shutdown(); /* after accounts */
purple_theme_manager_uninit();
purple_xfers_uninit();
purple_proxy_uninit();
@@ -246,9 +251,11 @@
purple_prefs_uninit();
purple_plugins_uninit();
+ /* after plugins */
+ purple_credential_manager_shutdown();
purple_protocol_manager_shutdown();
+ purple_cmds_uninit();
- purple_cmds_uninit();
purple_log_uninit();
/* Everything after util_uninit cannot try to write things to the
* confdir.
--- a/libpurple/meson.build Sat Jan 30 01:26:47 2021 -0600
+++ b/libpurple/meson.build Sat Jan 30 01:30:00 2021 -0600
@@ -56,6 +56,7 @@
'purplekeyvaluepair.c',
'purplemarkup.c',
'purplemessage.c',
+ 'purplenoopcredentialprovider.c',
'purpleoptions.c',
'purplepresence.c',
'purpleprotocolattention.c',
@@ -147,6 +148,7 @@
'purplekeyvaluepair.h',
'purplemarkup.h',
'purplemessage.h',
+ 'purplenoopcredentialprovider.h',
'purpleoptions.h',
'purplepresence.h',
'purpleprotocolattention.h',
--- a/libpurple/purplecredentialmanager.c Sat Jan 30 01:26:47 2021 -0600
+++ b/libpurple/purplecredentialmanager.c Sat Jan 30 01:30:00 2021 -0600
@@ -23,6 +23,7 @@
#include "core.h"
#include "debug.h"
#include "prefs.h"
+#include "purplenoopcredentialprovider.h"
#include "purpleprivate.h"
#include "util.h"
@@ -155,12 +156,17 @@
static void
purple_credential_manager_init(PurpleCredentialManager *manager) {
PurpleCredentialManagerPrivate *priv = NULL;
+ PurpleCredentialProvider *noop = NULL;
priv = purple_credential_manager_get_instance_private(manager);
priv->providers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
g_object_unref);
+ noop = purple_noop_credential_provider_new();
+ purple_credential_manager_register_provider(manager, noop, NULL);
+ g_object_unref(G_OBJECT(noop));
+
/* Connect to the core-initialized signal so we can alert the user if we
* were unable to find their credential provider.
*/
@@ -253,7 +259,21 @@
void
purple_credential_manager_shutdown(void) {
- g_clear_object(&default_manager);
+ if(PURPLE_IS_CREDENTIAL_MANAGER(default_manager)) {
+ PurpleCredentialManagerPrivate *priv = NULL;
+ guint size = 0;
+
+ priv = purple_credential_manager_get_instance_private(default_manager);
+
+ size = g_hash_table_size(priv->providers);
+ if(size > 0) {
+ g_warning("purple_credential_manager_shutdown called while %d "
+ "providers were still registered. Skipping shutdown",
+ size);
+ } else {
+ g_clear_object(&default_manager);
+ }
+ }
}
/******************************************************************************
@@ -380,8 +400,7 @@
g_clear_object(&old);
- purple_debug_info("PurpleCredentialProvider",
- "set active provider to '%s'", id);
+ purple_debug_info("credential-manager", "set active provider to '%s'", id);
return TRUE;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplenoopcredentialprovider.c Sat Jan 30 01:30:00 2021 -0600
@@ -0,0 +1,116 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * 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 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n-lib.h>
+
+#include "purplenoopcredentialprovider.h"
+
+#include "purplecredentialmanager.h"
+
+struct _PurpleNoopCredentialProvider {
+ PurpleCredentialProvider parent;
+};
+
+G_DEFINE_TYPE(PurpleNoopCredentialProvider, purple_noop_credential_provider,
+ PURPLE_TYPE_CREDENTIAL_PROVIDER)
+
+/******************************************************************************
+ * PurpleCredentialProvider Implementation
+ *****************************************************************************/
+static void
+purple_noop_credential_provider_read_password_async(PurpleCredentialProvider *provider,
+ PurpleAccount *account,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer data)
+{
+ GTask *task = g_task_new(G_OBJECT(provider), cancellable, callback, data);
+
+ g_task_return_new_error(task, PURPLE_CREDENTIAL_MANAGER_DOMAIN, 0,
+ _("provider does not store passwords"));
+
+ g_object_unref(G_OBJECT(task));
+}
+
+static gchar *
+purple_noop_credential_provider_read_password_finish(PurpleCredentialProvider *provider,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_pointer(G_TASK(result), error);
+}
+
+static void
+purple_noop_credential_provider_write_password_async(PurpleCredentialProvider *provider,
+ PurpleAccount *account,
+ const gchar *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer data)
+{
+ GTask *task = g_task_new(G_OBJECT(provider), cancellable, callback, data);
+
+ g_task_return_new_error(task, PURPLE_CREDENTIAL_MANAGER_DOMAIN, 0,
+ _("provider does not store passwords"));
+
+ g_object_unref(G_OBJECT(task));
+}
+
+static gboolean
+purple_noop_credential_provider_write_password_finish(PurpleCredentialProvider *provider,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_boolean(G_TASK(result), error);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+static void
+purple_noop_credential_provider_init(PurpleNoopCredentialProvider *provider) {
+}
+
+static void
+purple_noop_credential_provider_class_init(PurpleNoopCredentialProviderClass *klass)
+{
+ PurpleCredentialProviderClass *provider_class = NULL;
+
+ provider_class = PURPLE_CREDENTIAL_PROVIDER_CLASS(klass);
+ provider_class->read_password_async =
+ purple_noop_credential_provider_read_password_async;
+ provider_class->read_password_finish =
+ purple_noop_credential_provider_read_password_finish;
+ provider_class->write_password_async =
+ purple_noop_credential_provider_write_password_async;
+ provider_class->write_password_finish =
+ purple_noop_credential_provider_write_password_finish;
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleCredentialProvider *
+purple_noop_credential_provider_new(void) {
+ return PURPLE_CREDENTIAL_PROVIDER(g_object_new(
+ PURPLE_TYPE_NOOP_CREDENTIAL_PROVIDER,
+ "id", "noop-provider",
+ "name", _("None"),
+ NULL
+ ));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplenoopcredentialprovider.h Sat Jan 30 01:30:00 2021 -0600
@@ -0,0 +1,70 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * 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 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <purple.h> may be included directly"
+#endif
+
+#ifndef PURPLE_NOOP_CREDENTIAL_PROVIDER_H
+#define PURPLE_NOOP_CREDENTIAL_PROVIDER_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <purplecredentialprovider.h>
+
+/**
+ * SECTION:purplenoopcredentialprovider
+ * @section_id: libpurple-purplenoopcredentialprovider
+ * @title: No Operation Credential Provider Object
+ *
+ * This is the "None" credential provider that always returns failures so that
+ * the user is forced to enter a password.
+ */
+
+G_BEGIN_DECLS
+
+/**
+ * PurpleNoopCredentialProvider:
+ *
+ * #PurpleNoopCredentialProvider is a #PurpleCredentialProvider that does not
+ * actually provider credentials. It is used to implement the default behavior
+ * of requiring users to input passwords.
+ *
+ * Since: 3.0.0
+ */
+
+#define PURPLE_TYPE_NOOP_CREDENTIAL_PROVIDER (purple_noop_credential_provider_get_type())
+G_DECLARE_FINAL_TYPE(PurpleNoopCredentialProvider,
+ purple_noop_credential_provider,
+ PURPLE, NOOP_CREDENTIAL_PROVIDER, PurpleCredentialProvider)
+
+/**
+ * purple_noop_credential_provider_new:
+ *
+ * Creates a new #PurpleNoopCredentialProvider instance. You typically will
+ * not need to call this directly as #PurpleCredentialManager will create one
+ * for itself.
+ *
+ * Returns: (transfer full): The new #PurpleNoopCredentialProvider instance.
+ */
+PurpleCredentialProvider *purple_noop_credential_provider_new(void);
+
+G_END_DECLS
+
+#endif /* PURPLE_NOOP_CREDENTIAL_PROVIDER */
--- a/pidgin/pidgincredentialproviderstore.c Sat Jan 30 01:26:47 2021 -0600
+++ b/pidgin/pidgincredentialproviderstore.c Sat Jan 30 01:30:00 2021 -0600
@@ -156,12 +156,12 @@
manager = purple_credential_manager_get_default();
- g_signal_connect(G_OBJECT(manager), "provider-registered",
- G_CALLBACK(purple_credential_provider_store_registered_cb),
- store);
- g_signal_connect(G_OBJECT(manager), "provider-unregistered",
- G_CALLBACK(purple_credential_provider_store_unregistered_cb),
- store);
+ g_signal_connect_object(G_OBJECT(manager), "provider-registered",
+ G_CALLBACK(purple_credential_provider_store_registered_cb),
+ store, 0);
+ g_signal_connect_object(G_OBJECT(manager), "provider-unregistered",
+ G_CALLBACK(purple_credential_provider_store_unregistered_cb),
+ store, 0);
}
static void
--- a/po/POTFILES.in Sat Jan 30 01:26:47 2021 -0600
+++ b/po/POTFILES.in Sat Jan 30 01:30:00 2021 -0600
@@ -253,6 +253,7 @@
libpurple/purplekeyvaluepair.c
libpurple/purplemarkup.c
libpurple/purplemessage.c
+libpurple/purplenoopcredentialprovider.c
libpurple/purpleoptions.c
libpurple/purplepresence.c
libpurple/purpleprotocolattention.c