From 52878cdd47b069555c4140037850337855eb5167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20G=C3=B6m=C3=B6ri?= Date: Fri, 1 Mar 2024 20:59:19 +0100 Subject: [PATCH] Optionally block enabling configured feature flags via Management UI/API Useful to avoid accidentally enabling for example experiemental feature flags from the Management UI on sensitive clusters. --- .../rabbit_mgmt_wm_feature_flag_enable.erl | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/deps/rabbitmq_management/src/rabbit_mgmt_wm_feature_flag_enable.erl b/deps/rabbitmq_management/src/rabbit_mgmt_wm_feature_flag_enable.erl index 9922dbcb2104..701c5924daaa 100644 --- a/deps/rabbitmq_management/src/rabbit_mgmt_wm_feature_flag_enable.erl +++ b/deps/rabbitmq_management/src/rabbit_mgmt_wm_feature_flag_enable.erl @@ -38,13 +38,18 @@ accept_content(ReqData, #context{} = Context) -> NameS = rabbit_mgmt_util:id(name, ReqData), try Name = list_to_existing_atom(binary_to_list(NameS)), - case rabbit_feature_flags:enable(Name) of - ok -> - {true, ReqData, Context}; - {error, Reason1} -> - FormattedReason1 = rabbit_ff_extra:format_error(Reason1), - rabbit_mgmt_util:bad_request( - list_to_binary(FormattedReason1), ReqData, Context) + case is_feature_flag_blocked(Name) of + {true, Message} -> + rabbit_web_dispatch_access_control:not_authorised(Message, ReqData, Context); + false -> + case rabbit_feature_flags:enable(Name) of + ok -> + {true, ReqData, Context}; + {error, Reason1} -> + FormattedReason1 = rabbit_ff_extra:format_error(Reason1), + rabbit_mgmt_util:bad_request( + list_to_binary(FormattedReason1), ReqData, Context) + end end catch _:badarg -> @@ -53,3 +58,8 @@ accept_content(ReqData, #context{} = Context) -> rabbit_mgmt_util:bad_request( list_to_binary(FormattedReason2), ReqData, Context) end. + +-spec is_feature_flag_blocked(rabbit_feature_flags:feature_name()) -> {true, string()} | false. +is_feature_flag_blocked(Name) -> + BlockedFFs = application:get_env(rabbitmq_management, blocked_feature_flags, []), + proplists:get_value(Name, BlockedFFs, false).