Merge 0.9->0.10
[prosody.git] / plugins / mod_privacy.lua
index 18d7b703e2d7897da8d79c09c3d670e2871c04d1..aaa8e383b5a6a6dbd11b18f304c041c8de576d68 100644 (file)
@@ -2,23 +2,23 @@
 -- Copyright (C) 2009-2010 Matthew Wild
 -- Copyright (C) 2009-2010 Waqas Hussain
 -- Copyright (C) 2009 Thilo Cestonaro
--- 
+--
 -- This project is MIT/X11 licensed. Please see the
 -- COPYING file in the source package for more information.
 --
 
 module:add_feature("jabber:iq:privacy");
 
-local prosody = prosody;
 local st = require "util.stanza";
-local datamanager = require "util.datamanager";
-local bare_sessions, full_sessions = bare_sessions, full_sessions;
+local bare_sessions, full_sessions = prosody.bare_sessions, prosody.full_sessions;
 local util_Jid = require "util.jid";
 local jid_bare = util_Jid.bare;
 local jid_split, jid_join = util_Jid.split, util_Jid.join;
 local load_roster = require "core.rostermanager".load_roster;
 local to_number = tonumber;
 
+local privacy_storage = module:open_store();
+
 function isListUsed(origin, name, privacy_lists)
        local user = bare_sessions[origin.username.."@"..origin.host];
        if user then
@@ -101,9 +101,9 @@ function deleteList(privacy_lists, origin, stanza, name)
        return {"modify", "bad-request", "Not existing list specifed to be deleted."};
 end
 
-function createOrReplaceList (privacy_lists, origin, stanza, name, entries, roster)
+function createOrReplaceList (privacy_lists, origin, stanza, name, entries)
        local bare_jid = origin.username.."@"..origin.host;
-       
+
        if privacy_lists.lists == nil then
                privacy_lists.lists = {};
        end
@@ -119,14 +119,14 @@ function createOrReplaceList (privacy_lists, origin, stanza, name, entries, rost
                if to_number(item.attr.order) == nil or to_number(item.attr.order) < 0 or orderCheck[item.attr.order] ~= nil then
                        return {"modify", "bad-request", "Order attribute not valid."};
                end
-               
+
                if item.attr.type ~= nil and item.attr.type ~= "jid" and item.attr.type ~= "subscription" and item.attr.type ~= "group" then
                        return {"modify", "bad-request", "Type attribute not valid."};
                end
-               
+
                local tmp = {};
                orderCheck[item.attr.order] = true;
-               
+
                tmp["type"] = item.attr.type;
                tmp["value"] = item.attr.value;
                tmp["action"] = item.attr.action;
@@ -135,13 +135,13 @@ function createOrReplaceList (privacy_lists, origin, stanza, name, entries, rost
                tmp["presence-out"] = false;
                tmp["message"] = false;
                tmp["iq"] = false;
-               
+
                if #item.tags > 0 then
                        for _,tag in ipairs(item.tags) do
                                tmp[tag.name] = true;
                        end
                end
-               
+
                if tmp.type == "subscription" then
                        if      tmp.value ~= "both" and
                                tmp.value ~= "to" and
@@ -150,13 +150,13 @@ function createOrReplaceList (privacy_lists, origin, stanza, name, entries, rost
                                return {"cancel", "bad-request", "Subscription value must be both, to, from or none."};
                        end
                end
-               
+
                if tmp.action ~= "deny" and tmp.action ~= "allow" then
                        return {"cancel", "bad-request", "Action must be either deny or allow."};
                end
                list.items[#list.items + 1] = tmp;
        end
-       
+
        table.sort(list, function(a, b) return a.order < b.order; end);
 
        origin.send(st.reply(stanza));
@@ -207,18 +207,18 @@ function getList(privacy_lists, origin, stanza, name)
                        return {"cancel", "item-not-found", "Unknown list specified."};
                end
        end
-       
+
        origin.send(reply);
        return true;
 end
 
 module:hook("iq/bare/jabber:iq:privacy:query", function(data)
        local origin, stanza = data.origin, data.stanza;
-       
+
        if stanza.attr.to == nil then -- only service requests to own bare JID
                local query = stanza.tags[1]; -- the query element
                local valid = false;
-               local privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or { lists = {} };
+               local privacy_lists = privacy_storage:get(origin.username) or { lists = {} };
 
                if privacy_lists.lists[1] then -- Code to migrate from old privacy lists format, remove in 0.8
                        module:log("info", "Upgrading format of stored privacy lists for %s@%s", origin.username, origin.host);
@@ -273,7 +273,7 @@ module:hook("iq/bare/jabber:iq:privacy:query", function(data)
                        end
                        origin.send(st.error_reply(stanza, valid[1], valid[2], valid[3]));
                else
-                       datamanager.store(origin.username, origin.host, "privacy", privacy_lists);
+                       privacy_storage:set(origin.username, privacy_lists);
                end
                return true;
        end
@@ -281,16 +281,16 @@ end);
 
 function checkIfNeedToBeBlocked(e, session)
        local origin, stanza = e.origin, e.stanza;
-       local privacy_lists = datamanager.load(session.username, session.host, "privacy") or {};
+       local privacy_lists = privacy_storage:get(session.username) or {};
        local bare_jid = session.username.."@"..session.host;
        local to = stanza.attr.to or bare_jid;
        local from = stanza.attr.from;
-       
+
        local is_to_user = bare_jid == jid_bare(to);
        local is_from_user = bare_jid == jid_bare(from);
-       
+
        --module:log("debug", "stanza: %s, to: %s, from: %s", tostring(stanza.name), tostring(to), tostring(from));
-       
+
        if privacy_lists.lists == nil or
                not (session.activePrivacyList or privacy_lists.default)
        then
@@ -300,8 +300,7 @@ function checkIfNeedToBeBlocked(e, session)
                --module:log("debug", "Not blocking communications between user's resources");
                return; -- from one of a user's resource to another => HANDS OFF!
        end
-       
-       local item;
+
        local listname = session.activePrivacyList;
        if listname == nil then
                listname = privacy_lists.default; -- no active list selected, use default list
@@ -368,6 +367,10 @@ function checkIfNeedToBeBlocked(e, session)
                end
                if apply then
                        if block then
+                               -- drop and not bounce groupchat messages, otherwise users will get kicked
+                               if stanza.attr.type == "groupchat" then
+                                       return true;
+                               end
                                module:log("debug", "stanza blocked: %s, to: %s, from: %s", tostring(stanza.name), tostring(to), tostring(from));
                                if stanza.name == "message" then
                                        origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
@@ -392,7 +395,6 @@ function preCheckIncoming(e)
                end
                if resource == nil then
                        local prio = 0;
-                       local session_;
                        if bare_sessions[node.."@"..host] ~= nil then
                                for resource, session_ in pairs(bare_sessions[node.."@"..host].sessions) do
                                        if session_.priority ~= nil and session_.priority > prio then