27 |
27 |
28 local function add_to_roster(session, jid, item) |
28 local function add_to_roster(session, jid, item) |
29 if session.roster then |
29 if session.roster then |
30 local old_item = session.roster[jid]; |
30 local old_item = session.roster[jid]; |
31 session.roster[jid] = item; |
31 session.roster[jid] = item; |
32 if save_roster(session.username, session.host) then |
32 if save_roster(session.username, session.host, nil, jid) then |
33 return true; |
33 return true; |
34 else |
34 else |
35 session.roster[jid] = old_item; |
35 session.roster[jid] = old_item; |
36 return nil, "wait", "internal-server-error", "Unable to save roster"; |
36 return nil, "wait", "internal-server-error", "Unable to save roster"; |
37 end |
37 end |
42 |
42 |
43 local function remove_from_roster(session, jid) |
43 local function remove_from_roster(session, jid) |
44 if session.roster then |
44 if session.roster then |
45 local old_item = session.roster[jid]; |
45 local old_item = session.roster[jid]; |
46 session.roster[jid] = nil; |
46 session.roster[jid] = nil; |
47 if save_roster(session.username, session.host) then |
47 if save_roster(session.username, session.host, nil, jid) then |
48 return true; |
48 return true; |
49 else |
49 else |
50 session.roster[jid] = old_item; |
50 session.roster[jid] = old_item; |
51 return nil, "wait", "internal-server-error", "Unable to save roster"; |
51 return nil, "wait", "internal-server-error", "Unable to save roster"; |
52 end |
52 end |
121 hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster }); |
121 hosts[host].events.fire_event("roster-load", { username = username, host = host, roster = roster }); |
122 end |
122 end |
123 return roster, err; |
123 return roster, err; |
124 end |
124 end |
125 |
125 |
126 function save_roster(username, host, roster) |
126 function save_roster(username, host, roster, jid) |
127 if not um_user_exists(username, host) then |
127 if not um_user_exists(username, host) then |
128 log("debug", "not saving roster for %s@%s: the user doesn't exist", username, host); |
128 log("debug", "not saving roster for %s@%s: the user doesn't exist", username, host); |
129 return nil; |
129 return nil; |
130 end |
130 end |
131 |
131 |
132 log("debug", "save_roster: saving roster for %s@%s", username, host); |
132 log("debug", "save_roster: saving roster for %s@%s, (%s)", username, host, jid or "all contacts"); |
133 if not roster then |
133 if not roster then |
134 roster = hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster; |
134 roster = hosts[host] and hosts[host].sessions[username] and hosts[host].sessions[username].roster; |
135 --if not roster then |
135 --if not roster then |
136 -- --roster = load_roster(username, host); |
136 -- --roster = load_roster(username, host); |
137 -- return true; -- roster unchanged, no reason to save |
137 -- return true; -- roster unchanged, no reason to save |
141 local metadata = roster_metadata(roster); |
141 local metadata = roster_metadata(roster); |
142 if metadata.version ~= true then |
142 if metadata.version ~= true then |
143 metadata.version = (metadata.version or 0) + 1; |
143 metadata.version = (metadata.version or 0) + 1; |
144 end |
144 end |
145 if metadata.broken then return nil, "Not saving broken roster" end |
145 if metadata.broken then return nil, "Not saving broken roster" end |
146 local roster_store = require "core.storagemanager".open(host, "roster", "keyval"); |
146 if jid == nil then |
147 return roster_store:set(username, roster); |
147 local roster_store = require "core.storagemanager".open(host, "roster", "keyval"); |
|
148 return roster_store:set(username, roster); |
|
149 else |
|
150 local roster_store = require "core.storagemanager".open(host, "roster", "map"); |
|
151 return roster_store:set_keys(username, { [false] = metadata, [jid] = roster[jid] or roster_store.remove }); |
|
152 end |
148 end |
153 end |
149 log("warn", "save_roster: user had no roster to save"); |
154 log("warn", "save_roster: user had no roster to save"); |
150 return nil; |
155 return nil; |
151 end |
156 end |
152 |
157 |
158 item.subscription = "to"; |
163 item.subscription = "to"; |
159 else -- subscription == from |
164 else -- subscription == from |
160 item.subscription = "both"; |
165 item.subscription = "both"; |
161 end |
166 end |
162 item.ask = nil; |
167 item.ask = nil; |
163 return save_roster(username, host, roster); |
168 return save_roster(username, host, roster, jid); |
164 end |
169 end |
165 end |
170 end |
166 |
171 |
167 local is_contact_pending_out -- forward declaration |
172 local is_contact_pending_out -- forward declaration |
168 |
173 |
206 item.subscription = "to"; |
211 item.subscription = "to"; |
207 changed = true; |
212 changed = true; |
208 end |
213 end |
209 end |
214 end |
210 if changed then |
215 if changed then |
211 return save_roster(username, host, roster); |
216 return save_roster(username, host, roster, jid); |
212 end |
217 end |
213 end |
218 end |
214 |
219 |
215 local function _get_online_roster_subscription(jidA, jidB) |
220 local function _get_online_roster_subscription(jidA, jidB) |
216 local user = bare_sessions[jidA]; |
221 local user = bare_sessions[jidA]; |
239 local item = roster[jid]; |
244 local item = roster[jid]; |
240 if item and (item.subscription == "from" or item.subscription == "both") then |
245 if item and (item.subscription == "from" or item.subscription == "both") then |
241 return; -- false |
246 return; -- false |
242 end |
247 end |
243 roster[false].pending[jid] = true; |
248 roster[false].pending[jid] = true; |
244 return save_roster(username, host, roster); |
249 return save_roster(username, host, roster, jid); |
245 end |
250 end |
246 function is_contact_pending_out(username, host, jid) |
251 function is_contact_pending_out(username, host, jid) |
247 local roster = load_roster(username, host); |
252 local roster = load_roster(username, host); |
248 local item = roster[jid]; |
253 local item = roster[jid]; |
249 return item and item.ask; |
254 return item and item.ask; |
258 item = {subscription = "none", groups = {}}; |
263 item = {subscription = "none", groups = {}}; |
259 roster[jid] = item; |
264 roster[jid] = item; |
260 end |
265 end |
261 item.ask = "subscribe"; |
266 item.ask = "subscribe"; |
262 log("debug", "set_contact_pending_out: saving roster; set %s@%s.roster[%q].ask=subscribe", username, host, jid); |
267 log("debug", "set_contact_pending_out: saving roster; set %s@%s.roster[%q].ask=subscribe", username, host, jid); |
263 return save_roster(username, host, roster); |
268 return save_roster(username, host, roster, jid); |
264 end |
269 end |
265 local function unsubscribe(username, host, jid) |
270 local function unsubscribe(username, host, jid) |
266 local roster = load_roster(username, host); |
271 local roster = load_roster(username, host); |
267 local item = roster[jid]; |
272 local item = roster[jid]; |
268 if not item then return false; end |
273 if not item then return false; end |
273 if item.subscription == "both" then |
278 if item.subscription == "both" then |
274 item.subscription = "from"; |
279 item.subscription = "from"; |
275 elseif item.subscription == "to" then |
280 elseif item.subscription == "to" then |
276 item.subscription = "none"; |
281 item.subscription = "none"; |
277 end |
282 end |
278 return save_roster(username, host, roster); |
283 return save_roster(username, host, roster, jid); |
279 end |
284 end |
280 local function subscribed(username, host, jid) |
285 local function subscribed(username, host, jid) |
281 if is_contact_pending_in(username, host, jid) then |
286 if is_contact_pending_in(username, host, jid) then |
282 local roster = load_roster(username, host); |
287 local roster = load_roster(username, host); |
283 local item = roster[jid]; |
288 local item = roster[jid]; |
289 item.subscription = "from"; |
294 item.subscription = "from"; |
290 else -- subscription == to |
295 else -- subscription == to |
291 item.subscription = "both"; |
296 item.subscription = "both"; |
292 end |
297 end |
293 roster[false].pending[jid] = nil; |
298 roster[false].pending[jid] = nil; |
294 return save_roster(username, host, roster); |
299 return save_roster(username, host, roster, jid); |
295 end -- TODO else implement optional feature pre-approval (ask = subscribed) |
300 end -- TODO else implement optional feature pre-approval (ask = subscribed) |
296 end |
301 end |
297 local function unsubscribed(username, host, jid) |
302 local function unsubscribed(username, host, jid) |
298 local roster = load_roster(username, host); |
303 local roster = load_roster(username, host); |
299 local item = roster[jid]; |
304 local item = roster[jid]; |
309 elseif item.subscription == "both" then |
314 elseif item.subscription == "both" then |
310 item.subscription = "to"; |
315 item.subscription = "to"; |
311 is_subscribed = true; |
316 is_subscribed = true; |
312 end |
317 end |
313 end |
318 end |
314 local success = (pending or is_subscribed) and save_roster(username, host, roster); |
319 local success = (pending or is_subscribed) and save_roster(username, host, roster, jid); |
315 return success, pending, subscribed; |
320 return success, pending, subscribed; |
316 end |
321 end |
317 |
322 |
318 local function process_outbound_subscription_request(username, host, jid) |
323 local function process_outbound_subscription_request(username, host, jid) |
319 local roster = load_roster(username, host); |
324 local roster = load_roster(username, host); |
320 local item = roster[jid]; |
325 local item = roster[jid]; |
321 if item and (item.subscription == "none" or item.subscription == "from") then |
326 if item and (item.subscription == "none" or item.subscription == "from") then |
322 item.ask = "subscribe"; |
327 item.ask = "subscribe"; |
323 return save_roster(username, host, roster); |
328 return save_roster(username, host, roster, jid); |
324 end |
329 end |
325 end |
330 end |
326 |
331 |
327 --[[function process_outbound_subscription_approval(username, host, jid) |
332 --[[function process_outbound_subscription_approval(username, host, jid) |
328 local roster = load_roster(username, host); |
333 local roster = load_roster(username, host); |