plugins/muc/muc.lib.lua
author Waqas Hussain <waqas20@gmail.com>
Sun, 18 Oct 2009 06:49:40 +0500
changeset 1999 05054e360d89
parent 1998 40792c18a8e4
child 2005 478ba7e85862
permissions -rw-r--r--
MUC: Improved handling of error stanzas and made error messages concise.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     1
-- Prosody IM
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     2
-- Copyright (C) 2008-2009 Matthew Wild
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     3
-- Copyright (C) 2008-2009 Waqas Hussain
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     4
-- 
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     6
-- COPYING file in the source package for more information.
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     7
--
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     8
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     9
local datamanager = require "util.datamanager";
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    10
local datetime = require "util.datetime";
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    11
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    12
local jid_split = require "util.jid".split;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    13
local jid_bare = require "util.jid".bare;
1862
115f274dd17f MUC: Prep given JID when changing affiliation.
Waqas Hussain <waqas20@gmail.com>
parents: 1826
diff changeset
    14
local jid_prep = require "util.jid".prep;
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    15
local st = require "util.stanza";
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    16
local log = require "util.logger".init("mod_muc");
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    17
local multitable_new = require "util.multitable".new;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    18
local t_insert, t_remove = table.insert, table.remove;
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
    19
local setmetatable = setmetatable;
1778
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
    20
local base64 = require "util.encodings".base64;
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
    21
local md5 = require "util.hashes".md5;
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    22
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    23
local muc_domain = nil; --module:get_host();
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    24
local history_length = 20;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    25
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    26
------------
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    27
local function filter_xmlns_from_array(array, filters)
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    28
	local count = 0;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    29
	for i=#array,1,-1 do
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    30
		local attr = array[i].attr;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    31
		if filters[attr and attr.xmlns] then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    32
			t_remove(array, i);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    33
			count = count + 1;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    34
		end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    35
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    36
	return count;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    37
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    38
local function filter_xmlns_from_stanza(stanza, filters)
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    39
	if filters then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    40
		if filter_xmlns_from_array(stanza.tags, filters) ~= 0 then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    41
			return stanza, filter_xmlns_from_array(stanza, filters);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    42
		end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    43
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    44
	return stanza, 0;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    45
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    46
local presence_filters = {["http://jabber.org/protocol/muc"]=true;["http://jabber.org/protocol/muc#user"]=true};
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    47
local function get_filtered_presence(stanza)
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    48
	return filter_xmlns_from_stanza(st.clone(stanza):reset(), presence_filters);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    49
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    50
local kickable_error_conditions = {
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    51
	["gone"] = true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    52
	["internal-server-error"] = true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    53
	["item-not-found"] = true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    54
	["jid-malformed"] = true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    55
	["recipient-unavailable"] = true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    56
	["redirect"] = true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    57
	["remote-server-not-found"] = true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    58
	["remote-server-timeout"] = true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    59
	["service-unavailable"] = true;
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    60
	["malformed error"] = true;
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    61
};
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    62
local function get_error_condition(stanza)
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    63
	for _, tag in ipairs(stanza.tags) do
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    64
		if tag.name == "error" and (not(tag.attr.xmlns) or tag.attr.xmlns == "jabber:client") then
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    65
			for _, cond in ipairs(tag.tags) do
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    66
				if cond.attr.xmlns == "urn:ietf:params:xml:ns:xmpp-stanzas" then
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    67
					return cond.name;
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    68
				end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    69
			end
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    70
			return "malformed error";
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    71
		end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    72
	end
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    73
	return "malformed error";
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    74
end
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    75
local function is_kickable_error(stanza)
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    76
	local cond = get_error_condition(stanza);
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
    77
	return kickable_error_conditions[cond] and cond;
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    78
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    79
local function getUsingPath(stanza, path, getText)
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    80
	local tag = stanza;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    81
	for _, name in ipairs(path) do
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    82
		if type(tag) ~= 'table' then return; end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    83
		tag = tag:child_with_name(name);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    84
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    85
	if tag and getText then tag = table.concat(tag); end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    86
	return tag;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    87
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    88
local function getTag(stanza, path) return getUsingPath(stanza, path); end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    89
local function getText(stanza, path) return getUsingPath(stanza, path, true); end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    90
-----------
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    91
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    92
--[[function get_room_disco_info(room, stanza)
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    93
	return st.iq({type='result', id=stanza.attr.id, from=stanza.attr.to, to=stanza.attr.from}):query("http://jabber.org/protocol/disco#info")
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    94
		:tag("identity", {category='conference', type='text', name=room._data["name"]):up()
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    95
		:tag("feature", {var="http://jabber.org/protocol/muc"}); -- TODO cache disco reply
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    96
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    97
function get_room_disco_items(room, stanza)
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    98
	return st.iq({type='result', id=stanza.attr.id, from=stanza.attr.to, to=stanza.attr.from}):query("http://jabber.org/protocol/disco#items");
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    99
end -- TODO allow non-private rooms]]
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   100
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   101
--
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   102
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   103
local room_mt = {};
1737
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   104
room_mt.__index = room_mt;
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   105
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   106
function room_mt:get_default_role(affiliation)
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   107
	if affiliation == "owner" or affiliation == "admin" then
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   108
		return "moderator";
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   109
	elseif affiliation == "member" or not affiliation then
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   110
		return "participant";
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   111
	end
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   112
end
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   113
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   114
function room_mt:broadcast_presence(stanza, sid, code, nick)
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   115
	stanza = get_filtered_presence(stanza);
1825
f67e4bfc62f1 MUC: Renamed a variable name.
Waqas Hussain <waqas20@gmail.com>
parents: 1824
diff changeset
   116
	local occupant = self._occupants[stanza.attr.from];
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   117
	stanza:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
1825
f67e4bfc62f1 MUC: Renamed a variable name.
Waqas Hussain <waqas20@gmail.com>
parents: 1824
diff changeset
   118
		:tag("item", {affiliation=occupant.affiliation, role=occupant.role, nick=nick}):up();
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   119
	if code then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   120
		stanza:tag("status", {code=code}):up();
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   121
	end
1824
8e66c9d09f81 MUC: Refactored to remove some duplicate code.
Waqas Hussain <waqas20@gmail.com>
parents: 1819
diff changeset
   122
	self:broadcast_except_nick(stanza, stanza.attr.from);
8e66c9d09f81 MUC: Refactored to remove some duplicate code.
Waqas Hussain <waqas20@gmail.com>
parents: 1819
diff changeset
   123
	local me = self._occupants[stanza.attr.from];
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   124
	if me then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   125
		stanza:tag("status", {code='110'});
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   126
		stanza.attr.to = sid;
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   127
		self:route_stanza(stanza);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   128
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   129
end
1736
98f833669d7f MUC: Fixed function declarations.
Waqas Hussain <waqas20@gmail.com>
parents: 1735
diff changeset
   130
function room_mt:broadcast_message(stanza, historic)
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   131
	for occupant, o_data in pairs(self._occupants) do
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   132
		for jid in pairs(o_data.sessions) do
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   133
			stanza.attr.to = jid;
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   134
			self:route_stanza(stanza);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   135
		end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   136
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   137
	if historic then -- add to history
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   138
		local history = self._data['history'];
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   139
		if not history then history = {}; self._data['history'] = history; end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   140
		-- stanza = st.clone(stanza);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   141
		stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = muc_domain, stamp = datetime.datetime()}):up(); -- XEP-0203
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   142
		stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated)
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   143
		t_insert(history, st.clone(st.preserialize(stanza)));
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   144
		while #history > history_length do t_remove(history, 1) end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   145
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   146
end
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   147
function room_mt:broadcast_except_nick(stanza, nick)
1751
55ee6e792e3e MUC: Fixed a variable scoping bug causing problems with presence routing on affiliation/role change.
Waqas Hussain <waqas20@gmail.com>
parents: 1750
diff changeset
   148
	for rnick, occupant in pairs(self._occupants) do
