Mercurial > prosody-modules
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 |
