mod_presence, rostermanager: Bring outbound subscription cancellation in line with RFC6121.
authorWaqas Hussain <waqas20@gmail.com>
Wed, 01 Aug 2012 01:36:16 +0500
changeset 5060 b0e36777f715
parent 5059 246ba539a5cd
child 5061 186f34d88073
mod_presence, rostermanager: Bring outbound subscription cancellation in line with RFC6121.
core/rostermanager.lua
plugins/mod_presence.lua
--- a/core/rostermanager.lua	Wed Aug 01 01:36:13 2012 +0500
+++ b/core/rostermanager.lua	Wed Aug 01 01:36:16 2012 +0500
@@ -278,23 +278,21 @@
 	local roster = load_roster(username, host);
 	local item = roster[jid];
 	local pending = is_contact_pending_in(username, host, jid);
-	local changed = nil;
-	if is_contact_pending_in(username, host, jid) then
+	if pending then
 		roster.pending[jid] = nil; -- TODO maybe delete roster.pending if empty?
-		changed = true;
 	end
+	local subscribed;
 	if item then
 		if item.subscription == "from" then
 			item.subscription = "none";
-			changed = true;
+			subscribed = true;
 		elseif item.subscription == "both" then
 			item.subscription = "to";
-			changed = true;
+			subscribed = true;
 		end
 	end
-	if changed then
-		return save_roster(username, host, roster);
-	end
+	local success = (pending or subscribed) and save_roster(username, host, roster);
+	return success, pending, subscribed;
 end
 
 function process_outbound_subscription_request(username, host, jid)
--- a/plugins/mod_presence.lua	Wed Aug 01 01:36:13 2012 +0500
+++ b/plugins/mod_presence.lua	Wed Aug 01 01:36:16 2012 +0500
@@ -198,12 +198,19 @@
 		core_post_stanza(origin, stanza);
 		send_presence_of_available_resources(node, host, to_bare, origin);
 	elseif stanza.attr.type == "unsubscribed" then
-		-- 1. route stanza
-		-- 2. roster push (subscription = none or to)
-		if rostermanager.unsubscribed(node, host, to_bare) then
-			rostermanager.roster_push(node, host, to_bare);
+		-- 1. send unavailable
+		-- 2. route stanza
+		-- 3. roster push (subscription = from or both)
+		local success, pending_in, subscribed = rostermanager.unsubscribed(node, host, to_bare);
+		if success then
+			if subscribed then
+				rostermanager.roster_push(node, host, to_bare);
+			end
+			core_post_stanza(origin, stanza);
+			if subscribed then
+				send_presence_of_available_resources(node, host, to_bare, origin, st.presence({ type = "unavailable" }));
+			end
 		end
-		core_post_stanza(origin, stanza);
 	else
 		origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid presence type"));
 	end