Software /
code /
prosody
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 |
parent | 9235:7fbcabee6df1 |
child | 9245: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) |