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);