emqx_authz_api_mnesia_SUITE.erl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020-2023 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. %% http://www.apache.org/licenses/LICENSE-2.0
  8. %%
  9. %% Unless required by applicable law or agreed to in writing, software
  10. %% distributed under the License is distributed on an "AS IS" BASIS,
  11. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. %% See the License for the specific language governing permissions and
  13. %% limitations under the License.
  14. %%--------------------------------------------------------------------
  15. -module(emqx_authz_api_mnesia_SUITE).
  16. -compile(nowarn_export_all).
  17. -compile(export_all).
  18. -include("emqx_authz.hrl").
  19. -include_lib("eunit/include/eunit.hrl").
  20. -include_lib("common_test/include/ct.hrl").
  21. -import(emqx_mgmt_api_test_util, [request/3, uri/1]).
  22. all() ->
  23. emqx_common_test_helpers:all(?MODULE).
  24. groups() ->
  25. [].
  26. init_per_suite(Config) ->
  27. ok = emqx_mgmt_api_test_util:init_suite(
  28. [emqx_conf, emqx_authz],
  29. fun set_special_configs/1
  30. ),
  31. Config.
  32. end_per_suite(_Config) ->
  33. {ok, _} = emqx:update_config(
  34. [authorization],
  35. #{
  36. <<"no_match">> => <<"allow">>,
  37. <<"cache">> => #{<<"enable">> => <<"true">>},
  38. <<"sources">> => []
  39. }
  40. ),
  41. emqx_mgmt_api_test_util:end_suite([emqx_authz, emqx_conf]),
  42. ok.
  43. set_special_configs(emqx_dashboard) ->
  44. emqx_dashboard_api_test_helpers:set_default_config();
  45. set_special_configs(emqx_authz) ->
  46. {ok, _} = emqx:update_config([authorization, cache, enable], false),
  47. {ok, _} = emqx:update_config([authorization, no_match], deny),
  48. {ok, _} = emqx:update_config(
  49. [authorization, sources],
  50. [#{<<"type">> => <<"built_in_database">>}]
  51. ),
  52. ok;
  53. set_special_configs(_App) ->
  54. ok.
  55. %%------------------------------------------------------------------------------
  56. %% Testcases
  57. %%------------------------------------------------------------------------------
  58. t_api(_) ->
  59. {ok, 204, _} =
  60. request(
  61. post,
  62. uri(["authorization", "sources", "built_in_database", "rules", "users"]),
  63. [?USERNAME_RULES_EXAMPLE]
  64. ),
  65. {ok, 409, _} =
  66. request(
  67. post,
  68. uri(["authorization", "sources", "built_in_database", "rules", "users"]),
  69. [?USERNAME_RULES_EXAMPLE]
  70. ),
  71. {ok, 200, Request1} =
  72. request(
  73. get,
  74. uri(["authorization", "sources", "built_in_database", "rules", "users"]),
  75. []
  76. ),
  77. #{
  78. <<"data">> := [#{<<"username">> := <<"user1">>, <<"rules">> := Rules1}],
  79. <<"meta">> := #{
  80. <<"count">> := 1,
  81. <<"limit">> := 100,
  82. <<"page">> := 1,
  83. <<"hasnext">> := false
  84. }
  85. } = emqx_utils_json:decode(Request1),
  86. ?assertEqual(?USERNAME_RULES_EXAMPLE_COUNT, length(Rules1)),
  87. {ok, 200, Request1_1} =
  88. request(
  89. get,
  90. uri([
  91. "authorization",
  92. "sources",
  93. "built_in_database",
  94. "rules",
  95. "users?page=1&limit=20&like_username=noexist"
  96. ]),
  97. []
  98. ),
  99. ?assertEqual(
  100. #{
  101. <<"data">> => [],
  102. <<"meta">> => #{
  103. <<"limit">> => 20,
  104. <<"page">> => 1,
  105. <<"hasnext">> => false
  106. }
  107. },
  108. emqx_utils_json:decode(Request1_1)
  109. ),
  110. {ok, 200, Request2} =
  111. request(
  112. get,
  113. uri(["authorization", "sources", "built_in_database", "rules", "users", "user1"]),
  114. []
  115. ),
  116. #{<<"username">> := <<"user1">>, <<"rules">> := Rules1} = emqx_utils_json:decode(Request2),
  117. {ok, 204, _} =
  118. request(
  119. put,
  120. uri(["authorization", "sources", "built_in_database", "rules", "users", "user1"]),
  121. ?USERNAME_RULES_EXAMPLE#{rules => []}
  122. ),
  123. {ok, 200, Request3} =
  124. request(
  125. get,
  126. uri(["authorization", "sources", "built_in_database", "rules", "users", "user1"]),
  127. []
  128. ),
  129. #{<<"username">> := <<"user1">>, <<"rules">> := Rules2} = emqx_utils_json:decode(Request3),
  130. ?assertEqual(0, length(Rules2)),
  131. {ok, 204, _} =
  132. request(
  133. delete,
  134. uri(["authorization", "sources", "built_in_database", "rules", "users", "user1"]),
  135. []
  136. ),
  137. {ok, 404, _} =
  138. request(
  139. get,
  140. uri(["authorization", "sources", "built_in_database", "rules", "users", "user1"]),
  141. []
  142. ),
  143. {ok, 404, _} =
  144. request(
  145. delete,
  146. uri(["authorization", "sources", "built_in_database", "rules", "users", "user1"]),
  147. []
  148. ),
  149. % ensure that db contain a mix of records
  150. {ok, 204, _} =
  151. request(
  152. post,
  153. uri(["authorization", "sources", "built_in_database", "rules", "users"]),
  154. [?USERNAME_RULES_EXAMPLE]
  155. ),
  156. {ok, 204, _} =
  157. request(
  158. post,
  159. uri(["authorization", "sources", "built_in_database", "rules", "clients"]),
  160. [?CLIENTID_RULES_EXAMPLE]
  161. ),
  162. {ok, 409, _} =
  163. request(
  164. post,
  165. uri(["authorization", "sources", "built_in_database", "rules", "clients"]),
  166. [?CLIENTID_RULES_EXAMPLE]
  167. ),
  168. {ok, 200, Request4} =
  169. request(
  170. get,
  171. uri(["authorization", "sources", "built_in_database", "rules", "clients"]),
  172. []
  173. ),
  174. {ok, 200, Request5} =
  175. request(
  176. get,
  177. uri(["authorization", "sources", "built_in_database", "rules", "clients", "client1"]),
  178. []
  179. ),
  180. #{
  181. <<"data">> := [#{<<"clientid">> := <<"client1">>, <<"rules">> := Rules3}],
  182. <<"meta">> := #{<<"count">> := 1, <<"limit">> := 100, <<"page">> := 1}
  183. } =
  184. emqx_utils_json:decode(Request4),
  185. #{<<"clientid">> := <<"client1">>, <<"rules">> := Rules3} = emqx_utils_json:decode(Request5),
  186. ?assertEqual(?CLIENTID_RULES_EXAMPLE_COUNT, length(Rules3)),
  187. {ok, 204, _} =
  188. request(
  189. put,
  190. uri(["authorization", "sources", "built_in_database", "rules", "clients", "client1"]),
  191. ?CLIENTID_RULES_EXAMPLE#{rules => []}
  192. ),
  193. {ok, 200, Request6} =
  194. request(
  195. get,
  196. uri(["authorization", "sources", "built_in_database", "rules", "clients", "client1"]),
  197. []
  198. ),
  199. #{<<"clientid">> := <<"client1">>, <<"rules">> := Rules4} = emqx_utils_json:decode(Request6),
  200. ?assertEqual(0, length(Rules4)),
  201. {ok, 204, _} =
  202. request(
  203. delete,
  204. uri(["authorization", "sources", "built_in_database", "rules", "clients", "client1"]),
  205. []
  206. ),
  207. {ok, 404, _} =
  208. request(
  209. get,
  210. uri(["authorization", "sources", "built_in_database", "rules", "clients", "client1"]),
  211. []
  212. ),
  213. {ok, 404, _} =
  214. request(
  215. delete,
  216. uri(["authorization", "sources", "built_in_database", "rules", "clients", "client1"]),
  217. []
  218. ),
  219. {ok, 204, _} =
  220. request(
  221. post,
  222. uri(["authorization", "sources", "built_in_database", "rules", "all"]),
  223. ?ALL_RULES_EXAMPLE
  224. ),
  225. {ok, 200, Request7} =
  226. request(
  227. get,
  228. uri(["authorization", "sources", "built_in_database", "rules", "all"]),
  229. []
  230. ),
  231. #{<<"rules">> := Rules5} = emqx_utils_json:decode(Request7),
  232. ?assertEqual(?ALL_RULES_EXAMPLE_COUNT, length(Rules5)),
  233. {ok, 204, _} =
  234. request(
  235. delete,
  236. uri(["authorization", "sources", "built_in_database", "rules", "all"]),
  237. []
  238. ),
  239. {ok, 200, Request8} =
  240. request(
  241. get,
  242. uri(["authorization", "sources", "built_in_database", "rules", "all"]),
  243. []
  244. ),
  245. #{<<"rules">> := Rules6} = emqx_utils_json:decode(Request8),
  246. ?assertEqual(0, length(Rules6)),
  247. {ok, 204, _} =
  248. request(
  249. post,
  250. uri(["authorization", "sources", "built_in_database", "rules", "users"]),
  251. [
  252. #{username => erlang:integer_to_binary(N), rules => []}
  253. || N <- lists:seq(1, 20)
  254. ]
  255. ),
  256. {ok, 200, Request9} =
  257. request(
  258. get,
  259. uri(["authorization", "sources", "built_in_database", "rules", "users?page=2&limit=5"]),
  260. []
  261. ),
  262. #{<<"data">> := Data1} = emqx_utils_json:decode(Request9),
  263. ?assertEqual(5, length(Data1)),
  264. {ok, 204, _} =
  265. request(
  266. post,
  267. uri(["authorization", "sources", "built_in_database", "rules", "clients"]),
  268. [
  269. #{clientid => erlang:integer_to_binary(N), rules => []}
  270. || N <- lists:seq(1, 20)
  271. ]
  272. ),
  273. {ok, 200, Request10} =
  274. request(
  275. get,
  276. uri(["authorization", "sources", "built_in_database", "rules", "clients?limit=5"]),
  277. []
  278. ),
  279. #{<<"data">> := Data2} = emqx_utils_json:decode(Request10),
  280. ?assertEqual(5, length(Data2)),
  281. {ok, 400, Msg1} =
  282. request(
  283. delete,
  284. uri(["authorization", "sources", "built_in_database", "rules"]),
  285. []
  286. ),
  287. ?assertMatch({match, _}, re:run(Msg1, "must\sbe\sdisabled\sbefore")),
  288. {ok, 204, _} =
  289. request(
  290. put,
  291. uri(["authorization", "sources", "built_in_database"]),
  292. #{<<"enable">> => true, <<"type">> => <<"built_in_database">>}
  293. ),
  294. %% test idempotence
  295. {ok, 204, _} =
  296. request(
  297. put,
  298. uri(["authorization", "sources", "built_in_database"]),
  299. #{<<"enable">> => true, <<"type">> => <<"built_in_database">>}
  300. ),
  301. {ok, 204, _} =
  302. request(
  303. put,
  304. uri(["authorization", "sources", "built_in_database"]),
  305. #{<<"enable">> => false, <<"type">> => <<"built_in_database">>}
  306. ),
  307. {ok, 204, _} =
  308. request(
  309. delete,
  310. uri(["authorization", "sources", "built_in_database", "rules"]),
  311. []
  312. ),
  313. ?assertEqual(0, emqx_authz_mnesia:record_count()),
  314. ok.