Comparison

plugins/mod_account_activity.lua @ 13670:cb44753db100

Merge 13.0->trunk
author Matthew Wild <mwild1@gmail.com>
date Wed, 12 Feb 2025 17:16:09 +0000
parent 13668:6be7de547a25
child 13682:0055c177a54c
comparison
equal deleted inserted replaced
13666:528fcef83684 13670:cb44753db100
1 local jid = require "util.jid"; 1 local jid = require "prosody.util.jid";
2 local time = os.time; 2 local time = os.time;
3 3
4 local store = module:open_store(nil, "keyval+"); 4 local store = module:open_store(nil, "keyval+");
5 5
6 module:hook("authentication-success", function(event) 6 module:hook("authentication-success", function(event)
45 return true, ("%s (%s)"):format(os.date("%Y-%m-%d %H:%M:%S", last_timestamp), (is_online and "online" or "offline")); 45 return true, ("%s (%s)"):format(os.date("%Y-%m-%d %H:%M:%S", last_timestamp), (is_online and "online" or "offline"));
46 end; 46 end;
47 }); 47 });
48 48
49 module:add_item("shell-command", { 49 module:add_item("shell-command", {
50 section = "user";
51 section_desc = "View user activity data";
52 name = "list_inactive";
53 desc = "List inactive user accounts";
54 args = {
55 { name = "host"; type = "string" };
56 { name = "duration"; type = "string" };
57 };
58 host_selector = "host";
59 handler = function(self, host, duration) --luacheck: ignore 212/self
60 local um = require "prosody.core.usermanager";
61 local duration_sec = require "prosody.util.human.io".parse_duration(duration);
62 if not duration_sec then
63 return false, ("Invalid duration %q - try something like \"30d\""):format(duration);
64 end
65
66 local now = os.time();
67 local n_inactive, n_unknown = 0, 0;
68
69 for username in um.users(host) do
70 local last_active = store:get_key(username, "timestamp");
71 if not last_active then
72 local created_at = um.get_account_info(username, host).created;
73 if created_at and (now - created_at) > duration_sec then
74 self.session.print(username, "");
75 n_inactive = n_inactive + 1;
76 elseif not created_at then
77 n_unknown = n_unknown + 1;
78 end
79 elseif (now - last_active) > duration_sec then
80 self.session.print(username, os.date("%Y-%m-%dT%T", last_active));
81 n_inactive = n_inactive + 1;
82 end
83 end
84
85 if n_unknown > 0 then
86 return true, ("%d accounts inactive since %s (%d unknown)"):format(n_inactive, os.date("%Y-%m-%dT%T", now - duration_sec), n_unknown);
87 end
88 return true, ("%d accounts inactive since %s"):format(n_inactive, os.date("%Y-%m-%dT%T", now - duration_sec));
89 end;
90 });
91
92 module:add_item("shell-command", {
50 section = "migrate"; 93 section = "migrate";
51 section_desc = "Perform data migrations"; 94 section_desc = "Perform data migrations";
52 name = "account_activity_lastlog2"; 95 name = "account_activity_lastlog2";
53 desc = "Migrate account activity information from mod_lastlog2"; 96 desc = "Migrate account activity information from mod_lastlog2";
54 args = { { name = "host"; type = "string" } }; 97 args = { { name = "host"; type = "string" } };
55 host_selector = "host"; 98 host_selector = "host";
56 handler = function(self, host) --luacheck: ignore 212/host 99 handler = function(self, host) --luacheck: ignore 212/host
57 local lastlog2 = module:open_store("lastlog2", "keyval+"); 100 local lastlog2 = module:open_store("lastlog2", "keyval+");
58 local n_updated, n_errors, n_skipped = 0, 0, 0; 101 local n_updated, n_errors, n_skipped = 0, 0, 0;
59 102
60 local async = require "util.async"; 103 local async = require "prosody.util.async";
61 104
62 local p = require "util.promise".new(function (resolve) 105 local p = require "prosody.util.promise".new(function (resolve)
63 local async_runner = async.runner(function () 106 local async_runner = async.runner(function ()
64 local n = 0; 107 local n = 0;
65 for username in lastlog2:items() do 108 for username in lastlog2:items() do
66 n = n + 1; 109 n = n + 1;
67 if n % 100 == 0 then 110 if n % 100 == 0 then