55ee6e792e3e MUC: Fixed a variable scoping bug causing problems with presence routing on affiliation/role change.
Waqas Hussain <waqas20@gmail.com>
parents: 1750
diff changeset
   149
		if rnick ~= nick then
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   150
			for jid in pairs(occupant.sessions) do
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   151
				stanza.attr.to = jid;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   152
				self:route_stanza(stanza);
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   153
			end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   154
		end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   155
	end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   156
end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   157
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   158
function room_mt:send_occupant_list(to)
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   159
	local current_nick = self._jid_nick[to];
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   160
	for occupant, o_data in pairs(self._occupants) do
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   161
		if occupant ~= current_nick then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   162
			local pres = get_filtered_presence(o_data.sessions[o_data.jid]);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   163
			pres.attr.to, pres.attr.from = to, occupant;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   164
			pres:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   165
				:tag("item", {affiliation=o_data.affiliation, role=o_data.role}):up();
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   166
			self:route_stanza(pres);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   167
		end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   168
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   169
end
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   170
function room_mt:send_history(to)
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   171
	local history = self._data['history']; -- send discussion history
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   172
	if history then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   173
		for _, msg in ipairs(history) do
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   174
			msg = st.deserialize(msg);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   175
			msg.attr.to=to;
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   176
			self:route_stanza(msg);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   177
		end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   178
	end
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   179
	if self._data['subject'] then
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   180
		self:route_stanza(st.message({type='groupchat', from=self.jid, to=to}):tag("subject"):text(self._data['subject']));
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   181
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   182
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   183
1756
b2291156a9c2 MUC: Added service discovery replies for rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1755
diff changeset
   184
local function room_get_disco_info(self, stanza)
1808
e164fdb2d18f MUC: Added MUC feature to the disco#info replies of rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1778
diff changeset
   185
	return st.reply(stanza):query("http://jabber.org/protocol/disco#info")
e164fdb2d18f MUC: Added MUC feature to the disco#info replies of rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1778
diff changeset
   186
		:tag("identity", {category="conference", type="text"}):up()
e164fdb2d18f MUC: Added MUC feature to the disco#info replies of rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1778
diff changeset
   187
		:tag("feature", {var="http://jabber.org/protocol/muc"});
1756
b2291156a9c2 MUC: Added service discovery replies for rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1755
diff changeset
   188
end
b2291156a9c2 MUC: Added service discovery replies for rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1755
diff changeset
   189
local function room_get_disco_items(self, stanza)
b2291156a9c2 MUC: Added service discovery replies for rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1755
diff changeset
   190
	return st.reply(stanza):query("http://jabber.org/protocol/disco#items");
b2291156a9c2 MUC: Added service discovery replies for rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1755
diff changeset
   191
end
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   192
function room_mt:set_subject(current_nick, subject)
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   193
	-- TODO check nick's authority
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   194
	if subject == "" then subject = nil; end
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   195
	self._data['subject'] = subject;
