comparison mod_groups_internal/mod_groups_internal.lua @ 4383:1e7406b85add

mod_groups_internal: new module for grouping beyond mod_adhoc_groups
author Matthew Wild <mwild1@gmail.com>
date Mon, 25 Jan 2021 18:43:20 +0100
parents
children dfb34cc97028
comparison
equal deleted inserted replaced
4382:0d6b69777bc1 4383:1e7406b85add
1 local rostermanager = require"core.rostermanager";
2 local id = require "util.id";
3 local jid = require "util.jid";
4 local jid_join = jid.join;
5 local host = module.host;
6
7 local group_info_store = module:open_store("group_info");
8 local group_members_store = module:open_store("groups");
9 local group_memberships = module:open_store("groups", "map");
10
11 local is_contact_subscribed = rostermanager.is_contact_subscribed;
12
13 -- Make a *one-way* subscription. User will see when contact is online,
14 -- contact will not see when user is online.
15 local function subscribe(user, user_jid, contact, contact_jid)
16 -- Update user's roster to say subscription request is pending...
17 rostermanager.set_contact_pending_out(user, host, contact_jid);
18 -- Update contact's roster to say subscription request is pending...
19 rostermanager.set_contact_pending_in(contact, host, user_jid);
20 -- Update contact's roster to say subscription request approved...
21 rostermanager.subscribed(contact, host, user_jid);
22 -- Update user's roster to say subscription request approved...
23 rostermanager.process_inbound_subscription_approval(user, host, contact_jid);
24
25 -- Push updates to both rosters
26 rostermanager.roster_push(user, host, contact_jid);
27 rostermanager.roster_push(contact, host, user_jid);
28 end
29
30 local function user_groups(username)
31 return pairs(group_memberships:get_all(username) or {});
32 end
33
34 local function do_single_group_subscriptions(username, group_id)
35 local members = group_members_store:get(group_id);
36 if not members then return; end
37 local user_jid = jid_join(username, host);
38 for membername in pairs(members) do
39 if membername ~= username then
40 local member_jid = jid_join(membername, host);
41 if not is_contact_subscribed(username, host, member_jid) then
42 module:log("debug", "[group %s] Subscribing %s to %s", member_jid, user_jid);
43 subscribe(membername, member_jid, username, user_jid);
44 end
45 if not is_contact_subscribed(membername, host, user_jid) then
46 module:log("debug", "[group %s] Subscribing %s to %s", user_jid, member_jid);
47 subscribe(username, user_jid, membername, member_jid);
48 end
49 end
50 end
51 end
52
53 local function do_all_group_subscriptions_by_user(username)
54 for group_id in user_groups(username) do
55 do_single_group_subscriptions(username, group_id);
56 end
57 end
58
59 local function do_all_group_subscriptions_by_group(group_id)
60 for membername in pairs(get_members(group_id)) do
61 do_single_group_subscriptions(membername, group_id);
62 end
63 end
64
65 module:hook("resource-bind", function(event)
66 module:log("debug", "Updating group subscriptions...");
67 do_all_group_subscriptions_by_user(event.session.username);
68 end);
69
70 local function get_group_muc(group_id)
71 -- Group MUC
72 local group_info = group_info_store:get(group_id);
73 if group_info and group_info.muc_jid then
74 local muc_jid = group_info.muc_jid;
75 local mod_muc = hosts[jid.host(muc_jid)].modules.muc;
76 if mod_muc then
77 local room = mod_muc.get_room_from_jid(muc_jid);
78 if not room then
79 room = mod_muc.create_room(muc_jid);
80 end
81 return room;
82 end
83 end
84 end
85
86 --luacheck: ignore 131
87 function create(group_info, create_muc)
88 if not group_info.name then
89 return nil, "group-name-required";
90 end
91 local group_id = id.short();
92
93 if create_muc then
94 return nil, "not-implemented";
95 end
96
97 local ok = group_info_store:set(group_id, {
98 name = group_info.name;
99 });
100 if not ok then
101 return nil, "internal-server-error";
102 end
103 return group_id;
104 end
105
106 function get_info(group_id)
107 return group_info_store:get(group_id);
108 end
109
110 function set_info(group_id, info)
111 if not info then
112 return nil, "bad-request"
113 end
114
115 if not info.name or #info.name == 0 then
116 return nil, "bad-request"
117 end
118
119 local ok = group_info_store:set(group_id, info);
120 if not ok then
121 return nil, "internal-server-error";
122 end
123 return true
124 end
125
126 function get_members(group_id)
127 return group_members_store:get(group_id);
128 end
129
130 function exists(group_id)
131 return not not get_info(group_id);
132 end
133
134 function get_user_groups(username)
135 local groups = {};
136 do
137 local group_set = group_memberships:get_all(username);
138 if group_set then
139 for group_id in pairs(group_set) do
140 table.insert(groups, group_id);
141 end
142 end
143 end
144 return groups;
145 end
146
147 function delete(group_id)
148 if group_members_store:set(group_id, nil) then
149 return group_info_store:set(group_id, nil);
150 end
151 return nil, "internal-server-error";
152 end
153
154 function add_member(group_id, username)
155 local group_info = group_info_store:get(group_id);
156 if not group_info then
157 return nil, "group-not-found";
158 end
159 if not group_memberships:set(group_id, username, {}) then
160 return nil, "internal-server-error";
161 end
162 do_all_group_subscriptions_by_group(group_id);
163 return true;
164 end
165
166 function remove_member(group_id, username)
167 local group_info = group_info_store:get(group_id);
168 if not group_info then
169 return nil, "group-not-found";
170 end
171 if not group_memberships:set(group_id, username, nil) then
172 return nil, "internal-server-error";
173 end
174 return true;
175 end
176
177 -- Returns iterator over group ids
178 function groups()
179 return group_info_store:users();
180 end