xmlhandlers: Reject XML comments, processing instructions and (if supported by LuaExp...
[prosody.git] / plugins / mod_groups.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9
10 local groups;
11 local members;
12
13 local groups_file;
14
15 local jid, datamanager = require "util.jid", require "util.datamanager";
16 local jid_bare, jid_prep = jid.bare, jid.prep;
17
18 local module_host = module:get_host();
19
20 function inject_roster_contacts(username, host, roster)
21         module:log("warn", "Injecting group members to roster");
22         local bare_jid = username.."@"..host;
23         if not members[bare_jid] and not members[false] then return; end -- Not a member of any groups
24         
25         local function import_jids_to_roster(group_name)
26                 for jid in pairs(groups[group_name]) do
27                         -- Add them to roster
28                         --module:log("debug", "processing jid %s in group %s", tostring(jid), tostring(group_name));
29                         if jid ~= bare_jid then
30                                 if not roster[jid] then roster[jid] = {}; end
31                                 roster[jid].subscription = "both";
32                                 if not roster[jid].groups then
33                                         roster[jid].groups = { [group_name] = true };
34                                 end
35                                 roster[jid].groups[group_name] = true;
36                                 roster[jid].persist = false;
37                         end
38                 end
39         end
40
41         -- Find groups this JID is a member of
42         if members[bare_jid] then
43                 for _, group_name in ipairs(members[bare_jid]) do
44                         module:log("debug", "Importing group %s", group_name);
45                         import_jids_to_roster(group_name);
46                 end
47         end
48         
49         -- Import public groups
50         if members[false] then
51                 for _, group_name in ipairs(members[false]) do
52                         module:log("debug", "Importing group %s", group_name);
53                         import_jids_to_roster(group_name);
54                 end
55         end
56         
57         if roster[false] then
58                 roster[false].version = true;
59         end
60 end
61
62 function remove_virtual_contacts(username, host, datastore, data)
63         if host == module_host and datastore == "roster" then
64                 local new_roster = {};
65                 for jid, contact in pairs(data) do
66                         if contact.persist ~= false then
67                                 new_roster[jid] = contact;
68                         end
69                 end
70                 new_roster[false].version = nil; -- Version is void
71                 return username, host, datastore, new_roster;
72         end
73
74         return username, host, datastore, data;
75 end
76
77 function module.load()
78         groups_file = config.get(module:get_host(), "core", "groups_file");
79         if not groups_file then return; end
80         
81         module:hook("roster-load", inject_roster_contacts);
82         datamanager.add_callback(remove_virtual_contacts);
83         
84         groups = { default = {} };
85         members = { };
86         local curr_group = "default";
87         for line in io.lines(groups_file) do
88                 if line:match("^%s*%[.-%]%s*$") then
89                         curr_group = line:match("^%s*%[(.-)%]%s*$");
90                         if curr_group:match("^%+") then
91                                 curr_group = curr_group:gsub("^%+", "");
92                                 if not members[false] then
93                                         members[false] = {};
94                                 end
95                                 members[false][#members[false]+1] = curr_group; -- Is a public group
96                         end
97                         module:log("debug", "New group: %s", tostring(curr_group));
98                         groups[curr_group] = groups[curr_group] or {};
99                 else
100                         -- Add JID
101                         local jid = jid_prep(line:match("%S+"));
102                         if jid then
103                                 module:log("debug", "New member of %s: %s", tostring(curr_group), tostring(jid));
104                                 groups[curr_group][jid] = true;
105                                 members[jid] = members[jid] or {};
106                                 members[jid][#members[jid]+1] = curr_group;
107                         end
108                 end
109         end
110         module:log("info", "Groups loaded successfully");
111 end
112
113 function module.unload()
114         datamanager.remove_callback(remove_virtual_contacts);
115 end