| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793 |
- %%--------------------------------------------------------------------
- %% Copyright (c) 2021-2023 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_authn_api_SUITE).
- -compile(nowarn_export_all).
- -compile(export_all).
- -import(emqx_dashboard_api_test_helpers, [multipart_formdata_request/3]).
- -import(emqx_mgmt_api_test_util, [request/3, uri/1]).
- -include("emqx_authn.hrl").
- -include_lib("eunit/include/eunit.hrl").
- -define(TCP_DEFAULT, 'tcp:default').
- -define(assertAuthenticatorsMatch(Guard, Path),
- (fun() ->
- {ok, 200, Response} = request(get, uri(Path)),
- ?assertMatch(Guard, emqx_utils_json:decode(Response, [return_maps]))
- end)()
- ).
- all() ->
- emqx_common_test_helpers:all(?MODULE).
- groups() ->
- [].
- init_per_testcase(t_authenticator_fail, Config) ->
- meck:expect(emqx_authn_proto_v1, lookup_from_all_nodes, 3, [{error, {exception, badarg}}]),
- init_per_testcase(default, Config);
- init_per_testcase(_Case, Config) ->
- {ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
- emqx_authn_test_lib:delete_authenticators(
- [?CONF_NS_ATOM],
- ?GLOBAL
- ),
- emqx_authn_test_lib:delete_authenticators(
- [listeners, tcp, default, ?CONF_NS_ATOM],
- ?TCP_DEFAULT
- ),
- {atomic, ok} = mria:clear_table(emqx_authn_mnesia),
- Config.
- end_per_testcase(t_authenticator_fail, Config) ->
- meck:unload(emqx_authn_proto_v1),
- Config;
- end_per_testcase(_, Config) ->
- Config.
- init_per_suite(Config) ->
- emqx_config:erase(?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_BINARY),
- _ = application:load(emqx_conf),
- ok = emqx_mgmt_api_test_util:init_suite(
- [emqx_conf, emqx_authn]
- ),
- ?AUTHN:delete_chain(?GLOBAL),
- {ok, Chains} = ?AUTHN:list_chains(),
- ?assertEqual(length(Chains), 0),
- Config.
- end_per_suite(_Config) ->
- emqx_mgmt_api_test_util:end_suite([emqx_authn]),
- ok.
- %%------------------------------------------------------------------------------
- %% Tests
- %%------------------------------------------------------------------------------
- t_invalid_listener(_) ->
- {ok, 404, _} = request(get, uri(["listeners", "invalid", ?CONF_NS])),
- {ok, 404, _} = request(get, uri(["listeners", "in:valid", ?CONF_NS])).
- t_authenticators(_) ->
- test_authenticators([]).
- t_authenticator(_) ->
- test_authenticator([]).
- t_authenticator_fail(_) ->
- ValidConfig0 = emqx_authn_test_lib:http_example(),
- {ok, 200, _} = request(
- post,
- uri([?CONF_NS]),
- ValidConfig0
- ),
- ?assertMatch(
- {ok, 500, _},
- request(
- get,
- uri([?CONF_NS, "password_based:http", "status"])
- )
- ).
- t_authenticator_users(_) ->
- test_authenticator_users([]).
- t_authenticator_user(_) ->
- test_authenticator_user([]).
- t_authenticator_position(_) ->
- test_authenticator_position([]).
- t_authenticator_import_users(_) ->
- test_authenticator_import_users([]).
- %t_listener_authenticators(_) ->
- % test_authenticators(["listeners", ?TCP_DEFAULT]).
- %t_listener_authenticator(_) ->
- % test_authenticator(["listeners", ?TCP_DEFAULT]).
- %t_listener_authenticator_users(_) ->
- % test_authenticator_users(["listeners", ?TCP_DEFAULT]).
- %t_listener_authenticator_user(_) ->
- % test_authenticator_user(["listeners", ?TCP_DEFAULT]).
- %t_listener_authenticator_position(_) ->
- % test_authenticator_position(["listeners", ?TCP_DEFAULT]).
- %t_listener_authenticator_import_users(_) ->
- % test_authenticator_import_users(["listeners", ?TCP_DEFAULT]).
- t_aggregate_metrics(_) ->
- Metrics = #{
- 'emqx@node1.emqx.io' => #{
- metrics =>
- #{
- failed => 0,
- total => 1,
- rate => 0.0,
- rate_last5m => 0.0,
- rate_max => 0.1,
- success => 1,
- nomatch => 1
- }
- },
- 'emqx@node2.emqx.io' => #{
- metrics =>
- #{
- failed => 0,
- total => 1,
- rate => 0.0,
- rate_last5m => 0.0,
- rate_max => 0.1,
- success => 1,
- nomatch => 2
- }
- }
- },
- Res = emqx_authn_api:aggregate_metrics(maps:values(Metrics)),
- ?assertEqual(
- #{
- metrics =>
- #{
- failed => 0,
- total => 2,
- rate => 0.0,
- rate_last5m => 0.0,
- rate_max => 0.2,
- success => 2,
- nomatch => 3
- }
- },
- Res
- ).
- test_authenticators(PathPrefix) ->
- ValidConfig = emqx_authn_test_lib:http_example(),
- {ok, 200, _} = request(
- post,
- uri(PathPrefix ++ [?CONF_NS]),
- ValidConfig
- ),
- {ok, 409, _} = request(
- post,
- uri(PathPrefix ++ [?CONF_NS]),
- ValidConfig
- ),
- InvalidConfig0 = ValidConfig#{method => <<"delete">>},
- {ok, 400, _} = request(
- post,
- uri(PathPrefix ++ [?CONF_NS]),
- InvalidConfig0
- ),
- ValidConfig1 = ValidConfig#{
- method => <<"get">>,
- headers => #{<<"content-type">> => <<"application/json">>}
- },
- {ok, 204, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "password_based:http"]),
- ValidConfig1
- ),
- ?assertAuthenticatorsMatch(
- [#{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"http">>}],
- PathPrefix ++ [?CONF_NS]
- ).
- test_authenticator(PathPrefix) ->
- ValidConfig0 = emqx_authn_test_lib:http_example(),
- {ok, 200, _} = request(
- post,
- uri(PathPrefix ++ [?CONF_NS]),
- ValidConfig0
- ),
- {ok, 200, _} = request(
- get,
- uri(PathPrefix ++ [?CONF_NS, "password_based:http"])
- ),
- {ok, 200, Res} = request(
- get,
- uri(PathPrefix ++ [?CONF_NS, "password_based:http", "status"])
- ),
- {ok, RList} = emqx_utils_json:safe_decode(Res),
- Snd = fun({_, Val}) -> Val end,
- LookupVal = fun LookupV(List, RestJson) ->
- case List of
- [Name] -> Snd(lists:keyfind(Name, 1, RestJson));
- [Name | NS] -> LookupV(NS, Snd(lists:keyfind(Name, 1, RestJson)))
- end
- end,
- LookFun = fun(List) -> LookupVal(List, RList) end,
- MetricsList = [
- {<<"failed">>, 0},
- {<<"total">>, 0},
- {<<"rate">>, 0.0},
- {<<"rate_last5m">>, 0.0},
- {<<"rate_max">>, 0.0},
- {<<"success">>, 0}
- ],
- EqualFun = fun({M, V}) ->
- ?assertEqual(
- V,
- LookFun([
- <<"metrics">>,
- M
- ])
- )
- end,
- lists:map(EqualFun, MetricsList),
- ?assertEqual(
- <<"connected">>,
- LookFun([<<"status">>])
- ),
- ?assertMatch(
- {ok, 404, _},
- request(
- get,
- uri(PathPrefix ++ [?CONF_NS, "unknown_auth_chain", "status"])
- )
- ),
- {ok, 404, _} = request(
- get,
- uri(PathPrefix ++ [?CONF_NS, "password_based:redis"])
- ),
- {ok, 404, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "password_based:built_in_database"]),
- emqx_authn_test_lib:built_in_database_example()
- ),
- InvalidConfig0 = ValidConfig0#{method => <<"delete">>},
- {ok, 400, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "password_based:http"]),
- InvalidConfig0
- ),
- ValidConfig1 = ValidConfig0#{
- method => <<"get">>,
- headers => #{<<"content-type">> => <<"application/json">>}
- },
- {ok, 204, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "password_based:http"]),
- ValidConfig1
- ),
- ValidConfig2 = ValidConfig0#{pool_size => 9},
- {ok, 204, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "password_based:http"]),
- ValidConfig2
- ),
- {ok, 404, _} = request(
- delete,
- uri(PathPrefix ++ [?CONF_NS, "password_based:redis"])
- ),
- {ok, 204, _} = request(
- delete,
- uri(PathPrefix ++ [?CONF_NS, "password_based:http"])
- ),
- ?assertAuthenticatorsMatch([], PathPrefix ++ [?CONF_NS]).
- test_authenticator_users(PathPrefix) ->
- UsersUri = uri(PathPrefix ++ [?CONF_NS, "password_based:built_in_database", "users"]),
- {ok, 200, _} = request(
- post,
- uri(PathPrefix ++ [?CONF_NS]),
- emqx_authn_test_lib:built_in_database_example()
- ),
- {ok, Client} = emqtt:start_link(
- [
- {username, <<"u_event">>},
- {clientid, <<"c_event">>},
- {proto_ver, v5},
- {properties, #{'Session-Expiry-Interval' => 60}}
- ]
- ),
- process_flag(trap_exit, true),
- ?assertMatch({error, _}, emqtt:connect(Client)),
- timer:sleep(300),
- UsersUri0 = uri(PathPrefix ++ [?CONF_NS, "password_based:built_in_database", "status"]),
- {ok, 200, PageData0} = request(get, UsersUri0),
- case PathPrefix of
- [] ->
- #{
- <<"metrics">> := #{
- <<"total">> := 1,
- <<"success">> := 0,
- <<"nomatch">> := 1
- }
- } = emqx_utils_json:decode(PageData0, [return_maps]);
- ["listeners", 'tcp:default'] ->
- #{
- <<"metrics">> := #{
- <<"total">> := 1,
- <<"success">> := 0,
- <<"nomatch">> := 1
- }
- } = emqx_utils_json:decode(PageData0, [return_maps])
- end,
- InvalidUsers = [
- #{clientid => <<"u1">>, password => <<"p1">>},
- #{user_id => <<"u2">>},
- #{user_id => <<"u3">>, password => <<"p3">>, foobar => <<"foobar">>}
- ],
- lists:foreach(
- fun(User) -> {ok, 400, _} = request(post, UsersUri, User) end,
- InvalidUsers
- ),
- ValidUsers = [
- #{user_id => <<"u1">>, password => <<"p1">>},
- #{user_id => <<"u2">>, password => <<"p2">>, is_superuser => true},
- #{user_id => <<"u3">>, password => <<"p3">>}
- ],
- lists:foreach(
- fun(User) ->
- {ok, 201, UserData} = request(post, UsersUri, User),
- CreatedUser = emqx_utils_json:decode(UserData, [return_maps]),
- ?assertMatch(#{<<"user_id">> := _}, CreatedUser)
- end,
- ValidUsers
- ),
- {ok, Client1} = emqtt:start_link(
- [
- {username, <<"u1">>},
- {password, <<"p1">>},
- {clientid, <<"c_event">>},
- {proto_ver, v5},
- {properties, #{'Session-Expiry-Interval' => 60}}
- ]
- ),
- {ok, _} = emqtt:connect(Client1),
- timer:sleep(300),
- UsersUri01 = uri(PathPrefix ++ [?CONF_NS, "password_based:built_in_database", "status"]),
- {ok, 200, PageData01} = request(get, UsersUri01),
- case PathPrefix of
- [] ->
- #{
- <<"metrics">> := #{
- <<"total">> := 2,
- <<"success">> := 1,
- <<"nomatch">> := 1
- }
- } = emqx_utils_json:decode(PageData01, [return_maps]);
- ["listeners", 'tcp:default'] ->
- #{
- <<"metrics">> := #{
- <<"total">> := 2,
- <<"success">> := 1,
- <<"nomatch">> := 1
- }
- } = emqx_utils_json:decode(PageData01, [return_maps])
- end,
- {ok, 200, Page1Data} = request(get, UsersUri ++ "?page=1&limit=2"),
- #{
- <<"data">> := Page1Users,
- <<"meta">> :=
- #{
- <<"page">> := 1,
- <<"limit">> := 2,
- <<"count">> := 3
- }
- } =
- emqx_utils_json:decode(Page1Data, [return_maps]),
- {ok, 200, Page2Data} = request(get, UsersUri ++ "?page=2&limit=2"),
- #{
- <<"data">> := Page2Users,
- <<"meta">> :=
- #{
- <<"page">> := 2,
- <<"limit">> := 2,
- <<"count">> := 3
- }
- } = emqx_utils_json:decode(Page2Data, [return_maps]),
- ?assertEqual(2, length(Page1Users)),
- ?assertEqual(1, length(Page2Users)),
- ?assertEqual(
- [<<"u1">>, <<"u2">>, <<"u3">>],
- lists:usort([UserId || #{<<"user_id">> := UserId} <- Page1Users ++ Page2Users])
- ),
- {ok, 200, Super1Data} = request(get, UsersUri ++ "?page=1&limit=3&is_superuser=true"),
- #{
- <<"data">> := Super1Users,
- <<"meta">> :=
- #{
- <<"page">> := 1,
- <<"limit">> := 3,
- <<"count">> := 1
- }
- } = emqx_utils_json:decode(Super1Data, [return_maps]),
- ?assertEqual(
- [<<"u2">>],
- lists:usort([UserId || #{<<"user_id">> := UserId} <- Super1Users])
- ),
- {ok, 200, Super2Data} = request(get, UsersUri ++ "?page=1&limit=3&is_superuser=false"),
- #{
- <<"data">> := Super2Users,
- <<"meta">> :=
- #{
- <<"page">> := 1,
- <<"limit">> := 3,
- <<"count">> := 2
- }
- } = emqx_utils_json:decode(Super2Data, [return_maps]),
- ?assertEqual(
- [<<"u1">>, <<"u3">>],
- lists:usort([UserId || #{<<"user_id">> := UserId} <- Super2Users])
- ),
- ok.
- test_authenticator_user(PathPrefix) ->
- UsersUri = uri(PathPrefix ++ [?CONF_NS, "password_based:built_in_database", "users"]),
- {ok, 200, _} = request(
- post,
- uri(PathPrefix ++ [?CONF_NS]),
- emqx_authn_test_lib:built_in_database_example()
- ),
- User = #{user_id => <<"u1">>, password => <<"p1">>},
- {ok, 201, _} = request(post, UsersUri, User),
- {ok, 404, _} = request(get, UsersUri ++ "/u123"),
- {ok, 409, _} = request(post, UsersUri, User),
- {ok, 200, UserData} = request(get, UsersUri ++ "/u1"),
- FetchedUser = emqx_utils_json:decode(UserData, [return_maps]),
- ?assertMatch(#{<<"user_id">> := <<"u1">>}, FetchedUser),
- ?assertNotMatch(#{<<"password">> := _}, FetchedUser),
- ValidUserUpdates = [
- #{password => <<"p1">>},
- #{password => <<"p1">>, is_superuser => true}
- ],
- lists:foreach(
- fun(UserUpdate) -> {ok, 200, _} = request(put, UsersUri ++ "/u1", UserUpdate) end,
- ValidUserUpdates
- ),
- InvalidUserUpdates = [#{user_id => <<"u1">>, password => <<"p1">>}],
- lists:foreach(
- fun(UserUpdate) -> {ok, 400, _} = request(put, UsersUri ++ "/u1", UserUpdate) end,
- InvalidUserUpdates
- ),
- {ok, 404, _} = request(delete, UsersUri ++ "/u123"),
- {ok, 204, _} = request(delete, UsersUri ++ "/u1").
- test_authenticator_position(PathPrefix) ->
- AuthenticatorConfs = [
- emqx_authn_test_lib:http_example(),
- emqx_authn_test_lib:jwt_example(),
- emqx_authn_test_lib:built_in_database_example()
- ],
- lists:foreach(
- fun(Conf) ->
- {ok, 200, _} = request(
- post,
- uri(PathPrefix ++ [?CONF_NS]),
- Conf
- )
- end,
- AuthenticatorConfs
- ),
- ?assertAuthenticatorsMatch(
- [
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"http">>},
- #{<<"mechanism">> := <<"jwt">>},
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"built_in_database">>}
- ],
- PathPrefix ++ [?CONF_NS]
- ),
- %% Invalid moves
- {ok, 400, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "up"])
- ),
- {ok, 404, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "jwt", "position"])
- ),
- {ok, 404, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "before:invalid"])
- ),
- {ok, 404, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "before:password_based:redis"])
- ),
- %% Valid moves
- %% test front
- {ok, 204, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "front"])
- ),
- ?assertAuthenticatorsMatch(
- [
- #{<<"mechanism">> := <<"jwt">>},
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"http">>},
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"built_in_database">>}
- ],
- PathPrefix ++ [?CONF_NS]
- ),
- %% test rear
- {ok, 204, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "rear"])
- ),
- ?assertAuthenticatorsMatch(
- [
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"http">>},
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"built_in_database">>},
- #{<<"mechanism">> := <<"jwt">>}
- ],
- PathPrefix ++ [?CONF_NS]
- ),
- %% test before
- {ok, 204, _} = request(
- put,
- uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "before:password_based:built_in_database"])
- ),
- ?assertAuthenticatorsMatch(
- [
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"http">>},
- #{<<"mechanism">> := <<"jwt">>},
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"built_in_database">>}
- ],
- PathPrefix ++ [?CONF_NS]
- ),
- %% test after
- {ok, 204, _} = request(
- put,
- uri(
- PathPrefix ++
- [
- ?CONF_NS,
- "password_based%3Abuilt_in_database",
- "position",
- "after:password_based:http"
- ]
- )
- ),
- ?assertAuthenticatorsMatch(
- [
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"http">>},
- #{<<"mechanism">> := <<"password_based">>, <<"backend">> := <<"built_in_database">>},
- #{<<"mechanism">> := <<"jwt">>}
- ],
- PathPrefix ++ [?CONF_NS]
- ).
- test_authenticator_import_users(PathPrefix) ->
- ImportUri = uri(
- PathPrefix ++
- [?CONF_NS, "password_based:built_in_database", "import_users"]
- ),
- {ok, 200, _} = request(
- post,
- uri(PathPrefix ++ [?CONF_NS]),
- emqx_authn_test_lib:built_in_database_example()
- ),
- {ok, 400, _} = multipart_formdata_request(ImportUri, [], []),
- {ok, 400, _} = multipart_formdata_request(ImportUri, [], [
- {filenam, "user-credentials.json", <<>>}
- ]),
- Dir = code:lib_dir(emqx_authn, test),
- JSONFileName = filename:join([Dir, <<"data/user-credentials.json">>]),
- CSVFileName = filename:join([Dir, <<"data/user-credentials.csv">>]),
- {ok, JSONData} = file:read_file(JSONFileName),
- {ok, 204, _} = multipart_formdata_request(ImportUri, [], [
- {filename, "user-credentials.json", JSONData}
- ]),
- {ok, CSVData} = file:read_file(CSVFileName),
- {ok, 204, _} = multipart_formdata_request(ImportUri, [], [
- {filename, "user-credentials.csv", CSVData}
- ]).
- %% listener authn api is not supported since 5.1.0
- %% Don't support listener switch to global chain.
- ignore_switch_to_global_chain(_) ->
- {ok, 200, _} = request(
- post,
- uri([?CONF_NS]),
- emqx_authn_test_lib:built_in_database_example()
- ),
- {ok, 200, _} = request(
- post,
- uri([listeners, "tcp:default", ?CONF_NS]),
- emqx_authn_test_lib:built_in_database_example()
- ),
- {ok, 200, _} = request(
- post,
- uri([listeners, "tcp:default", ?CONF_NS]),
- maps:put(enable, false, emqx_authn_test_lib:http_example())
- ),
- GlobalUser = #{user_id => <<"global_user">>, password => <<"p1">>},
- {ok, 201, _} = request(
- post,
- uri([?CONF_NS, "password_based:built_in_database", "users"]),
- GlobalUser
- ),
- ListenerUser = #{user_id => <<"listener_user">>, password => <<"p1">>},
- {ok, 201, _} = request(
- post,
- uri([listeners, "tcp:default", ?CONF_NS, "password_based:built_in_database", "users"]),
- ListenerUser
- ),
- process_flag(trap_exit, true),
- %% Listener user should be OK
- {ok, Client0} = emqtt:start_link([
- {username, <<"listener_user">>},
- {password, <<"p1">>}
- ]),
- ?assertMatch(
- {ok, _},
- emqtt:connect(Client0)
- ),
- ok = emqtt:disconnect(Client0),
- %% Global user should not be OK
- {ok, Client1} = emqtt:start_link([
- {username, <<"global_user">>},
- {password, <<"p1">>}
- ]),
- ?assertMatch(
- {error, {unauthorized_client, _}},
- emqtt:connect(Client1)
- ),
- {ok, 204, _} = request(
- delete,
- uri([listeners, "tcp:default", ?CONF_NS, "password_based:built_in_database"])
- ),
- %% Now listener has only disabled authenticators, should allow anonymous access
- {ok, Client2} = emqtt:start_link([
- {username, <<"any_user">>},
- {password, <<"any_password">>}
- ]),
- ?assertMatch(
- {ok, _},
- emqtt:connect(Client2)
- ),
- ok = emqtt:disconnect(Client2),
- {ok, 204, _} = request(
- delete,
- uri([listeners, "tcp:default", ?CONF_NS, "password_based:http"])
- ),
- %% Local chain is empty now and should be removed
- %% Listener user should not be OK
- {ok, Client3} = emqtt:start_link([
- {username, <<"listener_user">>},
- {password, <<"p1">>}
- ]),
- ?assertMatch(
- {error, {unauthorized_client, _}},
- emqtt:connect(Client3)
- ),
- %% Global user should be now OK, switched back to the global chain
- {ok, Client4} = emqtt:start_link([
- {username, <<"global_user">>},
- {password, <<"p1">>}
- ]),
- ?assertMatch(
- {ok, _},
- emqtt:connect(Client4)
- ),
- ok = emqtt:disconnect(Client4).
- %%------------------------------------------------------------------------------
- %% Helpers
- %%------------------------------------------------------------------------------
- request(Method, Url) ->
- request(Method, Url, []).
|