view mod_adhoc_account_management/mod_adhoc_account_management.lua @ 2494:d300ae5dba87

mod_smacks: Fix some bugs with smacks-ack-delayed event triggering. The old code had several flaws which are addressed here. First of all this fixes the if statement guarding the event generation There where some timing glitches addressed by this commit as well.
author tmolitor <thilo@eightysoft.de>
date Sun, 12 Feb 2017 21:23:22 +0100
parents 1aa48916eb8b
children c6dd65354db0
line wrap: on
line source

local dataforms_new = require "util.dataforms".new;
local usermanager_set_password = require "core.usermanager".set_password;
local usermanager_test_password = require "core.usermanager".test_password;
local jid_split = require"util.jid".split;
local close_others = module:get_option_boolean("close_sessions_on_password_change", true)
local require_confirm = module:get_option_boolean("require_confirm_password", true)
local require_current = module:get_option_boolean("require_current_password", true)

local change_password_layout = {
	title = "Changing Your Password";
	instructions = "Fill out this form to change a your password.";

	{
		-- This is meta
		name = "FORM_TYPE",
		type = "hidden",
		-- Reuses form type from XEP 77
		value = "jabber:iq:register:changepassword",
	};
	{
		name = "password",
		type = "text-private",
		required = true,
		label = "New Password",
	};
};
if require_confirm then
	table.insert(change_password_layout, {
		name = "password-confirm",
		type = "text-private",
		required = true,
		label = "Confirm new password",
	});
end
if require_current then
	table.insert(change_password_layout, 2, {
		name = "password-current",
		type = "text-private",
		required = true,
		label = "Current password",
	});
end
change_password_layout = dataforms_new(change_password_layout);

function change_password_command_handler(self, data, state)
	if not state then -- New session, send the form
		return { status = "executing", actions  = { "complete" }, form = change_password_layout }, true;
	else
		if data.action == "cancel" then
			return { status = "canceled" };
		end

		-- Who are we talking to?
		local username, hostname = jid_split(data.from);
		if not username or hostname ~= module.host then
			return { status = "error", error = { type = "cancel",
				condition = "forbidden", message = "Invalid user or hostname." } };
		end

		-- Extract data from the form
		local fields = change_password_layout:data(data.form);

		-- Validate
		if require_current then
			if not fields["password-current"] or #fields["password-current"] == 0 then
				return { status = "error", error = { type = "modify",
					condition = "bad-request", message = "Please enter your current password" } };
			elseif not usermanager_test_password(username, hostname, fields["password-current"]) then
				return { status = "error", error = { type = "modify",
					condition = "bad-request", message = "Your current password was incorrect" } };
			end
		end

		if require_confirm and fields["password-confirm"] ~= fields["password"] then
			return { status = "error", error = { type = "modify",
				condition = "bad-request", message = "New password didn't match the confirmation" } };
		end

		if not fields.password or #fields.password == 0 then
			return { status = "error", error = { type = "modify",
				condition = "bad-request", message = "Please enter a new password" } };
		end

		-- All is good, so change password.
		module:log("debug", "About to usermanager.set_password(%q, password, %q)", username, hostname);
		local ok, err = usermanager_set_password(username, fields.password, hostname);
		if ok then
			if close_others then
				for _, sess in pairs(hosts[hostname].sessions[username].sessions) do
					if sess.full_jid ~= data.from then
						sess:close{ condition = "reset", text = "Password changed" }
					end
				end
			end
			return { status = "completed", info = "Password successfully changed" };
		else
			module:log("warn", "%s@%s could not change password: %s", username, hostname, tostring(err));
			return { status = "error", error = { type = "cancel",
				condition = "internal-server-error", message = "Could not save new password: "..tostring(err) } };
		end
	end
end

-- Feature requests? What could fit under account management?


local adhoc_new = module:require "adhoc".new;
local adhoc_passwd = adhoc_new("Change Password", "passwd", change_password_command_handler, "user");
module:add_item ("adhoc", adhoc_passwd);