]> granicus.if.org Git - ejabberd/commitdiff
Merge lastest commits from master
authorMickael Remond <mremond@process-one.net>
Thu, 31 Mar 2016 13:37:21 +0000 (15:37 +0200)
committerMickael Remond <mremond@process-one.net>
Thu, 31 Mar 2016 13:37:21 +0000 (15:37 +0200)
1  2 
src/ejabberd_commands.erl
src/mod_http_api.erl
test/elixir_SUITE.erl

index fd8ba03fe0a7d67c310270a0844e6b9e97c19beb,57285d6c6b4fa9150c2644f43685bb97e6fae897..dd14748d04df8600294f03f8db1acbd3c9862e2e
  -module(ejabberd_commands).
  -author('badlop@process-one.net').
  
 +-define(DEFAULT_VERSION, 1000000).
 +
  -export([init/0,
         list_commands/0,
 +       list_commands/1,
         get_command_format/1,
 -         get_command_format/2,
 +       get_command_format/2,
 +       get_command_format/3,
+          get_command_policy/1,
         get_command_definition/1,
 +       get_command_definition/2,
         get_tags_commands/0,
 +       get_tags_commands/1,
           get_commands/0,
         register_commands/1,
         unregister_commands/1,
@@@ -364,7 -339,18 +365,18 @@@ get_command_format(Name, Auth, Version
            {Args, Result}
      end.
  
 --spec get_command_definition(atom()) -> ejabberd_commands() | command_not_found.
+ -spec get_command_policy(atom()) -> {ok, open|user|admin|restricted} | {error, command_not_found}.
+ %% @doc return command policy.
+ get_command_policy(Name) ->
+     case get_command_definition(Name) of
+         #ejabberd_commands{policy = Policy} ->
+             {ok, Policy};
+         command_not_found ->
+             {error, command_not_found}
+     end.
 +-spec get_command_definition(atom()) -> ejabberd_commands().
  
  %% @doc Get the definition record of a command.
  get_command_definition(Name) ->
index f2b7a484b7246d9f2fe906aa58b7727065058a0b,c2b7d110030967323e1ad8d7943480c0c994f045..5775b215d7e90aafb360b3b24d729d19e4228dda
@@@ -186,10 -181,11 +188,12 @@@ check_permissions2(#request{ip={IP, _Po
                  true -> {allowed, Call, admin};
                  _ -> unauthorized_response()
              end;
 -        _ ->
 +        _E ->
 +          ?DEBUG("Unauthorized: ~p", [_E]),
              unauthorized_response()
-     end.
+     end;
+ check_permissions2(_Request, _Call, _Policy) ->
+     unauthorized_response().
  
  oauth_check_token(Scope, Token) when is_atom(Scope) ->
      oauth_check_token(atom_to_binary(Scope, utf8), Token);
@@@ -216,16 -209,14 +220,17 @@@ process([Call], #request{method = 'POST
          log(Call, Args, IP),
          case check_permissions(Req, Call) of
              {allowed, Cmd, Auth} ->
 -                {Code, Result} = handle(Cmd, Auth, Args),
 +                {Code, Result} = handle(Cmd, Auth, Args, Version),
                  json_response(Code, jiffy:encode(Result));
-             ErrorResponse -> %% Should we reply 403 ?
+             %% Warning: check_permission direcly formats 401 reply if not authorized
+             ErrorResponse ->
                  ErrorResponse
          end
 -    catch _:Error ->
 -        ?DEBUG("Bad Request: ~p", [Error]),
 +    catch _:{error,{_,invalid_json}} = _Err ->
 +          ?DEBUG("Bad Request: ~p", [_Err]),
 +          badrequest_response(<<"Invalid JSON input">>);
 +        _:_Error ->
 +        ?DEBUG("Bad Request: ~p ~p", [_Error, erlang:get_stacktrace()]),
          badrequest_response()
      end;
  process([Call], #request{method = 'GET', q = Data, ip = IP} = Req) ->
          log(Call, Args, IP),
          case check_permissions(Req, Call) of
              {allowed, Cmd, Auth} ->
 -                {Code, Result} = handle(Cmd, Auth, Args),
 +                {Code, Result} = handle(Cmd, Auth, Args, Version),
                  json_response(Code, jiffy:encode(Result));
+             %% Warning: check_permission direcly formats 401 reply if not authorized
              ErrorResponse ->
                  ErrorResponse
          end
@@@ -325,16 -272,17 +331,10 @@@ handle(Call, Auth, Args, Version) when 
              {400, <<"Error">>}
      end.
  
 -handle2(Call, Auth, Args) when is_atom(Call), is_list(Args) ->
 -    {ArgsF, _ResultF} = ejabberd_commands:get_command_format(Call, Auth),
 +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(Args, ArgsF),
-     case ejabberd_commands:execute_command(undefined, Auth, 
-                                          Call, ArgsFormatted, Version) of
-       {error, Error} ->
-           throw(Error);
-       Res ->
-           format_command_result(Call, Auth, Res, Version)
 -    case ejabberd_command(Auth, Call, ArgsFormatted, 400) of
 -        0 -> {200, <<"OK">>};
 -        1 -> {500, <<"500 Internal server error">>};
 -        400 -> {400, <<"400 Bad Request">>};
 -        401 -> {401, <<"401 Unauthorized">>};
 -        404 -> {404, <<"404 Not found">>};
 -        Res -> format_command_result(Call, Auth, Res)
--    end.
++    ejabberd_command(Auth, Call, ArgsFormatted, Version).
  
  get_elem_delete(A, L) ->
      case proplists:get_all_values(A, L) of
@@@ -414,26 -360,37 +414,37 @@@ process_unicode_codepoints(Str) -
  match(Args, Spec) ->
      [{Key, proplists:get_value(Key, Args, Default)} || {Key, Default} <- Spec].
  
 -ejabberd_command(Auth, Cmd, Args, Default) ->
++ejabberd_command(Auth, Cmd, Args, Version) ->
+     Access = case Auth of
+                  admin -> [];
+                  _ -> undefined
+              end,
 -    case catch ejabberd_commands:execute_command(Access, Auth, Cmd, Args) of
 -        {'EXIT', _} -> Default;
 -        {error, account_unprivileged} -> 401;
 -        {error, _} -> Default;
 -        Result -> Result
++    case ejabberd_commands:execute_command(Access, Auth, Cmd, Args, Version) of
++        {error, Error} ->
++            throw(Error);
++        Res ->
++            format_command_result(Cmd, Auth, Res, Version)
+     end.
  
 -format_command_result(Cmd, Auth, Result) ->
 -    {_, ResultFormat} = ejabberd_commands:get_command_format(Cmd, Auth),
 +format_command_result(Cmd, Auth, Result, Version) ->
 +    {_, ResultFormat} = ejabberd_commands:get_command_format(Cmd, Auth, Version),
      case {ResultFormat, Result} of
 -        {{_, rescode}, V} when V == true; V == ok ->
 -            {200, <<"">>};
 -        {{_, rescode}, _} ->
 -            {500, <<"">>};
 -        {{_, restuple}, {V1, Text1}} when V1 == true; V1 == ok ->
 -            {200, iolist_to_binary(Text1)};
 -        {{_, restuple}, {_, Text2}} ->
 -            {500, iolist_to_binary(Text2)};
 -        {{_, {list, _}}, _V} ->
 -            {_, L} = format_result(Result, ResultFormat),
 -            {200, L};
 -        {{_, {tuple, _}}, _V} ->
 -            {_, T} = format_result(Result, ResultFormat),
 -            {200, T};
 -        _ ->
 -            {200, {[format_result(Result, ResultFormat)]}}
 +      {{_, rescode}, V} when V == true; V == ok ->
 +          {200, 0};
 +      {{_, rescode}, _} ->
 +          {200, 1};
 +      {{_, restuple}, {V1, Text1}} when V1 == true; V1 == ok ->
 +          {200, iolist_to_binary(Text1)};
 +      {{_, restuple}, {_, Text2}} ->
 +          {500, iolist_to_binary(Text2)};
 +      {{_, {list, _}}, _V} ->
 +          {_, L} = format_result(Result, ResultFormat),
 +          {200, L};
 +      {{_, {tuple, _}}, _V} ->
 +          {_, T} = format_result(Result, ResultFormat),
 +          {200, T};
 +      _ ->
 +          {200, {[format_result(Result, ResultFormat)]}}
      end.
  
  format_result(Atom, {Name, atom}) ->
index f2c64773b533d4c88612cf15f2636eac0831db4f,041d0603e4247a717b24375e42be8cc23627ae03..7047d221e9e51eb2147e623d2edf2d998061de39
@@@ -66,12 -65,9 +66,14 @@@ undefined_function(Module, Func, Args) 
      error_handler:undefined_function(Module, Func,Args).
  
  run_elixir_test(Func) ->
-     'Elixir.ExUnit':start([]),
+     %% Elixir tests can be tagged as follow to be ignored (place before test start)
+     %% @tag pending: true
+     'Elixir.ExUnit':start([{exclude, [{pending, true}]}]),
 +    filelib:fold_files(test_dir(), ".*\\.exs\$", true,
 +                     fun (File, N) ->
 +                             'Elixir.Code':require_file(list_to_binary(File)),
 +                             N+1
 +                     end, 0),
      'Elixir.Code':load_file(list_to_binary(filename:join(test_dir(), atom_to_list(Func)))),
      %% I did not use map syntax, so that this file can still be build under R16
      ResultMap = 'Elixir.ExUnit':run(),