captcha_url option now accepts 'auto' value, and it's the default

This commit is contained in:
Badlop 2023-02-01 11:52:47 +01:00
parent 6c620f6f43
commit c4a2f8d64f
4 changed files with 69 additions and 8 deletions

View File

@ -441,18 +441,37 @@ do_create_image(Key, FileName) when is_binary(FileName) ->
get_prog_name() ->
case ejabberd_option:captcha_cmd() of
undefined ->
?DEBUG("The option captcha_cmd is not configured, "
?WARNING_MSG("The option captcha_cmd is not configured, "
"but some module wants to use the CAPTCHA "
"feature.",
[]),
false;
FileName ->
maybe_warning_norequesthandler(),
FileName
end.
maybe_warning_norequesthandler() ->
Host = hd(ejabberd_option:hosts()),
URL = get_auto_url(any, ?MODULE, Host),
case URL of
undefined ->
?WARNING_MSG("The option captcha_cmd is configured, "
"but there is NO request_handler in listen option "
"configured with ejabberd_captcha. Please check "
"https://docs.ejabberd.im/admin/configuration/basic/#captcha",
[]);
_ ->
ok
end.
-spec get_url(binary()) -> binary().
get_url(Str) ->
case ejabberd_option:captcha_url() of
auto ->
Host = ejabberd_config:get_myname(),
URL = get_auto_url(any, ?MODULE, Host),
<<URL/binary, $/, Str/binary>>;
undefined ->
URL = parse_captcha_host(),
<<URL/binary, "/captcha/", Str/binary>>;
@ -477,6 +496,40 @@ parse_captcha_host() ->
<<"http://", (ejabberd_config:get_myname())/binary>>
end.
get_auto_url(Tls, Module, Host) ->
case find_handler_port_path(Tls, Module) of
[] -> undefined;
TPPs ->
{ThisTls, Port, Path} = case lists:keyfind(true, 1, TPPs) of
false ->
lists:keyfind(false, 1, TPPs);
TPP ->
TPP
end,
Protocol = case ThisTls of
false -> <<"http">>;
true -> <<"https">>
end,
<<Protocol/binary,
"://", Host/binary, ":",
(integer_to_binary(Port))/binary,
"/",
(str:join(Path, <<"/">>))/binary>>
end.
find_handler_port_path(Tls, Module) ->
lists:filtermap(
fun({{Port, _, _},
ejabberd_http,
#{tls := ThisTls, request_handlers := Handlers}})
when (Tls == any) or (Tls == ThisTls) ->
case lists:keyfind(Module, 2, Handlers) of
false -> false;
{Path, Module} -> {true, {ThisTls, Port, Path}}
end;
(_) -> false
end, ets:tab2list(ejabberd_listener)).
get_transfer_protocol(PortString) ->
PortNumber = binary_to_integer(PortString),
PortListeners = get_port_listeners(PortNumber),

View File

@ -329,7 +329,7 @@ captcha_host() ->
captcha_limit() ->
ejabberd_config:get_option({captcha_limit, global}).
-spec captcha_url() -> 'undefined' | binary().
-spec captcha_url() -> 'auto' | 'undefined' | binary().
captcha_url() ->
ejabberd_config:get_option({captcha_url, global}).

View File

@ -123,7 +123,9 @@ opt_type(captcha_host) ->
opt_type(captcha_limit) ->
econf:pos_int(infinity);
opt_type(captcha_url) ->
econf:url();
econf:either(
econf:url(),
econf:enum([auto, undefined]));
opt_type(certfiles) ->
econf:list(econf:binary());
opt_type(cluster_backend) ->
@ -546,7 +548,7 @@ options() ->
{captcha_cmd, undefined},
{captcha_host, <<"">>},
{captcha_limit, infinity},
{captcha_url, undefined},
{captcha_url, auto},
{certfiles, undefined},
{cluster_backend, mnesia},
{cluster_nodes, []},

View File

@ -458,8 +458,8 @@ doc() ->
note => "improved in 23.01",
desc =>
?T("Full path to a script that generates http://../basic/#captcha[CAPTCHA] images. "
"@VERSION@ is replaced with ejabberd version number in XX.YY format. "
"@SEMVER@ is replaced with ejabberd version number in semver format "
"'@VERSION@' is replaced with ejabberd version number in 'XX.YY' format. "
"'@SEMVER@' is replaced with ejabberd version number in semver format "
"when compiled with Elixir's mix, or XX.YY format otherwise. "
"Alternatively, it can be the name of a module that implements ejabberd CAPTCHA support. "
"There is no default value: when this option is not "
@ -477,11 +477,17 @@ doc() ->
#{value => "String",
desc => ?T("Deprecated. Use _`captcha_url`_ instead.")}},
{captcha_url,
#{value => ?T("URL"),
#{value => ?T("URL | auto | undefined"),
note => "improved in 23.xx",
desc =>
?T("An URL where http://../basic/#captcha[CAPTCHA] requests should be sent. NOTE: you need "
"to configure 'request_handlers' for 'ejabberd_http' listener "
"as well. There is no default value.")}},
"as well. "
"If set to 'auto', it builds the URL using a 'request_handler' "
"already enabled, with encryption if available. "
"If set to 'undefined', it builds the URL using "
"the deprecated _`captcha_host`_ + /captcha. "
"The default value is 'auto'.")}},
{certfiles,
#{value => "[Path, ...]",
desc =>