1754
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   196
	if self.save then self:save(); end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   197
	local msg = st.message({type='groupchat', from=current_nick})
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   198
		:tag('subject'):text(subject):up();
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   199
	self:broadcast_message(msg, false);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   200
	return true;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   201
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   202
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   203
function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   204
	local from, to = stanza.attr.from, stanza.attr.to;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   205
	local room = jid_bare(to);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   206
	local current_nick = self._jid_nick[from];
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   207
	local type = stanza.attr.type;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   208
	log("debug", "room: %s, current_nick: %s, stanza: %s", room or "nil", current_nick or "nil", stanza:top_tag());
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   209
	if (select(2, jid_split(from)) == muc_domain) then error("Presence from the MUC itself!!!"); end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   210
	if stanza.name == "presence" then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   211
		local pr = get_filtered_presence(stanza);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   212
		pr.attr.from = current_nick;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   213
		if type == "error" then -- error, kick em out!
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   214
			if current_nick then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   215
				log("debug", "kicking %s from %s", current_nick, room);
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   216
				self:handle_to_occupant(origin, st.presence({type='unavailable', from=from, to=to})
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
   217
					:tag('status'):text('Kicked: '..get_error_condition(stanza))); -- send unavailable
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   218
			end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   219
		elseif type == "unavailable" then -- unavailable
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   220
			if current_nick then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   221
				log("debug", "%s leaving %s", current_nick, room);
1826
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   222
				local occupant = self._occupants[current_nick];
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   223
				local new_jid = next(occupant.sessions);
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   224
				if new_jid == from then new_jid = next(occupant.sessions, new_jid); end
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   225
				if new_jid then
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   226
					local jid = occupant.jid;
1826
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   227
					occupant.jid = new_jid;
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   228
					occupant.sessions[from] = nil;
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   229
					pr.attr.to = from;
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   230
					pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   231
						:tag("item", {affiliation=occupant.affiliation, role='none'}):up()
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   232
						:tag("status", {code='110'});
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   233
					self:route_stanza(pr);
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   234
					if jid ~= new_jid then
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   235
						pr = st.clone(occupant.sessions[new_jid])
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   236
							:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   237
							:tag("item", {affiliation=occupant.affiliation, role=occupant.role});
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   238
						self:broadcast_except_nick(pr, current_nick);
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   239
					end
1826
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   240
				else
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   241
					occupant.role = 'none';
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   242
					self:broadcast_presence(pr, from);
1826
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   243
					self._occupants[current_nick] = nil;
de165b5de254 MUC: Added multi-session support to the room-exiting occupant use case.
Waqas Hussain <waqas20@gmail.com>
parents: 1825
diff changeset
   244
				end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   245
				self._jid_nick[from] = nil;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   246
			end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   247
		elseif not type then -- available
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   248
			if current_nick then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   249
				--if #pr == #stanza or current_nick ~= to then -- commented because google keeps resending directed presence
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   250
					if current_nick == to then -- simple presence
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   251
						log("debug", "%s broadcasted presence", current_nick);
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   252
						self._occupants[current_nick].sessions[from] = pr;
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   253
						self:broadcast_presence(pr, from);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   254
					else -- change nick
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   255
						local occupant = self._occupants[current_nick];
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   256
						local is_multisession = next(occupant, next(occupant));
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   257
						if self._occupants[to] or is_multisession then
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   258
							log("debug", "%s couldn't change nick", current_nick);
1818
a394e0bd4847 MUC: Added legacy error codes to nickname conflict presence errors.
Waqas Hussain <waqas20@gmail.com>
parents: 1808
diff changeset
   259
							local reply = st.error_reply(stanza, "cancel", "conflict"):up();
a394e0bd4847 MUC: Added legacy error codes to nickname conflict presence errors.
Waqas Hussain <waqas20@gmail.com>
parents: 1808
diff changeset
   260
							reply.tags[1].attr.code = "409";
a394e0bd4847 MUC: Added legacy error codes to nickname conflict presence errors.
Waqas Hussain <waqas20@gmail.com>
parents: 1808
diff changeset
   261
							origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   262
						else
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   263
							local data = self._occupants[current_nick];
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   264
							local to_nick = select(3, jid_split(to));
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   265
							if to_nick then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   266
								log("debug", "%s (%s) changing nick to %s", current_nick, data.jid, to);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   267
								local p = st.presence({type='unavailable', from=current_nick});
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   268
								self:broadcast_presence(p, from, '303', to_nick);
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   269
								self._occupants[current_nick] = nil;
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   270
								self._occupants[to] = data;
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   271
								self._jid_nick[from] = to;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   272
								pr.attr.from = to;
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   273
								self._occupants[to].sessions[from] = pr;
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   274
								self:broadcast_presence(pr, from);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   275
							else
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   276
								--TODO malformed-jid
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   277
							end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   278
						end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   279
					end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   280
				--else -- possible rejoin
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   281
				--	log("debug", "%s had connection replaced", current_nick);
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   282
				--	self:handle_to_occupant(origin, st.presence({type='unavailable', from=from, to=to})
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   283
				--		:tag('status'):text('Replaced by new connection'):up()); -- send unavailable
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   284
				--	self:handle_to_occupant(origin, stanza); -- resend available
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   285
				--end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   286
			else -- enter room
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   287
				local new_nick = to;
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   288
				local is_merge;
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   289
				if self._occupants[to] then
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   290
					if jid_bare(from) ~= jid_bare(self._occupants[to].jid) then
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   291
						new_nick = nil;
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   292
					end
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   293
					is_merge = true;
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   294
				end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   295
				if not new_nick then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   296
					log("debug", "%s couldn't join due to nick conflict: %s", from, to);
1818
a394e0bd4847 MUC: Added legacy error codes to nickname conflict presence errors.
Waqas Hussain <waqas20@gmail.com>
parents: 1808
diff changeset
   297
					local reply = st.error_reply(stanza, "cancel", "conflict"):up();
a394e0bd4847 MUC: Added legacy error codes to nickname conflict presence errors.
Waqas Hussain <waqas20@gmail.com>
parents: 1808
diff changeset
   298
					reply.tags[1].attr.code = "409";
