Add default_users per #7208
This commit is contained in:
parent
f92e4a2a83
commit
89582422f5
|
@ -616,8 +616,6 @@ end}.
|
||||||
{datatype, string}
|
{datatype, string}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Default User / VHost
|
%% Default User / VHost
|
||||||
%% ====================
|
%% ====================
|
||||||
|
@ -681,64 +679,95 @@ fun(Conf) ->
|
||||||
[list_to_binary(Configure), list_to_binary(Read), list_to_binary(Write)]
|
[list_to_binary(Configure), list_to_binary(Read), list_to_binary(Write)]
|
||||||
end}.
|
end}.
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Extra Default Users
|
||||||
|
%% ====================
|
||||||
|
%%
|
||||||
|
|
||||||
|
{mapping, "default_users.$name.vhost_pattern", "rabbit.default_users", [
|
||||||
|
{validators, ["valid_regex"]},
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{mapping, "default_users.$name.password", "rabbit.default_users", [
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{mapping, "default_users.$name.configure", "rabbit.default_users", [
|
||||||
|
{validators, ["valid_regex"]},
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{mapping, "default_users.$name.read", "rabbit.default_users", [
|
||||||
|
{validators, ["valid_regex"]},
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{mapping, "default_users.$name.write", "rabbit.default_users", [
|
||||||
|
{validators, ["valid_regex"]},
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{mapping, "default_users.$name.tags", "rabbit.default_users", [
|
||||||
|
{datatype, {list, atom}}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{mapping, "default_users.$name.password", "rabbit.default_users", [
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{translation, "rabbit.default_users", fun(Conf) ->
|
||||||
|
case rabbit_cuttlefish:aggregate_props(Conf, ["default_users"]) of
|
||||||
|
[] -> cuttlefish:unset();
|
||||||
|
Props -> Props
|
||||||
|
end
|
||||||
|
end}.
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Default Policies
|
||||||
|
%% ====================
|
||||||
|
%%
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.vhost_pattern", "rabbit.default_policies.operator", [
|
{mapping, "default_policies.operator.$id.vhost_pattern", "rabbit.default_policies.operator", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, ".*"},
|
|
||||||
{validators, ["valid_regex"]},
|
{validators, ["valid_regex"]},
|
||||||
{datatype, string}
|
{datatype, string}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.queue_pattern", "rabbit.default_policies.operator", [
|
{mapping, "default_policies.operator.$id.queue_pattern", "rabbit.default_policies.operator", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, ".*"},
|
|
||||||
{validators, ["valid_regex"]},
|
{validators, ["valid_regex"]},
|
||||||
{datatype, string}
|
{datatype, string}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.expires", "rabbit.default_policies.operator", [
|
{mapping, "default_policies.operator.$id.expires", "rabbit.default_policies.operator", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, "1s"},
|
|
||||||
{datatype, {duration, ms}}
|
{datatype, {duration, ms}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.message_ttl", "rabbit.default_policies.operator", [
|
{mapping, "default_policies.operator.$id.message_ttl", "rabbit.default_policies.operator", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, "1s"},
|
|
||||||
{datatype, {duration, ms}}
|
{datatype, {duration, ms}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.max_length", "rabbit.default_policies.operator", [
|
{mapping, "default_policies.operator.$id.max_length", "rabbit.default_policies.operator", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, 100},
|
|
||||||
{validators, ["non_zero_positive_integer"]},
|
{validators, ["non_zero_positive_integer"]},
|
||||||
{datatype, integer}
|
{datatype, integer}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.max_length_bytes", "rabbit.default_policies.operator", [
|
{mapping, "default_policies.operator.$id.max_length_bytes", "rabbit.default_policies.operator", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, "1GB"},
|
|
||||||
{validators, ["non_zero_positive_integer"]},
|
{validators, ["non_zero_positive_integer"]},
|
||||||
{datatype, bytesize}
|
{datatype, bytesize}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.max_in_memory_bytes", "rabbit.default_policies.operator", [
|
{mapping, "default_policies.operator.$id.max_in_memory_bytes", "rabbit.default_policies.operator", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, "1GB"},
|
|
||||||
{validators, ["non_zero_positive_integer"]},
|
{validators, ["non_zero_positive_integer"]},
|
||||||
{datatype, bytesize}
|
{datatype, bytesize}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.max_in_memory_length", "rabbit.default_policies.operator",
|
{mapping, "default_policies.operator.$id.max_in_memory_length", "rabbit.default_policies.operator",
|
||||||
[
|
[
|
||||||
{include_default, 1},
|
|
||||||
{commented, 1000},
|
|
||||||
{validators, ["non_zero_positive_integer"]},
|
{validators, ["non_zero_positive_integer"]},
|
||||||
{datatype, integer}
|
{datatype, integer}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_policies.operator.$id.delivery_limit", "rabbit.default_policies.operator", [
|
{mapping, "default_policies.operator.$id.delivery_limit", "rabbit.default_policies.operator", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, 1},
|
|
||||||
{validators, ["non_zero_positive_integer"]},
|
{validators, ["non_zero_positive_integer"]},
|
||||||
{datatype, integer}
|
{datatype, integer}
|
||||||
]}.
|
]}.
|
||||||
|
@ -759,55 +788,37 @@ end}.
|
||||||
{["default_policies","operator",ID|T],V};
|
{["default_policies","operator",ID|T],V};
|
||||||
(E) -> E
|
(E) -> E
|
||||||
end),
|
end),
|
||||||
Props1 = lists:map(
|
case Props of
|
||||||
fun({K, Ss}) ->
|
|
||||||
{K,
|
|
||||||
lists:map(fun({N, V}) ->
|
|
||||||
{binary:replace(N, <<"_">>, <<"-">>, [global]), V}
|
|
||||||
end, Ss)}
|
|
||||||
end, Props),
|
|
||||||
case Props1 of
|
|
||||||
[] -> cuttlefish:unset();
|
[] -> cuttlefish:unset();
|
||||||
_ -> Props1
|
Props -> Props
|
||||||
end,
|
end
|
||||||
Props1
|
|
||||||
end}.
|
end}.
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Default VHost Limits
|
||||||
|
%% ====================
|
||||||
|
%%
|
||||||
|
|
||||||
{mapping, "default_limits.vhosts.$id.pattern", "rabbit.default_limits.vhosts", [
|
{mapping, "default_limits.vhosts.$id.pattern", "rabbit.default_limits.vhosts", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, ".*"},
|
|
||||||
{validators, ["valid_regex"]},
|
{validators, ["valid_regex"]},
|
||||||
{datatype, string}
|
{datatype, string}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_limits.vhosts.$id.max_connections", "rabbit.default_limits.vhosts", [
|
{mapping, "default_limits.vhosts.$id.max_connections", "rabbit.default_limits.vhosts", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, 1000},
|
|
||||||
{validators, [ "non_zero_positive_integer"]},
|
{validators, [ "non_zero_positive_integer"]},
|
||||||
{datatype, integer}
|
{datatype, integer}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{mapping, "default_limits.vhosts.$id.max_queues", "rabbit.default_limits.vhosts", [
|
{mapping, "default_limits.vhosts.$id.max_queues", "rabbit.default_limits.vhosts", [
|
||||||
{include_default, 1},
|
|
||||||
{commented, 100},
|
|
||||||
{validators, [ "non_zero_positive_integer"]},
|
{validators, [ "non_zero_positive_integer"]},
|
||||||
{datatype, integer}
|
{datatype, integer}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{translation, "rabbit.default_limits.vhosts", fun(Conf) ->
|
{translation, "rabbit.default_limits.vhosts", fun(Conf) ->
|
||||||
Props = rabbit_cuttlefish:aggregate_props(Conf, ["default_limits", "vhosts"]),
|
case rabbit_cuttlefish:aggregate_props(Conf, ["default_limits", "vhosts"]) of
|
||||||
Props1 = lists:map(
|
|
||||||
fun({K, Ss}) ->
|
|
||||||
{K,
|
|
||||||
lists:map(fun({N, V}) ->
|
|
||||||
{binary:replace(N, <<"_">>, <<"-">>, [global]), V}
|
|
||||||
end, Ss)}
|
|
||||||
end, Props),
|
|
||||||
case Props1 of
|
|
||||||
[] -> cuttlefish:unset();
|
[] -> cuttlefish:unset();
|
||||||
_ -> Props1
|
Props -> Props
|
||||||
end,
|
end
|
||||||
Props1
|
|
||||||
end}.
|
end}.
|
||||||
|
|
||||||
%% Tags for default user
|
%% Tags for default user
|
||||||
|
|
|
@ -141,40 +141,6 @@ parse_tags(Val) when is_list(Val) ->
|
||||||
[trim_tag(Tag) || Tag <- re:split(ValUnicode, ",", [unicode, {return, list}])]
|
[trim_tag(Tag) || Tag <- re:split(ValUnicode, ",", [unicode, {return, list}])]
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec default_limits(vhost:name()) -> proplists:proplist().
|
|
||||||
default_limits(Name) ->
|
|
||||||
AllLimits = application:get_env(rabbit, default_limits, []),
|
|
||||||
VHostLimits = proplists:get_value(vhosts, AllLimits, []),
|
|
||||||
Match = lists:search(fun({_, Ss}) ->
|
|
||||||
RE = proplists:get_value(<<"pattern">>, Ss, ".*"),
|
|
||||||
re:run(Name, RE, [{capture, none}]) =:= match
|
|
||||||
end, VHostLimits),
|
|
||||||
case Match of
|
|
||||||
{value, {_, Ss}} ->
|
|
||||||
proplists:delete(<<"pattern">>, Ss);
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec default_operator_policies(vhost:name()) ->
|
|
||||||
{binary(), binary(), proplists:proplist()} | not_found.
|
|
||||||
default_operator_policies(Name) ->
|
|
||||||
AllPolicies = application:get_env(rabbit, default_policies, []),
|
|
||||||
OpPolicies = proplists:get_value(operator, AllPolicies, []),
|
|
||||||
Match = lists:search(fun({_, Ss}) ->
|
|
||||||
RE = proplists:get_value(<<"vhost-pattern">>, Ss, ".*"),
|
|
||||||
re:run(Name, RE, [{capture, none}]) =:= match
|
|
||||||
end, OpPolicies),
|
|
||||||
case Match of
|
|
||||||
{value, {PolicyName, Ss}} ->
|
|
||||||
QPattern = proplists:get_value(<<"queue-pattern">>, Ss, ".*"),
|
|
||||||
Ss1 = proplists:delete(<<"queue-pattern">>, Ss),
|
|
||||||
Ss2 = proplists:delete(<<"vhost-pattern">>, Ss1),
|
|
||||||
{PolicyName, list_to_binary(QPattern), Ss2};
|
|
||||||
_ ->
|
|
||||||
not_found
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec add(vhost:name(), rabbit_types:username()) ->
|
-spec add(vhost:name(), rabbit_types:username()) ->
|
||||||
rabbit_types:ok_or_error(any()).
|
rabbit_types:ok_or_error(any()).
|
||||||
add(VHost, ActingUser) ->
|
add(VHost, ActingUser) ->
|
||||||
|
@ -227,7 +193,7 @@ do_add(Name, Metadata, ActingUser) ->
|
||||||
rabbit_log:info("Adding vhost '~ts' (description: '~ts', tags: ~tp)",
|
rabbit_log:info("Adding vhost '~ts' (description: '~ts', tags: ~tp)",
|
||||||
[Name, Description, Tags])
|
[Name, Description, Tags])
|
||||||
end,
|
end,
|
||||||
DefaultLimits = default_limits(Name),
|
DefaultLimits = rabbit_vhost_defaults:list_limits(Name),
|
||||||
{NewOrNot, VHost} = rabbit_db_vhost:create_or_get(Name, DefaultLimits, Metadata),
|
{NewOrNot, VHost} = rabbit_db_vhost:create_or_get(Name, DefaultLimits, Metadata),
|
||||||
case NewOrNot of
|
case NewOrNot of
|
||||||
new ->
|
new ->
|
||||||
|
@ -235,23 +201,7 @@ do_add(Name, Metadata, ActingUser) ->
|
||||||
existing ->
|
existing ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case DefaultLimits of
|
rabbit_vhost_defaults:apply(Name, ActingUser),
|
||||||
[] ->
|
|
||||||
ok;
|
|
||||||
_ ->
|
|
||||||
ok = rabbit_vhost_limit:set(Name, DefaultLimits, ActingUser),
|
|
||||||
rabbit_log:info("Applied default limits to vhost '~tp': ~tp",
|
|
||||||
[Name, DefaultLimits])
|
|
||||||
end,
|
|
||||||
case default_operator_policies(Name) of
|
|
||||||
not_found ->
|
|
||||||
ok;
|
|
||||||
{PolicyName, QPattern, Definition} = Policy ->
|
|
||||||
ok = rabbit_policy:set_op(Name, PolicyName, QPattern, Definition,
|
|
||||||
undefined, undefined, ActingUser),
|
|
||||||
rabbit_log:info("Applied default operator policy to vhost '~tp': ~tp",
|
|
||||||
[Name, Policy])
|
|
||||||
end,
|
|
||||||
_ = [begin
|
_ = [begin
|
||||||
Resource = rabbit_misc:r(Name, exchange, ExchangeName),
|
Resource = rabbit_misc:r(Name, exchange, ExchangeName),
|
||||||
rabbit_log:debug("Will declare an exchange ~tp", [Resource]),
|
rabbit_log:debug("Will declare an exchange ~tp", [Resource]),
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
%%
|
||||||
|
%% Copyright (c) 2023-2023 VMware, Inc. or its affiliates. All rights reserved.
|
||||||
|
%%
|
||||||
|
|
||||||
|
-module(rabbit_vhost_defaults).
|
||||||
|
|
||||||
|
-export([apply/2]).
|
||||||
|
-export([list_limits/1, list_operator_policies/1, list_users/1]).
|
||||||
|
|
||||||
|
-type definitions() :: [{binary(), term()}].
|
||||||
|
|
||||||
|
-record(policy, {
|
||||||
|
name :: binary(),
|
||||||
|
queue_pattern = <<".*">> :: binary(),
|
||||||
|
definition = [] :: definitions()
|
||||||
|
}).
|
||||||
|
|
||||||
|
-type user() :: #{
|
||||||
|
name := binary(),
|
||||||
|
configure := binary(),
|
||||||
|
read := binary(),
|
||||||
|
write := binary(),
|
||||||
|
password := binary(),
|
||||||
|
tags := [atom()],
|
||||||
|
_ => _
|
||||||
|
}.
|
||||||
|
|
||||||
|
%% Apply all matching defaults to a VHost.
|
||||||
|
-spec apply(vhost:name(), rabbit_types:username()) -> ok.
|
||||||
|
apply(VHost, ActingUser) ->
|
||||||
|
case list_limits(VHost) of
|
||||||
|
[] ->
|
||||||
|
ok;
|
||||||
|
L ->
|
||||||
|
ok = rabbit_vhost_limit:set(VHost, L, ActingUser),
|
||||||
|
rabbit_log:info("Applied default limits to vhost '~tp': ~tp", [VHost, L])
|
||||||
|
end,
|
||||||
|
lists:foreach(
|
||||||
|
fun(P) ->
|
||||||
|
ok = rabbit_policy:set_op(VHost, P#policy.name, P#policy.queue_pattern, P#policy.definition,
|
||||||
|
undefined, undefined, ActingUser),
|
||||||
|
rabbit_log:info("Applied default operator policy to vhost '~tp': ~tp", [VHost, P])
|
||||||
|
end,
|
||||||
|
list_operator_policies(VHost)
|
||||||
|
),
|
||||||
|
lists:foreach(
|
||||||
|
fun(U) ->
|
||||||
|
ok = add_user(VHost, U, ActingUser),
|
||||||
|
rabbit_log:info("Added default user to vhost '~tp': ~tp", [VHost, maps:remove(password, U)])
|
||||||
|
end,
|
||||||
|
list_users(VHost)
|
||||||
|
),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Helpers
|
||||||
|
%%
|
||||||
|
|
||||||
|
%% Limits that were configured with a matching vhost pattern.
|
||||||
|
-spec list_limits(vhost:name()) -> proplists:proplist().
|
||||||
|
list_limits(VHost) ->
|
||||||
|
AllLimits = application:get_env(rabbit, default_limits, []),
|
||||||
|
VHostLimits = proplists:get_value(vhosts, AllLimits, []),
|
||||||
|
Match = lists:search(
|
||||||
|
fun({_, Ss}) ->
|
||||||
|
RE = proplists:get_value(<<"pattern">>, Ss, ".*"),
|
||||||
|
re:run(VHost, RE, [{capture, none}]) =:= match
|
||||||
|
end,
|
||||||
|
VHostLimits
|
||||||
|
),
|
||||||
|
case Match of
|
||||||
|
{value, {_, Ss}} ->
|
||||||
|
Ss1 = proplists:delete(<<"pattern">>, Ss),
|
||||||
|
underscore_to_dash(Ss1);
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% Operator policies that were configured with a matching vhost pattern.
|
||||||
|
-spec list_operator_policies(vhost:name()) -> [#policy{}].
|
||||||
|
list_operator_policies(VHost) ->
|
||||||
|
AllPolicies = application:get_env(rabbit, default_policies, []),
|
||||||
|
OpPolicies = proplists:get_value(operator, AllPolicies, []),
|
||||||
|
lists:filtermap(
|
||||||
|
fun({PolicyName, Ss}) ->
|
||||||
|
RE = proplists:get_value(<<"vhost_pattern">>, Ss, ".*"),
|
||||||
|
case re:run(VHost, RE, [{capture, none}]) of
|
||||||
|
match ->
|
||||||
|
QPattern = proplists:get_value(<<"queue_pattern">>, Ss, <<".*">>),
|
||||||
|
Ss1 = proplists:delete(<<"queue_pattern">>, Ss),
|
||||||
|
Ss2 = proplists:delete(<<"vhost_pattern">>, Ss1),
|
||||||
|
{true, #policy{
|
||||||
|
name = PolicyName,
|
||||||
|
queue_pattern = QPattern,
|
||||||
|
definition = underscore_to_dash(Ss2)
|
||||||
|
}};
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
OpPolicies
|
||||||
|
).
|
||||||
|
|
||||||
|
%% Users (permissions) that were configured with a matching vhost pattern.
|
||||||
|
-spec list_users(vhost:name()) -> [user()].
|
||||||
|
list_users(VHost) ->
|
||||||
|
Users = application:get_env(rabbit, default_users, []),
|
||||||
|
lists:filtermap(
|
||||||
|
fun({Username, Ss}) ->
|
||||||
|
RE = proplists:get_value(<<"vhost_pattern">>, Ss, ".*"),
|
||||||
|
case re:run(VHost, RE, [{capture, none}]) of
|
||||||
|
match ->
|
||||||
|
C = rabbit_data_coercion:to_binary(
|
||||||
|
proplists:get_value(<<"configure">>, Ss, <<".*">>)
|
||||||
|
),
|
||||||
|
R = rabbit_data_coercion:to_binary(
|
||||||
|
proplists:get_value(<<"read">>, Ss, <<".*">>)
|
||||||
|
),
|
||||||
|
W = rabbit_data_coercion:to_binary(
|
||||||
|
proplists:get_value(<<"write">>, Ss, <<".*">>)
|
||||||
|
),
|
||||||
|
U0 = #{
|
||||||
|
name => Username,
|
||||||
|
tags => proplists:get_value(<<"tags">>, Ss, []),
|
||||||
|
configure => C,
|
||||||
|
read => R,
|
||||||
|
write => W
|
||||||
|
},
|
||||||
|
%% rabbit_auth_backend_internal:put_user relies on maps:is_key, can't pass
|
||||||
|
%% undefined through.
|
||||||
|
U1 = case proplists:get_value(<<"password">>, Ss, undefined) of
|
||||||
|
undefined ->
|
||||||
|
U0;
|
||||||
|
V ->
|
||||||
|
U0#{password => rabbit_data_coercion:to_binary(V)}
|
||||||
|
end,
|
||||||
|
{true, U1};
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
Users
|
||||||
|
).
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% Private
|
||||||
|
%%
|
||||||
|
|
||||||
|
%% Translate underscores to dashes in prop keys.
|
||||||
|
-spec underscore_to_dash(definitions()) -> definitions().
|
||||||
|
underscore_to_dash(Props) ->
|
||||||
|
lists:map(
|
||||||
|
fun({N, V}) ->
|
||||||
|
{binary:replace(N, <<"_">>, <<"-">>, [global]), V}
|
||||||
|
end,
|
||||||
|
Props
|
||||||
|
).
|
||||||
|
|
||||||
|
%% Add user iff it doesn't exist & set permissions per vhost.
|
||||||
|
-spec add_user(rabbit_types:vhost(), user(), rabbit_types:username()) -> ok.
|
||||||
|
add_user(VHost, #{name := Name, configure := C, write := W, read := R} = User, ActingUser) ->
|
||||||
|
%% put_user has its own existence check, but it still updates password if the user exists.
|
||||||
|
%% We want only the newly created users to have password set from the config.
|
||||||
|
rabbit_auth_backend_internal:exists(Name) orelse
|
||||||
|
rabbit_auth_backend_internal:put_user(User, ActingUser),
|
||||||
|
rabbit_auth_backend_internal:set_permissions(Name, VHost, C, W, R, ActingUser).
|
|
@ -1,3 +1,6 @@
|
||||||
|
% vim:ft=erlang:
|
||||||
|
%
|
||||||
|
|
||||||
[{internal_auth_backend,
|
[{internal_auth_backend,
|
||||||
"auth_backends.1 = internal",
|
"auth_backends.1 = internal",
|
||||||
[{rabbit,[{auth_backends,[rabbit_auth_backend_internal]}]}],
|
[{rabbit,[{auth_backends,[rabbit_auth_backend_internal]}]}],
|
||||||
|
@ -118,6 +121,20 @@ ssl_options.fail_if_no_peer_cert = true",
|
||||||
"disk_free_limit.absolute = 50000",
|
"disk_free_limit.absolute = 50000",
|
||||||
[{rabbit, [{disk_free_limit, 50000}]}],[]},
|
[{rabbit, [{disk_free_limit, 50000}]}],[]},
|
||||||
|
|
||||||
|
{default_users,
|
||||||
|
"
|
||||||
|
default_users.a.vhost_pattern = banana
|
||||||
|
default_users.a.tags = administrator,operator
|
||||||
|
default_users.a.password = SECRET
|
||||||
|
default_users.a.read = .*
|
||||||
|
",
|
||||||
|
[{rabbit, [{default_users, [
|
||||||
|
{<<"a">>, [{<<"vhost_pattern">>, "banana"},
|
||||||
|
{<<"tags">>, [administrator, operator]},
|
||||||
|
{<<"password">>, "SECRET"},
|
||||||
|
{<<"read">>, ".*"}]}]}]}],
|
||||||
|
[]},
|
||||||
|
|
||||||
{default_policies_operator,
|
{default_policies_operator,
|
||||||
"
|
"
|
||||||
default_policies.operator.a.expires = 1h
|
default_policies.operator.a.expires = 1h
|
||||||
|
@ -128,10 +145,10 @@ ssl_options.fail_if_no_peer_cert = true",
|
||||||
",
|
",
|
||||||
[{rabbit, [{default_policies, [{operator, [
|
[{rabbit, [{default_policies, [{operator, [
|
||||||
{<<"a">>, [{<<"expires">>, 3600000},
|
{<<"a">>, [{<<"expires">>, 3600000},
|
||||||
{<<"ha-mode">>, "exactly"},
|
{<<"ha_mode">>, "exactly"},
|
||||||
{<<"ha-params">>, 2},
|
{<<"ha_params">>, 2},
|
||||||
{<<"queue-pattern">>, "apple"},
|
{<<"queue_pattern">>, "apple"},
|
||||||
{<<"vhost-pattern">>, "banana"}]}]}]}]}],
|
{<<"vhost_pattern">>, "banana"}]}]}]}]}],
|
||||||
[]},
|
[]},
|
||||||
|
|
||||||
{default_vhost_limits,
|
{default_vhost_limits,
|
||||||
|
@ -141,7 +158,7 @@ ssl_options.fail_if_no_peer_cert = true",
|
||||||
",
|
",
|
||||||
[{rabbit, [{default_limits, [{vhosts, [
|
[{rabbit, [{default_limits, [{vhosts, [
|
||||||
{<<"a">>, [{<<"pattern">>, "banana"},
|
{<<"a">>, [{<<"pattern">>, "banana"},
|
||||||
{<<"max-queues">>, 10}]}]}]}]}],
|
{<<"max_queues">>, 10}]}]}]}]}],
|
||||||
[]},
|
[]},
|
||||||
|
|
||||||
{default_user_settings,
|
{default_user_settings,
|
||||||
|
|
|
@ -25,6 +25,7 @@ groups() ->
|
||||||
ClusterSize1Tests = [
|
ClusterSize1Tests = [
|
||||||
vhost_is_created_with_default_limits,
|
vhost_is_created_with_default_limits,
|
||||||
vhost_is_created_with_operator_policies,
|
vhost_is_created_with_operator_policies,
|
||||||
|
vhost_is_created_with_default_user,
|
||||||
single_node_vhost_deletion_forces_connection_closure,
|
single_node_vhost_deletion_forces_connection_closure,
|
||||||
vhost_failure_forces_connection_closure,
|
vhost_failure_forces_connection_closure,
|
||||||
vhost_creation_idempotency,
|
vhost_creation_idempotency,
|
||||||
|
@ -375,6 +376,44 @@ vhost_is_created_with_operator_policies(Config) ->
|
||||||
?assertNotEqual(not_found, rabbit_ct_broker_helpers:rpc(Config, 0,
|
?assertNotEqual(not_found, rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
rabbit_policy, lookup_op, [VHost, PolicyName])).
|
rabbit_policy, lookup_op, [VHost, PolicyName])).
|
||||||
|
|
||||||
|
vhost_is_created_with_default_user(Config) ->
|
||||||
|
VHost = <<"vhost1">>,
|
||||||
|
Username = <<"banana">>,
|
||||||
|
Perm = "apple",
|
||||||
|
Tags = [arbitrary],
|
||||||
|
Pwd = "SECRET",
|
||||||
|
Env = [{Username, [{<<"configure">>, Perm}, {<<"tags">>, [arbitrary]}, {<<"password">>, Pwd}]}],
|
||||||
|
WantUser = [{user, Username},{tags, Tags}],
|
||||||
|
WantPermissions = [[{vhost, VHost}, {configure, list_to_binary(Perm)}, {write, <<".*">>}, {read, <<".*">>}]],
|
||||||
|
?assertEqual(ok, rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
|
application, set_env, [rabbit, default_users, Env])),
|
||||||
|
?assertEqual(false, rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
|
rabbit_auth_backend_internal, exists, [Username])),
|
||||||
|
?assertEqual(ok, rabbit_ct_broker_helpers:add_vhost(Config, VHost)),
|
||||||
|
ct:pal("HAVE: ~p", [rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
|
rabbit_auth_backend_internal, list_user_permissions, [Username])]),
|
||||||
|
ct:pal("WANT: ~p", [WantPermissions]),
|
||||||
|
?assertEqual(WantPermissions, rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
|
rabbit_auth_backend_internal, list_user_permissions, [Username])),
|
||||||
|
HaveUser = lists:search(
|
||||||
|
fun (U) ->
|
||||||
|
case proplists:get_value(user, U) of
|
||||||
|
Username -> true;
|
||||||
|
undefined -> false
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
|
rabbit_auth_backend_internal, list_users, [])
|
||||||
|
),
|
||||||
|
?assertEqual({value, WantUser}, HaveUser),
|
||||||
|
?assertMatch({ok, _}, rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
|
rabbit_auth_backend_internal, user_login_authentication, [Username, [{password, list_to_binary(Pwd)}]])),
|
||||||
|
?assertEqual(ok, rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
|
application, unset_env, [rabbit, default_users])),
|
||||||
|
?assertEqual(ok, rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||||
|
rabbit_auth_backend_internal, delete_user, [Username,
|
||||||
|
<<"acting-user">>])).
|
||||||
|
|
||||||
parse_tags(Config) ->
|
parse_tags(Config) ->
|
||||||
rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, parse_tags1, [Config]).
|
rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, parse_tags1, [Config]).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue