Mercurial > prosody-hg
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 |
| parents | 8416d4619d80 |
| children | cdcfd93e2f43 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 })); |
