Skip to content

Commit 6ce68dd

Browse files
Merge pull request #14868 from rabbitmq/mergify/bp/v4.2.x/pr-14850
LDAP: make it possible to configure queries in `rabbitmq.conf` as multiline strings (supported as of Cuttlefish 3.6.x) (backport #14850)
2 parents c2a166e + 14a0e38 commit 6ce68dd

File tree

5 files changed

+209
-26
lines changed

5 files changed

+209
-26
lines changed

deps/rabbitmq_auth_backend_ldap/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ define PROJECT_APP_EXTRA_KEYS
3535
endef
3636

3737
LOCAL_DEPS = eldap public_key
38-
DEPS = rabbit_common rabbit
38+
DEPS = rabbit_common rabbit cuttlefish
3939
TEST_DEPS = ct_helper rabbitmq_ct_helpers rabbitmq_ct_client_helpers amqp_client
4040
dep_ct_helper = git https://github.com/extend/ct_helper.git master
4141

deps/rabbitmq_auth_backend_ldap/priv/schema/rabbitmq_auth_backend_ldap.schema

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
%% vim:ft=erlang:
2+
%% -*- mode: erlang; -*-
13
%% ----------------------------------------------------------------------------
24
%% RabbitMQ LDAP Plugin
35
%%
46
%% See https://www.rabbitmq.com/ldap.html for details.
57
%%
68
%% ----------------------------------------------------------------------------
79

8-
% {rabbitmq_auth_backend_ldap,
9-
% [
1010
%%
1111
%% Connecting to the LDAP server(s)
1212
%% ================================
@@ -191,25 +191,6 @@ end}.
191191
{mapping, "auth_ldap.group_lookup_base", "rabbitmq_auth_backend_ldap.group_lookup_base",
192192
[{datatype, [{enum, [none]}, string]}]}.
193193

194-
%% The LDAP plugin can perform a variety of queries against your
195-
%% LDAP server to determine questions of authorisation. See
196-
%% https://www.rabbitmq.com/ldap.html#authorisation for more
197-
%% information.
198-
199-
%% Set the query to use when determining vhost access
200-
%%
201-
%% {vhost_access_query, {in_group,
202-
%% "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}},
203-
204-
%% Set the query to use when determining resource (e.g., queue) access
205-
%%
206-
%% {resource_access_query, {constant, true}},
207-
208-
%% Set queries to determine which tags a user has
209-
%%
210-
%% {tag_queries, []}
211-
% ]},
212-
213194
%% Connect to the LDAP server using TLS
214195
%%
215196
%% {use_ssl, false},
@@ -341,6 +322,62 @@ fun(Conf) ->
341322
end
342323
end}.
343324

344-
345325
{mapping, "auth_ldap.ssl_options.hostname_verification", "rabbitmq_auth_backend_ldap.ssl_hostname_verification", [
346326
{datatype, {enum, [wildcard, none]}}]}.
327+
328+
%% The LDAP plugin can perform a variety of queries against your
329+
%% LDAP server to determine questions of authorisation. See
330+
%% https://rabbitmq.com/docs/ldap#authorisation for more
331+
%% information.
332+
333+
{mapping, "auth_ldap.queries.vhost_access", "rabbitmq_auth_backend_ldap.vhost_access_query",
334+
[{datatype, string}]}.
335+
336+
{translation, "rabbitmq_auth_backend_ldap.vhost_access_query",
337+
fun(Conf) ->
338+
case cuttlefish:conf_get("auth_ldap.queries.vhost_access", Conf, undefined) of
339+
undefined ->
340+
cuttlefish:unset();
341+
Query ->
342+
rabbit_auth_backend_ldap_util:parse_query(Query)
343+
end
344+
end}.
345+
346+
{mapping, "auth_ldap.queries.resource_access", "rabbitmq_auth_backend_ldap.resource_access_query",
347+
[{datatype, string}]}.
348+
349+
{translation, "rabbitmq_auth_backend_ldap.resource_access_query",
350+
fun(Conf) ->
351+
case cuttlefish:conf_get("auth_ldap.queries.resource_access", Conf, undefined) of
352+
undefined ->
353+
cuttlefish:unset();
354+
Query ->
355+
rabbit_auth_backend_ldap_util:parse_query(Query)
356+
end
357+
end}.
358+
359+
{mapping, "auth_ldap.queries.topic_access", "rabbitmq_auth_backend_ldap.topic_access_query",
360+
[{datatype, string}]}.
361+
362+
{translation, "rabbitmq_auth_backend_ldap.topic_access_query",
363+
fun(Conf) ->
364+
case cuttlefish:conf_get("auth_ldap.queries.topic_access", Conf, undefined) of
365+
undefined ->
366+
cuttlefish:unset();
367+
Query ->
368+
rabbit_auth_backend_ldap_util:parse_query(Query)
369+
end
370+
end}.
371+
372+
{mapping, "auth_ldap.queries.tags", "rabbitmq_auth_backend_ldap.tag_queries",
373+
[{datatype, string}]}.
374+
375+
{translation, "rabbitmq_auth_backend_ldap.tag_queries",
376+
fun(Conf) ->
377+
case cuttlefish:conf_get("auth_ldap.queries.tags", Conf, undefined) of
378+
undefined ->
379+
cuttlefish:unset();
380+
Query ->
381+
rabbit_auth_backend_ldap_util:parse_query(Query)
382+
end
383+
end}.

deps/rabbitmq_auth_backend_ldap/src/rabbit_auth_backend_ldap_util.erl

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
-module(rabbit_auth_backend_ldap_util).
99

10-
-export([fill/2, get_active_directory_args/1]).
10+
-export([fill/2, get_active_directory_args/1, parse_query/1]).
1111

1212
fill(Fmt, []) ->
1313
binary_to_list(iolist_to_binary(Fmt));
@@ -32,3 +32,57 @@ get_active_directory_args(Username) when is_binary(Username) ->
3232
% If Username is in Domain\User format, provide additional fill
3333
% template arguments
3434
get_active_directory_args(binary:split(Username, <<"\\">>, [trim_all])).
35+
36+
parse_query(Query) when is_binary(Query) ->
37+
parse_query(rabbit_data_coercion:to_unicode_charlist(Query));
38+
parse_query(Query0) when is_list(Query0) ->
39+
Query1 = fixup_query(Query0),
40+
parse_query_handle_erl_scan(erl_scan:string(Query1)).
41+
42+
fixup_query(Query0) ->
43+
Query1 = string:trim(Query0, both),
44+
fixup_query(lists:last(Query1) =:= $., Query1).
45+
46+
fixup_query(true, Query) ->
47+
Query;
48+
fixup_query(false, Query) ->
49+
Query ++ ".".
50+
51+
parse_query_handle_erl_scan({ok, Tokens, _EndLine}) ->
52+
parse_query_handle_exprs(erl_parse:parse_exprs(Tokens));
53+
parse_query_handle_erl_scan(Error) ->
54+
cuttlefish:invalid(fmt("invalid query: ~tp", [Error])).
55+
56+
parse_query_handle_exprs({ok, AbsForm}) ->
57+
parse_query_handle_eval(erl_eval:exprs(AbsForm, erl_eval:new_bindings()));
58+
parse_query_handle_exprs(Error) ->
59+
cuttlefish:invalid(fmt("invalid query: ~tp", [Error])).
60+
61+
parse_query_handle_eval({value, {constant, true}=T, _}) ->
62+
T;
63+
parse_query_handle_eval({value, {constant, false}=T, _}) ->
64+
T;
65+
parse_query_handle_eval({value, {in_group, _}=T, _}) ->
66+
T;
67+
parse_query_handle_eval({value, {in_group_nested, _, _}=T, _}) ->
68+
T;
69+
parse_query_handle_eval({value, {for, Q}=T, _}) when is_list(Q) ->
70+
T;
71+
parse_query_handle_eval({value, {'not', _}=T, _}) ->
72+
T;
73+
parse_query_handle_eval({value, {'and', Q}=T, _}) when is_list(Q) ->
74+
T;
75+
parse_query_handle_eval({value, {'or', Q}=T, _}) when is_list(Q) ->
76+
T;
77+
parse_query_handle_eval({value, {equals, _, _}=T, _}) ->
78+
T;
79+
parse_query_handle_eval({value, {match, _, _}=T, _}) ->
80+
T;
81+
parse_query_handle_eval({value, T, _}) when is_list(T) ->
82+
%% NB: tag_queries uses this form
83+
T;
84+
parse_query_handle_eval({value, Unexpected, _}) ->
85+
cuttlefish:invalid(fmt("invalid query: ~tp", [Unexpected])).
86+
87+
fmt(Fmt, Args) ->
88+
rabbit_data_coercion:to_unicode_charlist(io_lib:format(Fmt, Args)).

deps/rabbitmq_auth_backend_ldap/test/config_schema_SUITE_data/rabbitmq_auth_backend_ldap.snippets

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
%% vim:ft=erlang:
2+
%% -*- mode: erlang; -*-
3+
14
[{ldap_servers,
25
"auth_ldap.servers.1 = DC1.domain.com
36
auth_ldap.servers.2 = DC1.eng.domain.com",
@@ -334,5 +337,94 @@
334337
{versions,['tlsv1.2','tlsv1.1']}
335338
]},
336339
{use_ssl, true}]}],
337-
[]}
340+
[]},
341+
342+
{vhost_access_query,
343+
"auth_ldap.queries.vhost_access = '''
344+
{in_group,\"ou=${vhost}-users,ou=vhosts,dc=example,dc=com\"}
345+
'''",
346+
[
347+
{rabbitmq_auth_backend_ldap, [
348+
{vhost_access_query, {in_group,"ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}}
349+
]}
350+
],
351+
[rabbitmq_auth_backend_ldap]},
352+
353+
{vhost_access_query_period_ending,
354+
"auth_ldap.queries.vhost_access = '''
355+
{in_group,\"ou=${vhost}-users,ou=vhosts,dc=example,dc=com\"}.
356+
'''",
357+
[
358+
{rabbitmq_auth_backend_ldap, [
359+
{vhost_access_query, {in_group,"ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}}
360+
]}
361+
],
362+
[rabbitmq_auth_backend_ldap]},
363+
364+
{resource_access_query,
365+
"auth_ldap.queries.resource_access = '''
366+
{for, [
367+
{permission, configure, {in_group, \"cn=admin,dc=example,dc=com\"}},
368+
{permission, write, {for, [
369+
{resource, queue, {in_group, \"cn=admin,dc=example,dc=com\"}},
370+
{resource, exchange, {constant, true}}
371+
]}},
372+
{permission, read, {for, [
373+
{resource, exchange, {in_group, \"cn=admin,dc=example,dc=com\"}},
374+
{resource, queue, {constant, true}}
375+
]}}
376+
]}
377+
'''",
378+
[
379+
{rabbitmq_auth_backend_ldap, [
380+
{resource_access_query,
381+
{for, [
382+
{permission, configure, {in_group, "cn=admin,dc=example,dc=com"}},
383+
{permission, write, {for, [
384+
{resource, queue, {in_group, "cn=admin,dc=example,dc=com"}},
385+
{resource, exchange, {constant, true}}
386+
]}},
387+
{permission, read, {for, [
388+
{resource, exchange, {in_group, "cn=admin,dc=example,dc=com"}},
389+
{resource, queue, {constant, true}}
390+
]}}
391+
]}
392+
}
393+
]}
394+
],
395+
[rabbitmq_auth_backend_ldap]},
396+
397+
{topic_access_query,
398+
"auth_ldap.queries.topic_access = '''
399+
{for, [
400+
{permission, write, {match, {string, \"${routing_key}\"}, {string, \"^a\"}}},
401+
{permission, read, {constant, true}}
402+
]}
403+
'''",
404+
[
405+
{rabbitmq_auth_backend_ldap, [
406+
{topic_access_query,
407+
{for, [
408+
{permission, write, {match, {string, "${routing_key}"}, {string, "^a"}}},
409+
{permission, read, {constant, true}}
410+
]}
411+
}
412+
]}
413+
],
414+
[rabbitmq_auth_backend_ldap]},
415+
416+
{tag_queries,
417+
"auth_ldap.queries.tags = '''
418+
[{administrator, {constant, false}},
419+
{management, {constant, true}}]
420+
'''",
421+
[
422+
{rabbitmq_auth_backend_ldap, [
423+
{tag_queries, [
424+
{administrator, {constant, false}},
425+
{management, {constant, true}}
426+
]}
427+
]}
428+
],
429+
[rabbitmq_auth_backend_ldap]}
338430
].

rabbitmq-components.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ dep_accept = hex 0.3.5
4343
dep_cowboy = hex 2.14.1
4444
dep_cowlib = hex 2.16.0
4545
dep_credentials_obfuscation = hex 3.5.0
46-
dep_cuttlefish = hex 3.5.0
46+
dep_cuttlefish = hex 3.6.0
4747
dep_gen_batch_server = hex 0.8.8
4848
dep_jose = hex 1.11.10
4949
dep_khepri = hex 0.17.2

0 commit comments

Comments
 (0)