mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Add support for backwards compatibility in command argument names (#2908)
This commit is contained in:
parent
ad98d4a515
commit
fb77e2e8c0
@ -59,6 +59,7 @@
|
|||||||
%% access is: [accessRuleName] or [{Module, AccessOption, DefaultAccessRuleName}]
|
%% access is: [accessRuleName] or [{Module, AccessOption, DefaultAccessRuleName}]
|
||||||
access = [] :: [{atom(),atom(),atom()}|atom()],
|
access = [] :: [{atom(),atom(),atom()}|atom()],
|
||||||
result = {res, rescode} :: rterm() | '_' | '$2',
|
result = {res, rescode} :: rterm() | '_' | '$2',
|
||||||
|
args_rename = [] :: [{atom(),atom()}],
|
||||||
args_desc = none :: none | [string()] | '_',
|
args_desc = none :: none | [string()] | '_',
|
||||||
result_desc = none :: none | string() | '_',
|
result_desc = none :: none | string() | '_',
|
||||||
args_example = none :: none | [any()] | '_',
|
args_example = none :: none | [any()] | '_',
|
||||||
|
@ -353,7 +353,7 @@ list_commands(Version) ->
|
|||||||
args = Args,
|
args = Args,
|
||||||
desc = Desc} <- Commands].
|
desc = Desc} <- Commands].
|
||||||
|
|
||||||
-spec get_command_format(atom()) -> {[aterm()], rterm()}.
|
-spec get_command_format(atom()) -> {[aterm()], [{atom(),atom()}], rterm()}.
|
||||||
|
|
||||||
%% @doc Get the format of arguments and result of a command.
|
%% @doc Get the format of arguments and result of a command.
|
||||||
get_command_format(Name) ->
|
get_command_format(Name) ->
|
||||||
@ -363,19 +363,20 @@ get_command_format(Name, Version) when is_integer(Version) ->
|
|||||||
get_command_format(Name, Auth) ->
|
get_command_format(Name, Auth) ->
|
||||||
get_command_format(Name, Auth, ?DEFAULT_VERSION).
|
get_command_format(Name, Auth, ?DEFAULT_VERSION).
|
||||||
|
|
||||||
-spec get_command_format(atom(), noauth | admin | auth(), integer()) -> {[aterm()], rterm()}.
|
-spec get_command_format(atom(), noauth | admin | auth(), integer()) -> {[aterm()], [{atom(),atom()}], rterm()}.
|
||||||
get_command_format(Name, Auth, Version) ->
|
get_command_format(Name, Auth, Version) ->
|
||||||
Admin = is_admin(Name, Auth, #{}),
|
Admin = is_admin(Name, Auth, #{}),
|
||||||
#ejabberd_commands{args = Args,
|
#ejabberd_commands{args = Args,
|
||||||
result = Result,
|
result = Result,
|
||||||
|
args_rename = Rename,
|
||||||
policy = Policy} =
|
policy = Policy} =
|
||||||
get_command_definition(Name, Version),
|
get_command_definition(Name, Version),
|
||||||
case Policy of
|
case Policy of
|
||||||
user when Admin;
|
user when Admin;
|
||||||
Auth == noauth ->
|
Auth == noauth ->
|
||||||
{[{user, binary}, {server, binary} | Args], Result};
|
{[{user, binary}, {server, binary} | Args], Rename, Result};
|
||||||
_ ->
|
_ ->
|
||||||
{Args, Result}
|
{Args, Rename, Result}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec get_command_definition(atom()) -> ejabberd_commands().
|
-spec get_command_definition(atom()) -> ejabberd_commands().
|
||||||
|
@ -340,7 +340,7 @@ call_command([CmdString | Args], Auth, _AccessCommands, Version) ->
|
|||||||
CmdStringU = ejabberd_regexp:greplace(
|
CmdStringU = ejabberd_regexp:greplace(
|
||||||
list_to_binary(CmdString), <<"-">>, <<"_">>),
|
list_to_binary(CmdString), <<"-">>, <<"_">>),
|
||||||
Command = list_to_atom(binary_to_list(CmdStringU)),
|
Command = list_to_atom(binary_to_list(CmdStringU)),
|
||||||
{ArgsFormat, ResultFormat} = ejabberd_commands:get_command_format(Command, Auth, Version),
|
{ArgsFormat, _, ResultFormat} = ejabberd_commands:get_command_format(Command, Auth, Version),
|
||||||
case (catch format_args(Args, ArgsFormat)) of
|
case (catch format_args(Args, ArgsFormat)) of
|
||||||
ArgsFormatted when is_list(ArgsFormatted) ->
|
ArgsFormatted when is_list(ArgsFormatted) ->
|
||||||
CI = case Auth of
|
CI = case Auth of
|
||||||
@ -484,7 +484,7 @@ get_list_commands(Version) ->
|
|||||||
|
|
||||||
%% Return: {string(), [string()], string()}
|
%% Return: {string(), [string()], string()}
|
||||||
tuple_command_help({Name, _Args, Desc}) ->
|
tuple_command_help({Name, _Args, Desc}) ->
|
||||||
{Args, _} = ejabberd_commands:get_command_format(Name, admin),
|
{Args, _, _} = ejabberd_commands:get_command_format(Name, admin),
|
||||||
Arguments = [atom_to_list(ArgN) || {ArgN, _ArgF} <- Args],
|
Arguments = [atom_to_list(ArgN) || {ArgN, _ArgF} <- Args],
|
||||||
Prepend = case is_supported_args(Args) of
|
Prepend = case is_supported_args(Args) of
|
||||||
true -> "";
|
true -> "";
|
||||||
@ -796,7 +796,7 @@ print_usage_command2(Cmd, C, MaxC, ShCode) ->
|
|||||||
NameFmt = [" ", ?B("Command Name"), ": ", Cmd, "\n"],
|
NameFmt = [" ", ?B("Command Name"), ": ", Cmd, "\n"],
|
||||||
|
|
||||||
%% Initial indentation of result is 13 = length(" Arguments: ")
|
%% Initial indentation of result is 13 = length(" Arguments: ")
|
||||||
{ArgsDef, _} = ejabberd_commands:get_command_format(
|
{ArgsDef, _, _} = ejabberd_commands:get_command_format(
|
||||||
C#ejabberd_commands.name, admin),
|
C#ejabberd_commands.name, admin),
|
||||||
Args = [format_usage_ctype(ArgDef, 13) || ArgDef <- ArgsDef],
|
Args = [format_usage_ctype(ArgDef, 13) || ArgDef <- ArgsDef],
|
||||||
ArgsMargin = lists:duplicate(13, $\s),
|
ArgsMargin = lists:duplicate(13, $\s),
|
||||||
|
@ -339,9 +339,9 @@ handler(State, {call, Command, []}) ->
|
|||||||
handler(State, {call, Command, [{struct, []}]});
|
handler(State, {call, Command, [{struct, []}]});
|
||||||
handler(State,
|
handler(State,
|
||||||
{call, Command, [{struct, AttrL}]}) ->
|
{call, Command, [{struct, AttrL}]}) ->
|
||||||
{ArgsF, ResultF} = ejabberd_commands:get_command_format(Command, State#state.auth),
|
{ArgsF, ArgsR, ResultF} = ejabberd_commands:get_command_format(Command, State#state.auth),
|
||||||
try_do_command(State#state.access_commands,
|
try_do_command(State#state.access_commands,
|
||||||
State#state.auth, Command, AttrL, ArgsF, ResultF);
|
State#state.auth, Command, AttrL, ArgsF, ArgsR, ResultF);
|
||||||
%% If no other guard matches
|
%% If no other guard matches
|
||||||
handler(_State, Payload) ->
|
handler(_State, Payload) ->
|
||||||
build_fault_response(-112, "Unknown call: ~p",
|
build_fault_response(-112, "Unknown call: ~p",
|
||||||
@ -352,9 +352,9 @@ handler(_State, Payload) ->
|
|||||||
%% -----------------------------
|
%% -----------------------------
|
||||||
|
|
||||||
try_do_command(AccessCommands, Auth, Command, AttrL,
|
try_do_command(AccessCommands, Auth, Command, AttrL,
|
||||||
ArgsF, ResultF) ->
|
ArgsF, ArgsR, ResultF) ->
|
||||||
try do_command(AccessCommands, Auth, Command, AttrL,
|
try do_command(AccessCommands, Auth, Command, AttrL,
|
||||||
ArgsF, ResultF)
|
ArgsF, ArgsR, ResultF)
|
||||||
of
|
of
|
||||||
{command_result, ResultFormatted} ->
|
{command_result, ResultFormatted} ->
|
||||||
{false, {response, [ResultFormatted]}}
|
{false, {response, [ResultFormatted]}}
|
||||||
@ -389,14 +389,25 @@ build_fault_response(Code, ParseString, ParseArgs) ->
|
|||||||
?WARNING_MSG(FaultString, []),
|
?WARNING_MSG(FaultString, []),
|
||||||
{false, {response, {fault, Code, list_to_binary(FaultString)}}}.
|
{false, {response, {fault, Code, list_to_binary(FaultString)}}}.
|
||||||
|
|
||||||
do_command(AccessCommands, Auth, Command, AttrL, ArgsF,
|
do_command(AccessCommands, Auth, Command, AttrL, ArgsF, ArgsR,
|
||||||
ResultF) ->
|
ResultF) ->
|
||||||
ArgsFormatted = format_args(AttrL, ArgsF),
|
ArgsFormatted = format_args(rename_old_args(AttrL, ArgsR), ArgsF),
|
||||||
Auth2 = Auth#{extra_permissions => AccessCommands},
|
Auth2 = Auth#{extra_permissions => AccessCommands},
|
||||||
Result = ejabberd_commands:execute_command2(Command, ArgsFormatted, Auth2),
|
Result = ejabberd_commands:execute_command2(Command, ArgsFormatted, Auth2),
|
||||||
ResultFormatted = format_result(Result, ResultF),
|
ResultFormatted = format_result(Result, ResultF),
|
||||||
{command_result, ResultFormatted}.
|
{command_result, ResultFormatted}.
|
||||||
|
|
||||||
|
rename_old_args(Args, []) ->
|
||||||
|
Args;
|
||||||
|
rename_old_args(Args, [{OldName, NewName} | ArgsR]) ->
|
||||||
|
Args2 = case lists:keytake(OldName, 1, Args) of
|
||||||
|
{value, {OldName, Value}, ArgsTail} ->
|
||||||
|
[{NewName, Value} | ArgsTail];
|
||||||
|
false ->
|
||||||
|
Args
|
||||||
|
end,
|
||||||
|
rename_old_args(Args2, ArgsR).
|
||||||
|
|
||||||
%%-----------------------------
|
%%-----------------------------
|
||||||
%% Format arguments
|
%% Format arguments
|
||||||
%%-----------------------------
|
%%-----------------------------
|
||||||
|
@ -304,8 +304,8 @@ handle(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
handle2(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) ->
|
handle2(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) ->
|
||||||
{ArgsF, _ResultF} = ejabberd_commands:get_command_format(Call, Auth, Version),
|
{ArgsF, ArgsR, _ResultF} = ejabberd_commands:get_command_format(Call, Auth, Version),
|
||||||
ArgsFormatted = format_args(Call, Args, ArgsF),
|
ArgsFormatted = format_args(Call, rename_old_args(Args, ArgsR), ArgsF),
|
||||||
case ejabberd_commands:execute_command2(Call, ArgsFormatted, Auth, Version) of
|
case ejabberd_commands:execute_command2(Call, ArgsFormatted, Auth, Version) of
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
throw(Error);
|
throw(Error);
|
||||||
@ -313,6 +313,17 @@ handle2(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) ->
|
|||||||
format_command_result(Call, Auth, Res, Version)
|
format_command_result(Call, Auth, Res, Version)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
rename_old_args(Args, []) ->
|
||||||
|
Args;
|
||||||
|
rename_old_args(Args, [{OldName, NewName} | ArgsR]) ->
|
||||||
|
Args2 = case lists:keytake(OldName, 1, Args) of
|
||||||
|
{value, {OldName, Value}, ArgsTail} ->
|
||||||
|
[{NewName, Value} | ArgsTail];
|
||||||
|
false ->
|
||||||
|
Args
|
||||||
|
end,
|
||||||
|
rename_old_args(Args2, ArgsR).
|
||||||
|
|
||||||
get_elem_delete(Call, A, L, F) ->
|
get_elem_delete(Call, A, L, F) ->
|
||||||
case proplists:get_all_values(A, L) of
|
case proplists:get_all_values(A, L) of
|
||||||
[Value] -> {Value, proplists:delete(A, L)};
|
[Value] -> {Value, proplists:delete(A, L)};
|
||||||
@ -422,7 +433,7 @@ process_unicode_codepoints(Str) ->
|
|||||||
%% ----------------
|
%% ----------------
|
||||||
|
|
||||||
format_command_result(Cmd, Auth, Result, Version) ->
|
format_command_result(Cmd, Auth, Result, Version) ->
|
||||||
{_, ResultFormat} = ejabberd_commands:get_command_format(Cmd, Auth, Version),
|
{_, _, ResultFormat} = ejabberd_commands:get_command_format(Cmd, Auth, Version),
|
||||||
case {ResultFormat, Result} of
|
case {ResultFormat, Result} of
|
||||||
{{_, rescode}, V} when V == true; V == ok ->
|
{{_, rescode}, V} when V == true; V == ok ->
|
||||||
{200, 0};
|
{200, 0};
|
||||||
|
Loading…
Reference in New Issue
Block a user