comparison mod_bookmarks2/mod_bookmarks2.lua @ 4834:7ed2467c9bb5

mod_bookmarks2: Add simple support for legacy PEP queries This implements the publish and items PubSub queries of XEP-0048 version 1.1, ignoring item id, publish-options, and any other query.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Thu, 23 Dec 2021 17:44:35 +0100
parents fdd9e5d89d73
children 60b2dbe032c0
comparison
equal deleted inserted replaced
4833:15cf32e666da 4834:7ed2467c9bb5
28 module:hook("account-disco-info", function (event) 28 module:hook("account-disco-info", function (event)
29 -- This Time it’s Serious! 29 -- This Time it’s Serious!
30 event.reply:tag("feature", { var = namespace.."#compat" }):up(); 30 event.reply:tag("feature", { var = namespace.."#compat" }):up();
31 end); 31 end);
32 32
33 local function on_retrieve_private_xml(event) 33 local function generate_legacy_storage(items)
34 local stanza, session = event.stanza, event.origin;
35 local query = stanza:get_child("query", "jabber:iq:private");
36 if query == nil then
37 return;
38 end
39
40 local bookmarks = query:get_child("storage", "storage:bookmarks");
41 if bookmarks == nil then
42 return;
43 end
44
45 module:log("debug", "Getting private bookmarks: %s", bookmarks);
46
47 local username = session.username;
48 local jid = username.."@"..session.host;
49 local service = mod_pep.get_pep_service(username);
50 local ok, ret = service:get_items(namespace, session.full_jid);
51 if not ok then
52 if ret == "item-not-found" then
53 module:log("debug", "Got no PEP bookmarks item for %s, returning empty private bookmarks", jid);
54 session.send(st.reply(stanza):add_child(query));
55 else
56 module:log("error", "Failed to retrieve PEP bookmarks of %s: %s", jid, ret);
57 session.send(st.error_reply(stanza, "cancel", ret, "Failed to retrive bookmarks from PEP"));
58 end
59 return true;
60 end
61
62 local storage = st.stanza("storage", { xmlns = "storage:bookmarks" }); 34 local storage = st.stanza("storage", { xmlns = "storage:bookmarks" });
63 for _, item_id in ipairs(ret) do 35 for _, item_id in ipairs(items) do
64 local item = ret[item_id]; 36 local item = items[item_id];
65 local conference = st.stanza("conference"); 37 local conference = st.stanza("conference");
66 conference.attr.jid = item.attr.id; 38 conference.attr.jid = item.attr.id;
67 local bookmark = item:get_child("conference", namespace); 39 local bookmark = item:get_child("conference", namespace);
68 conference.attr.name = bookmark.attr.name; 40 conference.attr.name = bookmark.attr.name;
69 conference.attr.autojoin = bookmark.attr.autojoin; 41 conference.attr.autojoin = bookmark.attr.autojoin;
75 if password ~= nil then 47 if password ~= nil then
76 conference:text_tag("password", password):up(); 48 conference:text_tag("password", password):up();
77 end 49 end
78 storage:add_child(conference); 50 storage:add_child(conference);
79 end 51 end
52
53 return storage;
54 end
55
56 local function on_retrieve_legacy_pep(event)
57 local stanza, session = event.stanza, event.origin;
58 local pubsub = stanza:get_child("pubsub", "http://jabber.org/protocol/pubsub");
59 if pubsub == nil then
60 return;
61 end
62
63 local items = pubsub:get_child("items");
64 if items == nil then
65 return;
66 end
67
68 local node = items.attr.node;
69 if node ~= "storage:bookmarks" then
70 return;
71 end
72
73 local username = session.username;
74 local jid = username.."@"..session.host;
75 local service = mod_pep.get_pep_service(username);
76 local ok, ret = service:get_items(namespace, session.full_jid);
77 if not ok then
78 if ret == "item-not-found" then
79 module:log("debug", "Got no PEP bookmarks item for %s, returning empty legacy PEP bookmarks", jid);
80 session.send(st.reply(stanza):add_child(query));
81 else
82 module:log("error", "Failed to retrieve PEP bookmarks of %s: %s", jid, ret);
83 session.send(st.error_reply(stanza, "cancel", ret, "Failed to retrive bookmarks from PEP"));
84 end
85 return true;
86 end
87
88 local storage = generate_legacy_storage(ret);
89
90 module:log("debug", "Sending back legacy PEP for %s: %s", jid, storage);
91 session.send(st.reply(stanza)
92 :tag("pubsub", {xmlns = "http://jabber.org/protocol/pubsub"})
93 :tag("items", {node = "storage:bookmarks"})
94 :tag("item", {id = "current"})
95 :add_child(storage));
96 return true;
97 end
98
99 local function on_retrieve_private_xml(event)
100 local stanza, session = event.stanza, event.origin;
101 local query = stanza:get_child("query", "jabber:iq:private");
102 if query == nil then
103 return;
104 end
105
106 local bookmarks = query:get_child("storage", "storage:bookmarks");
107 if bookmarks == nil then
108 return;
109 end
110
111 module:log("debug", "Getting private bookmarks: %s", bookmarks);
112
113 local username = session.username;
114 local jid = username.."@"..session.host;
115 local service = mod_pep.get_pep_service(username);
116 local ok, ret = service:get_items(namespace, session.full_jid);
117 if not ok then
118 if ret == "item-not-found" then
119 module:log("debug", "Got no PEP bookmarks item for %s, returning empty private bookmarks", jid);
120 session.send(st.reply(stanza):add_child(query));
121 else
122 module:log("error", "Failed to retrieve PEP bookmarks of %s: %s", jid, ret);
123 session.send(st.error_reply(stanza, "cancel", ret, "Failed to retrive bookmarks from PEP"));
124 end
125 return true;
126 end
127
128 local storage = generate_legacy_storage(ret);
80 129
81 module:log("debug", "Sending back private for %s: %s", jid, storage); 130 module:log("debug", "Sending back private for %s: %s", jid, storage);
82 session.send(st.reply(stanza):query("jabber:iq:private"):add_child(storage)); 131 session.send(st.reply(stanza):query("jabber:iq:private"):add_child(storage));
83 return true; 132 return true;
84 end 133 end
188 end 237 end
189 end 238 end
190 return true; 239 return true;
191 end 240 end
192 241
242 -- Synchronise legacy PEP to PEP.
243 local function on_publish_legacy_pep(event)
244 local stanza, session = event.stanza, event.origin;
245 local pubsub = stanza:get_child("pubsub", "http://jabber.org/protocol/pubsub");
246 if pubsub == nil then
247 return;
248 end
249
250 local publish = pubsub:get_child("publish");
251 if publish == nil or publish.attr.node ~= "storage:bookmarks" then
252 return;
253 end
254
255 local item = publish:get_child("item");
256 if item == nil then
257 return;
258 end
259
260 -- Here we ignore the item id, it’ll be generated as 'current' anyway.
261
262 local bookmarks = item:get_child("storage", "storage:bookmarks");
263 if bookmarks == nil then
264 return;
265 end
266
267 -- We also ignore the publish-options.
268
269 module:log("debug", "Legacy PEP bookmarks set by client, publishing to PEP.");
270
271 local ok, err = publish_to_pep(session.full_jid, bookmarks, true);
272 if not ok then
273 module:log("error", "Failed to publish to PEP bookmarks for %s@%s: %s", session.username, session.host, err);
274 session.send(st.error_reply(stanza, "cancel", "internal-server-error", "Failed to store bookmarks to PEP"));
275 return true;
276 end
277
278 session.send(st.reply(stanza));
279 return true;
280 end
281
193 -- Synchronise Private XML to PEP. 282 -- Synchronise Private XML to PEP.
194 local function on_publish_private_xml(event) 283 local function on_publish_private_xml(event)
195 local stanza, session = event.stanza, event.origin; 284 local stanza, session = event.stanza, event.origin;
196 local query = stanza:get_child("query", "jabber:iq:private"); 285 local query = stanza:get_child("query", "jabber:iq:private");
197 if query == nil then 286 if query == nil then
201 local bookmarks = query:get_child("storage", "storage:bookmarks"); 290 local bookmarks = query:get_child("storage", "storage:bookmarks");
202 if bookmarks == nil then 291 if bookmarks == nil then
203 return; 292 return;
204 end 293 end
205 294
206 module:log("debug", "Private bookmarks set by client, publishing to pep."); 295 module:log("debug", "Private bookmarks set by client, publishing to PEP.");
207 296
208 local ok, err = publish_to_pep(session.full_jid, bookmarks, true); 297 local ok, err = publish_to_pep(session.full_jid, bookmarks, true);
209 if not ok then 298 if not ok then
210 module:log("error", "Failed to publish to PEP bookmarks for %s@%s: %s", session.username, session.host, err); 299 module:log("error", "Failed to publish to PEP bookmarks for %s@%s: %s", session.username, session.host, err);
211 session.send(st.error_reply(stanza, "cancel", "internal-server-error", "Failed to store bookmarks to PEP")); 300 session.send(st.error_reply(stanza, "cancel", "internal-server-error", "Failed to store bookmarks to PEP"));
298 return on_retrieve_private_xml(event); 387 return on_retrieve_private_xml(event);
299 else 388 else
300 return on_publish_private_xml(event); 389 return on_publish_private_xml(event);
301 end 390 end
302 end, 1); 391 end, 1);
392 module:hook("iq/bare/http://jabber.org/protocol/pubsub:pubsub", function (event)
393 if event.stanza.attr.type == "get" then
394 return on_retrieve_legacy_pep(event);
395 else
396 return on_publish_legacy_pep(event);
397 end
398 end, 1);
303 module:hook("resource-bind", migrate_legacy_bookmarks); 399 module:hook("resource-bind", migrate_legacy_bookmarks);
304 module:handle_items("pep-service", function (event) 400 module:handle_items("pep-service", function (event)
305 local service = event.item.service; 401 local service = event.item.service;
306 module:hook_object_event(service.events, "node-created", on_node_created); 402 module:hook_object_event(service.events, "node-created", on_node_created);
307 end, function () end, true); 403 end, function () end, true);