view mod_register_redirect/mod_register_redirect.lua @ 5668:ecfd7aece33b

mod_measure_modules: Report module statuses via OpenMetrics Someone in the chat asked about a health check endpoint, which reminded me of mod_http_status, which provides access to module statuses with full details. After that, this idea came about, which seems natural. As noted in the README, it could be used to monitor that critical modules are in fact loaded correctly. As more modules use the status API, the more useful this module and mod_http_status becomes.
author Kim Alvefur <zash@zash.se>
date Fri, 06 Oct 2023 18:34:39 +0200
parents 2023cba9ead0
children
line wrap: on
line source

-- (C) 2010-2011 Marco Cirillo (LW.Org)
-- (C) 2011 Kim Alvefur
--
-- Registration Redirect module for Prosody
--
-- Redirects IP addresses not in the whitelist to a web page or another method to complete the registration.

local st = require "util.stanza"
local cman = require "core.configmanager"

local ip_wl = module:get_option_set("registration_whitelist", { "127.0.0.1", "::1" })
local url = module:get_option_string("registration_url", nil)
local inst_text = module:get_option_string("registration_text", nil)
local oob = module:get_option_boolean("registration_oob", true)
local admins_g = cman.get("*", "core", "admins")
local admins_l = cman.get(module:get_host(), "core", "admins")
local no_wl = module:get_option_boolean("no_registration_whitelist", false)

if type(admins_g) ~= "table" then admins_g = nil end
if type(admins_l) ~= "table" then admins_l = nil end

function reg_redirect(event)
	local stanza, origin = event.stanza, event.origin

	if not no_wl and ip_wl:contains(origin.ip) then return; end

	-- perform checks to set default responses and sanity checks.
	if not inst_text then
		if url and oob then
			if url:match("^%w+[:].*$") then
				if url:match("^(%w+)[:].*$") == "http" or url:match("^(%w+)[:].*$") == "https" then
					inst_text = "Please visit "..url.." to register an account on this server."
				elseif url:match("^(%w+)[:].*$") == "mailto" then
					inst_text = "Please send an e-mail at "..url:match("^%w+[:](.*)$").." to register an account on this server."
				elseif url:match("^(%w+)[:].*$") == "xmpp" then
					inst_text = "Please contact "..module:get_host().."'s server administrator via xmpp to register an account on this server at: "..url:match("^%w+[:](.*)$")
				else
					module:log("error", "This module supports only http/https, mailto or xmpp as URL formats.")
					module:log("error", "If you want to use personalized instructions without an Out-Of-Band method,")
					module:log("error", "specify: register_oob = false; -- in your configuration along your banner string (register_text).")
					return origin.send(st.error_reply(stanza, "wait", "internal-server-error")) -- bouncing request.
				end
			else
				module:log("error", "Please check your configuration, the URL you specified is invalid")
				return origin.send(st.error_reply(stanza, "wait", "internal-server-error")) -- bouncing request.
			end
		else
			if admins_l then
				local ajid; for _,v in ipairs(admins_l) do ajid = v ; break end
				inst_text = "Please contact "..module:get_host().."'s server administrator via xmpp to register an account on this server at: "..ajid
			else
				if admins_g then
					local ajid; for _,v in ipairs(admins_g) do ajid = v ; break end
					inst_text = "Please contact "..module:get_host().."'s server administrator via xmpp to register an account on this server at: "..ajid
				else
					module:log("error", "Please be sure to, _at the very least_, configure one server administrator either global or hostwise...")
					module:log("error", "if you want to use this module, or read it's configuration wiki at: https://modules.prosody.im/mod_register_redirect.html")
					return origin.send(st.error_reply(stanza, "wait", "internal-server-error")) -- bouncing request.
				end
			end
		end
	elseif inst_text and url and oob then
		if not url:match("^%w+[:].*$") then
			module:log("error", "Please check your configuration, the URL specified is not valid.")
			return origin.send(st.error_reply(stanza, "wait", "internal-server-error")) -- bouncing request.
		end
	end

	-- Prepare replies.
	local reply = st.reply(event.stanza)
	if oob then
		reply:query("jabber:iq:register")
			:tag("instructions"):text(inst_text):up()
			:tag("x", {xmlns = "jabber:x:oob"})
				:tag("url"):text(url);
	else
		reply:query("jabber:iq:register")
			:tag("instructions"):text(inst_text):up()
	end

	if stanza.attr.type == "get" then
		return origin.send(reply)
	else
		return origin.send(st.error_reply(stanza, "cancel", "not-authorized"))
	end
end

module:hook("stanza/iq/jabber:iq:register:query", reg_redirect, 10)