]> granicus.if.org Git - ejabberd/commitdiff
Add support for backwards compatibility in command argument names (#2908)
authorBadlop <badlop@process-one.net>
Tue, 18 Jun 2019 09:09:35 +0000 (11:09 +0200)
committerBadlop <badlop@process-one.net>
Wed, 19 Jun 2019 07:30:53 +0000 (09:30 +0200)
include/ejabberd_commands.hrl
src/ejabberd_commands.erl
src/ejabberd_ctl.erl
src/ejabberd_xmlrpc.erl
src/mod_http_api.erl

index 1e24cc5d5423ef9de69581dc2219dcf0764935ee..e3c498ca6cf52ced1fa964a6774adb1619666ed8 100644 (file)
@@ -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()] | '_',
index 921047e9f0b1495741f99c663421387ffcbd72cc..d01a885955c5ef475857f3261a802f7a785ecea0 100644 (file)
@@ -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().
index e1c29400812fb5d9c2b0d8c22ab4cb23cf9afd19..989064f66820c170b015a9c67f7df338e1df3987 100644 (file)
@@ -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),
index 3552e766fdc4522036d4e0a7241134a56b01fc61..de65355b986bd5bde354b9567b9e4462db120910 100644 (file)
@@ -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
 %%-----------------------------
index 4e2ecdcdd1c35239699afc072318ca881937f721..28228f3e5147a1b56aeb2b1cba4a45b2d3347f99 100644 (file)
@@ -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};