a394e0bd4847 MUC: Added legacy error codes to nickname conflict presence errors.
Waqas Hussain <waqas20@gmail.com>
parents: 1808
diff changeset
   299
					origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   300
				else
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   301
					log("debug", "%s joining as %s", from, to);
1737
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   302
					if not next(self._affiliations) then -- new room, no owners
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   303
						self._affiliations[jid_bare(from)] = "owner";
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   304
					end
1740
b37ccf9bec89 MUC: Send appropriate error to banned users on join.
Waqas Hussain <waqas20@gmail.com>
parents: 1739
diff changeset
   305
					local affiliation = self:get_affiliation(from);
b37ccf9bec89 MUC: Send appropriate error to banned users on join.
Waqas Hussain <waqas20@gmail.com>
parents: 1739
diff changeset
   306
					local role = self:get_default_role(affiliation)
b37ccf9bec89 MUC: Send appropriate error to banned users on join.
Waqas Hussain <waqas20@gmail.com>
parents: 1739
diff changeset
   307
					if role then -- new occupant
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   308
						if not is_merge then
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   309
							self._occupants[to] = {affiliation=affiliation, role=role, jid=from, sessions={[from]=get_filtered_presence(stanza)}};
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   310
						else
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   311
							self._occupants[to].sessions[from] = get_filtered_presence(stanza);
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   312
						end
1740
b37ccf9bec89 MUC: Send appropriate error to banned users on join.
Waqas Hussain <waqas20@gmail.com>
parents: 1739
diff changeset
   313
						self._jid_nick[from] = to;
b37ccf9bec89 MUC: Send appropriate error to banned users on join.
Waqas Hussain <waqas20@gmail.com>
parents: 1739
diff changeset
   314
						self:send_occupant_list(from);
b37ccf9bec89 MUC: Send appropriate error to banned users on join.
Waqas Hussain <waqas20@gmail.com>
parents: 1739
diff changeset
   315
						pr.attr.from = to;
1989
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   316
						if not is_merge then
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   317
							self:broadcast_presence(pr, from);
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   318
						else
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   319
							pr.attr.to = from;
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   320
							self:route_stanza(pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   321
								:tag("item", {affiliation=affiliation, role=role}):up()
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   322
								:tag("status", {code='110'}));
97c3236cc4ac MUC: Multiple sessions per nick.
Waqas Hussain <waqas20@gmail.com>
parents: 1862
diff changeset
   323
						end
1740
b37ccf9bec89 MUC: Send appropriate error to banned users on join.
Waqas Hussain <waqas20@gmail.com>
parents: 1739
diff changeset
   324
						self:send_history(from);
b37ccf9bec89 MUC: Send appropriate error to banned users on join.
Waqas Hussain <waqas20@gmail.com>
parents: 1739
diff changeset
   325
					else -- banned
1819
ed1911be26c7 MUC: Added legacy error code to the presence error returned when a banned user attempts to join.
Waqas Hussain <waqas20@gmail.com>
parents: 1818
diff changeset
   326
						local reply = st.error_reply(stanza, "auth", "forbidden"):up();
ed1911be26c7 MUC: Added legacy error code to the presence error returned when a banned user attempts to join.
Waqas Hussain <waqas20@gmail.com>
parents: 1818
diff changeset
   327
						reply.tags[1].attr.code = "403";
ed1911be26c7 MUC: Added legacy error code to the presence error returned when a banned user attempts to join.
Waqas Hussain <waqas20@gmail.com>
parents: 1818
diff changeset
   328
						origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   329
					end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   330
				end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   331
			end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   332
		elseif type ~= 'result' then -- bad type
1998
40792c18a8e4 MUC: Ignore invisible presence (incorrectly broadcasted or forwarded by ejabberd).
Waqas Hussain <waqas20@gmail.com>
parents: 1997
diff changeset
   333
			if type ~= 'visible' and type ~= 'invisible' then -- COMPAT ejabberd can broadcast or forward XEP-0018 presences
40792c18a8e4 MUC: Ignore invisible presence (incorrectly broadcasted or forwarded by ejabberd).
Waqas Hussain <waqas20@gmail.com>
parents: 1997
diff changeset
   334
				origin.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME correct error?
40792c18a8e4 MUC: Ignore invisible presence (incorrectly broadcasted or forwarded by ejabberd).
Waqas Hussain <waqas20@gmail.com>
parents: 1997
diff changeset
   335
			end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   336
		end
1778
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   337
	elseif not current_nick then -- not in room
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   338
		if type == "error" or type == "result" then
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   339
			local id = stanza.name == "iq" and stanza.attr.id and base64.decode(stanza.attr.id);
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   340
			local _nick, _id, _hash = (id or ""):match("^(.+)%z(.*)%z(.+)$");
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   341
			local occupant = self._occupants[stanza.attr.to];
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   342
			if occupant and _nick and self._jid_nick[_nick] and _id and _hash then
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   343
				local id, _to = stanza.attr.id;
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   344
				for jid in pairs(occupant.sessions) do
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   345
					if md5(jid) == _hash then
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   346
						_to = jid;
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   347
						break;
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   348
					end
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   349
				end
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   350
				if _to then
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   351
					stanza.attr.to, stanza.attr.from, stanza.attr.id = _to, self._jid_nick[_nick], _id;
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   352
					self:route_stanza(stanza);
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   353
					stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id;
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   354
				end
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   355
			end
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   356
		else
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   357
			origin.send(st.error_reply(stanza, "cancel", "not-acceptable"));
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   358
		end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   359
	elseif stanza.name == "message" and type == "groupchat" then -- groupchat messages not allowed in PM
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   360
		origin.send(st.error_reply(stanza, "modify", "bad-request"));
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
   361
	elseif current_nick and stanza.name == "message" and type == "error" and is_kickable_error(stanza) then
