Merge to default to fix conflicts

Mon, 24 Oct 2016 17:11:11 -0500

author
Mike Ruprecht <cmaiku@gmail.com>
date
Mon, 24 Oct 2016 17:11:11 -0500
changeset 38181
6dc8cae57962
parent 38180
443e8d364db7 (current diff)
parent 38163
d33dfb9939a1 (diff)
child 38182
783878958371

Merge to default to fix conflicts

bitbucket-pipelines.yml file | annotate | diff | comparison | revisions
--- a/bitbucket-pipelines.yml	Sun Oct 09 18:32:16 2016 -0500
+++ b/bitbucket-pipelines.yml	Mon Oct 24 17:11:11 2016 -0500
@@ -8,4 +8,14 @@
           - ./autogen.sh --enable-debug --enable-gtk-doc
           - make -s -j$(nproc)
           - make -s -j$(nproc) distcheck
+  branches:
+    release-2.x.y:
+      - step:
+          image: pidgin/release-builder:release-2.x.y
+          script:
+            - set -ex
+            - ./autogen.sh --enable-debug
+            - make -s -j$(nproc)
+            - make -s -j$(nproc) check
+            - make distcheck
 
--- a/configure.ac	Sun Oct 09 18:32:16 2016 -0500
+++ b/configure.ac	Mon Oct 24 17:11:11 2016 -0500
@@ -1522,19 +1522,29 @@
 dnl # Check for Secret Service headers
 dnl #######################################################################
 
-# disabled - see secretservice.c
-#AC_ARG_ENABLE(libsecret, [AC_HELP_STRING([--disable-libsecret], [enable Secret Service support])], enable_secret_service=no, enable_secret_service=yes)
+AC_ARG_ENABLE(libsecret,
+	[AC_HELP_STRING([--disable-libsecret], [enable Secret Service support])],
+	enable_secret_service="$enableval", enable_secret_service="$is_not_win32")
 
-#if test "x$enable_secret_service" = "xyes" ; then
-#	PKG_CHECK_MODULES(SECRETSERVICE, [libsecret-1], [
-#		AC_SUBST(SECRETSERVICE_CFLAGS)
-#		AC_SUBST(SECRETSERVICE_LIBS)
-#		AC_DEFINE(HAVE_SECRETSERVICE, 1, [Define if we have Secret Service.])
-#	])
-#fi
+if test "x$enable_secret_service" = "xyes" ; then
+	PKG_CHECK_MODULES(SECRETSERVICE, [libsecret-1], [
+		AC_SUBST(SECRETSERVICE_CFLAGS)
+		AC_SUBST(SECRETSERVICE_LIBS)
+		AC_DEFINE(HAVE_SECRETSERVICE, 1, [Define if we have Secret Service.])
+	], [
+		AC_MSG_RESULT(no)
+		enable_secret_service="no"
+		if test "x$force_deps" = "xyes" ; then
+			AC_MSG_ERROR([
+Libsecret development headers not found
+Use --disable-libsecret if you do not need it.
+])
+		fi
+	])
 
-#AM_CONDITIONAL(ENABLE_SECRETSERVICE, test "x$enable_secret_service" = "xyes")
-AM_CONDITIONAL(ENABLE_SECRETSERVICE, test "x1" = "x2")
+fi
+
+AM_CONDITIONAL(ENABLE_SECRETSERVICE, test "x$enable_secret_service" = "xyes")
 
 dnl #######################################################################
 dnl # Check for GNOME Keyring headers
@@ -2254,7 +2264,7 @@
 echo
 echo Build with GNOME Keyring...... : $enable_gnome_keyring
 echo Build with KWallet............ : $enable_kwallet
-#echo Build with Secret Service..... : $enable_secret_service
+echo Build with Secret Service..... : $enable_secret_service
 echo
 echo Build with plugin support..... : $enable_plugins
 echo Enable Introspection...........: $enable_introspection
