mirror of
https://github.com/bjc/prosody.git
synced 2025-04-04 05:37:39 +03:00
core.rostermanager/mod_roster: Support for roster versioning
This commit is contained in:
parent
39ac97e87a
commit
000fa4bb34
2 changed files with 30 additions and 15 deletions
|
@ -15,6 +15,7 @@ local setmetatable = setmetatable;
|
|||
local format = string.format;
|
||||
local loadfile, setfenv, pcall = loadfile, setfenv, pcall;
|
||||
local pairs, ipairs = pairs, ipairs;
|
||||
local tostring = tostring;
|
||||
|
||||
local hosts = hosts;
|
||||
|
||||
|
@ -54,10 +55,11 @@ function remove_from_roster(session, jid)
|
|||
end
|
||||
|
||||
function roster_push(username, host, jid)
|
||||
if jid ~= "pending" and hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster then
|
||||
local roster = jid and jid ~= "pending" and hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster;
|
||||
if roster then
|
||||
local item = hosts[host].sessions[username].roster[jid];
|
||||
local stanza = st.iq({type="set"});
|
||||
stanza:tag("query", {xmlns = "jabber:iq:roster"});
|
||||
stanza:tag("query", {xmlns = "jabber:iq:roster", ver = tostring(roster[false].version or "1") });
|
||||
if item then
|
||||
stanza:tag("item", {jid = jid, subscription = item.subscription, name = item.name, ask = item.ask});
|
||||
for group in pairs(item.groups) do
|
||||
|
@ -85,6 +87,7 @@ function load_roster(username, host)
|
|||
if not roster then
|
||||
log("debug", "load_roster: loading for new user: "..username.."@"..host);
|
||||
roster = datamanager.load(username, host, "roster") or {};
|
||||
if not roster[false] then roster[false] = { }; end
|
||||
hosts[host].sessions[username].roster = roster;
|
||||
end
|
||||
return roster;
|
||||
|
@ -97,8 +100,11 @@ end
|
|||
function save_roster(username, host)
|
||||
log("debug", "save_roster: saving roster for "..username.."@"..host);
|
||||
if hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster then
|
||||
local roster = hosts[host].sessions[username].roster;
|
||||
roster[false].version = (roster[false].version or 1) + 1;
|
||||
return datamanager.store(username, host, "roster", hosts[host].sessions[username].roster);
|
||||
end
|
||||
log("warn", "save_roster: user had no roster to save");
|
||||
return nil;
|
||||
end
|
||||
|
||||
|
@ -271,4 +277,4 @@ end]]
|
|||
|
||||
|
||||
|
||||
return _M;
|
||||
return _M;
|
||||
|
|
|
@ -12,6 +12,7 @@ local st = require "util.stanza"
|
|||
|
||||
local jid_split = require "util.jid".split;
|
||||
local t_concat = table.concat;
|
||||
local tostring = tostring;
|
||||
|
||||
local handle_presence = require "core.presencemanager".handle_presence;
|
||||
local rm_remove_from_roster = require "core.rostermanager".remove_from_roster;
|
||||
|
@ -27,19 +28,26 @@ module:add_iq_handler("c2s", "jabber:iq:roster",
|
|||
if stanza.attr.type == "get" then
|
||||
local roster = st.reply(stanza)
|
||||
:query("jabber:iq:roster");
|
||||
for jid in pairs(session.roster) do
|
||||
if jid ~= "pending" then
|
||||
roster:tag("item", {
|
||||
jid = jid,
|
||||
subscription = session.roster[jid].subscription,
|
||||
ask = session.roster[jid].ask,
|
||||
name = session.roster[jid].name,
|
||||
});
|
||||
for group in pairs(session.roster[jid].groups) do
|
||||
roster:tag("group"):text(group):up();
|
||||
|
||||
local ver = stanza.tags[1].attr.ver
|
||||
|
||||
if (not ver) or tonumber(ver) ~= (session.roster[false].version or 1) then
|
||||
-- Client does not support versioning, or has stale roster
|
||||
for jid in pairs(session.roster) do
|
||||
if jid ~= "pending" and jid then
|
||||
roster:tag("item", {
|
||||
jid = jid,
|
||||
subscription = session.roster[jid].subscription,
|
||||
ask = session.roster[jid].ask,
|
||||
name = session.roster[jid].name,
|
||||
});
|
||||
for group in pairs(session.roster[jid].groups) do
|
||||
roster:tag("group"):text(group):up();
|
||||
end
|
||||
roster:up(); -- move out from item
|
||||
end
|
||||
roster:up(); -- move out from item
|
||||
end
|
||||
roster.tags[1].attr.ver = tostring(session.roster[false].version or "1");
|
||||
end
|
||||
session.send(roster);
|
||||
session.interested = true; -- resource is interested in roster updates
|
||||
|
@ -47,7 +55,8 @@ module:add_iq_handler("c2s", "jabber:iq:roster",
|
|||
elseif stanza.attr.type == "set" then
|
||||
local query = stanza.tags[1];
|
||||
if #query.tags == 1 and query.tags[1].name == "item"
|
||||
and query.tags[1].attr.xmlns == "jabber:iq:roster" and query.tags[1].attr.jid
|
||||
and query.tags[1].attr.xmlns == "jabber:iq:roster" and query.tags[1].attr.jid
|
||||
-- Protection against overwriting roster.pending, until we move it
|
||||
and query.tags[1].attr.jid ~= "pending" then
|
||||
local item = query.tags[1];
|
||||
local from_node, from_host = jid_split(stanza.attr.from);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue