192 lines
9.3 KiB
Erlang
192 lines
9.3 KiB
Erlang
%%--------------------------------------------------------------------
|
||
%% Copyright (c) 2020-2021 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_authentication_SUITE).
|
||
|
||
-compile(export_all).
|
||
-compile(nowarn_export_all).
|
||
|
||
-include_lib("common_test/include/ct.hrl").
|
||
-include_lib("eunit/include/eunit.hrl").
|
||
|
||
-define(AUTH, emqx_authentication).
|
||
|
||
all() ->
|
||
emqx_ct:all(?MODULE).
|
||
|
||
init_per_suite(Config) ->
|
||
emqx_ct_helpers:start_apps([emqx_authentication]),
|
||
Config.
|
||
|
||
end_per_suite(_) ->
|
||
emqx_ct_helpers:stop_apps([emqx_authentication]),
|
||
ok.
|
||
|
||
t_chain(_) ->
|
||
ChainID = <<"mychain">>,
|
||
?assertMatch({ok, #{id := ChainID, services := []}}, ?AUTH:create_chain(#{id => ChainID})),
|
||
?assertEqual({error, {already_exists, {chain, ChainID}}}, ?AUTH:create_chain(#{id => ChainID})),
|
||
?assertMatch({ok, #{id := ChainID, services := []}}, ?AUTH:lookup_chain(ChainID)),
|
||
?assertEqual(ok, ?AUTH:delete_chain(ChainID)),
|
||
?assertMatch({error, {not_found, {chain, ChainID}}}, ?AUTH:lookup_chain(ChainID)),
|
||
ok.
|
||
|
||
t_service(_) ->
|
||
ChainID = <<"mychain">>,
|
||
?assertMatch({ok, #{id := ChainID, services := []}}, ?AUTH:create_chain(#{id => ChainID})),
|
||
?assertMatch({ok, #{id := ChainID, services := []}}, ?AUTH:lookup_chain(ChainID)),
|
||
|
||
ServiceName1 = <<"myservice1">>,
|
||
ServiceParams1 = #{name => ServiceName1,
|
||
type => mnesia,
|
||
params => #{
|
||
user_id_type => <<"username">>,
|
||
password_hash_algorithm => <<"sha256">>}},
|
||
?assertEqual({ok, [ServiceParams1]}, ?AUTH:add_services(ChainID, [ServiceParams1])),
|
||
?assertEqual({ok, ServiceParams1}, ?AUTH:lookup_service(ChainID, ServiceName1)),
|
||
?assertEqual({ok, [ServiceParams1]}, ?AUTH:list_services(ChainID)),
|
||
?assertEqual({error, {already_exists, {service, ServiceName1}}}, ?AUTH:add_services(ChainID, [ServiceParams1])),
|
||
|
||
ServiceName2 = <<"myservice2">>,
|
||
ServiceParams2 = ServiceParams1#{name => ServiceName2},
|
||
?assertEqual({ok, [ServiceParams2]}, ?AUTH:add_services(ChainID, [ServiceParams2])),
|
||
?assertMatch({ok, #{id := ChainID, services := [ServiceParams1, ServiceParams2]}}, ?AUTH:lookup_chain(ChainID)),
|
||
?assertEqual({ok, ServiceParams2}, ?AUTH:lookup_service(ChainID, ServiceName2)),
|
||
?assertEqual({ok, [ServiceParams1, ServiceParams2]}, ?AUTH:list_services(ChainID)),
|
||
|
||
?assertEqual(ok, ?AUTH:move_service_to_the_front(ChainID, ServiceName2)),
|
||
?assertEqual({ok, [ServiceParams2, ServiceParams1]}, ?AUTH:list_services(ChainID)),
|
||
?assertEqual(ok, ?AUTH:move_service_to_the_end(ChainID, ServiceName2)),
|
||
?assertEqual({ok, [ServiceParams1, ServiceParams2]}, ?AUTH:list_services(ChainID)),
|
||
?assertEqual(ok, ?AUTH:move_service_to_the_nth(ChainID, ServiceName2, 1)),
|
||
?assertEqual({ok, [ServiceParams2, ServiceParams1]}, ?AUTH:list_services(ChainID)),
|
||
?assertEqual({error, out_of_range}, ?AUTH:move_service_to_the_nth(ChainID, ServiceName2, 3)),
|
||
?assertEqual({error, out_of_range}, ?AUTH:move_service_to_the_nth(ChainID, ServiceName2, 0)),
|
||
?assertEqual(ok, ?AUTH:delete_services(ChainID, [ServiceName1, ServiceName2])),
|
||
?assertEqual({ok, []}, ?AUTH:list_services(ChainID)),
|
||
?assertEqual(ok, ?AUTH:delete_chain(ChainID)),
|
||
ok.
|
||
|
||
t_mnesia_service(_) ->
|
||
ChainID = <<"mychain">>,
|
||
?assertMatch({ok, #{id := ChainID, services := []}}, ?AUTH:create_chain(#{id => ChainID})),
|
||
|
||
ServiceName = <<"myservice">>,
|
||
ServiceParams = #{name => ServiceName,
|
||
type => mnesia,
|
||
params => #{
|
||
user_id_type => <<"username">>,
|
||
password_hash_algorithm => <<"sha256">>}},
|
||
?assertEqual({ok, [ServiceParams]}, ?AUTH:add_services(ChainID, [ServiceParams])),
|
||
|
||
UserInfo = #{<<"user_id">> => <<"myuser">>,
|
||
<<"password">> => <<"mypass">>},
|
||
?assertEqual({ok, #{user_id => <<"myuser">>}}, ?AUTH:add_user(ChainID, ServiceName, UserInfo)),
|
||
?assertEqual({ok, #{user_id => <<"myuser">>}}, ?AUTH:lookup_user(ChainID, ServiceName, <<"myuser">>)),
|
||
ClientInfo = #{chain_id => ChainID,
|
||
username => <<"myuser">>,
|
||
password => <<"mypass">>},
|
||
?assertEqual(ok, ?AUTH:authenticate(ClientInfo)),
|
||
ClientInfo2 = ClientInfo#{username => <<"baduser">>},
|
||
?assertEqual({error, user_not_found}, ?AUTH:authenticate(ClientInfo2)),
|
||
ClientInfo3 = ClientInfo#{password => <<"badpass">>},
|
||
?assertEqual({error, bad_password}, ?AUTH:authenticate(ClientInfo3)),
|
||
UserInfo2 = UserInfo#{<<"password">> => <<"mypass2">>},
|
||
?assertEqual({ok, #{user_id => <<"myuser">>}}, ?AUTH:update_user(ChainID, ServiceName, <<"myuser">>, UserInfo2)),
|
||
ClientInfo4 = ClientInfo#{password => <<"mypass2">>},
|
||
?assertEqual(ok, ?AUTH:authenticate(ClientInfo4)),
|
||
?assertEqual(ok, ?AUTH:delete_user(ChainID, ServiceName, <<"myuser">>)),
|
||
?assertEqual({error, not_found}, ?AUTH:lookup_user(ChainID, ServiceName, <<"myuser">>)),
|
||
|
||
?assertEqual({ok, #{user_id => <<"myuser">>}}, ?AUTH:add_user(ChainID, ServiceName, UserInfo)),
|
||
?assertMatch({ok, #{user_id := <<"myuser">>}}, ?AUTH:lookup_user(ChainID, ServiceName, <<"myuser">>)),
|
||
?assertEqual(ok, ?AUTH:delete_services(ChainID, [ServiceName])),
|
||
?assertEqual({ok, [ServiceParams]}, ?AUTH:add_services(ChainID, [ServiceParams])),
|
||
?assertMatch({error, not_found}, ?AUTH:lookup_user(ChainID, ServiceName, <<"myuser">>)),
|
||
|
||
?assertEqual(ok, ?AUTH:delete_chain(ChainID)),
|
||
?assertEqual([], ets:tab2list(mnesia_basic_auth)),
|
||
ok.
|
||
|
||
t_import(_) ->
|
||
ChainID = <<"mychain">>,
|
||
?assertMatch({ok, #{id := ChainID, services := []}}, ?AUTH:create_chain(#{id => ChainID})),
|
||
|
||
ServiceName = <<"myservice">>,
|
||
ServiceParams = #{name => ServiceName,
|
||
type => mnesia,
|
||
params => #{
|
||
user_id_type => <<"username">>,
|
||
password_hash_algorithm => <<"sha256">>}},
|
||
?assertEqual({ok, [ServiceParams]}, ?AUTH:add_services(ChainID, [ServiceParams])),
|
||
|
||
Dir = code:lib_dir(emqx_authentication, test),
|
||
?assertEqual(ok, ?AUTH:import_users(ChainID, ServiceName, filename:join([Dir, "data/user-credentials.json"]))),
|
||
?assertEqual(ok, ?AUTH:import_users(ChainID, ServiceName, filename:join([Dir, "data/user-credentials.csv"]))),
|
||
?assertMatch({ok, #{user_id := <<"myuser1">>}}, ?AUTH:lookup_user(ChainID, ServiceName, <<"myuser1">>)),
|
||
?assertMatch({ok, #{user_id := <<"myuser3">>}}, ?AUTH:lookup_user(ChainID, ServiceName, <<"myuser3">>)),
|
||
ClientInfo1 = #{chain_id => ChainID,
|
||
username => <<"myuser1">>,
|
||
password => <<"mypassword1">>},
|
||
?assertEqual(ok, ?AUTH:authenticate(ClientInfo1)),
|
||
ClientInfo2 = ClientInfo1#{username => <<"myuser3">>,
|
||
password => <<"mypassword3">>},
|
||
?assertEqual(ok, ?AUTH:authenticate(ClientInfo2)),
|
||
?assertEqual(ok, ?AUTH:delete_chain(ChainID)),
|
||
ok.
|
||
|
||
t_multi_mnesia_service(_) ->
|
||
ChainID = <<"mychain">>,
|
||
?assertMatch({ok, #{id := ChainID, services := []}}, ?AUTH:create_chain(#{id => ChainID})),
|
||
|
||
ServiceName1 = <<"myservice1">>,
|
||
ServiceParams1 = #{name => ServiceName1,
|
||
type => mnesia,
|
||
params => #{
|
||
user_id_type => <<"username">>,
|
||
password_hash_algorithm => <<"sha256">>}},
|
||
ServiceName2 = <<"myservice2">>,
|
||
ServiceParams2 = #{name => ServiceName2,
|
||
type => mnesia,
|
||
params => #{
|
||
user_id_type => <<"clientid">>,
|
||
password_hash_algorithm => <<"sha256">>}},
|
||
?assertEqual({ok, [ServiceParams1]}, ?AUTH:add_services(ChainID, [ServiceParams1])),
|
||
?assertEqual({ok, [ServiceParams2]}, ?AUTH:add_services(ChainID, [ServiceParams2])),
|
||
|
||
?assertEqual({ok, #{user_id => <<"myuser">>}},
|
||
?AUTH:add_user(ChainID, ServiceName1,
|
||
#{<<"user_id">> => <<"myuser">>,
|
||
<<"password">> => <<"mypass1">>})),
|
||
?assertEqual({ok, #{user_id => <<"myclient">>}},
|
||
?AUTH:add_user(ChainID, ServiceName2,
|
||
#{<<"user_id">> => <<"myclient">>,
|
||
<<"password">> => <<"mypass2">>})),
|
||
ClientInfo1 = #{chain_id => ChainID,
|
||
username => <<"myuser">>,
|
||
clientid => <<"myclient">>,
|
||
password => <<"mypass1">>},
|
||
?assertEqual(ok, ?AUTH:authenticate(ClientInfo1)),
|
||
?assertEqual(ok, ?AUTH:move_service_to_the_front(ChainID, ServiceName2)),
|
||
?assertEqual({error, bad_password}, ?AUTH:authenticate(ClientInfo1)),
|
||
ClientInfo2 = ClientInfo1#{password => <<"mypass2">>},
|
||
?assertEqual(ok, ?AUTH:authenticate(ClientInfo2)),
|
||
?assertEqual(ok, ?AUTH:delete_chain(ChainID)),
|
||
ok.
|
||
|
||
|
||
|