--- a/libpurple/plugins/keyrings/secretservice.c	Sun Oct 09 18:32:16 2016 -0500
+++ b/libpurple/plugins/keyrings/secretservice.c	Mon Oct 24 17:11:11 2016 -0500
@@ -21,17 +21,15 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
  */
 
-#error "This keyring needs some more work (see TODO)"
-
 /* TODO
  *
- * This keyring needs some more work, so it will be disabled until its quality
- * was raised. Some of the pain points:
- *  - throws a lot of g_warnings
- *  - it doesn't notify about some backend faults (like access denied), some of
- *    them are not handled at all
- *  - it could use libsecret's Complete API
- *  - code formatting could be better
+ * This keyring now works (at the time of this writing), but there are
+ * some inconvenient edge cases. When looking up passwords, libsecret
+ * doesn't error if the keyring is locked. Therefore, it appears to
+ * this plugin that there's no stored password. libpurple seems to
+ * handle this as gracefully as possible, but it's still inconvenient.
+ * This plugin could possibly be ported to use libsecret's "Complete API"
+ * to resolve this if desired.
  */
 
 #include "internal.h"
@@ -53,6 +51,7 @@
 #define SECRETSERVICE_DOMAIN      (g_quark_from_static_string(SECRETSERVICE_ID))
 
 static PurpleKeyring *keyring_handler = NULL;
+static GCancellable *keyring_cancellable = NULL;
 
 static const SecretSchema purple_schema = {
 	"im.pidgin.Purple", SECRET_SCHEMA_NONE,
@@ -78,6 +77,62 @@
 /*     Keyring interface                       */
 /***********************************************/
 static void
+ss_g_error_to_keyring_error(GError **error, PurpleAccount *account)
+{
+	GError *old_error;
+	GError *new_error = NULL;
+
+	g_return_if_fail(error != NULL);
+
+	old_error = *error;
+
+	if (g_error_matches(old_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+		new_error = g_error_new(PURPLE_KEYRING_ERROR,
+			PURPLE_KEYRING_ERROR_CANCELLED,
+			_("Operation cancelled."));
+	} else if (g_error_matches(old_error, G_DBUS_ERROR,
+				G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND) ||
+			g_error_matches(old_error, G_DBUS_ERROR,
+				G_DBUS_ERROR_IO_ERROR)) {
+		purple_debug_info("keyring-libsecret",
+			"Failed to communicate with Secret "
+			"Service (account: %s (%s)).\n",
+			purple_account_get_username(account),
+			purple_account_get_protocol_id(account));
+		new_error = g_error_new(PURPLE_KEYRING_ERROR,
+			PURPLE_KEYRING_ERROR_BACKENDFAIL,
+			"Failed to communicate with Secret "
+			"Service (account: %s).",
+			purple_account_get_username(account));
+	} else if (g_error_matches(old_error, SECRET_ERROR,
+			SECRET_ERROR_IS_LOCKED)) {
+		purple_debug_info("keyring-libsecret",
+			"Secret Service is locked (account: %s (%s)).\n",
+			purple_account_get_username(account),
+			purple_account_get_protocol_id(account));
+		new_error = g_error_new(PURPLE_KEYRING_ERROR,
+			PURPLE_KEYRING_ERROR_ACCESSDENIED,
+			"Secret Service is locked (account: %s).",
+			purple_account_get_username(account));
+	} else {
+		purple_debug_error("keyring-libsecret",
+			"Unknown error (account: %s (%s), "
+			"domain: %s, code: %d): %s.\n",
+			purple_account_get_username(account),
+			purple_account_get_protocol_id(account),
+			g_quark_to_string(old_error->domain),
+			old_error->code, old_error->message);
+		new_error = g_error_new(PURPLE_KEYRING_ERROR,
+			PURPLE_KEYRING_ERROR_BACKENDFAIL,
+			"Unknown error (account: %s).",
+			purple_account_get_username(account));
+	}
+
+	g_clear_error(error);
+	g_propagate_error(error, new_error);
+}
+
+static void
 ss_read_continue(GObject *object, GAsyncResult *result, gpointer data)
 {
 	InfoStorage *storage = data;
@@ -89,53 +144,19 @@
 	password = secret_password_lookup_finish(result, &error);
 
 	if (error != NULL) {
-		int code = error->code;
-
-		switch (code) {
-			case G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND:
-			case G_DBUS_ERROR_IO_ERROR:
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_BACKENDFAIL,
-					"Failed to communicate with Secret "
-					"Service (account : %s).",
-					purple_account_get_username(account));
-				if (cb != NULL)
-					cb(account, NULL, error, storage->user_data);
-				g_error_free(error);
-				break;
-
-			default:
-				purple_debug_error("keyring-libsecret",
-					"Unknown error (account: %s (%s), "
-					"domain: %s, code: %d): %s.\n",
-					purple_account_get_username(account),
-					purple_account_get_protocol_id(account),
-					g_quark_to_string(error->domain), code,
-						error->message);
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_BACKENDFAIL,
-					"Unknown error (account : %s).",
-					purple_account_get_username(account));
-				if (cb != NULL)
-					cb(account, NULL, error, storage->user_data);
-				g_error_free(error);
-				break;
-		}
-
+		ss_g_error_to_keyring_error(&error, account);
 	} else if (password == NULL) {
 		error = g_error_new(PURPLE_KEYRING_ERROR,
 			PURPLE_KEYRING_ERROR_NOPASSWORD,
 			"No password found for account: %s",
 			purple_account_get_username(account));
-		if (cb != NULL)
-			cb(account, NULL, error, storage->user_data);
-		g_error_free(error);
-
-	} else {
-		if (cb != NULL)
-			cb(account, password, NULL, storage->user_data);
 	}
 
+	if (cb != NULL) {
+		cb(account, password, error, storage->user_data);
+	}
+
+	g_clear_error(&error);
 	g_free(storage);
 }
 
