Software /
code /
prosody-modules
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 |
parent | 4739:fdd9e5d89d73 |
child | 4835: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); |