1996
3e6b36c6d7b7 MUC: Kick occupants on sending error messages to other occupants.
Waqas Hussain <waqas20@gmail.com>
parents: 1989
diff changeset
   362
		log("debug", "%s kicked from %s for sending an error message", current_nick, self.jid);
3e6b36c6d7b7 MUC: Kick occupants on sending error messages to other occupants.
Waqas Hussain <waqas20@gmail.com>
parents: 1989
diff changeset
   363
		self:handle_to_occupant(origin, st.presence({type='unavailable', from=stanza.attr.from, to=stanza.attr.to})
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
   364
			:tag('status'):text('Kicked: '..get_error_condition(stanza))); -- send unavailable
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   365
	else -- private stanza
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   366
		local o_data = self._occupants[to];
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   367
		if o_data then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   368
			log("debug", "%s sent private stanza to %s (%s)", from, to, o_data.jid);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   369
			local jid = o_data.jid;
1778
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   370
			local bare = jid_bare(jid);
1769
39865fbbb2f7 MUC: Preserve stanza attributes for private messages.
Waqas Hussain <waqas20@gmail.com>
parents: 1768
diff changeset
   371
			stanza.attr.to, stanza.attr.from = jid, current_nick;
1778
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   372
			local id = stanza.attr.id;
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   373
			if stanza.name=='iq' and type=='get' and stanza.tags[1].attr.xmlns == 'vcard-temp' and bare ~= jid then
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   374
				stanza.attr.to = bare;
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   375
				stanza.attr.id = base64.encode(jid.."\0"..id.."\0"..md5(from));
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   376
			end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   377
			self:route_stanza(stanza);
1778
f4213d84ba8a MUC: Correct routing of vCard requests to bare JID.
Waqas Hussain <waqas20@gmail.com>
parents: 1769
diff changeset
   378
			stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id;
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   379
		elseif type ~= "error" and type ~= "result" then -- recipient not in room
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   380
			origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Recipient not in room"));
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   381
		end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   382
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   383
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   384
1754
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   385
function room_mt:handle_form(origin, stanza)
1757
157e438823ba MUC: Fixed traceback on unauthorized access of the room configuration form.
Waqas Hussain <waqas20@gmail.com>
parents: 1756
diff changeset
   386
	if self:get_affiliation(stanza.attr.from) ~= "owner" then origin.send(st.error_reply(stanza, "auth", "forbidden")); return; end
1754
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   387
	if stanza.attr.type == "get" then
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   388
		local title = "Configuration for "..self.jid;
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   389
		origin.send(st.reply(stanza):query("http://jabber.org/protocol/muc#owner")
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   390
			:tag("x", {xmlns='jabber:x:data', type='form'})
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   391
				:tag("title"):text(title):up()
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   392
				:tag("instructions"):text(title):up()
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   393
				:tag("field", {type='hidden', var='FORM_TYPE'}):tag("value"):text("http://jabber.org/protocol/muc#roomconfig"):up():up()
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   394
				:tag("field", {type='boolean', label='Make Room Persistent?', var='muc#roomconfig_persistentroom'})
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   395
					:tag("value"):text(self._data.persistent and "1" or "0"):up()
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   396
				:up()
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   397
				:tag("field", {type='boolean', label='Make Room Publicly Searchable?', var='muc#roomconfig_publicroom'})
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   398
					:tag("value"):text(self._data.hidden and "0" or "1"):up()
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   399
				:up()
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   400
		);
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   401
	elseif stanza.attr.type == "set" then
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   402
		local query = stanza.tags[1];
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   403
		local form;
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   404
		for _, tag in ipairs(query.tags) do if tag.name == "x" and tag.attr.xmlns == "jabber:x:data" then form = tag; break; end end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   405
		if not form then origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); return; end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   406
		if form.attr.type == "cancel" then origin.send(st.reply(stanza)); return; end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   407
		if form.attr.type ~= "submit" then origin.send(st.error_reply(stanza, "cancel", "bad-request")); return; end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   408
		local fields = {};
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   409
		for _, field in pairs(form.tags) do
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   410
			if field.name == "field" and field.attr.var and field.tags[1].name == "value" and #field.tags[1].tags == 0 then
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   411
				fields[field.attr.var] = field.tags[1][1] or "";
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   412
			end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   413
		end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   414
		if fields.FORM_TYPE ~= "http://jabber.org/protocol/muc#roomconfig" then origin.send(st.error_reply(stanza, "cancel", "bad-request")); return; end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   415
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   416
		local persistent = fields['muc#roomconfig_persistentroom'];
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   417
		if persistent == "0" or persistent == "false" then persistent = nil; elseif persistent == "1" or persistent == "true" then persistent = true;
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   418
		else origin.send(st.error_reply(stanza, "cancel", "bad-request")); return; end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   419
		self._data.persistent = persistent;
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   420
		module:log("debug", "persistent=%s", tostring(persistent));
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   421
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   422
		local public = fields['muc#roomconfig_publicroom'];
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   423
		if public == "0" or public == "false" then public = nil; elseif public == "1" or public == "true" then public = true;
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   424
		else origin.send(st.error_reply(stanza, "cancel", "bad-request")); return; end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   425
		self._data.hidden = not public and true or nil;
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   426
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   427
		if self.save then self:save(true); end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   428
		origin.send(st.reply(stanza));
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   429
	end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   430
end
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   431
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   432
function room_mt:handle_to_room(origin, stanza) -- presence changes and groupchat messages, along with disco/etc
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   433
	local type = stanza.attr.type;
