Mercurial > 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 |
| 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); |
