diff --git a/include/ejabberd_commands.hrl b/include/ejabberd_commands.hrl index 1e24cc5d5..e3c498ca6 100644 --- a/include/ejabberd_commands.hrl +++ b/include/ejabberd_commands.hrl @@ -59,6 +59,7 @@ %% access is: [accessRuleName] or [{Module, AccessOption, DefaultAccessRuleName}] access = [] :: [{atom(),atom(),atom()}|atom()], result = {res, rescode} :: rterm() | '_' | '$2', + args_rename = [] :: [{atom(),atom()}], args_desc = none :: none | [string()] | '_', result_desc = none :: none | string() | '_', args_example = none :: none | [any()] | '_', diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl index 921047e9f..d01a88595 100644 --- a/src/ejabberd_commands.erl +++ b/src/ejabberd_commands.erl @@ -353,7 +353,7 @@ list_commands(Version) -> args = Args, 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. 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, ?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) -> Admin = is_admin(Name, Auth, #{}), #ejabberd_commands{args = Args, result = Result, + args_rename = Rename, policy = Policy} = get_command_definition(Name, Version), case Policy of user when Admin; Auth == noauth -> - {[{user, binary}, {server, binary} | Args], Result}; + {[{user, binary}, {server, binary} | Args], Rename, Result}; _ -> - {Args, Result} + {Args, Rename, Result} end. -spec get_command_definition(atom()) -> ejabberd_commands(). diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index e1c294008..989064f66 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -340,7 +340,7 @@ call_command([CmdString | Args], Auth, _AccessCommands, Version) -> CmdStringU = ejabberd_regexp:greplace( list_to_binary(CmdString), <<"-">>, <<"_">>), 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 ArgsFormatted when is_list(ArgsFormatted) -> CI = case Auth of @@ -484,7 +484,7 @@ get_list_commands(Version) -> %% Return: {string(), [string()], string()} 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], Prepend = case is_supported_args(Args) of true -> ""; @@ -796,7 +796,7 @@ print_usage_command2(Cmd, C, MaxC, ShCode) -> NameFmt = [" ", ?B("Command Name"), ": ", Cmd, "\n"], %% 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), Args = [format_usage_ctype(ArgDef, 13) || ArgDef <- ArgsDef], ArgsMargin = lists:duplicate(13, $\s), diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl index 3552e766f..de65355b9 100644 --- a/src/ejabberd_xmlrpc.erl +++ b/src/ejabberd_xmlrpc.erl @@ -339,9 +339,9 @@ handler(State, {call, Command, []}) -> handler(State, {call, Command, [{struct, []}]}); handler(State, {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, - State#state.auth, Command, AttrL, ArgsF, ResultF); + State#state.auth, Command, AttrL, ArgsF, ArgsR, ResultF); %% If no other guard matches handler(_State, Payload) -> build_fault_response(-112, "Unknown call: ~p", @@ -352,9 +352,9 @@ handler(_State, Payload) -> %% ----------------------------- try_do_command(AccessCommands, Auth, Command, AttrL, - ArgsF, ResultF) -> + ArgsF, ArgsR, ResultF) -> try do_command(AccessCommands, Auth, Command, AttrL, - ArgsF, ResultF) + ArgsF, ArgsR, ResultF) of {command_result, ResultFormatted} -> {false, {response, [ResultFormatted]}} @@ -389,14 +389,25 @@ build_fault_response(Code, ParseString, ParseArgs) -> ?WARNING_MSG(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) -> - ArgsFormatted = format_args(AttrL, ArgsF), + ArgsFormatted = format_args(rename_old_args(AttrL, ArgsR), ArgsF), Auth2 = Auth#{extra_permissions => AccessCommands}, Result = ejabberd_commands:execute_command2(Command, ArgsFormatted, Auth2), ResultFormatted = format_result(Result, ResultF), {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 %%----------------------------- diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index 4e2ecdcdd..28228f3e5 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -304,8 +304,8 @@ handle(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) -> end. handle2(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) -> - {ArgsF, _ResultF} = ejabberd_commands:get_command_format(Call, Auth, Version), - ArgsFormatted = format_args(Call, Args, ArgsF), + {ArgsF, ArgsR, _ResultF} = ejabberd_commands:get_command_format(Call, Auth, Version), + ArgsFormatted = format_args(Call, rename_old_args(Args, ArgsR), ArgsF), case ejabberd_commands:execute_command2(Call, ArgsFormatted, Auth, Version) of {error, 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) 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) -> case proplists:get_all_values(A, L) of [Value] -> {Value, proplists:delete(A, L)}; @@ -422,7 +433,7 @@ process_unicode_codepoints(Str) -> %% ---------------- 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 {{_, rescode}, V} when V == true; V == ok -> {200, 0};