1745
15039fac3693 MUC: Some fixes for minor bugs in IQ handling.
Waqas Hussain <waqas20@gmail.com>
parents: 1744
diff changeset
   434
	local xmlns = stanza.tags[1] and stanza.tags[1].attr.xmlns;
1753
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   435
	if stanza.name == "iq" then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   436
		if xmlns == "http://jabber.org/protocol/disco#info" and type == "get" then
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   437
			origin.send(room_get_disco_info(self, stanza));
1753
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   438
		elseif xmlns == "http://jabber.org/protocol/disco#items" and type == "get" then
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   439
			origin.send(room_get_disco_items(self, stanza));
1753
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   440
		elseif xmlns == "http://jabber.org/protocol/muc#admin" then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   441
			local actor = stanza.attr.from;
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   442
			local affiliation = self:get_affiliation(actor);
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   443
			local current_nick = self._jid_nick[actor];
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   444
			local role = current_nick and self._occupants[current_nick].role or self:get_default_role(affiliation);
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   445
			local item = stanza.tags[1].tags[1];
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   446
			if item and item.name == "item" then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   447
				if type == "set" then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   448
					local callback = function() origin.send(st.reply(stanza)); end
1862
115f274dd17f MUC: Prep given JID when changing affiliation.
Waqas Hussain <waqas20@gmail.com>
parents: 1826
diff changeset
   449
					if item.attr.jid then -- Validate provided JID
115f274dd17f MUC: Prep given JID when changing affiliation.
Waqas Hussain <waqas20@gmail.com>
parents: 1826
diff changeset
   450
						item.attr.jid = jid_prep(item.attr.jid);
115f274dd17f MUC: Prep given JID when changing affiliation.
Waqas Hussain <waqas20@gmail.com>
parents: 1826
diff changeset
   451
						if not item.attr.jid then
115f274dd17f MUC: Prep given JID when changing affiliation.
Waqas Hussain <waqas20@gmail.com>
parents: 1826
diff changeset
   452
							origin.send(st.error_reply(stanza, "modify", "jid-malformed"));
115f274dd17f MUC: Prep given JID when changing affiliation.
Waqas Hussain <waqas20@gmail.com>
parents: 1826
diff changeset
   453
							return;
115f274dd17f MUC: Prep given JID when changing affiliation.
Waqas Hussain <waqas20@gmail.com>
parents: 1826
diff changeset
   454
						end
115f274dd17f MUC: Prep given JID when changing affiliation.
Waqas Hussain <waqas20@gmail.com>
parents: 1826
diff changeset
   455
					end
1753
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   456
					if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   457
						local occupant = self._occupants[self.jid.."/"..item.attr.nick];
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   458
						if occupant then item.attr.jid = occupant.jid; end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   459
					end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   460
					if item.attr.affiliation and item.attr.jid and not item.attr.role then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   461
						local success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, callback);
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   462
						if not success then origin.send(st.error_reply(stanza, errtype, err)); end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   463
					elseif item.attr.role and item.attr.nick and not item.attr.affiliation then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   464
						local success, errtype, err = self:set_role(actor, self.jid.."/"..item.attr.nick, item.attr.role, callback);
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   465
						if not success then origin.send(st.error_reply(stanza, errtype, err)); end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   466
					else
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   467
						origin.send(st.error_reply(stanza, "cancel", "bad-request"));
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   468
					end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   469
				elseif type == "get" then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   470
					local _aff = item.attr.affiliation;
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   471
					local _rol = item.attr.role;
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   472
					if _aff and not _rol then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   473
						if affiliation == "owner" or (affiliation == "admin" and _aff ~= "owner" and _aff ~= "admin") then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   474
							local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin");
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   475
							for jid, affiliation in pairs(self._affiliations) do
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   476
								if affiliation == _aff then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   477
									reply:tag("item", {affiliation = _aff, jid = jid}):up();
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   478
								end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   479
							end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   480
							origin.send(reply);
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   481
						else
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   482
							origin.send(st.error_reply(stanza, "auth", "forbidden"));
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   483
						end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   484
					elseif _rol and not _aff then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   485
						if role == "moderator" then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   486
							-- TODO allow admins and owners not in room? Provide read-only access to everyone who can see the participants anyway?
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   487
							if _rol == "none" then _rol = nil; end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   488
							local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin");
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   489
							for nick, occupant in pairs(self._occupants) do
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   490
								if occupant.role == _rol then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   491
									reply:tag("item", {nick = nick, role = _rol or "none", affiliation = occupant.affiliation or "none", jid = occupant.jid}):up();
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   492
								end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   493
							end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   494
							origin.send(reply);
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   495
						else
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   496
							origin.send(st.error_reply(stanza, "auth", "forbidden"));
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   497
						end
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   498
					else
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   499
						origin.send(st.error_reply(stanza, "cancel", "bad-request"));
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   500
					end
1744
265863a5612b MUC: Added support for requesting various lists (owner, admin, voice, etc).
Waqas Hussain <waqas20@gmail.com>
parents: 1743
diff changeset
   501
				end
1753
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   502
			elseif type == "set" or type == "get" then
a84901db4085 MUC: Refactored IQ handling to be more easily extensible.
Waqas Hussain <waqas20@gmail.com>
parents: 1752
diff changeset
   503
				origin.send(st.error_reply(stanza, "cancel", "bad-request"));
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   504
			end
1754
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   505
		elseif xmlns == "http://jabber.org/protocol/muc#owner" and (type == "get" or type == "set") and stanza.tags[1].name == "query" then
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   506
			self:handle_form(origin, stanza);
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   507
		elseif type == "set" or type == "get" then
