comparison mod_privacy/mod_privacy.lua @ 8:10502594a49b

adds mod_privacy; lists creating, editing and deletion working.
author Thilo Cestonaro <thilo@cestona.ro>
date Fri, 25 Sep 2009 16:56:50 +0200
parents
children 7d70faba234c
comparison
equal deleted inserted replaced
7:473b14c59797 8:10502594a49b
1 -- Prosody IM
2 -- Copyright (C) 2008-2009 Matthew Wild
3 -- Copyright (C) 2008-2009 Waqas Hussain
4 -- Copyright (C) 2009 Thilo Cestonaro
5 --
6 -- This project is MIT/X11 licensed. Please see the
7 -- COPYING file in the source package for more information.
8 --
9
10
11 local prosody = prosody;
12 local helpers = require "util/helpers";
13 local st = require "util.stanza";
14 local datamanager = require "util.datamanager";
15 local privacy_lists = nil
16 local bare_sessions = bare_sessions;
17
18
19 function findNamedList (name)
20 local ret = nil
21 if privacy_lists.lists == nil then return nil; end
22
23 for i=1, #privacy_lists.lists do
24 if privacy_lists.lists[i].name == name then
25 ret = i;
26 break;
27 end
28 end
29 return ret;
30 end
31
32 function declineList (origin, stanza, which)
33 module:log("info", "User requests to decline the use of privacy list: %s", which);
34 privacy_lists[which] = nil;
35 origin.send(st.reply(stanza));
36 return true;
37 end
38
39 function activateList (origin, stanza, which, name)
40 module:log("info", "User requests to change the privacy list: %s, to be list named %s", which, name);
41 local ret = false;
42 local idx = findNamedList(name);
43
44 if privacy_lists[which] == nil then
45 privacy_lists[which] = "";
46 end
47
48 if privacy_lists[which] ~= name and idx ~= nil then
49 privacy_lists[which] = name;
50 origin.send(st.reply(stanza));
51 ret = true;
52 end
53 return ret;
54 end
55
56 function deleteList (origin, stanza, name)
57 module:log("info", "User requests to delete privacy list: %s", name);
58 local ret = false;
59 local idx = findNamedList(name);
60
61 if idx ~= nil then
62 table.remove(privacy_lists.lists, idx);
63 origin.send(st.reply(stanza));
64 ret = true;
65 end
66 return ret;
67 end
68
69 function createOrReplaceList (origin, stanza, name, entries)
70 module:log("info", "User requests to create / replace list named %s, item count: %d", name, #entries);
71 local ret = true;
72 local idx = findNamedList(name);
73 local bare_jid = origin.username.."@"..origin.host;
74
75 if privacy_lists.lists == nil then
76 privacy_lists.lists = {};
77 end
78
79 if idx == nil then
80 idx = #privacy_lists.lists + 1;
81 end
82
83 local list = {};
84 list.name = name;
85 list.items = {};
86
87 for _,item in ipairs(entries) do
88 tmp = {};
89 tmp["type"] = item.attr.type;
90 tmp["value"] = item.attr.value;
91 tmp["action"] = item.attr.action;
92 tmp["order"] = item.attr.order;
93 tmp["presence-in"] = false;
94 tmp["presence-out"] = false;
95 tmp["message"] = false;
96 tmp["iq"] = false;
97
98 if #item.tags > 0 then
99 for _,tag in ipairs(item.tags) do
100 tmp[tag.name] = true;
101 end
102 end
103 list.items[#list.items + 1] = tmp;
104 end
105
106 privacy_lists.lists[idx] = list;
107 origin.send(st.reply(stanza));
108 if bare_sessions[bare_jid] ~= nil then
109 iq = st.iq ( { type = "set", id="push1" } );
110 iq:tag ("query", { xmlns = "jabber:iq:privacy" } );
111 iq:tag ("list", { name = list.name } ):up();
112 iq:up();
113 for resource, session in pairs(bare_sessions[bare_jid].sessions) do
114 iq.attr.to = bare_jid.."/"..resource
115 session.send(iq);
116 end
117 end
118 return true;
119 end
120
121 function getList(origin, stanza, name)
122 module:log("info", "User requests list named: %s", name or "nil");
123 local ret = true;
124 local idx = findNamedList(name);
125 local reply = st.reply(stanza);
126 reply = reply:tag("query", {xmlns="jabber:iq:privacy"});
127
128 if idx == nil then
129 reply:tag("active", {name=privacy_lists.active or ""}):up();
130 reply:tag("default", {name=privacy_lists.default or ""}):up();
131 if privacy_lists.lists then
132 for _,list in ipairs(privacy_lists.lists) do
133 reply:tag("list", {name=list.name}):up();
134 end
135 end
136 else
137 list = privacy_lists.lists[idx];
138 reply = reply:tag("list", {name=list.name});
139 for _,item in ipairs(list.items) do
140 reply:tag("item", {type=item.type, value=item.value, action=item.action, order=item.order});
141 if item["message"] then reply:tag("message"):up(); end
142 if item["iq"] then reply:tag("iq"):up(); end
143 if item["presence-in"] then reply:tag("presence-in"):up(); end
144 if item["presence-out"] then reply:tag("presence-out"):up(); end
145 reply:up();
146 end
147 end
148
149 origin.send(reply);
150 return ret;
151 end
152
153 -- "[tagname]/[target-type]/[payload-namespace]:[payload-tagname]"
154 module:hook("iq/bare/jabber:iq:privacy:query", function(data)
155 local origin, stanza = data.origin, data.stanza;
156
157 if stanza.attr.to == nil then -- only service requests to own bare JID
158 local query = stanza.tags[1]; -- the query element
159 local valid = false;
160 privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or {};
161
162 if stanza.attr.type == "set" then
163 if #query.tags >= 1 then
164 for _,tag in ipairs(query.tags) do
165 if tag.name == "active" or tag.name == "default" then
166 if tag.attr.name == nil then -- Client declines the use of active / default list
167 valid = declineList(origin, stanza, tag.name);
168 else -- Client requests change of active / default list
169 valid = activateList(origin, stanza, tag.name, tag.attr.name);
170 end
171 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
173 valid = deleteList(origin, stanza, tag.attr.name);
174 else -- Client edits a privacy list
175 valid = createOrReplaceList(origin, stanza, tag.attr.name, tag.tags)
176 end
177 end
178 end
179 end
180 elseif stanza.attr.type == "get" then
181 local name = nil;
182 if #query.tags >= 1 then
183 for _,tag in ipairs(query.tags) do
184 if tag.name == "list" then -- Client requests a privacy list from server
185 name = tag.attr.name;
186 break;
187 end
188 end
189 end
190 valid = getList(origin, stanza, name);
191 end
192
193 if valid == false then
194 origin.send(st.error_reply(stanza, "modify", "bad-request"));
195 else
196 datamanager.store(origin.username, origin.host, "privacy", privacy_lists);
197 end
198 return true;
199 end
200 return false;
201 end, 500);
202
203 function checkIfNeedToBeBlocked(e)
204 return false;
205 end
206
207 module:hook("pre-message/full", checkIfNeedToBeBlocked, 500);
208 module:hook("pre-iq/bare", checkIfNeedToBeBlocked, 500);
209 module:hook("pre-presence/bare", checkIfNeedToBeBlocked, 500);
210
211 -- helpers.log_events(hosts["albastru.de"].events, "albastru.de");
212 -- helpers.log_events(prosody.events, "*");
213
214 module:log("info", "mod_privacy loaded ...");