Comparison

plugins/mod_pubsub/mod_pubsub.lua @ 5690:630e7224a65f

mod_pubsub: Utilize mod_disco, instead of reimplementing disco handling
author Florian Zeitz <florob@babelmonkeys.de>
date Wed, 05 Jun 2013 00:01:17 +0200
parent 5626:8416d4619d80
child 5851:cdcfd93e2f43
child 5970:6a2c3293d4d7
comparison
equal deleted inserted replaced
5689:832ea1e9ac9e 5690:630e7224a65f
15 local service; 15 local service;
16 16
17 local lib_pubsub = module:require "pubsub"; 17 local lib_pubsub = module:require "pubsub";
18 local handlers = lib_pubsub.handlers; 18 local handlers = lib_pubsub.handlers;
19 local pubsub_error_reply = lib_pubsub.pubsub_error_reply; 19 local pubsub_error_reply = lib_pubsub.pubsub_error_reply;
20
21 module:depends("disco");
22 module:add_identity("pubsub", "service", pubsub_disco_name);
23 module:add_feature("http://jabber.org/protocol/pubsub");
20 24
21 function handle_pubsub_iq(event) 25 function handle_pubsub_iq(event)
22 local origin, stanza = event.origin, event.stanza; 26 local origin, stanza = event.origin, event.stanza;
23 local pubsub = stanza.tags[1]; 27 local pubsub = stanza.tags[1];
24 local action = pubsub.tags[1]; 28 local action = pubsub.tags[1];
48 end 52 end
49 end 53 end
50 54
51 module:hook("iq/host/"..xmlns_pubsub..":pubsub", handle_pubsub_iq); 55 module:hook("iq/host/"..xmlns_pubsub..":pubsub", handle_pubsub_iq);
52 module:hook("iq/host/"..xmlns_pubsub_owner..":pubsub", handle_pubsub_iq); 56 module:hook("iq/host/"..xmlns_pubsub_owner..":pubsub", handle_pubsub_iq);
53
54 local disco_info;
55 57
56 local feature_map = { 58 local feature_map = {
57 create = { "create-nodes", "instant-nodes", "item-ids" }; 59 create = { "create-nodes", "instant-nodes", "item-ids" };
58 retract = { "delete-items", "retract-items" }; 60 retract = { "delete-items", "retract-items" };
59 purge = { "purge-nodes" }; 61 purge = { "purge-nodes" };
62 get_items = { "retrieve-items" }; 64 get_items = { "retrieve-items" };
63 add_subscription = { "subscribe" }; 65 add_subscription = { "subscribe" };
64 get_subscriptions = { "retrieve-subscriptions" }; 66 get_subscriptions = { "retrieve-subscriptions" };
65 }; 67 };
66 68
67 local function add_disco_features_from_service(disco, service) 69 local function add_disco_features_from_service(service)
68 for method, features in pairs(feature_map) do 70 for method, features in pairs(feature_map) do
69 if service[method] then 71 if service[method] then
70 for _, feature in ipairs(features) do 72 for _, feature in ipairs(features) do
71 if feature then 73 if feature then
72 disco:tag("feature", { var = xmlns_pubsub.."#"..feature }):up(); 74 module:add_feature(xmlns_pubsub.."#"..feature);
73 end 75 end
74 end 76 end
75 end 77 end
76 end 78 end
77 for affiliation in pairs(service.config.capabilities) do 79 for affiliation in pairs(service.config.capabilities) do
78 if affiliation ~= "none" and affiliation ~= "owner" then 80 if affiliation ~= "none" and affiliation ~= "owner" then
79 disco:tag("feature", { var = xmlns_pubsub.."#"..affiliation.."-affiliation" }):up(); 81 module:add_feature(xmlns_pubsub.."#"..affiliation.."-affiliation");
80 end 82 end
81 end 83 end
82 end 84 end
83 85
84 local function build_disco_info(service) 86 module:hook("host-disco-info-node", function (event)
85 local disco_info = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info" }) 87 local stanza, origin, reply, node = event.stanza, event.origin, event.reply, event.node;
86 :tag("identity", { category = "pubsub", type = "service", name = pubsub_disco_name }):up() 88 local ok, ret = service:get_nodes(stanza.attr.from);
87 :tag("feature", { var = "http://jabber.org/protocol/pubsub" }):up(); 89 if ok and not ret[node] then
88 add_disco_features_from_service(disco_info, service); 90 return;
89 return disco_info; 91 end
90 end 92 if not ok then
91 93 return origin.send(pubsub_error_reply(stanza, ret));
92 module:hook("iq-get/host/http://jabber.org/protocol/disco#info:query", function (event) 94 end
93 local origin, stanza = event.origin, event.stanza; 95 event.exists = true;
94 local node = stanza.tags[1].attr.node; 96 reply:tag("identity", { category = "pubsub", type = "leaf" });
95 if not node then
96 return origin.send(st.reply(stanza):add_child(disco_info));
97 else
98 local ok, ret = service:get_nodes(stanza.attr.from);
99 if ok and not ret[node] then
100 ok, ret = false, "item-not-found";
101 end
102 if not ok then
103 return origin.send(pubsub_error_reply(stanza, ret));
104 end
105 local reply = st.reply(stanza)
106 :tag("query", { xmlns = "http://jabber.org/protocol/disco#info", node = node })
107 :tag("identity", { category = "pubsub", type = "leaf" });
108 return origin.send(reply);
109 end
110 end); 97 end);
111 98
112 local function handle_disco_items_on_node(event) 99 module:hook("host-disco-items-node", function (event)
113 local stanza, origin = event.stanza, event.origin; 100 local stanza, origin, reply, node = event.stanza, event.origin, event.reply, event.node;
114 local query = stanza.tags[1];
115 local node = query.attr.node;
116 local ok, ret = service:get_items(node, stanza.attr.from); 101 local ok, ret = service:get_items(node, stanza.attr.from);
117 if not ok then 102 if not ok then
118 return origin.send(pubsub_error_reply(stanza, ret)); 103 return origin.send(pubsub_error_reply(stanza, ret));
119 end 104 end
120 105
121 local reply = st.reply(stanza)
122 :tag("query", { xmlns = "http://jabber.org/protocol/disco#items", node = node });
123
124 for id, item in pairs(ret) do 106 for id, item in pairs(ret) do
125 reply:tag("item", { jid = module.host, name = id }):up(); 107 reply:tag("item", { jid = module.host, name = id }):up();
126 end 108 end
127 109 event.exists = true;
128 return origin.send(reply); 110 end);
129 end 111
130 112
131 113 module:hook("host-disco-items", function (event)
132 module:hook("iq-get/host/http://jabber.org/protocol/disco#items:query", function (event) 114 local stanza, origin, reply = event.stanza, event.origin, event.reply;
133 if event.stanza.tags[1].attr.node then
134 return handle_disco_items_on_node(event);
135 end
136 local ok, ret = service:get_nodes(event.stanza.attr.from); 115 local ok, ret = service:get_nodes(event.stanza.attr.from);
137 if not ok then 116 if not ok then
138 event.origin.send(pubsub_error_reply(event.stanza, ret)); 117 return origin.send(pubsub_error_reply(event.stanza, ret));
139 else 118 end
140 local reply = st.reply(event.stanza) 119 for node, node_obj in pairs(ret) do
141 :tag("query", { xmlns = "http://jabber.org/protocol/disco#items" }); 120 reply:tag("item", { jid = module.host, node = node, name = node_obj.config.name }):up();
142 for node, node_obj in pairs(ret) do 121 end
143 reply:tag("item", { jid = module.host, node = node, name = node_obj.config.name }):up();
144 end
145 event.origin.send(reply);
146 end
147 return true;
148 end); 122 end);
149 123
150 local admin_aff = module:get_option_string("default_admin_affiliation", "owner"); 124 local admin_aff = module:get_option_string("default_admin_affiliation", "owner");
151 local function get_affiliation(jid) 125 local function get_affiliation(jid)
152 local bare_jid = jid_bare(jid); 126 local bare_jid = jid_bare(jid);
156 end 130 end
157 131
158 function set_service(new_service) 132 function set_service(new_service)
159 service = new_service; 133 service = new_service;
160 module.environment.service = service; 134 module.environment.service = service;
161 disco_info = build_disco_info(service); 135 add_disco_features_from_service(service);
162 end 136 end
163 137
164 function module.save() 138 function module.save()
165 return { service = service }; 139 return { service = service };
166 end 140 end
167 141
168 function module.restore(data) 142 function module.restore(data)
169 set_service(data.service); 143 set_service(data.service);
170 end 144 end
171 145
172 set_service(pubsub.new({ 146 function module.load()
173 capabilities = { 147 if module.reloading then return; end
174 none = { 148
175 create = false; 149 set_service(pubsub.new({
176 publish = false; 150 capabilities = {
177 retract = false; 151 none = {
178 get_nodes = true; 152 create = false;
179 153 publish = false;
180 subscribe = true; 154 retract = false;
181 unsubscribe = true; 155 get_nodes = true;
182 get_subscription = true; 156
183 get_subscriptions = true; 157 subscribe = true;
184 get_items = true; 158 unsubscribe = true;
185 159 get_subscription = true;
186 subscribe_other = false; 160 get_subscriptions = true;
187 unsubscribe_other = false; 161 get_items = true;
188 get_subscription_other = false; 162
189 get_subscriptions_other = false; 163 subscribe_other = false;
190 164 unsubscribe_other = false;
191 be_subscribed = true; 165 get_subscription_other = false;
192 be_unsubscribed = true; 166 get_subscriptions_other = false;
193 167
194 set_affiliation = false; 168 be_subscribed = true;
169 be_unsubscribed = true;
170
171 set_affiliation = false;
172 };
173 publisher = {
174 create = false;
175 publish = true;
176 retract = true;
177 get_nodes = true;
178
179 subscribe = true;
180 unsubscribe = true;
181 get_subscription = true;
182 get_subscriptions = true;
183 get_items = true;
184
185 subscribe_other = false;
186 unsubscribe_other = false;
187 get_subscription_other = false;
188 get_subscriptions_other = false;
189
190 be_subscribed = true;
191 be_unsubscribed = true;
192
193 set_affiliation = false;
194 };
195 owner = {
196 create = true;
197 publish = true;
198 retract = true;
199 delete = true;
200 get_nodes = true;
201
202 subscribe = true;
203 unsubscribe = true;
204 get_subscription = true;
205 get_subscriptions = true;
206 get_items = true;
207
208
209 subscribe_other = true;
210 unsubscribe_other = true;
211 get_subscription_other = true;
212 get_subscriptions_other = true;
213
214 be_subscribed = true;
215 be_unsubscribed = true;
216
217 set_affiliation = true;
218 };
195 }; 219 };
196 publisher = { 220
197 create = false; 221 autocreate_on_publish = autocreate_on_publish;
198 publish = true; 222 autocreate_on_subscribe = autocreate_on_subscribe;
199 retract = true; 223
200 get_nodes = true; 224 broadcaster = simple_broadcast;
201 225 get_affiliation = get_affiliation;
202 subscribe = true; 226
203 unsubscribe = true; 227 normalize_jid = jid_bare;
204 get_subscription = true; 228 }));
205 get_subscriptions = true; 229 end
206 get_items = true;
207
208 subscribe_other = false;
209 unsubscribe_other = false;
210 get_subscription_other = false;
211 get_subscriptions_other = false;
212
213 be_subscribed = true;
214 be_unsubscribed = true;
215
216 set_affiliation = false;
217 };
218 owner = {
219 create = true;
220 publish = true;
221 retract = true;
222 delete = true;
223 get_nodes = true;
224
225 subscribe = true;
226 unsubscribe = true;
227 get_subscription = true;
228 get_subscriptions = true;
229 get_items = true;
230
231
232 subscribe_other = true;
233 unsubscribe_other = true;
234 get_subscription_other = true;
235 get_subscriptions_other = true;
236
237 be_subscribed = true;
238 be_unsubscribed = true;
239
240 set_affiliation = true;
241 };
242 };
243
244 autocreate_on_publish = autocreate_on_publish;
245 autocreate_on_subscribe = autocreate_on_subscribe;
246
247 broadcaster = simple_broadcast;
248 get_affiliation = get_affiliation;
249
250 normalize_jid = jid_bare;
251 }));