mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +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 = [] :: [{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()] | '_',
|
||||
|
@ -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().
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
%%-----------------------------
|
||||
|
@ -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};
|
||||
|
Loading…
Reference in New Issue
Block a user