chore(authz): test Mongo backend with real Mongo

This commit is contained in:
Ilya Averyanov 2021-12-15 23:06:38 +03:00
parent 28c319b6c4
commit a21f67a67e
4 changed files with 286 additions and 194 deletions

View File

@ -97,7 +97,7 @@ replvar(Selector, #{clientid := Clientid,
, bin(Clientid), [global, {return, binary}]),
V2 = re:replace( V1, emqx_authz:ph_to_re(?PH_S_USERNAME)
, bin(Username), [global, {return, binary}]),
V3 = re:replace( V2, emqx_authz:ph_to_re(?PH_S_HOST)
V3 = re:replace( V2, emqx_authz:ph_to_re(?PH_S_PEERHOST)
, inet_parse:ntoa(IpAddress), [global, {return, binary}]),
maps:put(K, V3, AccIn);
InFun(K, V, AccIn) -> maps:put(K, V, AccIn)

View File

@ -69,7 +69,6 @@ set_special_configs(_) ->
%% Testcases
%%------------------------------------------------------------------------------
t_topic_rules(_Config) ->
ClientInfo = #{clientid => <<"clientid">>,
username => <<"username">>,
@ -78,106 +77,14 @@ t_topic_rules(_Config) ->
listener => {tcp, default}
},
%% No rules
ok = emqx_authz_test_lib:test_no_topic_rules(ClientInfo, fun setup_client_samples/2),
ok = setup_samples([]),
ok = setup_config(#{}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{deny, subscribe, <<"#">>},
{deny, subscribe, <<"subs">>},
{deny, publish, <<"pub">>}]),
%% Publish rules
Samples0 = populate_records(
[#{<<"topics">> => [<<"eq testpub1/${username}">>]},
#{<<"topics">> => [<<"testpub2/${clientid}">>, <<"testpub3/#">>]}],
#{<<"permission">> => <<"allow">>,
<<"action">> => <<"publish">>,
<<"username">> => <<"username">>}),
ok = setup_samples(Samples0),
ok = setup_config(#{}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{deny, publish, <<"testpub1/username">>},
{allow, publish, <<"testpub1/${username}">>},
{allow, publish, <<"testpub2/clientid">>},
{allow, publish, <<"testpub3/foobar">>},
{deny, publish, <<"testpub2/username">>},
{deny, publish, <<"testpub1/clientid">>},
{deny, subscribe, <<"testpub1/username">>},
{deny, subscribe, <<"testpub2/clientid">>},
{deny, subscribe, <<"testpub3/foobar">>}]),
%% Subscribe rules
Samples1 = populate_records(
[#{<<"topics">> => [<<"eq testsub1/${username}">>]},
#{<<"topics">> => [<<"testsub2/${clientid}">>, <<"testsub3/#">>]}],
#{<<"permission">> => <<"allow">>,
<<"action">> => <<"subscribe">>,
<<"username">> => <<"username">>}),
ok = setup_samples(Samples1),
ok = setup_config(#{}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{deny, subscribe, <<"testsub1/username">>},
{allow, subscribe, <<"testsub1/${username}">>},
{allow, subscribe, <<"testsub2/clientid">>},
{allow, subscribe, <<"testsub3/foobar">>},
{allow, subscribe, <<"testsub3/+/foobar">>},
{allow, subscribe, <<"testsub3/#">>},
{deny, subscribe, <<"testsub2/username">>},
{deny, subscribe, <<"testsub1/clientid">>},
{deny, subscribe, <<"testsub4/foobar">>},
{deny, publish, <<"testsub1/username">>},
{deny, publish, <<"testsub2/clientid">>},
{deny, publish, <<"testsub3/foobar">>}]),
%% All rules
Samples2 = populate_records(
[#{<<"topics">> => [<<"eq testall1/${username}">>]},
#{<<"topics">> => [<<"testall2/${clientid}">>, <<"testall3/#">>]}],
#{<<"permission">> => <<"allow">>,
<<"action">> => <<"all">>,
<<"username">> => <<"username">>}),
ok = setup_samples(Samples2),
ok = setup_config(#{}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{deny, subscribe, <<"testall1/username">>},
{allow, subscribe, <<"testall1/${username}">>},
{allow, subscribe, <<"testall2/clientid">>},
{allow, subscribe, <<"testall3/foobar">>},
{allow, subscribe, <<"testall3/+/foobar">>},
{allow, subscribe, <<"testall3/#">>},
{deny, publish, <<"testall1/username">>},
{allow, publish, <<"testall1/${username}">>},
{allow, publish, <<"testall2/clientid">>},
{allow, publish, <<"testall3/foobar">>},
{deny, subscribe, <<"testall2/username">>},
{deny, subscribe, <<"testall1/clientid">>},
{deny, subscribe, <<"testall4/foobar">>},
{deny, publish, <<"testall2/username">>},
{deny, publish, <<"testall1/clientid">>},
{deny, publish, <<"testall4/foobar">>}]).
ok = emqx_authz_test_lib:test_allow_topic_rules(ClientInfo, fun setup_client_samples/2),
ok = emqx_authz_test_lib:test_deny_topic_rules(ClientInfo, fun setup_client_samples/2).
t_complex_selector(_) ->
%% atom and string values also supported
ClientInfo = #{clientid => clientid,
username => "username",
peerhost => {127,0,0,1},
@ -205,6 +112,60 @@ t_complex_selector(_) ->
ClientInfo,
[{allow, publish, <<"t">>}]).
t_mongo_error(_Config) ->
ClientInfo = #{clientid => <<"clientid">>,
username => <<"username">>,
peerhost => {127,0,0,1},
zone => default,
listener => {tcp, default}
},
ok = setup_samples([]),
ok = setup_config(
#{<<"selector">> => #{<<"$badoperator">> => <<"$badoperator">>}}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{deny, publish, <<"t">>}]).
t_lookups(_Config) ->
ClientInfo = #{clientid => <<"clientid">>,
cn => <<"cn">>,
dn => <<"dn">>,
username => <<"username">>,
peerhost => {127,0,0,1},
zone => default,
listener => {tcp, default}
},
ByClientid = #{<<"clientid">> => <<"clientid">>,
<<"topics">> => [<<"a">>],
<<"action">> => <<"all">>,
<<"permission">> => <<"allow">>},
ok = setup_samples([ByClientid]),
ok = setup_config(
#{<<"selector">> => #{<<"clientid">> => <<"${clientid}">>}}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{allow, subscribe, <<"a">>},
{deny, subscribe, <<"b">>}]),
ByPeerhost = #{<<"peerhost">> => <<"127.0.0.1">>,
<<"topics">> => [<<"a">>],
<<"action">> => <<"all">>,
<<"permission">> => <<"allow">>},
ok = setup_samples([ByPeerhost]),
ok = setup_config(
#{<<"selector">> => #{<<"peerhost">> => <<"${peerhost}">>}}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{allow, subscribe, <<"a">>},
{deny, subscribe, <<"b">>}]).
%%------------------------------------------------------------------------------
%% Helpers
%%------------------------------------------------------------------------------
@ -217,6 +178,23 @@ setup_samples(AclRecords) ->
{{true, _}, _} = mc_worker_api:insert(?MONGO_CLIENT, <<"acl">>, AclRecords),
ok.
setup_client_samples(ClientInfo, Samples) ->
#{username := Username} = ClientInfo,
Records = lists:map(
fun(Sample) ->
#{topics := Topics,
permission := Permission,
action := Action} = Sample,
#{<<"topics">> => Topics,
<<"permission">> => Permission,
<<"action">> => Action,
<<"username">> => Username}
end,
Samples),
setup_samples(Records),
setup_config(#{<<"selector">> => #{<<"username">> => <<"${username}">>}}).
reset_samples() ->
{true, _} = mc_worker_api:delete(?MONGO_CLIENT, <<"acl">>, #{}),
ok.

View File

@ -76,96 +76,10 @@ t_topic_rules(_Config) ->
listener => {tcp, default}
},
%% No rules
ok = emqx_authz_test_lib:test_no_topic_rules(ClientInfo, fun setup_client_samples/2),
ok = setup_sample(#{}),
ok = setup_config(#{}),
ok = emqx_authz_test_lib:test_allow_topic_rules(ClientInfo, fun setup_client_samples/2).
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{deny, subscribe, <<"#">>},
{deny, subscribe, <<"subs">>},
{deny, publish, <<"pub">>}]),
%% Publish rules
Sample0 = #{<<"mqtt_user:username">> =>
#{<<"testpub1/${username}">> => <<"publish">>,
<<"testpub2/${clientid}">> => <<"publish">>,
<<"testpub3/#">> => <<"publish">>
}
},
ok = setup_sample(Sample0),
ok = setup_config(#{}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{allow, publish, <<"testpub1/username">>},
{allow, publish, <<"testpub2/clientid">>},
{allow, publish, <<"testpub3/foobar">>},
{deny, publish, <<"testpub2/username">>},
{deny, publish, <<"testpub1/clientid">>},
{deny, subscribe, <<"testpub1/username">>},
{deny, subscribe, <<"testpub2/clientid">>},
{deny, subscribe, <<"testpub3/foobar">>}]),
%% Subscribe rules
Sample1 = #{<<"mqtt_user:username">> =>
#{<<"testsub1/${username}">> => <<"subscribe">>,
<<"testsub2/${clientid}">> => <<"subscribe">>,
<<"testsub3/#">> => <<"subscribe">>
}
},
ok = setup_sample(Sample1),
ok = setup_config(#{}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{allow, subscribe, <<"testsub1/username">>},
{allow, subscribe, <<"testsub2/clientid">>},
{allow, subscribe, <<"testsub3/foobar">>},
{allow, subscribe, <<"testsub3/+/foobar">>},
{allow, subscribe, <<"testsub3/#">>},
{deny, subscribe, <<"testsub2/username">>},
{deny, subscribe, <<"testsub1/clientid">>},
{deny, subscribe, <<"testsub4/foobar">>},
{deny, publish, <<"testsub1/username">>},
{deny, publish, <<"testsub2/clientid">>},
{deny, publish, <<"testsub3/foobar">>}]),
%% All rules
Sample2 = #{<<"mqtt_user:username">> =>
#{<<"testall1/${username}">> => <<"all">>,
<<"testall2/${clientid}">> => <<"all">>,
<<"testall3/#">> => <<"all">>
}
},
ok = setup_sample(Sample2),
ok = setup_config(#{}),
ok = emqx_authz_test_lib:test_samples(
ClientInfo,
[{allow, subscribe, <<"testall1/username">>},
{allow, subscribe, <<"testall2/clientid">>},
{allow, subscribe, <<"testall3/foobar">>},
{allow, subscribe, <<"testall3/+/foobar">>},
{allow, subscribe, <<"testall3/#">>},
{allow, publish, <<"testall1/username">>},
{allow, publish, <<"testall2/clientid">>},
{allow, publish, <<"testall3/foobar">>},
{deny, subscribe, <<"testall2/username">>},
{deny, subscribe, <<"testall1/clientid">>},
{deny, subscribe, <<"testall4/foobar">>},
{deny, publish, <<"testall2/username">>},
{deny, publish, <<"testall1/clientid">>},
{deny, publish, <<"testall4/foobar">>}]).
t_lookups(_Config) ->
ClientInfo = #{clientid => <<"clientid">>,
@ -267,6 +181,23 @@ setup_sample(AuthzData) ->
end,
maps:to_list(AuthzData)).
setup_client_samples(ClientInfo, Samples) ->
#{username := Username} = ClientInfo,
Key = <<"mqtt_user:", Username/binary>>,
lists:foreach(
fun(Sample) ->
#{topics := Topics,
permission := <<"allow">>,
action := Action} = Sample,
lists:foreach(
fun(Topic) ->
q(["HSET", Key, Topic, Action])
end,
Topics)
end,
Samples),
setup_config(#{}).
setup_config(SpecialParams) ->
ok = emqx_authz_test_lib:reset_authorizers(deny, false),
Config = maps:merge(raw_redis_authz_config(), SpecialParams),

View File

@ -41,6 +41,15 @@ setup_config(BaseConfig, SpecialParams) ->
{ok, _} = emqx_authz:update(?CMD_REPLACE, [Config]),
ok.
is_tcp_server_available(Host, Port) ->
case gen_tcp:connect(Host, Port, [], ?DEFAULT_CHECK_AVAIL_TIMEOUT) of
{ok, Socket} ->
gen_tcp:close(Socket),
true;
{error, _} ->
false
end.
test_samples(ClientInfo, Samples) ->
lists:foreach(
fun({Expected, Action, Topic}) ->
@ -56,11 +65,185 @@ test_samples(ClientInfo, Samples) ->
end,
Samples).
is_tcp_server_available(Host, Port) ->
case gen_tcp:connect(Host, Port, [], ?DEFAULT_CHECK_AVAIL_TIMEOUT) of
{ok, Socket} ->
gen_tcp:close(Socket),
true;
{error, _} ->
false
end.
test_no_topic_rules(ClientInfo, SetupSamples) ->
%% No rules
ok = SetupSamples(ClientInfo, []),
ok = test_samples(
ClientInfo,
[{deny, subscribe, <<"#">>},
{deny, subscribe, <<"subs">>},
{deny, publish, <<"pub">>}]).
test_allow_topic_rules(ClientInfo, SetupSamples) ->
Samples = [#{
topics => [<<"eq testpub1/${username}">>,
<<"testpub2/${clientid}">>,
<<"testpub3/#">>],
permission => <<"allow">>,
action => <<"publish">>
},
#{
topics => [<<"eq testsub1/${username}">>,
<<"testsub2/${clientid}">>,
<<"testsub3/#">>],
permission => <<"allow">>,
action => <<"subscribe">>
},
#{
topics => [<<"eq testall1/${username}">>,
<<"testall2/${clientid}">>,
<<"testall3/#">>],
permission => <<"allow">>,
action => <<"all">>
}
],
ok = SetupSamples(ClientInfo, Samples),
ok = test_samples(
ClientInfo,
[
%% Publish rules
{deny, publish, <<"testpub1/username">>},
{allow, publish, <<"testpub1/${username}">>},
{allow, publish, <<"testpub2/clientid">>},
{allow, publish, <<"testpub3/foobar">>},
{deny, publish, <<"testpub2/username">>},
{deny, publish, <<"testpub1/clientid">>},
{deny, subscribe, <<"testpub1/username">>},
{deny, subscribe, <<"testpub2/clientid">>},
{deny, subscribe, <<"testpub3/foobar">>},
%% Subscribe rules
{deny, subscribe, <<"testsub1/username">>},
{allow, subscribe, <<"testsub1/${username}">>},
{allow, subscribe, <<"testsub2/clientid">>},
{allow, subscribe, <<"testsub3/foobar">>},
{allow, subscribe, <<"testsub3/+/foobar">>},
{allow, subscribe, <<"testsub3/#">>},
{deny, subscribe, <<"testsub2/username">>},
{deny, subscribe, <<"testsub1/clientid">>},
{deny, subscribe, <<"testsub4/foobar">>},
{deny, publish, <<"testsub1/username">>},
{deny, publish, <<"testsub2/clientid">>},
{deny, publish, <<"testsub3/foobar">>},
%% All rules
{deny, subscribe, <<"testall1/username">>},
{allow, subscribe, <<"testall1/${username}">>},
{allow, subscribe, <<"testall2/clientid">>},
{allow, subscribe, <<"testall3/foobar">>},
{allow, subscribe, <<"testall3/+/foobar">>},
{allow, subscribe, <<"testall3/#">>},
{deny, publish, <<"testall1/username">>},
{allow, publish, <<"testall1/${username}">>},
{allow, publish, <<"testall2/clientid">>},
{allow, publish, <<"testall3/foobar">>},
{deny, subscribe, <<"testall2/username">>},
{deny, subscribe, <<"testall1/clientid">>},
{deny, subscribe, <<"testall4/foobar">>},
{deny, publish, <<"testall2/username">>},
{deny, publish, <<"testall1/clientid">>},
{deny, publish, <<"testall4/foobar">>}
]).
test_deny_topic_rules(ClientInfo, SetupSamples) ->
Samples = [
#{
topics => [<<"#">>],
permission => <<"allow">>,
action => <<"all">>
},
#{
topics => [<<"eq testpub1/${username}">>,
<<"testpub2/${clientid}">>,
<<"testpub3/#">>],
permission => <<"deny">>,
action => <<"publish">>
},
#{
topics => [<<"eq testsub1/${username}">>,
<<"testsub2/${clientid}">>,
<<"testsub3/#">>],
permission => <<"deny">>,
action => <<"subscribe">>
},
#{
topics => [<<"eq testall1/${username}">>,
<<"testall2/${clientid}">>,
<<"testall3/#">>],
permission => <<"deny">>,
action => <<"all">>
}
],
ok = SetupSamples(ClientInfo, Samples),
ok = test_samples(
ClientInfo,
[
%% Publish rules
{allow, publish, <<"testpub1/username">>},
{deny, publish, <<"testpub1/${username}">>},
{deny, publish, <<"testpub2/clientid">>},
{deny, publish, <<"testpub3/foobar">>},
{allow, publish, <<"testpub2/username">>},
{allow, publish, <<"testpub1/clientid">>},
{allow, subscribe, <<"testpub1/username">>},
{allow, subscribe, <<"testpub2/clientid">>},
{allow, subscribe, <<"testpub3/foobar">>},
%% Subscribe rules
{allow, subscribe, <<"testsub1/username">>},
{deny, subscribe, <<"testsub1/${username}">>},
{deny, subscribe, <<"testsub2/clientid">>},
{deny, subscribe, <<"testsub3/foobar">>},
{deny, subscribe, <<"testsub3/+/foobar">>},
{deny, subscribe, <<"testsub3/#">>},
{allow, subscribe, <<"testsub2/username">>},
{allow, subscribe, <<"testsub1/clientid">>},
{allow, subscribe, <<"testsub4/foobar">>},
{allow, publish, <<"testsub1/username">>},
{allow, publish, <<"testsub2/clientid">>},
{allow, publish, <<"testsub3/foobar">>},
%% All rules
{allow, subscribe, <<"testall1/username">>},
{deny, subscribe, <<"testall1/${username}">>},
{deny, subscribe, <<"testall2/clientid">>},
{deny, subscribe, <<"testall3/foobar">>},
{deny, subscribe, <<"testall3/+/foobar">>},
{deny, subscribe, <<"testall3/#">>},
{allow, publish, <<"testall1/username">>},
{deny, publish, <<"testall1/${username}">>},
{deny, publish, <<"testall2/clientid">>},
{deny, publish, <<"testall3/foobar">>},
{allow, subscribe, <<"testall2/username">>},
{allow, subscribe, <<"testall1/clientid">>},
{allow, subscribe, <<"testall4/foobar">>},
{allow, publish, <<"testall2/username">>},
{allow, publish, <<"testall1/clientid">>},
{allow, publish, <<"testall4/foobar">>}
]).