@@ -148,74 +169,57 @@
 	storage->cb = cb;
 	storage->user_data = data;
 
-	secret_password_lookup(&purple_schema, NULL, ss_read_continue, storage,
+	secret_password_lookup(&purple_schema, keyring_cancellable,
+		ss_read_continue, storage,
 		"user", purple_account_get_username(account),
 		"protocol", purple_account_get_protocol_id(account), NULL);
 }
 
 static void
-ss_save_continue(GObject *object, GAsyncResult *result, gpointer data)
+ss_save_continue(GError *error, gpointer data)
 {
 	InfoStorage *storage = data;
 	PurpleKeyringSaveCallback cb;
-	GError *error = NULL;
 	PurpleAccount *account;
 
 	account = storage->account;
 	cb = storage->cb;
 
-	secret_password_store_finish(result, &error);
-
 	if (error != NULL) {
-		int code = error->code;
-
-		switch (code) {
-			case G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND:
-			case G_DBUS_ERROR_IO_ERROR:
-				purple_debug_info("keyring-libsecret",
-					"Failed to communicate with Secret "
-					"Service (account : %s (%s)).\n",
-					purple_account_get_username(account),
-					purple_account_get_protocol_id(account));
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_BACKENDFAIL,
-					"Failed to communicate with Secret Service (account : %s).",
-					purple_account_get_username(account));
-				if (cb != NULL)
-					cb(account, error, storage->user_data);
-				g_error_free(error);
-				break;
-
-			default:
-				purple_debug_error("keyring-libsecret",
-					"Unknown error (account: %s (%s), "
-					"domain: %s, code: %d): %s.\n",
-					purple_account_get_username(account),
-					purple_account_get_protocol_id(account),
-					g_quark_to_string(error->domain), code,
-						error->message);
-				error = g_error_new(PURPLE_KEYRING_ERROR,
-					PURPLE_KEYRING_ERROR_BACKENDFAIL,
-					"Unknown error (account : %s).",
-					purple_account_get_username(account));
-				if (cb != NULL)
-					cb(account, error, storage->user_data);
-				g_error_free(error);
-				break;
-		}
-
+		ss_g_error_to_keyring_error(&error, account);
 	} else {
 		purple_debug_info("keyring-libsecret", "Password for %s updated.\n",
 			purple_account_get_username(account));
-
-		if (cb != NULL)
-			cb(account, NULL, storage->user_data);
 	}
 
