aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_invites.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mod_invites.lua')
-rw-r--r--plugins/mod_invites.lua203
1 files changed, 106 insertions, 97 deletions
diff --git a/plugins/mod_invites.lua b/plugins/mod_invites.lua
index 88690f7e..5ee9430a 100644
--- a/plugins/mod_invites.lua
+++ b/plugins/mod_invites.lua
@@ -1,10 +1,12 @@
-local id = require "util.id";
-local it = require "util.iterators";
+local id = require "prosody.util.id";
+local it = require "prosody.util.iterators";
local url = require "socket.url";
-local jid_node = require "util.jid".node;
-local jid_split = require "util.jid".split;
+local jid_node = require "prosody.util.jid".node;
+local jid_split = require "prosody.util.jid".split;
+local argparse = require "prosody.util.argparse";
+local human_io = require "prosody.util.human.io";
-local default_ttl = module:get_option_number("invite_expiry", 86400 * 7);
+local default_ttl = module:get_option_period("invite_expiry", "1 week");
local token_storage;
if prosody.process_type == "prosody" or prosody.shutdown then
@@ -201,53 +203,103 @@ function use(token) --luacheck: ignore 131/use
end
--- shell command
-do
- -- Since the console is global this overwrites the command for
- -- each host it's loaded on, but this should be fine.
-
- local get_module = require "core.modulemanager".get_module;
-
- local console_env = module:shared("/*/admin_shell/env");
-
- -- luacheck: ignore 212/self
- console_env.invite = {};
- function console_env.invite:create_account(user_jid)
- local username, host = jid_split(user_jid);
- local mod_invites, err = get_module(host, "invites");
- if not mod_invites then return nil, err or "mod_invites not loaded on this host"; end
- local invite, err = mod_invites.create_account(username);
+module:add_item("shell-command", {
+ section = "invite";
+ section_desc = "Create and manage invitations";
+ name = "create_account";
+ desc = "Create an invitation to make an account on this server with the specified JID (supply only a hostname to allow any username)";
+ args = { { name = "user_jid", type = "string" } };
+ host_selector = "user_jid";
+
+ handler = function (self, user_jid) --luacheck: ignore 212/self
+ local username = jid_split(user_jid);
+ local invite, err = create_account(username);
if not invite then return nil, err; end
return true, invite.landing_page or invite.uri;
- end
-
- function console_env.invite:create_contact(user_jid, allow_registration)
- local username, host = jid_split(user_jid);
- local mod_invites, err = get_module(host, "invites");
- if not mod_invites then return nil, err or "mod_invites not loaded on this host"; end
- local invite, err = mod_invites.create_contact(username, allow_registration);
+ end;
+});
+
+module:add_item("shell-command", {
+ section = "invite";
+ section_desc = "Create and manage invitations";
+ name = "create_contact";
+ desc = "Create an invitation to become contacts with the specified user";
+ args = { { name = "user_jid", type = "string" }, { name = "allow_registration" } };
+ host_selector = "user_jid";
+
+ handler = function (self, user_jid, allow_registration) --luacheck: ignore 212/self
+ local username = jid_split(user_jid);
+ local invite, err = create_contact(username, allow_registration);
if not invite then return nil, err; end
return true, invite.landing_page or invite.uri;
- end
-end
+ end;
+});
+
+local subcommands = {};
--- prosodyctl command
function module.command(arg)
- if #arg < 2 or arg[1] ~= "generate" then
+ local opts = argparse.parse(arg, { short_params = { h = "help"; ["?"] = "help" } });
+ local cmd = table.remove(arg, 1); -- pop command
+ if opts.help or not cmd or not subcommands[cmd] then
print("usage: prosodyctl mod_"..module.name.." generate example.com");
return 2;
end
- table.remove(arg, 1); -- pop command
+ return subcommands[cmd](arg);
+end
- local sm = require "core.storagemanager";
- local mm = require "core.modulemanager";
+function subcommands.generate(arg)
+ local function help(short)
+ print("usage: prosodyctl mod_" .. module.name .. " generate DOMAIN --reset USERNAME")
+ print("usage: prosodyctl mod_" .. module.name .. " generate DOMAIN [--admin] [--role ROLE] [--group GROUPID]...")
+ if short then return 2 end
+ print()
+ print("This command has two modes: password reset and new account.")
+ print("If --reset is given, the command operates in password reset mode and in new account mode otherwise.")
+ print()
+ print("required arguments in password reset mode:")
+ print()
+ print(" --reset USERNAME Generate a password reset link for the given USERNAME.")
+ print()
+ print("optional arguments in new account mode:")
+ print()
+ print(" --admin Make the new user privileged")
+ print(" Equivalent to --role prosody:admin")
+ print(" --role ROLE Grant the given ROLE to the new user")
+ print(" --group GROUPID Add the user to the group with the given ID")
+ print(" Can be specified multiple times")
+ print(" --expires-after T Time until the invite expires (e.g. '1 week')")
+ print()
+ print("--group can be specified multiple times; the user will be added to all groups.")
+ print()
+ print("--reset and the other options cannot be mixed.")
+ return 2
+ end
- local host = arg[1];
- assert(prosody.hosts[host], "Host "..tostring(host).." does not exist");
+ local earlyopts = argparse.parse(arg, { short_params = { h = "help"; ["?"] = "help" } });
+ if earlyopts.help or not earlyopts[1] then
+ return help();
+ end
+
+ local sm = require "prosody.core.storagemanager";
+ local mm = require "prosody.core.modulemanager";
+
+ local host = table.remove(arg, 1); -- pop host
+ if not host then return help(true) end
sm.initialize_host(host);
- table.remove(arg, 1); -- pop host
module.host = host; --luacheck: ignore 122/module
token_storage = module:open_store("invite_token", "map");
+ local opts = argparse.parse(arg, {
+ short_params = { h = "help"; ["?"] = "help"; g = "group" };
+ value_params = { group = true; reset = true; role = true };
+ array_params = { group = true; role = true };
+ });
+
+ if opts.help then
+ return help();
+ end
+
-- Load mod_invites
local invites = module:depends("invites");
-- Optional community module that if used, needs to be loaded here
@@ -257,71 +309,28 @@ function module.command(arg)
end
local allow_reset;
- local roles;
- local groups = {};
-
- while #arg > 0 do
- local value = arg[1];
- table.remove(arg, 1);
- if value == "--help" then
- print("usage: prosodyctl mod_"..module.name.." generate DOMAIN --reset USERNAME")
- print("usage: prosodyctl mod_"..module.name.." generate DOMAIN [--admin] [--role ROLE] [--group GROUPID]...")
- print()
- print("This command has two modes: password reset and new account.")
- print("If --reset is given, the command operates in password reset mode and in new account mode otherwise.")
- print()
- print("required arguments in password reset mode:")
- print()
- print(" --reset USERNAME Generate a password reset link for the given USERNAME.")
- print()
- print("optional arguments in new account mode:")
- print()
- print(" --admin Make the new user privileged")
- print(" Equivalent to --role prosody:admin")
- print(" --role ROLE Grant the given ROLE to the new user")
- print(" --group GROUPID Add the user to the group with the given ID")
- print(" Can be specified multiple times")
- print()
- print("--role and --admin override each other; the last one wins")
- print("--group can be specified multiple times; the user will be added to all groups.")
- print()
- print("--reset and the other options cannot be mixed.")
- return 2
- elseif value == "--reset" then
- local nodeprep = require "util.encodings".stringprep.nodeprep;
- local username = nodeprep(arg[1])
- table.remove(arg, 1);
- if not username then
- print("Please supply a valid username to generate a reset link for");
- return 2;
- end
- allow_reset = username;
- elseif value == "--admin" then
- roles = { ["prosody:admin"] = true };
- elseif value == "--role" then
- local rolename = arg[1];
- if not rolename then
- print("Please supply a role name");
- return 2;
- end
- roles = { [rolename] = true };
- table.remove(arg, 1);
- elseif value == "--group" or value == "-g" then
- local groupid = arg[1];
- if not groupid then
- print("Please supply a group ID")
- return 2;
- end
- table.insert(groups, groupid);
- table.remove(arg, 1);
- else
- print("unexpected argument: "..value)
+
+ if opts.reset then
+ local nodeprep = require "prosody.util.encodings".stringprep.nodeprep;
+ local username = nodeprep(opts.reset)
+ if not username then
+ print("Please supply a valid username to generate a reset link for");
+ return 2;
end
+ allow_reset = username;
+ end
+
+ local roles = opts.role or {};
+ local groups = opts.groups or {};
+
+ if opts.admin then
+ -- Insert it first since we don't get order out of argparse
+ table.insert(roles, 1, "prosody:admin");
end
local invite;
if allow_reset then
- if roles then
+ if roles[1] then
print("--role/--admin and --reset are mutually exclusive")
return 2;
end
@@ -333,7 +342,7 @@ function module.command(arg)
invite = assert(invites.create_account(nil, {
roles = roles,
groups = groups
- }));
+ }, opts.expires_after and human_io.parse_duration(opts.expires_after)));
end
print(invite.landing_page or invite.uri);