Mercurial > prosody-hg
view plugins/mod_groups.lua @ 13920:2169be3581ae 13.0
migrator: Allow migrating between different configs of the same driver
This was notably a problem with SQL since mod_storage_sql is a single
module that connects to different SQL databases. The problem was that
since it was already loaded once, the output configuration was not
applied and it would have migrated to the origin database.
This essentially reloads the module after updating the configuration,
which should work with all storage modules as long as everything they
need are kept in the 'provider' or driver table.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sun, 03 Aug 2025 15:14:20 +0200 |
| parents | 74b9e05af71e |
| children |
line wrap: on
line source
-- Prosody IM -- Copyright (C) 2008-2010 Matthew Wild -- Copyright (C) 2008-2010 Waqas Hussain -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- local groups; local members; local datamanager = require "prosody.util.datamanager"; local jid_prep = require "prosody.util.jid".prep; local module_host = module:get_host(); function inject_roster_contacts(event) local username, host= event.username, event.host; --module:log("debug", "Injecting group members to roster"); local bare_jid = username.."@"..host; if not members[bare_jid] and not members[false] then return; end -- Not a member of any groups local roster = event.roster; local function import_jids_to_roster(group_name) for jid in pairs(groups[group_name]) do -- Add them to roster --module:log("debug", "processing jid %s in group %s", jid, group_name); if jid ~= bare_jid then if not roster[jid] then roster[jid] = {}; end roster[jid].subscription = "both"; if groups[group_name][jid] then roster[jid].name = groups[group_name][jid]; end if not roster[jid].groups then roster[jid].groups = { [group_name] = true }; end roster[jid].groups[group_name] = true; roster[jid].persist = false; end end end -- Find groups this JID is a member of if members[bare_jid] then for _, group_name in ipairs(members[bare_jid]) do --module:log("debug", "Importing group %s", group_name); import_jids_to_roster(group_name); end end -- Import public groups if members[false] then for _, group_name in ipairs(members[false]) do --module:log("debug", "Importing group %s", group_name); import_jids_to_roster(group_name); end end if roster[false] then roster[false].version = true; end end function remove_virtual_contacts(username, host, datastore, data) if host == module_host and datastore == "roster" then local new_roster = {}; for jid, contact in pairs(data) do if contact.persist ~= false then new_roster[jid] = contact; end end if new_roster[false] then new_roster[false].version = nil; -- Version is void end return username, host, datastore, new_roster; end return username, host, datastore, data; end function module.load() local groups_file = module:get_option_path("groups_file", nil, "config"); if not groups_file then return; end module:hook("roster-load", inject_roster_contacts); datamanager.add_callback(remove_virtual_contacts); groups = { default = {} }; members = { }; local curr_group = "default"; for line in io.lines(groups_file) do if line:match("^%s*%[.-%]%s*$") then curr_group = line:match("^%s*%[(.-)%]%s*$"); if curr_group:match("^%+") then curr_group = curr_group:gsub("^%+", ""); if not members[false] then members[false] = {}; end members[false][#members[false]+1] = curr_group; -- Is a public group end module:log("debug", "New group: %s", curr_group); groups[curr_group] = groups[curr_group] or {}; else -- Add JID local entryjid, name = line:match("([^=]*)=?(.*)"); module:log("debug", "entryjid = '%s', name = '%s'", entryjid, name); local jid; jid = jid_prep(entryjid:match("%S+")); if jid then module:log("debug", "New member of %s: %s", curr_group, jid); groups[curr_group][jid] = name or false; members[jid] = members[jid] or {}; members[jid][#members[jid]+1] = curr_group; elseif entryjid:match("%S") then module:log("warn", "Invalid JID: %q", entryjid); end end end module:log("info", "Groups loaded successfully"); end function module.unload() datamanager.remove_callback(remove_virtual_contacts); end -- Public for other modules to access function group_contains(group_name, jid) return groups[group_name][jid]; end
