Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2019-06-18 12:09:35 +0300
committerBadlop <badlop@process-one.net>2019-06-19 10:30:53 +0300
commitfb77e2e8c0a63e5ac3a3888dfbde92f1057c3089 (patch)
tree8e26287da0e79e429921fdfcec531a69f3b07b43
parentad98d4a5150dd6c4701c6cdb08c934754f34e477 (diff)
Add support for backwards compatibility in command argument names (#2908)
-rw-r--r--include/ejabberd_commands.hrl1
-rw-r--r--src/ejabberd_commands.erl9
-rw-r--r--src/ejabberd_ctl.erl6
-rw-r--r--src/ejabberd_xmlrpc.erl23
-rw-r--r--src/mod_http_api.erl17
5 files changed, 40 insertions, 16 deletions
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};