Software /
code /
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 |
parent | 8:10502594a49b |
child | 11:529819205379 |
child | 14: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); |