Mercurial > prosody-modules
comparison mod_privacy/mod_privacy.lua @ 10:7d70faba234c
some error reporting during list editing
| author | Thilo Cestonaro <thilo@cestona.ro> |
|---|---|
| date | Fri, 25 Sep 2009 21:50:01 +0200 |
| parents | 10502594a49b |
| children | 529819205379 0892941186f2 |
comparison
equal
deleted
inserted
replaced
| 9:2be8bcce5b18 | 10:7d70faba234c |
|---|---|
| 10 | 10 |
| 11 local prosody = prosody; | 11 local prosody = prosody; |
| 12 local helpers = require "util/helpers"; | 12 local helpers = require "util/helpers"; |
| 13 local st = require "util.stanza"; | 13 local st = require "util.stanza"; |
| 14 local datamanager = require "util.datamanager"; | 14 local datamanager = require "util.datamanager"; |
| 15 local privacy_lists = nil | |
| 16 local bare_sessions = bare_sessions; | 15 local bare_sessions = bare_sessions; |
| 17 | 16 |
| 18 | 17 |
| 19 function findNamedList (name) | 18 function findNamedList (privacy_lists, name) |
| 20 local ret = nil | 19 local ret = nil |
| 21 if privacy_lists.lists == nil then return nil; end | 20 if privacy_lists.lists == nil then return nil; end |
| 22 | 21 |
| 23 for i=1, #privacy_lists.lists do | 22 for i=1, #privacy_lists.lists do |
| 24 if privacy_lists.lists[i].name == name then | 23 if privacy_lists.lists[i].name == name then |
| 27 end | 26 end |
| 28 end | 27 end |
| 29 return ret; | 28 return ret; |
| 30 end | 29 end |
| 31 | 30 |
| 32 function declineList (origin, stanza, which) | 31 function declineList (privacy_lists, origin, stanza, which) |
| 33 module:log("info", "User requests to decline the use of privacy list: %s", which); | 32 module:log("info", "User requests to decline the use of privacy list: %s", which); |
| 34 privacy_lists[which] = nil; | 33 privacy_lists[which] = nil; |
| 35 origin.send(st.reply(stanza)); | 34 origin.send(st.reply(stanza)); |
| 36 return true; | 35 return true; |
| 37 end | 36 end |
| 38 | 37 |
| 39 function activateList (origin, stanza, which, name) | 38 function activateList (privacy_lists, origin, stanza, which, name) |
| 40 module:log("info", "User requests to change the privacy list: %s, to be list named %s", which, name); | 39 module:log("info", "User requests to change the privacy list: %s, to be list named %s", which, name); |
| 41 local ret = false; | 40 local ret = false; |
| 42 local idx = findNamedList(name); | 41 local idx = findNamedList(privacy_lists, name); |
| 43 | 42 |
| 44 if privacy_lists[which] == nil then | 43 if privacy_lists[which] == nil then |
| 45 privacy_lists[which] = ""; | 44 privacy_lists[which] = ""; |
| 46 end | 45 end |
| 47 | 46 |
| 51 ret = true; | 50 ret = true; |
| 52 end | 51 end |
| 53 return ret; | 52 return ret; |
| 54 end | 53 end |
| 55 | 54 |
| 56 function deleteList (origin, stanza, name) | 55 function deleteList (privacy_lists, origin, stanza, name) |
| 57 module:log("info", "User requests to delete privacy list: %s", name); | 56 module:log("info", "User requests to delete privacy list: %s", name); |
| 58 local ret = false; | 57 local ret = false; |
| 59 local idx = findNamedList(name); | 58 local idx = findNamedList(privacy_lists, name); |
| 60 | 59 |
| 61 if idx ~= nil then | 60 if idx ~= nil then |
| 62 table.remove(privacy_lists.lists, idx); | 61 table.remove(privacy_lists.lists, idx); |
| 63 origin.send(st.reply(stanza)); | 62 origin.send(st.reply(stanza)); |
| 64 ret = true; | 63 ret = true; |
| 65 end | 64 end |
| 66 return ret; | 65 return ret; |
| 67 end | 66 end |
| 68 | 67 |
| 69 function createOrReplaceList (origin, stanza, name, entries) | 68 local function sortByOrder(a, b) |
| 69 if a.order < b.order then | |
| 70 return true; | |
| 71 end | |
| 72 return false; | |
| 73 end | |
| 74 | |
| 75 function createOrReplaceList (privacy_lists, origin, stanza, name, entries) | |
| 70 module:log("info", "User requests to create / replace list named %s, item count: %d", name, #entries); | 76 module:log("info", "User requests to create / replace list named %s, item count: %d", name, #entries); |
| 71 local ret = true; | 77 local ret = true; |
| 72 local idx = findNamedList(name); | 78 local idx = findNamedList(privacy_lists, name); |
| 73 local bare_jid = origin.username.."@"..origin.host; | 79 local bare_jid = origin.username.."@"..origin.host; |
| 74 | 80 |
| 75 if privacy_lists.lists == nil then | 81 if privacy_lists.lists == nil then |
| 76 privacy_lists.lists = {}; | 82 privacy_lists.lists = {}; |
| 77 end | 83 end |
| 100 tmp[tag.name] = true; | 106 tmp[tag.name] = true; |
| 101 end | 107 end |
| 102 end | 108 end |
| 103 list.items[#list.items + 1] = tmp; | 109 list.items[#list.items + 1] = tmp; |
| 104 end | 110 end |
| 111 | |
| 112 table.sort(list, sortByOrder); | |
| 105 | 113 |
| 106 privacy_lists.lists[idx] = list; | 114 privacy_lists.lists[idx] = list; |
| 107 origin.send(st.reply(stanza)); | 115 origin.send(st.reply(stanza)); |
| 108 if bare_sessions[bare_jid] ~= nil then | 116 if bare_sessions[bare_jid] ~= nil then |
| 109 iq = st.iq ( { type = "set", id="push1" } ); | 117 iq = st.iq ( { type = "set", id="push1" } ); |
| 116 end | 124 end |
| 117 end | 125 end |
| 118 return true; | 126 return true; |
| 119 end | 127 end |
| 120 | 128 |
| 121 function getList(origin, stanza, name) | 129 function getList(privacy_lists, origin, stanza, name) |
| 122 module:log("info", "User requests list named: %s", name or "nil"); | 130 module:log("info", "User requests list named: %s", name or "nil"); |
| 123 local ret = true; | 131 local ret = false; |
| 124 local idx = findNamedList(name); | |
| 125 local reply = st.reply(stanza); | 132 local reply = st.reply(stanza); |
| 126 reply = reply:tag("query", {xmlns="jabber:iq:privacy"}); | 133 reply:tag("query", {xmlns="jabber:iq:privacy"}); |
| 127 | 134 |
| 128 if idx == nil then | 135 if name == nil then |
| 129 reply:tag("active", {name=privacy_lists.active or ""}):up(); | 136 reply:tag("active", {name=privacy_lists.active or ""}):up(); |
| 130 reply:tag("default", {name=privacy_lists.default or ""}):up(); | 137 reply:tag("default", {name=privacy_lists.default or ""}):up(); |
| 131 if privacy_lists.lists then | 138 if privacy_lists.lists then |
| 132 for _,list in ipairs(privacy_lists.lists) do | 139 for _,list in ipairs(privacy_lists.lists) do |
| 133 reply:tag("list", {name=list.name}):up(); | 140 reply:tag("list", {name=list.name}):up(); |
| 134 end | 141 end |
| 142 ret = true; | |
| 135 end | 143 end |
| 136 else | 144 else |
| 137 list = privacy_lists.lists[idx]; | 145 local idx = findNamedList(privacy_lists, name); |
| 138 reply = reply:tag("list", {name=list.name}); | 146 log("debug", "list idx: %d", idx or -1); |
| 139 for _,item in ipairs(list.items) do | 147 if idx ~= nil then |
| 140 reply:tag("item", {type=item.type, value=item.value, action=item.action, order=item.order}); | 148 list = privacy_lists.lists[idx]; |
| 141 if item["message"] then reply:tag("message"):up(); end | 149 reply = reply:tag("list", {name=list.name}); |
| 142 if item["iq"] then reply:tag("iq"):up(); end | 150 for _,item in ipairs(list.items) do |
| 143 if item["presence-in"] then reply:tag("presence-in"):up(); end | 151 reply:tag("item", {type=item.type, value=item.value, action=item.action, order=item.order}); |
| 144 if item["presence-out"] then reply:tag("presence-out"):up(); end | 152 if item["message"] then reply:tag("message"):up(); end |
| 145 reply:up(); | 153 if item["iq"] then reply:tag("iq"):up(); end |
| 146 end | 154 if item["presence-in"] then reply:tag("presence-in"):up(); end |
| 147 end | 155 if item["presence-out"] then reply:tag("presence-out"):up(); end |
| 148 | 156 reply:up(); |
| 149 origin.send(reply); | 157 end |
| 158 ret = true; | |
| 159 end | |
| 160 end | |
| 161 | |
| 162 if ret then | |
| 163 origin.send(reply); | |
| 164 end | |
| 150 return ret; | 165 return ret; |
| 151 end | 166 end |
| 152 | 167 |
| 153 -- "[tagname]/[target-type]/[payload-namespace]:[payload-tagname]" | 168 -- "[tagname]/[target-type]/[payload-namespace]:[payload-tagname]" |
| 154 module:hook("iq/bare/jabber:iq:privacy:query", function(data) | 169 module:hook("iq/bare/jabber:iq:privacy:query", function(data) |
| 155 local origin, stanza = data.origin, data.stanza; | 170 local origin, stanza = data.origin, data.stanza; |
| 156 | 171 |
| 157 if stanza.attr.to == nil then -- only service requests to own bare JID | 172 if stanza.attr.to == nil then -- only service requests to own bare JID |
| 173 local err_reply = nil; | |
| 158 local query = stanza.tags[1]; -- the query element | 174 local query = stanza.tags[1]; -- the query element |
| 159 local valid = false; | 175 local valid = false; |
| 160 privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or {}; | 176 local privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or {}; |
| 161 | 177 |
| 162 if stanza.attr.type == "set" then | 178 if stanza.attr.type == "set" then |
| 163 if #query.tags >= 1 then | 179 if #query.tags >= 1 then |
| 164 for _,tag in ipairs(query.tags) do | 180 for _,tag in ipairs(query.tags) do |
| 165 if tag.name == "active" or tag.name == "default" then | 181 if tag.name == "active" or tag.name == "default" then |
| 166 if tag.attr.name == nil then -- Client declines the use of active / default list | 182 if tag.attr.name == nil then -- Client declines the use of active / default list |
| 167 valid = declineList(origin, stanza, tag.name); | 183 valid = declineList(privacy_lists, origin, stanza, tag.name); |
| 168 else -- Client requests change of active / default list | 184 else -- Client requests change of active / default list |
| 169 valid = activateList(origin, stanza, tag.name, tag.attr.name); | 185 valid = activateList(privacy_lists, origin, stanza, tag.name, tag.attr.name); |
| 186 err_reply = st.error_reply(stanza, "cancel", "item-not-found"); | |
| 170 end | 187 end |
| 171 elseif tag.name == "list" and tag.attr.name then -- Client adds / edits a privacy list | 188 elseif tag.name == "list" and tag.attr.name then -- Client adds / edits a privacy list |
| 172 if #tag.tags == 0 then -- Client removes a privacy list | 189 if #tag.tags == 0 then -- Client removes a privacy list |
| 173 valid = deleteList(origin, stanza, tag.attr.name); | 190 valid = deleteList(privacy_lists, origin, stanza, tag.attr.name); |
| 174 else -- Client edits a privacy list | 191 else -- Client edits a privacy list |
| 175 valid = createOrReplaceList(origin, stanza, tag.attr.name, tag.tags) | 192 valid = createOrReplaceList(privacy_lists, origin, stanza, tag.attr.name, tag.tags) |
| 176 end | 193 end |
| 177 end | 194 end |
| 178 end | 195 end |
| 179 end | 196 end |
| 180 elseif stanza.attr.type == "get" then | 197 elseif stanza.attr.type == "get" then |
| 181 local name = nil; | 198 local name = nil; |
| 199 local listsToRetrieve = 0; | |
| 182 if #query.tags >= 1 then | 200 if #query.tags >= 1 then |
| 183 for _,tag in ipairs(query.tags) do | 201 for _,tag in ipairs(query.tags) do |
| 184 if tag.name == "list" then -- Client requests a privacy list from server | 202 if tag.name == "list" then -- Client requests a privacy list from server |
| 185 name = tag.attr.name; | 203 name = tag.attr.name; |
| 186 break; | 204 listsToRetrieve = listsToRetrieve + 1; |
| 187 end | 205 end |
| 188 end | 206 end |
| 189 end | 207 end |
| 190 valid = getList(origin, stanza, name); | 208 if listsToRetrieve == 0 or listsToRetrieve == 1 then |
| 209 valid = getList(privacy_lists, origin, stanza, name); | |
| 210 err_reply = st.error_reply(stanza, "cancel", "item-not-found"); | |
| 211 end | |
| 191 end | 212 end |
| 192 | 213 |
| 193 if valid == false then | 214 if valid == false then |
| 194 origin.send(st.error_reply(stanza, "modify", "bad-request")); | 215 if err_reply == nil then |
| 216 err_reply = st.error_reply(stanza, "modify", "bad-request"); | |
| 217 end | |
| 218 origin.send(err_reply); | |
| 195 else | 219 else |
| 196 datamanager.store(origin.username, origin.host, "privacy", privacy_lists); | 220 datamanager.store(origin.username, origin.host, "privacy", privacy_lists); |
| 197 end | 221 end |
| 198 return true; | 222 return true; |
| 199 end | 223 end |
| 200 return false; | 224 return false; |
| 201 end, 500); | 225 end, 500); |
| 202 | 226 |
| 203 function checkIfNeedToBeBlocked(e) | 227 function checkIfNeedToBeBlocked(e) |
| 228 local origin, stanza = e.origin, e.stanza; | |
| 229 local privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or {}; | |
| 230 if privacy_lists.lists ~= nil then | |
| 231 end | |
| 204 return false; | 232 return false; |
| 205 end | 233 end |
| 206 | 234 |
| 207 module:hook("pre-message/full", checkIfNeedToBeBlocked, 500); | 235 module:hook("pre-message/full", checkIfNeedToBeBlocked, 500); |
| 208 module:hook("pre-iq/bare", checkIfNeedToBeBlocked, 500); | 236 module:hook("pre-iq/bare", checkIfNeedToBeBlocked, 500); |
