Software /
code /
prosody
Comparison
plugins/mod_pubsub/pubsub.lib.lua @ 5626:8416d4619d80
mod_pubsub: Split out handlers into a module library
author | Florian Zeitz <florob@babelmonkeys.de> |
---|---|
date | Fri, 17 May 2013 18:33:32 +0200 |
child | 5851:cdcfd93e2f43 |
comparison
equal
deleted
inserted
replaced
5625:e67891ad18d6 | 5626:8416d4619d80 |
---|---|
1 local st = require "util.stanza"; | |
2 local uuid_generate = require "util.uuid".generate; | |
3 | |
4 local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; | |
5 local xmlns_pubsub_errors = "http://jabber.org/protocol/pubsub#errors"; | |
6 | |
7 local _M = {}; | |
8 | |
9 local handlers = {}; | |
10 _M.handlers = handlers; | |
11 | |
12 local pubsub_errors = { | |
13 ["conflict"] = { "cancel", "conflict" }; | |
14 ["invalid-jid"] = { "modify", "bad-request", nil, "invalid-jid" }; | |
15 ["jid-required"] = { "modify", "bad-request", nil, "jid-required" }; | |
16 ["nodeid-required"] = { "modify", "bad-request", nil, "nodeid-required" }; | |
17 ["item-not-found"] = { "cancel", "item-not-found" }; | |
18 ["not-subscribed"] = { "modify", "unexpected-request", nil, "not-subscribed" }; | |
19 ["forbidden"] = { "cancel", "forbidden" }; | |
20 }; | |
21 local function pubsub_error_reply(stanza, error) | |
22 local e = pubsub_errors[error]; | |
23 local reply = st.error_reply(stanza, unpack(e, 1, 3)); | |
24 if e[4] then | |
25 reply:tag(e[4], { xmlns = xmlns_pubsub_errors }):up(); | |
26 end | |
27 return reply; | |
28 end | |
29 _M.pubsub_error_reply = pubsub_error_reply; | |
30 | |
31 function handlers.get_items(origin, stanza, items, service) | |
32 local node = items.attr.node; | |
33 local item = items:get_child("item"); | |
34 local id = item and item.attr.id; | |
35 | |
36 if not node then | |
37 return origin.send(pubsub_error_reply(stanza, "nodeid-required")); | |
38 end | |
39 local ok, results = service:get_items(node, stanza.attr.from, id); | |
40 if not ok then | |
41 return origin.send(pubsub_error_reply(stanza, results)); | |
42 end | |
43 | |
44 local data = st.stanza("items", { node = node }); | |
45 for _, entry in pairs(results) do | |
46 data:add_child(entry); | |
47 end | |
48 local reply; | |
49 if data then | |
50 reply = st.reply(stanza) | |
51 :tag("pubsub", { xmlns = xmlns_pubsub }) | |
52 :add_child(data); | |
53 else | |
54 reply = pubsub_error_reply(stanza, "item-not-found"); | |
55 end | |
56 return origin.send(reply); | |
57 end | |
58 | |
59 function handlers.get_subscriptions(origin, stanza, subscriptions, service) | |
60 local node = subscriptions.attr.node; | |
61 local ok, ret = service:get_subscriptions(node, stanza.attr.from, stanza.attr.from); | |
62 if not ok then | |
63 return origin.send(pubsub_error_reply(stanza, ret)); | |
64 end | |
65 local reply = st.reply(stanza) | |
66 :tag("pubsub", { xmlns = xmlns_pubsub }) | |
67 :tag("subscriptions"); | |
68 for _, sub in ipairs(ret) do | |
69 reply:tag("subscription", { node = sub.node, jid = sub.jid, subscription = 'subscribed' }):up(); | |
70 end | |
71 return origin.send(reply); | |
72 end | |
73 | |
74 function handlers.set_create(origin, stanza, create, service) | |
75 local node = create.attr.node; | |
76 local ok, ret, reply; | |
77 if node then | |
78 ok, ret = service:create(node, stanza.attr.from); | |
79 if ok then | |
80 reply = st.reply(stanza); | |
81 else | |
82 reply = pubsub_error_reply(stanza, ret); | |
83 end | |
84 else | |
85 repeat | |
86 node = uuid_generate(); | |
87 ok, ret = service:create(node, stanza.attr.from); | |
88 until ok or ret ~= "conflict"; | |
89 if ok then | |
90 reply = st.reply(stanza) | |
91 :tag("pubsub", { xmlns = xmlns_pubsub }) | |
92 :tag("create", { node = node }); | |
93 else | |
94 reply = pubsub_error_reply(stanza, ret); | |
95 end | |
96 end | |
97 return origin.send(reply); | |
98 end | |
99 | |
100 function handlers.set_delete(origin, stanza, delete, service) | |
101 local node = delete.attr.node; | |
102 | |
103 local reply, notifier; | |
104 if not node then | |
105 return origin.send(pubsub_error_reply(stanza, "nodeid-required")); | |
106 end | |
107 local ok, ret = service:delete(node, stanza.attr.from); | |
108 if ok then | |
109 reply = st.reply(stanza); | |
110 else | |
111 reply = pubsub_error_reply(stanza, ret); | |
112 end | |
113 return origin.send(reply); | |
114 end | |
115 | |
116 function handlers.set_subscribe(origin, stanza, subscribe, service) | |
117 local node, jid = subscribe.attr.node, subscribe.attr.jid; | |
118 if not (node and jid) then | |
119 return origin.send(pubsub_error_reply(stanza, jid and "nodeid-required" or "invalid-jid")); | |
120 end | |
121 --[[ | |
122 local options_tag, options = stanza.tags[1]:get_child("options"), nil; | |
123 if options_tag then | |
124 options = options_form:data(options_tag.tags[1]); | |
125 end | |
126 --]] | |
127 local options_tag, options; -- FIXME | |
128 local ok, ret = service:add_subscription(node, stanza.attr.from, jid, options); | |
129 local reply; | |
130 if ok then | |
131 reply = st.reply(stanza) | |
132 :tag("pubsub", { xmlns = xmlns_pubsub }) | |
133 :tag("subscription", { | |
134 node = node, | |
135 jid = jid, | |
136 subscription = "subscribed" | |
137 }):up(); | |
138 if options_tag then | |
139 reply:add_child(options_tag); | |
140 end | |
141 else | |
142 reply = pubsub_error_reply(stanza, ret); | |
143 end | |
144 origin.send(reply); | |
145 end | |
146 | |
147 function handlers.set_unsubscribe(origin, stanza, unsubscribe, service) | |
148 local node, jid = unsubscribe.attr.node, unsubscribe.attr.jid; | |
149 if not (node and jid) then | |
150 return origin.send(pubsub_error_reply(stanza, jid and "nodeid-required" or "invalid-jid")); | |
151 end | |
152 local ok, ret = service:remove_subscription(node, stanza.attr.from, jid); | |
153 local reply; | |
154 if ok then | |
155 reply = st.reply(stanza); | |
156 else | |
157 reply = pubsub_error_reply(stanza, ret); | |
158 end | |
159 return origin.send(reply); | |
160 end | |
161 | |
162 function handlers.set_publish(origin, stanza, publish, service) | |
163 local node = publish.attr.node; | |
164 if not node then | |
165 return origin.send(pubsub_error_reply(stanza, "nodeid-required")); | |
166 end | |
167 local item = publish:get_child("item"); | |
168 local id = (item and item.attr.id); | |
169 if not id then | |
170 id = uuid_generate(); | |
171 if item then | |
172 item.attr.id = id; | |
173 end | |
174 end | |
175 local ok, ret = service:publish(node, stanza.attr.from, id, item); | |
176 local reply; | |
177 if ok then | |
178 reply = st.reply(stanza) | |
179 :tag("pubsub", { xmlns = xmlns_pubsub }) | |
180 :tag("publish", { node = node }) | |
181 :tag("item", { id = id }); | |
182 else | |
183 reply = pubsub_error_reply(stanza, ret); | |
184 end | |
185 return origin.send(reply); | |
186 end | |
187 | |
188 function handlers.set_retract(origin, stanza, retract, service) | |
189 local node, notify = retract.attr.node, retract.attr.notify; | |
190 notify = (notify == "1") or (notify == "true"); | |
191 local item = retract:get_child("item"); | |
192 local id = item and item.attr.id | |
193 if not (node and id) then | |
194 return origin.send(pubsub_error_reply(stanza, node and "item-not-found" or "nodeid-required")); | |
195 end | |
196 local reply, notifier; | |
197 if notify then | |
198 notifier = st.stanza("retract", { id = id }); | |
199 end | |
200 local ok, ret = service:retract(node, stanza.attr.from, id, notifier); | |
201 if ok then | |
202 reply = st.reply(stanza); | |
203 else | |
204 reply = pubsub_error_reply(stanza, ret); | |
205 end | |
206 return origin.send(reply); | |
207 end | |
208 | |
209 function handlers.set_purge(origin, stanza, purge, service) | |
210 local node, notify = purge.attr.node, purge.attr.notify; | |
211 notify = (notify == "1") or (notify == "true"); | |
212 local reply; | |
213 if not node then | |
214 return origin.send(pubsub_error_reply(stanza, "nodeid-required")); | |
215 end | |
216 local ok, ret = service:purge(node, stanza.attr.from, notify); | |
217 if ok then | |
218 reply = st.reply(stanza); | |
219 else | |
220 reply = pubsub_error_reply(stanza, ret); | |
221 end | |
222 return origin.send(reply); | |
223 end | |
224 | |
225 return _M; |