emqx_dashboard_api_test_helpers.erl 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2022-2024 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_dashboard_api_test_helpers).
  17. -export([
  18. set_default_config/0,
  19. set_default_config/1,
  20. set_default_config/2,
  21. set_default_config/3,
  22. request/2,
  23. request/3,
  24. request/4,
  25. request/5,
  26. multipart_formdata_request/3,
  27. multipart_formdata_request/4,
  28. host/0,
  29. uri/0,
  30. uri/1,
  31. uri/2
  32. ]).
  33. -define(HOST, "http://127.0.0.1:18083").
  34. -define(API_VERSION, "v5").
  35. -define(BASE_PATH, "api").
  36. set_default_config() ->
  37. set_default_config(<<"admin">>).
  38. set_default_config(DefaultUsername) ->
  39. set_default_config(DefaultUsername, false).
  40. set_default_config(DefaultUsername, HAProxyEnabled) ->
  41. set_default_config(DefaultUsername, HAProxyEnabled, #{}).
  42. set_default_config(DefaultUsername, HAProxyEnabled, Opts) ->
  43. Config = #{
  44. listeners => #{
  45. http => #{
  46. bind => maps:get(bind, Opts, 18083),
  47. inet6 => false,
  48. ipv6_v6only => false,
  49. max_connections => 512,
  50. num_acceptors => 4,
  51. send_timeout => 5000,
  52. backlog => 512,
  53. proxy_header => HAProxyEnabled
  54. }
  55. },
  56. default_username => DefaultUsername,
  57. default_password => <<"public">>,
  58. i18n_lang => en
  59. },
  60. emqx_config:put([dashboard], Config),
  61. ok.
  62. request(Method, Url) ->
  63. request(Method, Url, []).
  64. request(Method, Url, Body) ->
  65. request(<<"admin">>, Method, Url, Body).
  66. request(Username, Method, Url, Body) ->
  67. request(Username, <<"public">>, Method, Url, Body).
  68. request(Username, Password, Method, Url, Body) ->
  69. Request =
  70. case Body of
  71. [] when
  72. Method =:= get orelse Method =:= put orelse
  73. Method =:= head orelse Method =:= delete orelse
  74. Method =:= trace
  75. ->
  76. {Url, [auth_header(Username, Password)]};
  77. _ ->
  78. {Url, [auth_header(Username, Password)], "application/json",
  79. emqx_utils_json:encode(Body)}
  80. end,
  81. ct:pal("Method: ~p, Request: ~p", [Method, Request]),
  82. case httpc:request(Method, Request, [], [{body_format, binary}]) of
  83. {error, socket_closed_remotely} ->
  84. {error, socket_closed_remotely};
  85. {ok, {{"HTTP/1.1", Code, _}, _Headers, Return}} ->
  86. {ok, Code, Return};
  87. {ok, {Reason, _, _}} ->
  88. {error, Reason}
  89. end.
  90. host() ->
  91. ?HOST.
  92. uri() ->
  93. uri([]).
  94. uri(Parts) when is_list(Parts) ->
  95. uri(host(), Parts).
  96. uri(Host, Parts) when is_list(Host), is_list(Parts) ->
  97. NParts = [E || E <- Parts],
  98. Host ++ "/" ++ to_list(filename:join([?BASE_PATH, ?API_VERSION | NParts])).
  99. auth_header(Username) ->
  100. auth_header(Username, <<"public">>).
  101. auth_header(Username, Password) ->
  102. {ok, _Role, Token} = emqx_dashboard_admin:sign_token(Username, Password),
  103. {"Authorization", "Bearer " ++ binary_to_list(Token)}.
  104. multipart_formdata_request(Url, Fields, Files) ->
  105. multipart_formdata_request(Url, <<"admin">>, Fields, Files).
  106. multipart_formdata_request(Url, Username, Fields, Files) ->
  107. Boundary =
  108. "------------" ++ integer_to_list(rand:uniform(99999999999999999)) ++
  109. integer_to_list(erlang:system_time(millisecond)),
  110. Body = format_multipart_formdata(Boundary, Fields, Files),
  111. ContentType = lists:concat(["multipart/form-data; boundary=", Boundary]),
  112. Headers =
  113. [
  114. auth_header(Username),
  115. {"Content-Length", integer_to_list(length(Body))}
  116. ],
  117. case httpc:request(post, {Url, Headers, ContentType, Body}, [], []) of
  118. {error, socket_closed_remotely} ->
  119. {error, socket_closed_remotely};
  120. {ok, {{"HTTP/1.1", Code, _}, _Headers, Return}} ->
  121. {ok, Code, Return};
  122. {ok, {Reason, _, _}} ->
  123. {error, Reason}
  124. end.
  125. format_multipart_formdata(Boundary, Fields, Files) ->
  126. FieldParts = lists:map(
  127. fun({FieldName, FieldContent}) ->
  128. [
  129. lists:concat(["--", Boundary]),
  130. lists:concat([
  131. "Content-Disposition: form-data; name=\"", atom_to_list(FieldName), "\""
  132. ]),
  133. "",
  134. to_list(FieldContent)
  135. ]
  136. end,
  137. Fields
  138. ),
  139. FieldParts2 = lists:append(FieldParts),
  140. FileParts = lists:map(
  141. fun({FieldName, FileName, FileContent}) ->
  142. [
  143. lists:concat(["--", Boundary]),
  144. lists:concat([
  145. "Content-Disposition: form-data; name=\"",
  146. atom_to_list(FieldName),
  147. "\"; filename=\"",
  148. FileName,
  149. "\""
  150. ]),
  151. lists:concat(["Content-Type: ", "application/octet-stream"]),
  152. "",
  153. to_list(FileContent)
  154. ]
  155. end,
  156. Files
  157. ),
  158. FileParts2 = lists:append(FileParts),
  159. EndingParts = [lists:concat(["--", Boundary, "--"]), ""],
  160. Parts = lists:append([FieldParts2, FileParts2, EndingParts]),
  161. string:join(Parts, "\r\n").
  162. to_list(Bin) when is_binary(Bin) -> binary_to_list(Bin);
  163. to_list(Str) when is_list(Str) -> Str.