changeset 24820:0700833f0c5d

Commit patch #7670: Implement xep-0191 (simple blocking) for jabber protocols from Vijay Raghunathan (a co-worker of mine). We're testing this at Meebo and it seems to work ok. Closes #7670.
author Mark Doliner <mark@kingant.net>
date Mon, 22 Dec 2008 07:51:06 +0000
parents 95c9c306d582
children 75690a3eeee0 280ffb4d954f
files ChangeLog libpurple/protocols/jabber/disco.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/jabber.h libpurple/protocols/jabber/libxmpp.c
diffstat 5 files changed, 118 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Dec 21 18:01:37 2008 +0000
+++ b/ChangeLog	Mon Dec 22 07:51:06 2008 +0000
@@ -7,6 +7,9 @@
 	* Don't ignore namespace information when parsing XMPP data. (Michal
 	  Witkowski)
 
+	XMPP:
+	* Support for XEP-0191 blocking.  (Vijay Raghunathan)
+
 version 2.5.3 (12/20/2008):
 	libpurple:
 	* The Buddy State Notification plugin no longer prints duplicate
--- a/libpurple/protocols/jabber/disco.c	Sun Dec 21 18:01:37 2008 +0000
+++ b/libpurple/protocols/jabber/disco.c	Mon Dec 22 07:51:06 2008 +0000
@@ -355,6 +355,11 @@
 		jabber_adhoc_server_get_list(js);
 	}
 
+	/* If the server supports blocking, request the block list */
+	if (js->server_caps & JABBER_CAP_BLOCKING) {
+		jabber_request_block_list(js);
+	}
+
 	/* If there are manually specified bytestream proxies, query them */
 	ft_proxies = purple_account_get_string(js->gc->account, "ft_proxies", NULL);
 	if (ft_proxies) {
@@ -454,6 +459,8 @@
 			jabber_google_roster_init(js);
 		} else if (!strcmp("http://jabber.org/protocol/commands", var)) {
 			js->server_caps |= JABBER_CAP_ADHOC;
+		} else if (!strcmp("urn:xmpp:blocking", var)) {
+			js->server_caps |= JABBER_CAP_BLOCKING;
 		}
 	}
 
--- a/libpurple/protocols/jabber/jabber.c	Sun Dec 21 18:01:37 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Mon Dec 22 07:51:06 2008 +0000
@@ -31,6 +31,7 @@
 #include "message.h"
 #include "notify.h"
 #include "pluginpref.h"
+#include "privacy.h"
 #include "proxy.h"
 #include "prpl.h"
 #include "request.h"
@@ -1454,6 +1455,106 @@
 	js->idle = idle ? time(NULL) - idle : idle;
 }
 
