diff --git a/apps/emqx_auth_mongo/src/emqx_auth_mongo.erl b/apps/emqx_auth_mongo/src/emqx_auth_mongo.erl index 1c9d1e879..5c2342559 100644 --- a/apps/emqx_auth_mongo/src/emqx_auth_mongo.erl +++ b/apps/emqx_auth_mongo/src/emqx_auth_mongo.erl @@ -161,7 +161,16 @@ test_client_info() -> %%-------------------------------------------------------------------- replvars(VarList, ClientInfo) -> - lists:map(fun(Var) -> replvar(Var, ClientInfo) end, VarList). + lists:foldl( + fun(Var, Selector) -> + case replvar(Var, ClientInfo) of + %% assumes that all fields are binaries... + {unmatchable, Field} -> [{Field, []} | Selector]; + Interpolated -> [Interpolated | Selector] + end + end, + [], + VarList). replvar({Field, <<"%u">>}, #{username := Username}) -> {Field, Username}; @@ -171,8 +180,8 @@ replvar({Field, <<"%C">>}, #{cn := CN}) -> {Field, CN}; replvar({Field, <<"%d">>}, #{dn := DN}) -> {Field, DN}; -replvar(Selector, _ClientInfo) -> - Selector. +replvar({Field, _PlaceHolder}, _ClientInfo) -> + {unmatchable, Field}. %%-------------------------------------------------------------------- %% MongoDB Connect/Query diff --git a/apps/emqx_auth_mongo/test/emqx_auth_mongo_SUITE.erl b/apps/emqx_auth_mongo/test/emqx_auth_mongo_SUITE.erl index 6e85a66a2..d27d46971 100644 --- a/apps/emqx_auth_mongo/test/emqx_auth_mongo_SUITE.erl +++ b/apps/emqx_auth_mongo/test/emqx_auth_mongo_SUITE.erl @@ -265,6 +265,26 @@ t_authn_full_selector_variables(Config) -> EnvFields), ok. +t_authn_interpolation_no_info(_Config) -> + Valid = #{zone => external, clientid => <<"client1">>, + username => <<"plain">>, password => <<"plain">>}, + ?assertMatch({ok, _}, emqx_access_control:authenticate(Valid)), + try + %% has values that are equal to placeholders + InterpolationUser = #{ <<"username">> => <<"%u">> + , <<"password">> => <<"plain">> + , <<"salt">> => <<"salt">> + , <<"is_superuser">> => true + }, + {ok, Conn} = ?POOL(?APP), + {{true, _}, _} = mongo_api:insert(Conn, ?MONGO_CL_USER, InterpolationUser), + Invalid = maps:without([username], Valid), + ?assertMatch({error, not_authorized}, emqx_access_control:authenticate(Invalid)) + after + deinit_mongo_data(), + init_mongo_data() + end. + %% authenticates, but superquery returns no documents t_authn_empty_is_superuser_collection(_Config) -> {ok, SuperQuery} = application:get_env(emqx_auth_mongo, super_query),