Mercurial > prosody-hg
comparison plugins/mod_pubsub/pubsub.lib.lua @ 9244:b3b156bd9914
mod_pubsub: Use field mapping in util.dataforms
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 01 Sep 2018 03:01:55 +0200 |
| parents | 7fbcabee6df1 |
| children | cc32aae5c7da |
comparison
equal
deleted
inserted
replaced
| 9243:a4c52e304e6f | 9244:b3b156bd9914 |
|---|---|
| 51 name = "FORM_TYPE"; | 51 name = "FORM_TYPE"; |
| 52 value = "http://jabber.org/protocol/pubsub#node_config"; | 52 value = "http://jabber.org/protocol/pubsub#node_config"; |
| 53 }; | 53 }; |
| 54 { | 54 { |
| 55 type = "text-single"; | 55 type = "text-single"; |
| 56 name = "pubsub#title"; | 56 name = "title"; |
| 57 var = "pubsub#title"; | |
| 57 label = "Title"; | 58 label = "Title"; |
| 58 }; | 59 }; |
| 59 { | 60 { |
| 60 type = "text-single"; | 61 type = "text-single"; |
| 61 name = "pubsub#description"; | 62 name = "description"; |
| 63 var = "pubsub#description"; | |
| 62 label = "Description"; | 64 label = "Description"; |
| 63 }; | 65 }; |
| 64 { | 66 { |
| 65 type = "text-single"; | 67 type = "text-single"; |
| 66 name = "pubsub#type"; | 68 name = "payload_type"; |
| 69 var = "pubsub#type"; | |
| 67 label = "The type of node data, usually specified by the namespace of the payload (if any)"; | 70 label = "The type of node data, usually specified by the namespace of the payload (if any)"; |
| 68 }; | 71 }; |
| 69 { | 72 { |
| 70 type = "text-single"; | 73 type = "text-single"; |
| 71 name = "pubsub#max_items"; | 74 name = "max_items"; |
| 75 var = "pubsub#max_items"; | |
| 72 label = "Max # of items to persist"; | 76 label = "Max # of items to persist"; |
| 73 }; | 77 }; |
| 74 { | 78 { |
| 75 type = "boolean"; | 79 type = "boolean"; |
| 76 name = "pubsub#persist_items"; | 80 name = "persist_items"; |
| 81 var = "pubsub#persist_items"; | |
| 77 label = "Persist items to storage"; | 82 label = "Persist items to storage"; |
| 78 }; | 83 }; |
| 79 { | 84 { |
| 80 type = "list-single"; | 85 type = "list-single"; |
| 81 name = "pubsub#access_model"; | 86 name = "access_model"; |
| 87 var = "pubsub#access_model"; | |
| 82 label = "Specify the subscriber model"; | 88 label = "Specify the subscriber model"; |
| 83 options = { | 89 options = { |
| 84 "authorize", | 90 "authorize", |
| 85 "open", | 91 "open", |
| 86 "presence", | 92 "presence", |
| 88 "whitelist", | 94 "whitelist", |
| 89 }; | 95 }; |
| 90 }; | 96 }; |
| 91 { | 97 { |
| 92 type = "list-single"; | 98 type = "list-single"; |
| 93 name = "pubsub#publish_model"; | 99 name = "publish_model"; |
| 100 var = "pubsub#publish_model"; | |
| 94 label = "Specify the publisher model"; | 101 label = "Specify the publisher model"; |
| 95 options = { | 102 options = { |
| 96 "publishers"; | 103 "publishers"; |
| 97 "subscribers"; | 104 "subscribers"; |
| 98 "open"; | 105 "open"; |
| 100 }; | 107 }; |
| 101 { | 108 { |
| 102 type = "boolean"; | 109 type = "boolean"; |
| 103 value = true; | 110 value = true; |
| 104 label = "Whether to deliver event notifications"; | 111 label = "Whether to deliver event notifications"; |
| 105 name = "pubsub#deliver_notifications"; | 112 name = "notify_items"; |
| 113 var = "pubsub#deliver_notifications"; | |
| 106 }; | 114 }; |
| 107 { | 115 { |
| 108 type = "boolean"; | 116 type = "boolean"; |
| 109 value = true; | 117 value = true; |
| 110 label = "Whether to deliver payloads with event notifications"; | 118 label = "Whether to deliver payloads with event notifications"; |
| 111 name = "pubsub#deliver_payloads"; | 119 name = "include_payload"; |
| 120 var = "pubsub#deliver_payloads"; | |
| 112 }; | 121 }; |
| 113 { | 122 { |
| 114 type = "list-single"; | 123 type = "list-single"; |
| 115 name = "pubsub#notification_type"; | 124 name = "notification_type"; |
| 125 var = "pubsub#notification_type"; | |
| 116 label = "Specify the delivery style for notifications"; | 126 label = "Specify the delivery style for notifications"; |
| 117 options = { | 127 options = { |
| 118 { label = "Messages of type normal", value = "normal" }, | 128 { label = "Messages of type normal", value = "normal" }, |
| 119 { label = "Messages of type headline", value = "headline", default = true }, | 129 { label = "Messages of type headline", value = "headline", default = true }, |
| 120 }; | 130 }; |
| 121 }; | 131 }; |
| 122 { | 132 { |
| 123 type = "boolean"; | 133 type = "boolean"; |
| 124 label = "Whether to notify subscribers when the node is deleted"; | 134 label = "Whether to notify subscribers when the node is deleted"; |
| 125 name = "pubsub#notify_delete"; | 135 name = "notify_delete"; |
| 136 var = "pubsub#notify_delete"; | |
| 126 value = true; | 137 value = true; |
| 127 }; | 138 }; |
| 128 { | 139 { |
| 129 type = "boolean"; | 140 type = "boolean"; |
| 130 label = "Whether to notify subscribers when items are removed from the node"; | 141 label = "Whether to notify subscribers when items are removed from the node"; |
| 131 name = "pubsub#notify_retract"; | 142 name = "notify_retract"; |
| 143 var = "pubsub#notify_retract"; | |
| 132 value = true; | 144 value = true; |
| 133 }; | 145 }; |
| 134 }; | 146 }; |
| 135 | 147 |
| 136 local subscribe_options_form = dataform { | 148 local subscribe_options_form = dataform { |
| 163 { | 175 { |
| 164 type = "text-single"; | 176 type = "text-single"; |
| 165 name = "pubsub#type"; | 177 name = "pubsub#type"; |
| 166 }; | 178 }; |
| 167 }; | 179 }; |
| 168 | |
| 169 local config_field_map = { | |
| 170 title = "pubsub#title"; | |
| 171 description = "pubsub#description"; | |
| 172 payload_type = "pubsub#type"; | |
| 173 max_items = "pubsub#max_items"; | |
| 174 persist_items = "pubsub#persist_items"; | |
| 175 notification_type = "pubsub#notification_type"; | |
| 176 access_model = "pubsub#access_model"; | |
| 177 publish_model = "pubsub#publish_model"; | |
| 178 notify_items = "pubsub#deliver_notifications"; | |
| 179 notify_delete = "pubsub#notify_delete"; | |
| 180 notify_retract = "pubsub#notify_retract"; | |
| 181 include_payload = "pubsub#deliver_payloads"; | |
| 182 }; | |
| 183 local reverse_config_field_map = {}; | |
| 184 for k, v in pairs(config_field_map) do reverse_config_field_map[v] = k; end | |
| 185 | |
| 186 -- util.pubsub is meant to be agnostic to XEP-0060 | |
| 187 local function config_to_xep0060(node_config) | |
| 188 return { | |
| 189 ["pubsub#title"] = node_config["title"]; | |
| 190 ["pubsub#description"] = node_config["description"]; | |
| 191 ["pubsub#type"] = node_config["payload_type"]; | |
| 192 ["pubsub#max_items"] = tostring(node_config["max_items"]); | |
| 193 ["pubsub#persist_items"] = node_config["persist_items"]; | |
| 194 ["pubsub#notification_type"] = node_config["notification_type"]; | |
| 195 ["pubsub#access_model"] = node_config["access_model"]; | |
| 196 ["pubsub#publish_model"] = node_config["publish_model"]; | |
| 197 ["pubsub#deliver_notifications"] = node_config["notify_items"]; | |
| 198 ["pubsub#notify_delete"] = node_config["notify_delete"]; | |
| 199 ["pubsub#notify_retract"] = node_config["notify_retract"]; | |
| 200 ["pubsub#deliver_payloads"] = node_config["include_payload"]; | |
| 201 } | |
| 202 end | |
| 203 | |
| 204 local function config_from_xep0060(config, strict) | |
| 205 local ret = {}; | |
| 206 for config_field, config_value in pairs(config) do | |
| 207 local mapped_name = reverse_config_field_map[config_field]; | |
| 208 if mapped_name then | |
| 209 -- FIXME: The intention is to add "subtype" support to | |
| 210 -- util.dataforms, which will remove the need for this | |
| 211 -- ugly hack | |
| 212 if mapped_name == "max_items" then | |
| 213 config_value = tonumber(config_value); | |
| 214 end | |
| 215 ret[mapped_name] = config_value; | |
| 216 elseif strict and config_field ~= "FORM_TYPE" then | |
| 217 return nil, "unknown-field", config_field; | |
| 218 end | |
| 219 end | |
| 220 return ret; | |
| 221 end | |
| 222 | 180 |
| 223 local service_method_feature_map = { | 181 local service_method_feature_map = { |
| 224 add_subscription = { "subscribe", "subscription-options" }; | 182 add_subscription = { "subscribe", "subscription-options" }; |
| 225 create = { "create-nodes", "instant-nodes", "item-ids", "create-and-configure" }; | 183 create = { "create-nodes", "instant-nodes", "item-ids", "create-and-configure" }; |
| 226 delete = { "delete-nodes" }; | 184 delete = { "delete-nodes" }; |
| 443 local form_data, err = node_config_form:data(config_form); | 401 local form_data, err = node_config_form:data(config_form); |
| 444 if not form_data then | 402 if not form_data then |
| 445 origin.send(st.error_reply(stanza, "modify", "bad-request", err)); | 403 origin.send(st.error_reply(stanza, "modify", "bad-request", err)); |
| 446 return true; | 404 return true; |
| 447 end | 405 end |
| 448 config = config_from_xep0060(form_data); | 406 config = form_data; |
| 449 end | 407 end |
| 450 if node then | 408 if node then |
| 451 ok, ret = service:create(node, stanza.attr.from, config); | 409 ok, ret = service:create(node, stanza.attr.from, config); |
| 452 if ok then | 410 if ok then |
| 453 reply = st.reply(stanza); | 411 reply = st.reply(stanza); |
| 596 local required_config = nil; | 554 local required_config = nil; |
| 597 local publish_options = stanza.tags[1]:get_child("publish-options"); | 555 local publish_options = stanza.tags[1]:get_child("publish-options"); |
| 598 if publish_options then | 556 if publish_options then |
| 599 -- Ensure that the node configuration matches the values in publish-options | 557 -- Ensure that the node configuration matches the values in publish-options |
| 600 local publish_options_form = publish_options:get_child("x", "jabber:x:data"); | 558 local publish_options_form = publish_options:get_child("x", "jabber:x:data"); |
| 601 required_config = config_from_xep0060(node_config_form:data(publish_options_form), true); | 559 required_config = node_config_form:data(publish_options_form); |
| 602 end | 560 end |
| 603 local item = publish:get_child("item"); | 561 local item = publish:get_child("item"); |
| 604 local id = (item and item.attr.id); | 562 local id = (item and item.attr.id); |
| 605 if not id then | 563 if not id then |
| 606 id = uuid_generate(); | 564 id = uuid_generate(); |
| 677 if not ok then | 635 if not ok then |
| 678 origin.send(pubsub_error_reply(stanza, node_config)); | 636 origin.send(pubsub_error_reply(stanza, node_config)); |
| 679 return true; | 637 return true; |
| 680 end | 638 end |
| 681 | 639 |
| 682 local pubsub_form_data = config_to_xep0060(node_config); | |
| 683 local reply = st.reply(stanza) | 640 local reply = st.reply(stanza) |
| 684 :tag("pubsub", { xmlns = xmlns_pubsub_owner }) | 641 :tag("pubsub", { xmlns = xmlns_pubsub_owner }) |
| 685 :tag("configure", { node = node }) | 642 :tag("configure", { node = node }) |
| 686 :add_child(node_config_form:form(pubsub_form_data)); | 643 :add_child(node_config_form:form(node_config)); |
| 687 origin.send(reply); | 644 origin.send(reply); |
| 688 return true; | 645 return true; |
| 689 end | 646 end |
| 690 | 647 |
| 691 function handlers.owner_set_configure(origin, stanza, config, service) | 648 function handlers.owner_set_configure(origin, stanza, config, service) |
| 706 local ok, old_config = service:get_node_config(node, stanza.attr.from); | 663 local ok, old_config = service:get_node_config(node, stanza.attr.from); |
| 707 if not ok then | 664 if not ok then |
| 708 origin.send(pubsub_error_reply(stanza, old_config)); | 665 origin.send(pubsub_error_reply(stanza, old_config)); |
| 709 return true; | 666 return true; |
| 710 end | 667 end |
| 711 local form_data, err = node_config_form:data(config_form, old_config); | 668 local new_config, err = node_config_form:data(config_form, old_config); |
| 712 if not form_data then | 669 if not new_config then |
| 713 origin.send(st.error_reply(stanza, "modify", "bad-request", err)); | 670 origin.send(st.error_reply(stanza, "modify", "bad-request", err)); |
| 714 return true; | 671 return true; |
| 715 end | 672 end |
| 716 local new_config = config_from_xep0060(form_data); | |
| 717 local ok, err = service:set_node_config(node, stanza.attr.from, new_config); | 673 local ok, err = service:set_node_config(node, stanza.attr.from, new_config); |
| 718 if not ok then | 674 if not ok then |
| 719 origin.send(pubsub_error_reply(stanza, err)); | 675 origin.send(pubsub_error_reply(stanza, err)); |
| 720 return true; | 676 return true; |
| 721 end | 677 end |
| 722 origin.send(st.reply(stanza)); | 678 origin.send(st.reply(stanza)); |
| 723 return true; | 679 return true; |
| 724 end | 680 end |
| 725 | 681 |
| 726 function handlers.owner_get_default(origin, stanza, default, service) -- luacheck: ignore 212/default | 682 function handlers.owner_get_default(origin, stanza, default, service) -- luacheck: ignore 212/default |
| 727 local pubsub_form_data = config_to_xep0060(service.node_defaults); | |
| 728 local reply = st.reply(stanza) | 683 local reply = st.reply(stanza) |
| 729 :tag("pubsub", { xmlns = xmlns_pubsub_owner }) | 684 :tag("pubsub", { xmlns = xmlns_pubsub_owner }) |
| 730 :tag("default") | 685 :tag("default") |
| 731 :add_child(node_config_form:form(pubsub_form_data)); | 686 :add_child(node_config_form:form(service.node_defaults)); |
| 732 origin.send(reply); | 687 origin.send(reply); |
| 733 return true; | 688 return true; |
| 734 end | 689 end |
| 735 | 690 |
| 736 function handlers.owner_get_affiliations(origin, stanza, affiliations, service) | 691 function handlers.owner_get_affiliations(origin, stanza, affiliations, service) |
