Mercurial > prosody-hg
comparison plugins/mod_bookmarks.lua @ 12171:b2923a3b4e02
mod_bookmarks: Make sure legacy bookmarks node exists to hold access model
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Mon, 10 Jan 2022 00:11:36 +0100 |
| parents | 750abaf99baf |
| children | 2515033c2a74 |
comparison
equal
deleted
inserted
replaced
| 12170:750abaf99baf | 12171:b2923a3b4e02 |
|---|---|
| 352 failed = true; | 352 failed = true; |
| 353 break; | 353 break; |
| 354 end | 354 end |
| 355 end | 355 end |
| 356 if not failed then | 356 if not failed then |
| 357 module:log("debug", "Successfully migrated legacy PEP bookmarks of %s to bookmarks 2, attempting deletion of the node.", jid); | 357 module:log("debug", "Successfully migrated legacy PEP bookmarks of %s to bookmarks 2, clearing items.", jid); |
| 358 local ok, err = service:delete(namespace_legacy, jid); | 358 local ok, err = service:purge(namespace_legacy, jid, false); |
| 359 if not ok then | 359 if not ok then |
| 360 module:log("error", "Failed to delete legacy PEP bookmarks for %s: %s", jid, err); | 360 module:log("error", "Failed to delete legacy PEP bookmarks for %s: %s", jid, err); |
| 361 end | 361 end |
| 362 end | |
| 363 end | |
| 364 | |
| 365 local ok, current_legacy_config = service:get_node_config(namespace_legacy, jid); | |
| 366 if not ok or current_legacy_config["access_model"] ~= "whitelist" then | |
| 367 -- The legacy node must exist in order for the access model to apply to the | |
| 368 -- XEP-0411 COMPAT broadcasts (which bypass the pubsub service entirely), | |
| 369 -- so create or reconfigure it to be useless. | |
| 370 -- | |
| 371 -- FIXME It would be handy to have a publish model that prevents the owner | |
| 372 -- from publishing, but the affiliation takes priority | |
| 373 local config = { | |
| 374 ["persist_items"] = false; | |
| 375 ["max_items"] = 1; | |
| 376 ["send_last_published_item"] = "never"; | |
| 377 ["access_model"] = "whitelist"; | |
| 378 }; | |
| 379 local ok, err; | |
| 380 if ret == "item-not-found" then | |
| 381 ok, err = service:create(namespace_legacy, jid, config); | |
| 382 else | |
| 383 ok, err = service:set_node_config(namespace_legacy, jid, config); | |
| 384 end | |
| 385 if not ok then | |
| 386 module:log("error", "Setting legacy bookmarks node config failed: %s", err); | |
| 387 return ok, err; | |
| 362 end | 388 end |
| 363 end | 389 end |
| 364 | 390 |
| 365 local data, err = private_storage:get(username, "storage:storage:bookmarks"); | 391 local data, err = private_storage:get(username, "storage:storage:bookmarks"); |
| 366 if not data then | 392 if not data then |
| 387 if not ok then | 413 if not ok then |
| 388 module:log("error", "Failed to remove legacy bookmarks of %s: %s", jid, err); | 414 module:log("error", "Failed to remove legacy bookmarks of %s: %s", jid, err); |
| 389 return; | 415 return; |
| 390 end | 416 end |
| 391 module:log("debug", "Removed legacy bookmarks of %s, migration done!", jid); | 417 module:log("debug", "Removed legacy bookmarks of %s, migration done!", jid); |
| 392 end | |
| 393 | |
| 394 local function on_node_created(event) | |
| 395 local service, node, actor = event.service, event.node, event.actor; | |
| 396 if node ~= namespace_legacy then | |
| 397 return; | |
| 398 end | |
| 399 | |
| 400 module:log("debug", "Something tried to create legacy PEP bookmarks for %s.", actor); | |
| 401 local ok, err = service:delete(namespace_legacy, actor); | |
| 402 if not ok then | |
| 403 module:log("error", "Failed to delete legacy PEP bookmarks for %s: %s", actor, err); | |
| 404 end | |
| 405 module:log("debug", "Legacy PEP bookmarks node of %s deleted.", actor); | |
| 406 end | 418 end |
| 407 | 419 |
| 408 module:hook("iq/bare/jabber:iq:private:query", function (event) | 420 module:hook("iq/bare/jabber:iq:private:query", function (event) |
| 409 if event.stanza.attr.type == "get" then | 421 if event.stanza.attr.type == "get" then |
| 410 return on_retrieve_private_xml(event); | 422 return on_retrieve_private_xml(event); |
| 428 local ok, bookmarks = service:get_items(namespace, event.actor); | 440 local ok, bookmarks = service:get_items(namespace, event.actor); |
| 429 if bookmarks == "item-not-found" then ok, bookmarks = true, {} end | 441 if bookmarks == "item-not-found" then ok, bookmarks = true, {} end |
| 430 if not ok then return end | 442 if not ok then return end |
| 431 local legacy_bookmarks_item = st.stanza("item", { xmlns = xmlns_pubsub; id = "current" }) | 443 local legacy_bookmarks_item = st.stanza("item", { xmlns = xmlns_pubsub; id = "current" }) |
| 432 :add_child(generate_legacy_storage(bookmarks)); | 444 :add_child(generate_legacy_storage(bookmarks)); |
| 433 -- FIXME This broadcasts to any and all contacts who sent +notify because the node does not exist, so defaults apply. | |
| 434 service:broadcast("items", namespace_legacy, { --[[ no subscribers ]] }, legacy_bookmarks_item, event.actor); | 445 service:broadcast("items", namespace_legacy, { --[[ no subscribers ]] }, legacy_bookmarks_item, event.actor); |
| 435 end | 446 end |
| 436 local function broadcast_legacy_removal(event) | 447 local function broadcast_legacy_removal(event) |
| 437 if event.node ~= namespace then return end | 448 if event.node ~= namespace then return end |
| 438 return legacy_broadcast(event); | 449 return legacy_broadcast(event); |
| 443 local service = mod_pep.get_pep_service(event.origin.username); | 454 local service = mod_pep.get_pep_service(event.origin.username); |
| 444 legacy_broadcast({ service = service, actor = event.origin.full_jid }); | 455 legacy_broadcast({ service = service, actor = event.origin.full_jid }); |
| 445 end); | 456 end); |
| 446 module:handle_items("pep-service", function (event) | 457 module:handle_items("pep-service", function (event) |
| 447 local service = event.item.service; | 458 local service = event.item.service; |
| 448 module:hook_object_event(service.events, "node-created", on_node_created); | |
| 449 module:hook_object_event(service.events, "item-published/" .. namespace, legacy_broadcast); | 459 module:hook_object_event(service.events, "item-published/" .. namespace, legacy_broadcast); |
| 450 module:hook_object_event(service.events, "item-retracted", broadcast_legacy_removal); | 460 module:hook_object_event(service.events, "item-retracted", broadcast_legacy_removal); |
| 451 module:hook_object_event(service.events, "node-purged", broadcast_legacy_removal); | 461 module:hook_object_event(service.events, "node-purged", broadcast_legacy_removal); |
| 452 module:hook_object_event(service.events, "node-deleted", broadcast_legacy_removal); | 462 module:hook_object_event(service.events, "node-deleted", broadcast_legacy_removal); |
| 453 end, function (event) | 463 end, function (event) |
| 454 local service = event.item.service; | 464 local service = event.item.service; |
| 455 module:unhook_object_event(service.events, "node-created", on_node_created); | |
| 456 module:unhook_object_event(service.events, "item-published/" .. namespace, legacy_broadcast); | 465 module:unhook_object_event(service.events, "item-published/" .. namespace, legacy_broadcast); |
| 457 module:unhook_object_event(service.events, "item-retracted", broadcast_legacy_removal); | 466 module:unhook_object_event(service.events, "item-retracted", broadcast_legacy_removal); |
| 458 module:unhook_object_event(service.events, "node-purged", broadcast_legacy_removal); | 467 module:unhook_object_event(service.events, "node-purged", broadcast_legacy_removal); |
| 459 module:unhook_object_event(service.events, "node-deleted", broadcast_legacy_removal); | 468 module:unhook_object_event(service.events, "node-deleted", broadcast_legacy_removal); |
| 460 end, true); | 469 end, true); |
