Comparison

core/rostermanager.lua @ 10563:e8db377a2983

Merge 0.11->trunk
author Kim Alvefur <zash@zash.se>
date Tue, 24 Dec 2019 00:39:45 +0100
parent 10514:f0e9e5bda415
child 10570:962efe23975d
comparison
equal deleted inserted replaced
10562:670afc079f68 10563:e8db377a2983
10 10
11 11
12 local log = require "util.logger".init("rostermanager"); 12 local log = require "util.logger".init("rostermanager");
13 13
14 local new_id = require "util.id".short; 14 local new_id = require "util.id".short;
15 local new_cache = require "util.cache".new;
15 16
16 local pairs = pairs; 17 local pairs = pairs;
17 local tostring = tostring; 18 local tostring = tostring;
18 local type = type; 19 local type = type;
19 20
109 if roster then return roster; end 110 if roster then return roster; end
110 log("debug", "load_roster: loading for new user: %s", jid); 111 log("debug", "load_roster: loading for new user: %s", jid);
111 else -- Attempt to load roster for non-loaded user 112 else -- Attempt to load roster for non-loaded user
112 log("debug", "load_roster: loading for offline user: %s", jid); 113 log("debug", "load_roster: loading for offline user: %s", jid);
113 end 114 end
115 local roster_cache = hosts[host] and hosts[host].roster_cache;
116 if not roster_cache then
117 if hosts[host] then
118 roster_cache = new_cache(1024);
119 hosts[host].roster_cache = roster_cache;
120 end
121 else
122 roster = roster_cache:get(jid);
123 if roster then
124 log("debug", "load_roster: cache hit");
125 roster_cache:set(jid, roster);
126 if user then user.roster = roster; end
127 return roster;
128 else
129 log("debug", "load_roster: cache miss, loading from storage");
130 end
131 end
114 local roster_store = storagemanager.open(host, "roster", "keyval"); 132 local roster_store = storagemanager.open(host, "roster", "keyval");
115 local data, err = roster_store:get(username); 133 local data, err = roster_store:get(username);
116 roster = data or {}; 134 roster = data or {};
117 if user then user.roster = roster; end 135 if user then user.roster = roster; end
118 local legacy_pending = roster.pending and type(roster.pending.subscription) ~= "string"; 136 local legacy_pending = roster.pending and type(roster.pending.subscription) ~= "string";
132 end 150 end
133 end 151 end
134 if not err then 152 if not err then
135 hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster }); 153 hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster });
136 end 154 end
155 if roster_cache and not user then
156 log("debug", "load_roster: caching loaded roster");
157 roster_cache:set(jid, roster);
158 end
137 return roster, err; 159 return roster, err;
138 end 160 end
139 161
140 function save_roster(username, host, roster, jid) 162 function save_roster(username, host, roster, jid)
141 if not um_user_exists(username, host) then 163 if not um_user_exists(username, host) then
261 return item and (item.subscription == "to" or item.subscription == "both"), err; 283 return item and (item.subscription == "to" or item.subscription == "both"), err;
262 end 284 end
263 285
264 function is_contact_pending_in(username, host, jid) 286 function is_contact_pending_in(username, host, jid)
265 local roster = load_roster(username, host); 287 local roster = load_roster(username, host);
266 return roster[false].pending[jid]; 288 return roster[false].pending[jid] ~= nil;
267 end 289 end
268 local function set_contact_pending_in(username, host, jid) 290 local function set_contact_pending_in(username, host, jid, stanza)
269 local roster = load_roster(username, host); 291 local roster = load_roster(username, host);
270 local item = roster[jid]; 292 local item = roster[jid];
271 if item and (item.subscription == "from" or item.subscription == "both") then 293 if item and (item.subscription == "from" or item.subscription == "both") then
272 return; -- false 294 return; -- false
273 end 295 end
274 roster[false].pending[jid] = true; 296 roster[false].pending[jid] = st.is_stanza(stanza) and st.preserialize(stanza) or true;
275 return save_roster(username, host, roster, jid); 297 return save_roster(username, host, roster, jid);
276 end 298 end
277 function is_contact_pending_out(username, host, jid) 299 function is_contact_pending_out(username, host, jid)
278 local roster = load_roster(username, host); 300 local roster = load_roster(username, host);
279 local item = roster[jid]; 301 local item = roster[jid];
280 return item and item.ask; 302 return item and item.ask;
303 end
304 local function is_contact_preapproved(username, host, jid)
305 local roster = load_roster(username, host);
306 local item = roster[jid];
307 return item and (item.approved == "true");
281 end 308 end
282 local function set_contact_pending_out(username, host, jid) -- subscribe 309 local function set_contact_pending_out(username, host, jid) -- subscribe
283 local roster = load_roster(username, host); 310 local roster = load_roster(username, host);
284 local item = roster[jid]; 311 local item = roster[jid];
285 if item and (item.ask or item.subscription == "to" or item.subscription == "both") then 312 if item and (item.ask or item.subscription == "to" or item.subscription == "both") then
307 item.subscription = "none"; 334 item.subscription = "none";
308 end 335 end
309 return save_roster(username, host, roster, jid); 336 return save_roster(username, host, roster, jid);
310 end 337 end
311 local function subscribed(username, host, jid) 338 local function subscribed(username, host, jid)
339 local roster = load_roster(username, host);
340 local item = roster[jid];
341
312 if is_contact_pending_in(username, host, jid) then 342 if is_contact_pending_in(username, host, jid) then
313 local roster = load_roster(username, host);
314 local item = roster[jid];
315 if not item then -- FIXME should roster item be auto-created? 343 if not item then -- FIXME should roster item be auto-created?
316 item = {subscription = "none", groups = {}}; 344 item = {subscription = "none", groups = {}};
317 roster[jid] = item; 345 roster[jid] = item;
318 end 346 end
319 if item.subscription == "none" then 347 if item.subscription == "none" then
321 else -- subscription == to 349 else -- subscription == to
322 item.subscription = "both"; 350 item.subscription = "both";
323 end 351 end
324 roster[false].pending[jid] = nil; 352 roster[false].pending[jid] = nil;
325 return save_roster(username, host, roster, jid); 353 return save_roster(username, host, roster, jid);
326 end -- TODO else implement optional feature pre-approval (ask = subscribed) 354 elseif not item or item.subscription == "none" or item.subscription == "to" then
355 -- Contact is not subscribed and has not sent a subscription request.
356 -- We store a pre-approval as per RFC6121 3.4
357 if not item then
358 item = {subscription = "none", groups = {}};
359 roster[jid] = item;
360 end
361 item.approved = "true";
362 log("debug", "Storing preapproval for %s", jid);
363 return save_roster(username, host, roster, jid);
364 end
327 end 365 end
328 local function unsubscribed(username, host, jid) 366 local function unsubscribed(username, host, jid)
329 local roster = load_roster(username, host); 367 local roster = load_roster(username, host);
330 local item = roster[jid]; 368 local item = roster[jid];
331 local pending = is_contact_pending_in(username, host, jid); 369 local pending = is_contact_pending_in(username, host, jid);
379 is_user_subscribed = is_user_subscribed; 417 is_user_subscribed = is_user_subscribed;
380 is_contact_pending_in = is_contact_pending_in; 418 is_contact_pending_in = is_contact_pending_in;
381 set_contact_pending_in = set_contact_pending_in; 419 set_contact_pending_in = set_contact_pending_in;
382 is_contact_pending_out = is_contact_pending_out; 420 is_contact_pending_out = is_contact_pending_out;
383 set_contact_pending_out = set_contact_pending_out; 421 set_contact_pending_out = set_contact_pending_out;
422 is_contact_preapproved = is_contact_preapproved;
384 unsubscribe = unsubscribe; 423 unsubscribe = unsubscribe;
385 subscribed = subscribed; 424 subscribed = subscribed;
386 unsubscribed = unsubscribed; 425 unsubscribed = unsubscribed;
387 process_outbound_subscription_request = process_outbound_subscription_request; 426 process_outbound_subscription_request = process_outbound_subscription_request;
388 }; 427 };