Software / code / prosody
Comparison
plugins/mod_pep.lua @ 2331:4842ce0c3be4
Merge with trunk
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Mon, 07 Dec 2009 18:32:50 +0000 |
| parent | 2327:5839f303addf |
| child | 2384:7bec10f26082 |
| child | 2923:b7049746bd29 |
comparison
equal
deleted
inserted
replaced
| 2330:e80790636cbe | 2331:4842ce0c3be4 |
|---|---|
| 35 end | 35 end |
| 36 | 36 |
| 37 module:add_identity("pubsub", "pep", "Prosody"); | 37 module:add_identity("pubsub", "pep", "Prosody"); |
| 38 module:add_feature("http://jabber.org/protocol/pubsub#publish"); | 38 module:add_feature("http://jabber.org/protocol/pubsub#publish"); |
| 39 | 39 |
| 40 local function publish(session, node, item) | 40 local function subscription_presence(user_bare, recipient) |
| 41 local recipient_bare = jid_bare(recipient); | |
| 42 if (recipient_bare == user_bare) then return true end | |
| 43 local item = load_roster(jid_split(user_bare))[recipient_bare]; | |
| 44 return item and (item.subscription == 'from' or item.subscription == 'both'); | |
| 45 end | |
| 46 | |
| 47 local function publish(session, node, id, item) | |
| 41 item.attr.xmlns = nil; | 48 item.attr.xmlns = nil; |
| 42 local disable = #item.tags ~= 1 or #item.tags[1].tags == 0; | 49 local disable = #item.tags ~= 1 or #item.tags[1] == 0; |
| 43 if #item.tags == 0 then item.name = "retract"; end | 50 if #item.tags == 0 then item.name = "retract"; end |
| 44 local bare = session.username..'@'..session.host; | 51 local bare = session.username..'@'..session.host; |
| 45 local stanza = st.message({from=bare, type='headline'}) | 52 local stanza = st.message({from=bare, type='headline'}) |
| 46 :tag('event', {xmlns='http://jabber.org/protocol/pubsub#event'}) | 53 :tag('event', {xmlns='http://jabber.org/protocol/pubsub#event'}) |
| 47 :tag('items', {node=node}) | 54 :tag('items', {node=node}) |
| 56 user_data[node] = nil; | 63 user_data[node] = nil; |
| 57 if not next(user_data) then data[bare] = nil; end | 64 if not next(user_data) then data[bare] = nil; end |
| 58 end | 65 end |
| 59 else | 66 else |
| 60 if not user_data then user_data = {}; data[bare] = user_data; end | 67 if not user_data then user_data = {}; data[bare] = user_data; end |
| 61 user_data[node] = stanza; | 68 user_data[node] = {id or "1", item}; |
| 62 end | 69 end |
| 63 | 70 |
| 64 -- broadcast | 71 -- broadcast |
| 65 for recipient, notify in pairs(recipients[bare] or NULL) do | 72 for recipient, notify in pairs(recipients[bare] or NULL) do |
| 66 if notify[node] then | 73 if notify[node] then |
| 67 stanza.attr.to = recipient; | 74 stanza.attr.to = recipient; |
| 68 core_post_stanza(session, stanza); | 75 core_post_stanza(session, stanza); |
| 72 local function publish_all(user, recipient, session) | 79 local function publish_all(user, recipient, session) |
| 73 local d = data[user]; | 80 local d = data[user]; |
| 74 local notify = recipients[user] and recipients[user][recipient]; | 81 local notify = recipients[user] and recipients[user][recipient]; |
| 75 if d and notify then | 82 if d and notify then |
| 76 for node in pairs(notify) do | 83 for node in pairs(notify) do |
| 77 local message = d[node]; | 84 if d[node] then |
| 78 if message then | 85 local id, item = unpack(d[node]); |
| 79 message.attr.to = recipient; | 86 session.send(st.message({from=user, to=recipient, type='headline'}) |
| 80 session.send(message); | 87 :tag('event', {xmlns='http://jabber.org/protocol/pubsub#event'}) |
| 88 :tag('items', {node=node}) | |
| 89 :add_child(item) | |
| 90 :up() | |
| 91 :up()); | |
| 81 end | 92 end |
| 82 end | 93 end |
| 83 end | 94 end |
| 84 end | 95 end |
| 85 | 96 |
| 104 end | 115 end |
| 105 | 116 |
| 106 module:hook("presence/bare", function(event) | 117 module:hook("presence/bare", function(event) |
| 107 -- inbound presence to bare JID recieved | 118 -- inbound presence to bare JID recieved |
| 108 local origin, stanza = event.origin, event.stanza; | 119 local origin, stanza = event.origin, event.stanza; |
| 109 | |
| 110 local user = stanza.attr.to or (origin.username..'@'..origin.host); | 120 local user = stanza.attr.to or (origin.username..'@'..origin.host); |
| 111 local bare = jid_bare(stanza.attr.from); | 121 |
| 112 local item = load_roster(jid_split(user))[bare]; | 122 if not stanza.attr.to or subscription_presence(user, stanza.attr.from) then |
| 113 if not stanza.attr.to or (item and (item.subscription == 'from' or item.subscription == 'both')) then | |
| 114 local recipient = stanza.attr.from; | 123 local recipient = stanza.attr.from; |
| 115 local current = recipients[user] and recipients[user][recipient]; | 124 local current = recipients[user] and recipients[user][recipient]; |
| 116 local hash = get_caps_hash_from_presence(stanza, current); | 125 local hash = get_caps_hash_from_presence(stanza, current); |
| 117 if current == hash then return; end | 126 if current == hash then return; end |
| 118 if not hash then | 127 if not hash then |
| 133 end | 142 end |
| 134 end, 10); | 143 end, 10); |
| 135 | 144 |
| 136 module:hook("iq/bare/http://jabber.org/protocol/pubsub:pubsub", function(event) | 145 module:hook("iq/bare/http://jabber.org/protocol/pubsub:pubsub", function(event) |
| 137 local session, stanza = event.origin, event.stanza; | 146 local session, stanza = event.origin, event.stanza; |
| 147 local payload = stanza.tags[1]; | |
| 148 | |
| 138 if stanza.attr.type == 'set' and (not stanza.attr.to or jid_bare(stanza.attr.from) == stanza.attr.to) then | 149 if stanza.attr.type == 'set' and (not stanza.attr.to or jid_bare(stanza.attr.from) == stanza.attr.to) then |
| 139 local payload = stanza.tags[1]; | 150 payload = payload.tags[1]; |
| 140 if payload.name == 'pubsub' then -- <pubsub xmlns='http://jabber.org/protocol/pubsub'> | 151 if payload and (payload.name == 'publish' or payload.name == 'retract') and payload.attr.node then -- <publish node='http://jabber.org/protocol/tune'> |
| 152 local node = payload.attr.node; | |
| 141 payload = payload.tags[1]; | 153 payload = payload.tags[1]; |
| 142 if payload and (payload.name == 'publish' or payload.name == 'retract') and payload.attr.node then -- <publish node='http://jabber.org/protocol/tune'> | 154 if payload and payload.name == "item" then -- <item> |
| 143 local node = payload.attr.node; | 155 local id = payload.attr.id; |
| 144 payload = payload.tags[1]; | 156 session.send(st.reply(stanza)); |
| 145 if payload and payload.name == "item" then -- <item> | 157 publish(session, node, id, st.clone(payload)); |
| 146 session.send(st.reply(stanza)); | 158 return true; |
| 147 publish(session, node, st.clone(payload)); | 159 end |
| 160 end | |
| 161 elseif stanza.attr.type == 'get' then | |
| 162 local user = stanza.attr.to and jid_bare(stanza.attr.to) or session.username..'@'..session.host; | |
| 163 if subscription_presence(user, stanza.attr.from) then | |
| 164 local user_data = data[user]; | |
| 165 local node, requested_id; | |
| 166 payload = payload.tags[1]; | |
| 167 if payload and payload.name == 'items' then | |
| 168 node = payload.attr.node; | |
| 169 local item = payload.tags[1]; | |
| 170 if item and item.name == "item" then | |
| 171 requested_id = item.attr.id; | |
| 172 end | |
| 173 end | |
| 174 if node and user_data and user_data[node] then -- Send the last item | |
| 175 local id, item = unpack(user_data[node]); | |
| 176 if not requested_id or id == requested_id then | |
| 177 local stanza = st.reply(stanza) | |
| 178 :tag('pubsub', {xmlns='http://jabber.org/protocol/pubsub'}) | |
| 179 :tag('items', {node=node}) | |
| 180 :add_child(item) | |
| 181 :up() | |
| 182 :up(); | |
| 183 session.send(stanza); | |
| 148 return true; | 184 return true; |
| 149 end | 185 else -- requested item doesn't exist |
| 150 end | 186 local stanza = st.reply(stanza) |
| 187 :tag('pubsub', {xmlns='http://jabber.org/protocol/pubsub'}) | |
| 188 :tag('items', {node=node}) | |
| 189 :up(); | |
| 190 session.send(stanza); | |
| 191 return true; | |
| 192 end | |
| 193 elseif node then -- node doesn't exist | |
| 194 session.send(st.error_reply(stanza, 'cancel', 'item-not-found')); | |
| 195 return true; | |
| 196 else --invalid request | |
| 197 session.send(st.error_reply(stanza, 'modify', 'bad-request')); | |
| 198 return true; | |
| 199 end | |
| 200 else --no presence subscription | |
| 201 session.send(st.error_reply(stanza, 'auth', 'not-authorized') | |
| 202 :tag('presence-subscription-required', {xmlns='http://jabber.org/protocol/pubsub#errors'})); | |
| 203 return true; | |
| 151 end | 204 end |
| 152 end | 205 end |
| 153 end); | 206 end); |
| 154 | 207 |
| 155 local function calculate_hash(disco_info) | 208 local function calculate_hash(disco_info) |