| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606 |
- %%--------------------------------------------------------------------
- %% Copyright (c) 2020-2024 EMQ Technologies Co., Ltd. All Rights Reserved.
- %%
- %% Licensed under the Apache License, Version 2.0 (the "License");
- %% you may not use this file except in compliance with the License.
- %% You may obtain a copy of the License at
- %%
- %% http://www.apache.org/licenses/LICENSE-2.0
- %%
- %% Unless required by applicable law or agreed to in writing, software
- %% distributed under the License is distributed on an "AS IS" BASIS,
- %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- %% See the License for the specific language governing permissions and
- %% limitations under the License.
- %%--------------------------------------------------------------------
- -module(emqx_mgmt_api_api_keys_SUITE).
- -compile(export_all).
- -compile(nowarn_export_all).
- -include_lib("eunit/include/eunit.hrl").
- -include_lib("common_test/include/ct.hrl").
- -include_lib("emqx_dashboard/include/emqx_dashboard_rbac.hrl").
- -if(?EMQX_RELEASE_EDITION == ee).
- -define(EE_CASES, [
- t_ee_create,
- t_ee_update,
- t_ee_authorize_viewer,
- t_ee_authorize_admin,
- t_ee_authorize_publisher
- ]).
- -else.
- -define(EE_CASES, []).
- -endif.
- -define(APP, emqx_app).
- -record(?APP, {
- name = <<>> :: binary() | '_',
- api_key = <<>> :: binary() | '_',
- api_secret_hash = <<>> :: binary() | '_',
- enable = true :: boolean() | '_',
- desc = <<>> :: binary() | '_',
- expired_at = 0 :: integer() | undefined | infinity | '_',
- created_at = 0 :: integer() | '_'
- }).
- all() -> [{group, parallel}, {group, sequence}].
- suite() -> [{timetrap, {minutes, 1}}].
- groups() ->
- [
- {parallel, [parallel], [t_create, t_update, t_delete, t_authorize, t_create_unexpired_app]},
- {parallel, [parallel], ?EE_CASES},
- {sequence, [], [t_bootstrap_file, t_bootstrap_file_with_role, t_create_failed]}
- ].
- init_per_suite(Config) ->
- emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_management]),
- Config.
- end_per_suite(_) ->
- emqx_mgmt_api_test_util:end_suite([emqx_conf, emqx_management]).
- t_bootstrap_file(_) ->
- TestPath = <<"/api/v5/status">>,
- Bin = <<"test-1:secret-1\ntest-2:secret-2">>,
- File = "./bootstrap_api_keys.txt",
- ok = file:write_file(File, Bin),
- update_file(File),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-2">>, <<"secret-2">>)),
- ?assertMatch({error, _}, auth_authorize(TestPath, <<"test-2">>, <<"secret-1">>)),
- %% relaunch to check if the table is changed.
- Bin1 = <<"test-1:new-secret-1\ntest-2:new-secret-2">>,
- ok = file:write_file(File, Bin1),
- update_file(File),
- ?assertMatch({error, _}, auth_authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
- ?assertMatch({error, _}, auth_authorize(TestPath, <<"test-2">>, <<"secret-2">>)),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-1">>, <<"new-secret-1">>)),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-2">>, <<"new-secret-2">>)),
- %% not error when bootstrap_file is empty
- update_file(<<>>),
- update_file("./bootstrap_apps_not_exist.txt"),
- ?assertMatch({error, _}, auth_authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
- ?assertMatch({error, _}, auth_authorize(TestPath, <<"test-2">>, <<"secret-2">>)),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-1">>, <<"new-secret-1">>)),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-2">>, <<"new-secret-2">>)),
- %% bad format
- BadBin = <<"test-1:secret-11\ntest-2 secret-12">>,
- ok = file:write_file(File, BadBin),
- update_file(File),
- ?assertMatch({error, #{reason := "invalid_format"}}, emqx_mgmt_auth:init_bootstrap_file()),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-1">>, <<"secret-11">>)),
- ?assertMatch({error, _}, auth_authorize(TestPath, <<"test-2">>, <<"secret-12">>)),
- update_file(<<>>),
- %% skip the empty line
- Bin2 = <<"test-3:new-secret-1\n\n\n \ntest-4:new-secret-2">>,
- ok = file:write_file(File, Bin2),
- update_file(File),
- ?assertMatch({error, _}, auth_authorize(TestPath, <<"test-3">>, <<"secret-1">>)),
- ?assertMatch({error, _}, auth_authorize(TestPath, <<"test-4">>, <<"secret-2">>)),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-3">>, <<"new-secret-1">>)),
- ?assertEqual(ok, auth_authorize(TestPath, <<"test-4">>, <<"new-secret-2">>)),
- ok.
- t_bootstrap_file_override(_) ->
- TestPath = <<"/api/v5/status">>,
- Bin =
- <<"test-1:secret-1\ntest-1:duplicated-secret-1\ntest-2:secret-2\ntest-2:duplicated-secret-2">>,
- File = "./bootstrap_api_keys.txt",
- ok = file:write_file(File, Bin),
- update_file(File),
- ?assertEqual(ok, emqx_mgmt_auth:init_bootstrap_file()),
- MatchFun = fun(ApiKey) -> mnesia:match_object(#?APP{api_key = ApiKey, _ = '_'}) end,
- ?assertMatch(
- {ok, [
- #?APP{
- name = <<"from_bootstrap_file_18926f94712af04e">>,
- api_key = <<"test-1">>
- }
- ]},
- emqx_mgmt_auth:trans(MatchFun, [<<"test-1">>])
- ),
- ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"duplicated-secret-1">>)),
- ?assertMatch(
- {ok, [
- #?APP{
- name = <<"from_bootstrap_file_de1c28a2e610e734">>,
- api_key = <<"test-2">>
- }
- ]},
- emqx_mgmt_auth:trans(MatchFun, [<<"test-2">>])
- ),
- ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"duplicated-secret-2">>)),
- ok.
- t_bootstrap_file_dup_override(_) ->
- TestPath = <<"/api/v5/status">>,
- TestApiKey = <<"test-1">>,
- Bin = <<"test-1:secret-1">>,
- File = "./bootstrap_api_keys.txt",
- ok = file:write_file(File, Bin),
- update_file(File),
- ?assertEqual(ok, emqx_mgmt_auth:init_bootstrap_file()),
- SameAppWithDiffName = #?APP{
- name = <<"name-1">>,
- api_key = <<"test-1">>,
- api_secret_hash = emqx_dashboard_admin:hash(<<"duplicated-secret-1">>),
- enable = true,
- desc = <<"dup api key">>,
- created_at = erlang:system_time(second),
- expired_at = infinity
- },
- WriteFun = fun(App) -> mnesia:write(App) end,
- MatchFun = fun(ApiKey) -> mnesia:match_object(#?APP{api_key = ApiKey, _ = '_'}) end,
- ?assertEqual({ok, ok}, emqx_mgmt_auth:trans(WriteFun, [SameAppWithDiffName])),
- %% as erlang term order
- ?assertMatch(
- {ok, [
- #?APP{
- name = <<"name-1">>,
- api_key = <<"test-1">>
- },
- #?APP{
- name = <<"from_bootstrap_file_18926f94712af04e">>,
- api_key = <<"test-1">>
- }
- ]},
- emqx_mgmt_auth:trans(MatchFun, [TestApiKey])
- ),
- update_file(File),
- %% Similar to loading bootstrap file at node startup
- %% the duplicated apikey in mnesia will be cleaned up
- ?assertEqual(ok, emqx_mgmt_auth:init_bootstrap_file()),
- ?assertMatch(
- {ok, [
- #?APP{
- name = <<"from_bootstrap_file_18926f94712af04e">>,
- api_key = <<"test-1">>
- }
- ]},
- emqx_mgmt_auth:trans(MatchFun, [<<"test-1">>])
- ),
- %% the last apikey in bootstrap file will override the all in mnesia and the previous one(s) in bootstrap file
- ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
- ok.
- -if(?EMQX_RELEASE_EDITION == ee).
- t_bootstrap_file_with_role(_) ->
- Search = fun(Name) ->
- lists:search(
- fun(#{api_key := AppName}) ->
- AppName =:= Name
- end,
- emqx_mgmt_auth:list()
- )
- end,
- Bin = <<"role-1:role-1:viewer\nrole-2:role-2:administrator\nrole-3:role-3">>,
- File = "./bootstrap_api_keys.txt",
- ok = file:write_file(File, Bin),
- update_file(File),
- ?assertMatch(
- {value, #{api_key := <<"role-1">>, role := <<"viewer">>}},
- Search(<<"role-1">>)
- ),
- ?assertMatch(
- {value, #{api_key := <<"role-2">>, role := <<"administrator">>}},
- Search(<<"role-2">>)
- ),
- ?assertMatch(
- {value, #{api_key := <<"role-3">>, role := <<"administrator">>}},
- Search(<<"role-3">>)
- ),
- %% bad role
- BadBin = <<"role-4:secret-11:bad\n">>,
- ok = file:write_file(File, BadBin),
- update_file(File),
- ?assertEqual(
- false,
- Search(<<"role-4">>)
- ),
- ok.
- -else.
- t_bootstrap_file_with_role(_) ->
- Search = fun(Name) ->
- lists:search(
- fun(#{api_key := AppName}) ->
- AppName =:= Name
- end,
- emqx_mgmt_auth:list()
- )
- end,
- Bin = <<"role-1:role-1:administrator\nrole-2:role-2">>,
- File = "./bootstrap_api_keys.txt",
- ok = file:write_file(File, Bin),
- update_file(File),
- ?assertMatch(
- {value, #{api_key := <<"role-1">>, role := <<"administrator">>}},
- Search(<<"role-1">>)
- ),
- ?assertMatch(
- {value, #{api_key := <<"role-2">>, role := <<"administrator">>}},
- Search(<<"role-2">>)
- ),
- %% only administrator
- OtherRoleBin = <<"role-3:role-3:viewer\n">>,
- ok = file:write_file(File, OtherRoleBin),
- update_file(File),
- ?assertEqual(
- false,
- Search(<<"role-3">>)
- ),
- %% bad role
- BadBin = <<"role-4:secret-11:bad\n">>,
- ok = file:write_file(File, BadBin),
- update_file(File),
- ?assertEqual(
- false,
- Search(<<"role-4">>)
- ),
- ok.
- -endif.
- auth_authorize(Path, Key, Secret) ->
- FakePath = erlang:list_to_binary(emqx_dashboard_swagger:relative_uri("/fake")),
- FakeReq = #{method => <<"GET">>, path => FakePath},
- emqx_mgmt_auth:authorize(Path, FakeReq, Key, Secret).
- update_file(File) ->
- ?assertMatch({ok, _}, emqx:update_config([<<"api_key">>], #{<<"bootstrap_file">> => File})).
- t_create(_Config) ->
- Name = <<"EMQX-API-KEY-1">>,
- {ok, Create} = create_app(Name),
- ?assertMatch(
- #{
- <<"api_key">> := _,
- <<"api_secret">> := _,
- <<"created_at">> := _,
- <<"desc">> := _,
- <<"enable">> := true,
- <<"expired_at">> := _,
- <<"name">> := Name
- },
- Create
- ),
- {ok, List} = list_app(),
- [App] = lists:filter(fun(#{<<"name">> := NameA}) -> NameA =:= Name end, List),
- ?assertEqual(false, maps:is_key(<<"api_secret">>, App)),
- {ok, App1} = read_app(Name),
- ?assertEqual(Name, maps:get(<<"name">>, App1)),
- ?assertEqual(true, maps:get(<<"enable">>, App1)),
- ?assertEqual(false, maps:is_key(<<"api_secret">>, App1)),
- ?assertEqual({error, {"HTTP/1.1", 404, "Not Found"}}, read_app(<<"EMQX-API-KEY-NO-EXIST">>)),
- ok.
- t_create_failed(_Config) ->
- BadRequest = {error, {"HTTP/1.1", 400, "Bad Request"}},
- ?assertEqual(BadRequest, create_app(<<" error format name">>)),
- LongName = iolist_to_binary(lists:duplicate(257, "A")),
- ?assertEqual(BadRequest, create_app(<<" error format name">>)),
- ?assertEqual(BadRequest, create_app(LongName)),
- {ok, List} = list_app(),
- CreateNum = 100 - erlang:length(List),
- Names = lists:map(
- fun(Seq) ->
- <<"EMQX-API-FAILED-KEY-", (integer_to_binary(Seq))/binary>>
- end,
- lists:seq(1, CreateNum)
- ),
- lists:foreach(fun(N) -> {ok, _} = create_app(N) end, Names),
- ?assertEqual(BadRequest, create_app(<<"EMQX-API-KEY-MAXIMUM">>)),
- lists:foreach(fun(N) -> {ok, _} = delete_app(N) end, Names),
- Name = <<"EMQX-API-FAILED-KEY-1">>,
- ?assertMatch({ok, _}, create_app(Name)),
- ?assertEqual(BadRequest, create_app(Name)),
- {ok, _} = delete_app(Name),
- ?assertMatch({ok, #{<<"name">> := Name}}, create_app(Name)),
- {ok, _} = delete_app(Name),
- ok.
- t_update(_Config) ->
- Name = <<"EMQX-API-UPDATE-KEY">>,
- {ok, _} = create_app(Name),
- ExpiredAt = to_rfc3339(erlang:system_time(second) + 10000),
- Change = #{
- expired_at => ExpiredAt,
- desc => <<"NoteVersion1"/utf8>>,
- enable => false
- },
- {ok, Update1} = update_app(Name, Change),
- ?assertEqual(Name, maps:get(<<"name">>, Update1)),
- ?assertEqual(false, maps:get(<<"enable">>, Update1)),
- ?assertEqual(<<"NoteVersion1"/utf8>>, maps:get(<<"desc">>, Update1)),
- ?assertEqual(
- calendar:rfc3339_to_system_time(binary_to_list(ExpiredAt)),
- calendar:rfc3339_to_system_time(binary_to_list(maps:get(<<"expired_at">>, Update1)))
- ),
- Unexpired1 = maps:without([expired_at], Change),
- {ok, Update2} = update_app(Name, Unexpired1),
- ?assertEqual(<<"infinity">>, maps:get(<<"expired_at">>, Update2)),
- Unexpired2 = Change#{expired_at => <<"infinity">>},
- {ok, Update3} = update_app(Name, Unexpired2),
- ?assertEqual(<<"infinity">>, maps:get(<<"expired_at">>, Update3)),
- ?assertEqual({error, {"HTTP/1.1", 404, "Not Found"}}, update_app(<<"Not-Exist">>, Change)),
- ok.
- t_delete(_Config) ->
- Name = <<"EMQX-API-DELETE-KEY">>,
- {ok, _Create} = create_app(Name),
- {ok, Delete} = delete_app(Name),
- ?assertEqual([], Delete),
- ?assertEqual({error, {"HTTP/1.1", 404, "Not Found"}}, delete_app(Name)),
- ok.
- t_authorize(_Config) ->
- Name = <<"EMQX-API-AUTHORIZE-KEY">>,
- {ok, #{<<"api_key">> := ApiKey, <<"api_secret">> := ApiSecret}} = create_app(Name),
- BasicHeader = emqx_common_test_http:auth_header(
- binary_to_list(ApiKey),
- binary_to_list(ApiSecret)
- ),
- SecretError = emqx_common_test_http:auth_header(
- binary_to_list(ApiKey),
- binary_to_list(ApiKey)
- ),
- KeyError = emqx_common_test_http:auth_header("not_found_key", binary_to_list(ApiSecret)),
- Unauthorized = {error, {"HTTP/1.1", 401, "Unauthorized"}},
- BanPath = emqx_mgmt_api_test_util:api_path(["banned"]),
- ApiKeyPath = emqx_mgmt_api_test_util:api_path(["api_key"]),
- UserPath = emqx_mgmt_api_test_util:api_path(["users"]),
- {ok, _Status} = emqx_mgmt_api_test_util:request_api(get, BanPath, BasicHeader),
- ?assertEqual(Unauthorized, emqx_mgmt_api_test_util:request_api(get, BanPath, KeyError)),
- ?assertEqual(Unauthorized, emqx_mgmt_api_test_util:request_api(get, BanPath, SecretError)),
- ?assertEqual(Unauthorized, emqx_mgmt_api_test_util:request_api(get, UserPath, BasicHeader)),
- {error, {{"HTTP/1.1", 401, "Unauthorized"}, _Headers, Body}} =
- emqx_mgmt_api_test_util:request_api(
- get,
- ApiKeyPath,
- [],
- BasicHeader,
- [],
- #{return_all => true}
- ),
- ?assertMatch(
- #{
- <<"code">> := <<"API_KEY_NOT_ALLOW">>,
- <<"message">> := _
- },
- emqx_utils_json:decode(Body, [return_maps])
- ),
- ?assertMatch(
- {ok, #{<<"api_key">> := _, <<"enable">> := false}},
- update_app(Name, #{enable => false})
- ),
- ?assertEqual(Unauthorized, emqx_mgmt_api_test_util:request_api(get, BanPath, BasicHeader)),
- Expired = #{
- expired_at => to_rfc3339(erlang:system_time(second) - 1),
- enable => true
- },
- ?assertMatch({ok, #{<<"api_key">> := _, <<"enable">> := true}}, update_app(Name, Expired)),
- ?assertEqual(Unauthorized, emqx_mgmt_api_test_util:request_api(get, BanPath, BasicHeader)),
- UnExpired = #{expired_at => infinity},
- ?assertMatch(
- {ok, #{<<"api_key">> := _, <<"expired_at">> := <<"infinity">>}},
- update_app(Name, UnExpired)
- ),
- {ok, _Status1} = emqx_mgmt_api_test_util:request_api(get, BanPath, BasicHeader),
- ok.
- t_create_unexpired_app(_Config) ->
- Name1 = <<"EMQX-UNEXPIRED-API-KEY-1">>,
- Name2 = <<"EMQX-UNEXPIRED-API-KEY-2">>,
- {ok, Create1} = create_unexpired_app(Name1, #{}),
- ?assertMatch(#{<<"expired_at">> := <<"infinity">>}, Create1),
- {ok, Create2} = create_unexpired_app(Name2, #{expired_at => <<"infinity">>}),
- ?assertMatch(#{<<"expired_at">> := <<"infinity">>}, Create2),
- ok.
- t_ee_create(_Config) ->
- Name = <<"EMQX-EE-API-KEY-1">>,
- {ok, Create} = create_app(Name, #{role => ?ROLE_API_VIEWER}),
- ?assertMatch(
- #{
- <<"api_key">> := _,
- <<"api_secret">> := _,
- <<"created_at">> := _,
- <<"desc">> := _,
- <<"enable">> := true,
- <<"expired_at">> := _,
- <<"name">> := Name,
- <<"role">> := ?ROLE_API_VIEWER
- },
- Create
- ),
- {ok, App} = read_app(Name),
- ?assertMatch(#{<<"name">> := Name, <<"role">> := ?ROLE_API_VIEWER}, App).
- t_ee_update(_Config) ->
- Name = <<"EMQX-EE-API-UPDATE-KEY">>,
- {ok, _} = create_app(Name, #{role => ?ROLE_API_VIEWER}),
- Change = #{
- desc => <<"NoteVersion1"/utf8>>,
- enable => false,
- role => ?ROLE_API_SUPERUSER
- },
- {ok, Update1} = update_app(Name, Change),
- ?assertEqual(?ROLE_API_SUPERUSER, maps:get(<<"role">>, Update1)),
- {ok, App} = read_app(Name),
- ?assertMatch(#{<<"name">> := Name, <<"role">> := ?ROLE_API_SUPERUSER}, App).
- t_ee_authorize_viewer(_Config) ->
- Name = <<"EMQX-EE-API-AUTHORIZE-KEY-VIEWER">>,
- {ok, #{<<"api_key">> := ApiKey, <<"api_secret">> := ApiSecret}} = create_app(Name, #{
- role => ?ROLE_API_VIEWER
- }),
- BasicHeader = emqx_common_test_http:auth_header(
- binary_to_list(ApiKey),
- binary_to_list(ApiSecret)
- ),
- BanPath = emqx_mgmt_api_test_util:api_path(["banned"]),
- ?assertMatch({ok, _}, emqx_mgmt_api_test_util:request_api(get, BanPath, BasicHeader)),
- ?assertMatch(
- {error, {_, 403, _}}, emqx_mgmt_api_test_util:request_api(delete, BanPath, BasicHeader)
- ).
- t_ee_authorize_admin(_Config) ->
- Name = <<"EMQX-EE-API-AUTHORIZE-KEY-ADMIN">>,
- {ok, #{<<"api_key">> := ApiKey, <<"api_secret">> := ApiSecret}} = create_app(Name, #{
- role => ?ROLE_API_SUPERUSER
- }),
- BasicHeader = emqx_common_test_http:auth_header(
- binary_to_list(ApiKey),
- binary_to_list(ApiSecret)
- ),
- BanPath = emqx_mgmt_api_test_util:api_path(["banned"]),
- ?assertMatch({ok, _}, emqx_mgmt_api_test_util:request_api(get, BanPath, BasicHeader)),
- ?assertMatch(
- {ok, _}, emqx_mgmt_api_test_util:request_api(delete, BanPath, BasicHeader)
- ).
- t_ee_authorize_publisher(_Config) ->
- Name = <<"EMQX-EE-API-AUTHORIZE-KEY-PUBLISHER">>,
- {ok, #{<<"api_key">> := ApiKey, <<"api_secret">> := ApiSecret}} = create_app(Name, #{
- role => ?ROLE_API_PUBLISHER
- }),
- BasicHeader = emqx_common_test_http:auth_header(
- binary_to_list(ApiKey),
- binary_to_list(ApiSecret)
- ),
- BanPath = emqx_mgmt_api_test_util:api_path(["banned"]),
- Publish = emqx_mgmt_api_test_util:api_path(["publish"]),
- ?assertMatch(
- {error, {_, 403, _}}, emqx_mgmt_api_test_util:request_api(get, BanPath, BasicHeader)
- ),
- ?assertMatch(
- {error, {_, 403, _}}, emqx_mgmt_api_test_util:request_api(delete, BanPath, BasicHeader)
- ),
- ?_assertMatch(
- {ok, _},
- emqx_mgmt_api_test_util:request_api(
- post,
- Publish,
- [],
- BasicHeader,
- #{topic => <<"t/t_ee_authorize_publisher">>, payload => <<"hello">>}
- )
- ).
- list_app() ->
- AuthHeader = emqx_dashboard_SUITE:auth_header_(),
- Path = emqx_mgmt_api_test_util:api_path(["api_key"]),
- case emqx_mgmt_api_test_util:request_api(get, Path, AuthHeader) of
- {ok, Apps} -> {ok, emqx_utils_json:decode(Apps, [return_maps])};
- Error -> Error
- end.
- read_app(Name) ->
- AuthHeader = emqx_dashboard_SUITE:auth_header_(),
- Path = emqx_mgmt_api_test_util:api_path(["api_key", Name]),
- case emqx_mgmt_api_test_util:request_api(get, Path, AuthHeader) of
- {ok, Res} -> {ok, emqx_utils_json:decode(Res, [return_maps])};
- Error -> Error
- end.
- create_app(Name) ->
- create_app(Name, #{}).
- create_app(Name, Extra) ->
- AuthHeader = emqx_dashboard_SUITE:auth_header_(),
- Path = emqx_mgmt_api_test_util:api_path(["api_key"]),
- ExpiredAt = to_rfc3339(erlang:system_time(second) + 1000),
- App = Extra#{
- name => Name,
- expired_at => ExpiredAt,
- desc => <<"Note"/utf8>>,
- enable => true
- },
- case emqx_mgmt_api_test_util:request_api(post, Path, "", AuthHeader, App) of
- {ok, Res} -> {ok, emqx_utils_json:decode(Res, [return_maps])};
- Error -> Error
- end.
- create_unexpired_app(Name, Params) ->
- AuthHeader = emqx_dashboard_SUITE:auth_header_(),
- Path = emqx_mgmt_api_test_util:api_path(["api_key"]),
- App = maps:merge(#{name => Name, desc => <<"Note"/utf8>>, enable => true}, Params),
- case emqx_mgmt_api_test_util:request_api(post, Path, "", AuthHeader, App) of
- {ok, Res} -> {ok, emqx_utils_json:decode(Res, [return_maps])};
- Error -> Error
- end.
- delete_app(Name) ->
- AuthHeader = emqx_dashboard_SUITE:auth_header_(),
- DeletePath = emqx_mgmt_api_test_util:api_path(["api_key", Name]),
- emqx_mgmt_api_test_util:request_api(delete, DeletePath, AuthHeader).
- update_app(Name, Change) ->
- AuthHeader = emqx_dashboard_SUITE:auth_header_(),
- UpdatePath = emqx_mgmt_api_test_util:api_path(["api_key", Name]),
- case emqx_mgmt_api_test_util:request_api(put, UpdatePath, "", AuthHeader, Change) of
- {ok, Update} -> {ok, emqx_utils_json:decode(Update, [return_maps])};
- Error -> Error
- end.
- to_rfc3339(Sec) ->
- list_to_binary(calendar:system_time_to_rfc3339(Sec)).
|