+	if (cb != NULL)
+		cb(account, error, storage->user_data);
+
+	g_clear_error(&error);
 	g_free(storage);
 }
 
 static void
+ss_store_continue(GObject *object, GAsyncResult *result, gpointer data)
+{
+	GError *error = NULL;
+
+	secret_password_store_finish(result, &error);
+
+	ss_save_continue(error, data);
+}
+
+static void
+ss_clear_continue(GObject *object, GAsyncResult *result, gpointer data)
+{
+	GError *error = NULL;
+
+	secret_password_clear_finish(result, &error);
+
+	ss_save_continue(error, data);
+}
+
+static void
 ss_save(PurpleAccount *account,
          const gchar *password,
          PurpleKeyringSaveCallback cb,
@@ -237,7 +241,8 @@
 
 		label = g_strdup_printf(_("Pidgin IM password for account %s"), username);
 		secret_password_store(&purple_schema, SECRET_COLLECTION_DEFAULT,
-			label, password, NULL, ss_save_continue, storage,
+			label, password, keyring_cancellable,
+			ss_store_continue, storage,
 			"user", username,
 			"protocol", purple_account_get_protocol_id(account),
 			NULL);
@@ -249,27 +254,42 @@
 			purple_account_get_username(account),
 			purple_account_get_protocol_id(account));
 
-		secret_password_clear(&purple_schema, NULL, ss_save_continue,
-			storage, "user", purple_account_get_username(account),
+		secret_password_clear(&purple_schema, keyring_cancellable,
+			ss_clear_continue, storage,
+			"user", purple_account_get_username(account),
 			"protocol", purple_account_get_protocol_id(account),
 			NULL);
 	}
 }
 
 static void
+ss_cancel(void)
+{
+	g_cancellable_cancel(keyring_cancellable);
+
+	/* Swap out cancelled cancellable for new one for further operations */
+	g_clear_object(&keyring_cancellable);
+	keyring_cancellable = g_cancellable_new();
+}
+
+static void
 ss_close(void)
 {
+	ss_cancel();
 }
 
 static gboolean
 ss_init(GError **error)
 {
+	keyring_cancellable = g_cancellable_new();
+
 	keyring_handler = purple_keyring_new();
 
 	purple_keyring_set_name(keyring_handler, _(SECRETSERVICE_NAME));
 	purple_keyring_set_id(keyring_handler, SECRETSERVICE_ID);
 	purple_keyring_set_read_password(keyring_handler, ss_read);
 	purple_keyring_set_save_password(keyring_handler, ss_save);
+	purple_keyring_set_cancel_requests(keyring_handler, ss_cancel);
 	purple_keyring_set_close_keyring(keyring_handler, ss_close);
 
 	purple_keyring_register(keyring_handler);
@@ -284,6 +304,8 @@
 	purple_keyring_unregister(keyring_handler);
 	purple_keyring_free(keyring_handler);
 	keyring_handler = NULL;
+
+	g_clear_object(&keyring_cancellable);
 }
 
 /***********************************************/
--- a/pidgin/data/pidgin-3-uninstalled.pc.in	Sun Oct 09 18:32:16 2016 -0500
+++ b/pidgin/data/pidgin-3-uninstalled.pc.in	Mon Oct 24 17:11:11 2016 -0500
@@ -15,7 +15,7 @@
 plugindir=${libdir}/pidgin
 
 Name: Pidgin
-Description: Pidgin is a GTK2-based instant messenger application.
+Description: Pidgin is a GTK3-based instant messenger application.
 Version: @VERSION@
-Requires: gtk+-2.0 purple-3
+Requires: gtk+-3.0 webkitgtk-3.0 purple-3
 Cflags: -I${abs_top_srcdir}

mercurial