+static void jabber_blocklist_parse(JabberStream *js, xmlnode *packet, gpointer data)
+{
+	xmlnode *blocklist, *item;
+	PurpleAccount *account;
+
+	blocklist = xmlnode_get_child_with_namespace(packet,
+			"blocklist", "urn:xmpp:blocking");
+	account = purple_connection_get_account(js->gc);
+
+	if (blocklist == NULL)
+		return;
+
+	item = xmlnode_get_child(blocklist, "item");
+	while (item != NULL) {
+		const char *jid = xmlnode_get_attrib(item, "jid");
+
+		purple_privacy_deny_add(account, jid, TRUE);
+		item = xmlnode_get_next_twin(item);
+	}
+}
+
+void jabber_request_block_list(JabberStream *js)
+{
+	JabberIq *iq;
+	xmlnode *blocklist;
+
+	iq = jabber_iq_new(js, JABBER_IQ_GET);
+
+	blocklist = xmlnode_new_child(iq->node, "blocklist");
+	xmlnode_set_namespace(blocklist, "urn:xmpp:blocking");
+
+	jabber_iq_set_callback(iq, jabber_blocklist_parse, NULL);
+
+	jabber_iq_send(iq);
+}
+
+void jabber_add_deny(PurpleConnection *gc, const char *who)
+{
+	JabberStream *js;
+	JabberIq *iq;
+	xmlnode *block, *item;
+
+	js = gc->proto_data;
+	if (js == NULL)
+		return;
+
+	if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER)
+	{
+		jabber_google_roster_add_deny(gc, who);
+		return;
+	}
+
+	if (!(js->server_caps & JABBER_CAP_BLOCKING))
+	{
+		purple_notify_error(NULL, _("Server doesn't support blocking"),
+							_("Server doesn't support blocking"), NULL);
+		return;
+	}
+
+	iq = jabber_iq_new(js, JABBER_IQ_SET);
+
+	block = xmlnode_new_child(iq->node, "block");
+	xmlnode_set_namespace(block, "urn:xmpp:blocking");
+
+	item = xmlnode_new_child(block, "item");
+	xmlnode_set_attrib(item, "jid", who);
+
+	jabber_iq_send(iq);
+}
+
+void jabber_rem_deny(PurpleConnection *gc, const char *who)
+{
+	JabberStream *js;
+	JabberIq *iq;
+	xmlnode *unblock, *item;
+
+	js = gc->proto_data;
+	if (js == NULL)
+		return;
+
+	if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER)
+	{
+		jabber_google_roster_rem_deny(gc, who);
+		return;
+	}
+
+	if (!(js->server_caps & JABBER_CAP_BLOCKING))
+		return;
+
+	iq = jabber_iq_new(js, JABBER_IQ_SET);
+
+	unblock = xmlnode_new_child(iq->node, "unblock");
+	xmlnode_set_namespace(unblock, "urn:xmpp:blocking");
+
+	item = xmlnode_new_child(unblock, "item");
+	xmlnode_set_attrib(item, "jid", who);
+
+	jabber_iq_send(iq);
+}
+
 void jabber_add_feature(const char *shortname, const char *namespace, JabberFeatureEnabled cb) {
 	JabberFeature *feat;
 
--- a/libpurple/protocols/jabber/jabber.h	Sun Dec 21 18:01:37 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.h	Mon Dec 22 07:51:06 2008 +0000
@@ -42,7 +42,8 @@
 
 	JABBER_CAP_PING			  = 1 << 11,
 	JABBER_CAP_ADHOC		  = 1 << 12,
-	
+	JABBER_CAP_BLOCKING       = 1 << 13,
+
 	JABBER_CAP_RETRIEVED      = 1 << 31
 } JabberCapabilities;
 
@@ -294,6 +295,9 @@
 void jabber_login(PurpleAccount *account);
 void jabber_close(PurpleConnection *gc);
 void jabber_idle_set(PurpleConnection *gc, int idle);
+void jabber_request_block_list(JabberStream *js);
+void jabber_add_deny(PurpleConnection *gc, const char *who);
+void jabber_rem_deny(PurpleConnection *gc, const char *who);
 void jabber_keepalive(PurpleConnection *gc);
 void jabber_register_gateway(JabberStream *js, const char *gateway);
 void jabber_register_account(PurpleAccount *account);
--- a/libpurple/protocols/jabber/libxmpp.c	Sun Dec 21 18:01:37 2008 +0000
+++ b/libpurple/protocols/jabber/libxmpp.c	Mon Dec 22 07:51:06 2008 +0000
@@ -77,9 +77,9 @@
 	jabber_roster_remove_buddy,		/* remove_buddy */
 	NULL,							/* remove_buddies */
 	NULL,							/* add_permit */
-	jabber_google_roster_add_deny,				/* add_deny */
+	jabber_add_deny,				/* add_deny */
 	NULL,							/* rem_permit */
-	jabber_google_roster_rem_deny,				/* rem_deny */
+	jabber_rem_deny,				/* rem_deny */
 	NULL,							/* set_permit_deny */
 	jabber_chat_join,				/* join_chat */
 	NULL,							/* reject_chat */