aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/features.lua2
-rw-r--r--plugins/mod_admin_shell.lua5
-rw-r--r--plugins/mod_flags.lua157
3 files changed, 163 insertions, 1 deletions
diff --git a/core/features.lua b/core/features.lua
index 99edde51..75cfa1d7 100644
--- a/core/features.lua
+++ b/core/features.lua
@@ -6,6 +6,8 @@ return {
"mod_bookmarks";
-- mod_server_info bundled
"mod_server_info";
+ -- mod_flags bundled
+ "mod_flags";
-- Roles, module.may and per-session authz
"permissions";
-- prosody.* namespace
diff --git a/plugins/mod_admin_shell.lua b/plugins/mod_admin_shell.lua
index 0b8d3c43..c32048c3 100644
--- a/plugins/mod_admin_shell.lua
+++ b/plugins/mod_admin_shell.lua
@@ -2431,12 +2431,15 @@ describe_command [[stats:show(pattern) - Show internal statistics, optionally fi
-- Undocumented currently, you can append :histogram() or :cfgraph() to stats:show() for rendered graphs.
function def_env.stats:show(name_filter)
local statsman = require "prosody.core.statsmanager"
+ local metric_registry = statsman.get_metric_registry();
+ if not metric_registry then
+ return nil, [[Statistics disabled. Try `statistics = "internal"` in the global section of the config file and restart.]];
+ end
local collect = statsman.collect
if collect then
-- force collection if in manual mode
collect()
end
- local metric_registry = statsman.get_metric_registry();
local displayed_stats = new_stats_context(self);
for family_name, metric_family in iterators.sorted_pairs(metric_registry:get_metric_families()) do
if not name_filter or family_name:match(name_filter) then
diff --git a/plugins/mod_flags.lua b/plugins/mod_flags.lua
new file mode 100644
index 00000000..694b608b
--- /dev/null
+++ b/plugins/mod_flags.lua
@@ -0,0 +1,157 @@
+local jid_node = require "prosody.util.jid".node;
+
+local flags = module:open_store("account_flags", "keyval+");
+
+-- API
+
+function add_flag(username, flag, comment)
+ local flag_data = {
+ when = os.time();
+ comment = comment;
+ };
+
+ local ok, err = flags:set_key(username, flag, flag_data);
+ if not ok then
+ return nil, err;
+ end
+
+ module:fire_event("user-flag-added/"..flag, {
+ user = username;
+ flag = flag;
+ data = flag_data;
+ });
+
+ return true;
+end
+
+function remove_flag(username, flag)
+ local ok, err = flags:set_key(username, flag, nil);
+ if not ok then
+ return nil, err;
+ end
+
+ module:fire_event("user-flag-removed/"..flag, {
+ user = username;
+ flag = flag;
+ });
+
+ return true;
+end
+
+function has_flag(username, flag) -- luacheck: ignore 131/has_flag
+ local ok, err = flags:get_key(username, flag);
+ if not ok and err then
+ error("Failed to check flags for user: "..err);
+ end
+ return not not ok;
+end
+
+function get_flag_info(username, flag) -- luacheck: ignore 131/get_flag_info
+ return flags:get_key(username, flag);
+end
+
+-- Shell commands
+
+local function get_username(jid)
+ return (assert(jid_node(jid), "please supply a valid user JID"));
+end
+
+module:add_item("shell-command", {
+ section = "flags";
+ section_desc = "View and manage flags on user accounts";
+ name = "list";
+ desc = "List flags for the given user account";
+ args = {
+ { name = "jid", type = "string" };
+ };
+ host_selector = "jid";
+ handler = function(self, jid) --luacheck: ignore 212/self
+ local c = 0;
+
+ local user_flags, err = flags:get(get_username(jid));
+
+ if not user_flags and err then
+ return false, "Unable to list flags: "..err;
+ end
+
+ if user_flags then
+ local print = self.session.print;
+
+ for flag_name, flag_data in pairs(user_flags) do
+ print(flag_name, os.date("%Y-%m-%d %R", flag_data.when), flag_data.comment);
+ c = c + 1;
+ end
+ end
+
+ return true, ("%d flags listed"):format(c);
+ end;
+});
+
+module:add_item("shell-command", {
+ section = "flags";
+ section_desc = "View and manage flags on user accounts";
+ name = "add";
+ desc = "Add a flag to the given user account, with optional comment";
+ args = {
+ { name = "jid", type = "string" };
+ { name = "flag", type = "string" };
+ { name = "comment", type = "string" };
+ };
+ host_selector = "jid";
+ handler = function(self, jid, flag, comment) --luacheck: ignore 212/self
+ local username = get_username(jid);
+
+ local ok, err = add_flag(username, flag, comment);
+ if not ok then
+ return false, "Failed to add flag: "..err;
+ end
+
+ return true, "Flag added";
+ end;
+});
+
+module:add_item("shell-command", {
+ section = "flags";
+ section_desc = "View and manage flags on user accounts";
+ name = "remove";
+ desc = "Remove a flag from the given user account";
+ args = {
+ { name = "jid", type = "string" };
+ { name = "flag", type = "string" };
+ };
+ host_selector = "jid";
+ handler = function(self, jid, flag) --luacheck: ignore 212/self
+ local username = get_username(jid);
+
+ local ok, err = remove_flag(username, flag);
+ if not ok then
+ return false, "Failed to remove flag: "..err;
+ end
+
+ return true, "Flag removed";
+ end;
+});
+
+module:add_item("shell-command", {
+ section = "flags";
+ section_desc = "View and manage flags on user accounts";
+ name = "find";
+ desc = "Find all user accounts with a given flag on the specified host";
+ args = {
+ { name = "host", type = "string" };
+ { name = "flag", type = "string" };
+ };
+ host_selector = "host";
+ handler = function(self, host, flag) --luacheck: ignore 212/self 212/host
+ local users_with_flag = flags:get_key_from_all(flag);
+
+ local print = self.session.print;
+ local c = 0;
+ for user, flag_data in pairs(users_with_flag) do
+ print(user, os.date("%Y-%m-%d %R", flag_data.when), flag_data.comment);
+ c = c + 1;
+ end
+
+ return true, ("%d accounts listed"):format(c);
+ end;
+});