67b66eec9777 MUC: Added support for room configuration forms, persistence and hidden rooms.
Waqas Hussain <waqas20@gmail.com>
parents: 1753
diff changeset
   508
			origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   509
		end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   510
	elseif stanza.name == "message" and type == "groupchat" then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   511
		local from, to = stanza.attr.from, stanza.attr.to;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   512
		local room = jid_bare(to);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   513
		local current_nick = self._jid_nick[from];
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   514
		if not current_nick then -- not in room
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   515
			origin.send(st.error_reply(stanza, "cancel", "not-acceptable"));
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   516
		else
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   517
			local from = stanza.attr.from;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   518
			stanza.attr.from = current_nick;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   519
			local subject = getText(stanza, {"subject"});
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   520
			if subject then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   521
				self:set_subject(current_nick, subject); -- TODO use broadcast_message_stanza
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   522
			else
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   523
				self:broadcast_message(stanza, true);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   524
			end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   525
		end
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
   526
	elseif stanza.name == "message" and type == "error" and is_kickable_error(stanza) then
1768
802c40384dd0 MUC: Don't kick on errors in private messages.
Waqas Hussain <waqas20@gmail.com>
parents: 1764
diff changeset
   527
		local current_nick = self._jid_nick[stanza.attr.from];
802c40384dd0 MUC: Don't kick on errors in private messages.
Waqas Hussain <waqas20@gmail.com>
parents: 1764
diff changeset
   528
		log("debug", "%s kicked from %s for sending an error message", current_nick, self.jid);
802c40384dd0 MUC: Don't kick on errors in private messages.
Waqas Hussain <waqas20@gmail.com>
parents: 1764
diff changeset
   529
		self:handle_to_occupant(origin, st.presence({type='unavailable', from=stanza.attr.from, to=stanza.attr.to})
1999
05054e360d89 MUC: Improved handling of error stanzas and made error messages concise.
Waqas Hussain <waqas20@gmail.com>
parents: 1998
diff changeset
   530
			:tag('status'):text('Kicked: '..get_error_condition(stanza))); -- send unavailable
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   531
	elseif stanza.name == "presence" then -- hack - some buggy clients send presence updates to the room rather than their nick
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   532
		local to = stanza.attr.to;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   533
		local current_nick = self._jid_nick[stanza.attr.from];
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   534
		if current_nick then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   535
			stanza.attr.to = current_nick;
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   536
			self:handle_to_occupant(origin, stanza);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   537
			stanza.attr.to = to;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   538
		elseif type ~= "error" and type ~= "result" then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   539
			origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   540
		end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   541
	elseif stanza.name == "message" and not stanza.attr.type and #stanza.tags == 1 and self._jid_nick[stanza.attr.from]
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   542
		and stanza.tags[1].name == "x" and stanza.tags[1].attr.xmlns == "http://jabber.org/protocol/muc#user" and #stanza.tags[1].tags == 1
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   543
		and stanza.tags[1].tags[1].name == "invite" and stanza.tags[1].tags[1].attr.to then
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   544
		local _from, _to = stanza.attr.from, stanza.attr.to;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   545
		local _invitee = stanza.tags[1].tags[1].attr.to;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   546
		stanza.attr.from, stanza.attr.to = _to, _invitee;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   547
		stanza.tags[1].tags[1].attr.from, stanza.tags[1].tags[1].attr.to = _from, nil;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   548
		self:route_stanza(stanza);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   549
		stanza.tags[1].tags[1].attr.from, stanza.tags[1].tags[1].attr.to = nil, _invitee;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   550
		stanza.attr.from, stanza.attr.to = _from, _to;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   551
	else
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   552
		if type == "error" or type == "result" then return; end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   553
		origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   554
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   555
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   556
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   557
function room_mt:handle_stanza(origin, stanza)
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   558
	local to_node, to_host, to_resource = jid_split(stanza.attr.to);
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   559
	if to_resource then
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   560
		self:handle_to_occupant(origin, stanza);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   561
	else
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   562
		self:handle_to_room(origin, stanza);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   563
	end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   564
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   565
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   566
function room_mt:route_stanza(stanza) end -- Replace with a routing function, e.g., function(room, stanza) core_route_stanza(origin, stanza); end
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   567
1737
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   568
function room_mt:get_affiliation(jid)
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   569
	local node, host, resource = jid_split(jid);
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   570
	local bare = node and node.."@"..host or host;
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   571
	local result = self._affiliations[bare]; -- Affiliations are granted, revoked, and maintained based on the user's bare JID.
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   572
	if not result and self._affiliations[host] == "outcast" then result = "outcast"; end -- host banned
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   573
	return result;
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   574
end
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   575
function room_mt:set_affiliation(actor, jid, affiliation, callback)
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   576
	jid = jid_bare(jid);
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   577
	if affiliation == "none" then affiliation = nil; end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   578
	if affiliation and affiliation ~= "outcast" and affiliation ~= "owner" and affiliation ~= "admin" and affiliation ~= "member" then
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   579
		return nil, "modify", "not-acceptable";
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   580
	end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   581
	if self:get_affiliation(actor) ~= "owner" then return nil, "cancel", "not-allowed"; end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   582
	if jid_bare(actor) == jid then return nil, "cancel", "not-allowed"; end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   583
	self._affiliations[jid] = affiliation;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   584
	local role = self:get_default_role(affiliation);
1750
a1c18470eeee MUC: Fixed: Unavailable presence was being sent for all role and affiliation changes. Now sent only for kicked occupants.
Waqas Hussain <waqas20@gmail.com>
parents: 1749
diff changeset
   585
	local p = st.presence()
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   586
		:tag("x", {xmlns = "http://jabber.org/protocol/muc#user"})
