diff --git a/deps/rabbitmq_auth_backend_ldap/src/rabbit_auth_backend_ldap.erl b/deps/rabbitmq_auth_backend_ldap/src/rabbit_auth_backend_ldap.erl index 7c6fb59bc85a..5729ff6946b2 100644 --- a/deps/rabbitmq_auth_backend_ldap/src/rabbit_auth_backend_ldap.erl +++ b/deps/rabbitmq_auth_backend_ldap/src/rabbit_auth_backend_ldap.erl @@ -17,7 +17,7 @@ -export([user_login_authentication/2, user_login_authorization/2, check_vhost_access/3, check_resource_access/4, check_topic_access/4, - state_can_expire/0]). + state_can_expire/0, format_multi_attr/1, format_multi_attr/2]). -export([get_connections/0]). @@ -699,14 +699,32 @@ get_attributes(AttrName, [#eldap_entry{attributes = A}|Rem]) -> get_attributes(AttrName, [_|Rem]) -> get_attributes(AttrName, Rem). %% Format multiple attribute values for logging -format_multi_attr(Attrs) -> - format_multi_attr(io_lib:printable_list(Attrs), Attrs). - +%% The attribute can be: +%% - an ascii string (Erlang recognizes it as a printable_list) +%% - an non-ascii string (Erlang does not recognize it as a printable_list) +%% - a list/array of strings, which may contain ascii only or non-ascii and ascii characters +utf8_list_to_string(List) -> unicode:characters_to_list(list_to_binary(List)). +join_utf8_list(Acc, Sep, List) -> Acc ++ utf8_list_to_string(List) ++ Sep. + +format_multi_attr_value(Acc, _Sep, []) -> Acc; +format_multi_attr_value(Acc, Sep, [H|T]) when is_list(H) -> + [H1|_T1] = H, + case H1 of + V when is_list(V) -> format_multi_attr_value(join_utf8_list(Acc, Sep, V), Sep, T); + _ -> format_multi_attr_value(join_utf8_list(Acc, Sep, H), Sep, T) + end; +format_multi_attr_value(Acc, Sep, List) -> join_utf8_list(Acc, Sep, List). + +format_multi_attr(Attrs) -> format_multi_attr(io_lib:printable_list(Attrs), Attrs). format_multi_attr(true, Attrs) -> Attrs; -format_multi_attr(_, Attrs) when is_list(Attrs) -> string:join(Attrs, "; "); +format_multi_attr(_, Attrs) when is_list(Attrs) -> + [H|_T] = Attrs, + case H of + V when is_list(V) -> format_multi_attr_value("", "; ", Attrs); + _ -> utf8_list_to_string(Attrs) + end; format_multi_attr(_, Error) -> Error. - %% In case of multiple attributes, check for equality bi-directionally is_multi_attr_member(Str1, Str2) -> lists:member(Str1, Str2) orelse lists:member(Str2, Str1). diff --git a/deps/rabbitmq_auth_backend_ldap/test/unit_SUITE.erl b/deps/rabbitmq_auth_backend_ldap/test/unit_SUITE.erl index ad393808d8a7..a17ccdb16aed 100644 --- a/deps/rabbitmq_auth_backend_ldap/test/unit_SUITE.erl +++ b/deps/rabbitmq_auth_backend_ldap/test/unit_SUITE.erl @@ -16,7 +16,8 @@ all() -> [ fill, ad_fill, - user_dn_pattern_gh_7161 + user_dn_pattern_gh_7161, + format_different_types_of_ldap_attribute_values ]. fill(_Config) -> @@ -51,3 +52,25 @@ user_dn_pattern_gh_7161(_Config) -> ok = application:load(rabbitmq_auth_backend_ldap), {ok, UserDnPattern} = application:get_env(rabbitmq_auth_backend_ldap, user_dn_pattern), ?assertEqual("${username}", UserDnPattern). + +utf8_list_to_string(StrangeList) -> + unicode:characters_to_list(list_to_binary(StrangeList)). + +heuristic_encoding_bin(Bin) when is_binary(Bin) -> + case unicode:characters_to_binary(Bin,utf8,utf8) of + Bin -> + utf8; + _ -> + latin1 + end. + +format_different_types_of_ldap_attribute_values(_Config) -> + AsciiOnlyAttr = [50,56,48,48,48,45], + ?assertEqual("28000-", rabbit_auth_backend_ldap:format_multi_attr("28000-")), + ?assertEqual("28000-", rabbit_auth_backend_ldap:format_multi_attr(AsciiOnlyAttr)), + + NonAsciiAttr = [50,56,48,48,48,45,195,159], + ?assertEqual("28000-ß", rabbit_auth_backend_ldap:format_multi_attr(NonAsciiAttr)), + + ?assertEqual("one; 28000-ß; two; ", rabbit_auth_backend_ldap:format_multi_attr(["one", NonAsciiAttr, "two"])), + ok.