1744
265863a5612b MUC: Added support for requesting various lists (owner, admin, voice, etc).
Waqas Hussain <waqas20@gmail.com>
parents: 1743
diff changeset
   587
			:tag("item", {affiliation=affiliation or "none", role=role or "none"}):up();
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   588
	local x = p.tags[1];
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   589
	local item = x.tags[1];
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   590
	if not role then -- getting kicked
1750
a1c18470eeee MUC: Fixed: Unavailable presence was being sent for all role and affiliation changes. Now sent only for kicked occupants.
Waqas Hussain <waqas20@gmail.com>
parents: 1749
diff changeset
   591
		p.attr.type = "unavailable";
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   592
		if affiliation == "outcast" then
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   593
			x:tag("status", {code="301"}):up(); -- banned
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   594
		else
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   595
			x:tag("status", {code="321"}):up(); -- affiliation change
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   596
		end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   597
	end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   598
	local modified_nicks = {};
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   599
	for nick, occupant in pairs(self._occupants) do
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   600
		if jid_bare(occupant.jid) == jid then
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   601
			if not role then -- getting kicked
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   602
				self._occupants[nick] = nil;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   603
			else
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   604
				t_insert(modified_nicks, nick);
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   605
				occupant.affiliation, occupant.role = affiliation, role;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   606
			end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   607
			p.attr.from = nick;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   608
			for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   609
				if not role then self._jid_nick[jid] = nil; end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   610
				p.attr.to = jid;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   611
				self:route_stanza(p);
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   612
			end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   613
		end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   614
	end
1755
1614e8e62ad5 MUC: Fixed an undefined global access.
Waqas Hussain <waqas20@gmail.com>
parents: 1754
diff changeset
   615
	if self.save then self:save(); end
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   616
	if callback then callback(); end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   617
	for _, nick in ipairs(modified_nicks) do
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   618
		p.attr.from = nick;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   619
		self:broadcast_except_nick(p, nick);
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   620
	end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   621
	return true;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   622
end
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   623
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   624
function room_mt:get_role(nick)
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   625
	local session = self._occupants[nick];
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   626
	return session and session.role or nil;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   627
end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   628
function room_mt:set_role(actor, nick, role, callback)
1752
4db786919805 MUC: Added kicking support.
Waqas Hussain <waqas20@gmail.com>
parents: 1751
diff changeset
   629
	if role == "none" then role = nil; end
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   630
	if role and role ~= "moderator" and role ~= "participant" and role ~= "visitor" then return nil, "modify", "not-acceptable"; end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   631
	if self:get_affiliation(actor) ~= "owner" then return nil, "cancel", "not-allowed"; end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   632
	local occupant = self._occupants[nick];
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   633
	if not occupant then return nil, "modify", "not-acceptable"; end
1743
d00b144f4bcf MUC: An admin or owner MUST NOT be able to revoke moderation privileges from another admin or owner.
Waqas Hussain <waqas20@gmail.com>
parents: 1742
diff changeset
   634
	if occupant.affiliation == "owner" or occupant.affiliation == "admin" then return nil, "cancel", "not-allowed"; end
1750
a1c18470eeee MUC: Fixed: Unavailable presence was being sent for all role and affiliation changes. Now sent only for kicked occupants.
Waqas Hussain <waqas20@gmail.com>
parents: 1749
diff changeset
   635
	local p = st.presence({from = nick})
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   636
		:tag("x", {xmlns = "http://jabber.org/protocol/muc#user"})
1744
265863a5612b MUC: Added support for requesting various lists (owner, admin, voice, etc).
Waqas Hussain <waqas20@gmail.com>
parents: 1743
diff changeset
   637
			:tag("item", {affiliation=occupant.affiliation or "none", nick=nick, role=role or "none"}):up();
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   638
	if not role then -- kick
1750
a1c18470eeee MUC: Fixed: Unavailable presence was being sent for all role and affiliation changes. Now sent only for kicked occupants.
Waqas Hussain <waqas20@gmail.com>
parents: 1749
diff changeset
   639
		p.attr.type = "unavailable";
1742
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   640
		self._occupants[nick] = nil;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   641
		for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   642
			self._jid_nick[jid] = nil;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   643
		end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   644
		p:tag("status", {code = "307"}):up();
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   645
	else
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   646
		occupant.role = role;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   647
	end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   648
	for jid in pairs(occupant.sessions) do -- send to all sessions of the nick
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   649
		p.attr.to = jid;
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   650
		self:route_stanza(p);
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   651
	end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   652
	if callback then callback(); end
1483a62d69bb MUC: Owners can now modify roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1740
diff changeset
   653
	self:broadcast_except_nick(p, nick);
1737
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   654
	return true;
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   655
end
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   656
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   657
local _M = {}; -- module "muc"
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   658
1749
cf2ade983e12 MUC: Changed a MUC library method into a function.
Waqas Hussain <waqas20@gmail.com>
parents: 1746
diff changeset
   659
function _M.new_room(jid)
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   660
	return setmetatable({
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   661
		jid = jid;
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   662
		_jid_nick = {};
1739
393abf245322 MUC: Renamed _participants table to _occupants
Waqas Hussain <waqas20@gmail.com>
parents: 1737
diff changeset
   663
		_occupants = {};
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   664
		_data = {};
1737
31c3eb5797c7 MUC: Initial support for roles and affiliations
Waqas Hussain <waqas20@gmail.com>
parents: 1736
diff changeset
   665
		_affiliations = {};
1735
81406277279e MUC: The MUC lib is now metatable based. Cleaned up code, etc.
Waqas Hussain <waqas20@gmail.com>
parents: 1734
diff changeset
   666
	}, room_mt);
1734
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   667
end
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   668
34ac9ba0aad6 MUC: Added initial MUC lib
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   669
return _M;