Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.0.5: Management UI: serve all static assets with a control-cache header (backport #12749) #12779

Merged
merged 7 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .github/workflows/test-management-ui-for-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,24 @@ jobs:
cd ${SELENIUM_DIR}
docker build -t mocha-test --target test .

- name: Run full ui suites on a standalone rabbitmq server
- name: Run short ui suites on a standalone rabbitmq server
run: |
RABBITMQ_DOCKER_IMAGE=bazel/packaging/docker-image:rabbitmq-amd64 \
${SELENIUM_DIR}/run-suites.sh
mkdir -p /tmp/full-suite
mv /tmp/selenium/* /tmp/full-suite
mkdir -p /tmp/full-suite/logs
mv ${SELENIUM_DIR}/logs/* /tmp/full-suite/logs
mkdir -p /tmp/full-suite/screens
mv ${SELENIUM_DIR}/screens/* /tmp/full-suite/screens

ADDON_PROFILES=cluster ${SELENIUM_DIR}/run-suites.sh short-suite-management-ui
mkdir -p /tmp/short-suite
mv /tmp/selenium/* /tmp/short-suite
mkdir -p /tmp/short-suite/logs
mv ${SELENIUM_DIR}/logs/* /tmp/short-suite/logs
mkdir -p /tmp/short-suite/screens
mv ${SELENIUM_DIR}/screens/* /tmp/short-suite/screens
- name: Upload Test Artifacts
if: always()
uses: actions/[email protected]
with:
name: test-artifacts-${{ matrix.browser }}-${{ matrix.erlang_version }}
path: |
/tmp/full-suite
/tmp/short-suite

summary-selenium:
needs:
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/test-management-ui.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ jobs:
- name: Run short ui suite on a 3-node rabbitmq cluster
run: |
RABBITMQ_DOCKER_IMAGE=bazel/packaging/docker-image:rabbitmq-amd64 \
ADDON_PROFILES=cluster ${SELENIUM_DIR}/run-suites.sh short-suite-management-ui
mkdir -p /tmp/short-suite
mv /tmp/selenium/* /tmp/short-suite
mkdir -p /tmp/short-suite/logs
mv ${SELENIUM_DIR}/logs/* /tmp/short-suite/logs
mkdir -p /tmp/short-suite/screens
mv ${SELENIUM_DIR}/screens/* /tmp/short-suite/screens
ADDON_PROFILES=cluster ${SELENIUM_DIR}/run-suites.sh full-suite-management-ui
mkdir -p /tmp/full-suite
mv /tmp/selenium/* /tmp/full-suite
mkdir -p /tmp/full-suite/logs
mv ${SELENIUM_DIR}/logs/* /tmp/full-suite/logs
mkdir -p /tmp/full-suite/screens
mv ${SELENIUM_DIR}/screens/* /tmp/full-suite/screens

- name: Upload Test Artifacts
if: always()
Expand Down
3 changes: 3 additions & 0 deletions deps/rabbitmq_management/app.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def all_beam_files(name = "all_beam_files"):
"src/rabbit_mgmt_wm_vhost.erl",
"src/rabbit_mgmt_wm_vhost_restart.erl",
"src/rabbit_mgmt_wm_vhosts.erl",
"src/rabbit_mgmt_wm_version.erl",
"src/rabbit_mgmt_wm_whoami.erl",
],
hdrs = [":public_and_private_hdrs"],
Expand Down Expand Up @@ -248,6 +249,7 @@ def all_test_beam_files(name = "all_test_beam_files"):
"src/rabbit_mgmt_wm_vhost.erl",
"src/rabbit_mgmt_wm_vhost_restart.erl",
"src/rabbit_mgmt_wm_vhosts.erl",
"src/rabbit_mgmt_wm_version.erl",
"src/rabbit_mgmt_wm_whoami.erl",
],
hdrs = [":public_and_private_hdrs"],
Expand Down Expand Up @@ -472,6 +474,7 @@ def all_srcs(name = "all_srcs"):
"src/rabbit_mgmt_wm_vhost.erl",
"src/rabbit_mgmt_wm_vhost_restart.erl",
"src/rabbit_mgmt_wm_vhosts.erl",
"src/rabbit_mgmt_wm_version.erl",
"src/rabbit_mgmt_wm_whoami.erl",
],
)
Expand Down
6 changes: 3 additions & 3 deletions deps/rabbitmq_management/priv/www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
<link href="css/main.css" rel="stylesheet" type="text/css"/>
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon"/>

<script type="module">
window.oauth = oauth_initialize_if_required();

<script type="module">
check_version()
window.oauth = oauth_initialize_if_required()
</script>


Expand Down
13 changes: 10 additions & 3 deletions deps/rabbitmq_management/priv/www/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,13 @@ function check_login () {
if (user == false || user.error) {
clear_auth();
if (oauth.enabled) {
//hide_popup_warn();
renderWarningMessageInLoginStatus(oauth, 'Not authorized');
} else {
//hide_popup_warn();
replace_content('login-status', '<p>Login failed</p>');
}
return false;
}

check_version()
hide_popup_warn()
replace_content('outer', format('layout', {}))
var user_login_session_timeout = parseInt(user.login_session_timeout)
Expand Down Expand Up @@ -1845,3 +1843,12 @@ function get_chart_range_type(arg) {
console.log('[WARNING]: range type not found for arg: ' + arg);
return 'basic';
}

function check_version() {
let curVersion = sync_get('/version')
let storedVersion = get_pref('version')
if (!storedVersion || storedVersion != curVersion) {
store_pref('version', curVersion)
location.reload()
}
}
28 changes: 17 additions & 11 deletions deps/rabbitmq_management/priv/www/js/oidc-oauth/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,18 +301,26 @@ export function oauth_completeLogin() {

export function oauth_initiateLogout() {
if (oauth.sp_initiated) {
mgr.metadataService.getEndSessionEndpoint().then(endpoint => {
if (endpoint == undefined) {
// Logout only from management UI
mgr.removeUser().then(res => {
clear_auth()
oauth_redirectToLogin()
return mgr.getUser().then(user => {
if (user != null) {
mgr.metadataService.getEndSessionEndpoint().then(endpoint => {
if (endpoint == undefined) {
// Logout only from management UI
mgr.removeUser().then(res => {
clear_auth()
oauth_redirectToLogin()
})
}else {
// OpenId Connect RP-Initiated Logout
mgr.signoutRedirect()
}
})
}else {
// OpenId Connect RP-Initiated Logout
mgr.signoutRedirect()
clear_auth()
go_to_home()
}
})

} else {
go_to_authority()
}
Expand Down Expand Up @@ -381,8 +389,7 @@ export function hasAnyResourceServerReady(oauth, onReadyCallback) {
return group;
}, {})
let warnings = []
for(var url in groupByProviderURL){
console.log(url + ': ' + groupByProviderURL[url]);
for(var url in groupByProviderURL){
const notReadyResources = groupByProviderURL[url].filter((oauthserver) => notReadyServers.includes(oauthserver.oauth_provider_url))
const notCompliantResources = groupByProviderURL[url].filter((oauthserver) => notCompliantServers.includes(oauthserver.oauth_provider_url))
if (notReadyResources.length == 1) {
Expand All @@ -396,7 +403,6 @@ export function hasAnyResourceServerReady(oauth, onReadyCallback) {
warnings.push(warningMessageOAuthResources(url, notCompliantResources, " not compliant"))
}
}
console.log("warnings:" + warnings)
oauth.declared_resource_servers_count = oauth.resource_servers.length
oauth.resource_servers = oauth.resource_servers.filter((resource) =>
!notReadyServers.includes(resource.oauth_provider_url) && !notCompliantServers.includes(resource.oauth_provider_url))
Expand Down
3 changes: 2 additions & 1 deletion deps/rabbitmq_management/src/rabbit_mgmt_dispatcher.erl
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,6 @@ dispatcher() ->
{"/auth/attempts/:node/source", rabbit_mgmt_wm_auth_attempts, [by_source]},
{"/login", rabbit_mgmt_wm_login, []},
{"/config/effective", rabbit_mgmt_wm_environment, []},
{"/auth/hash_password/:password", rabbit_mgmt_wm_hash_password, []}
{"/auth/hash_password/:password", rabbit_mgmt_wm_hash_password, []},
{"/version", rabbit_mgmt_wm_version, []}
].
8 changes: 6 additions & 2 deletions deps/rabbitmq_management/src/rabbit_mgmt_headers.erl
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,18 @@ set_common_permission_headers(ReqData0, EndpointModule) ->
lists:foldl(fun(Fun, ReqData) ->
Fun(ReqData, EndpointModule)
end, ReqData0,
[fun set_csp_headers/2,
[fun set_etag_based_cache_headers/2,
fun set_csp_headers/2,
fun set_hsts_headers/2,
fun set_cors_headers/2,
fun set_content_type_options_header/2,
fun set_xss_protection_header/2,
fun set_frame_options_header/2]).

set_etag_based_cache_headers(ReqData0, _Module) ->
cowboy_req:set_resp_header(<<"cache-control">>, <<"public, max-age=0, must-revalidate">>, ReqData0).

set_no_cache_headers(ReqData0, _Module) ->
ReqData1 = cowboy_req:set_resp_header(<<"cache-control">>, <<"no-cache, no-store, must-revalidate">>, ReqData0),
ReqData1 = cowboy_req:set_resp_header(<<"cache-control">>, <<"no-cache, no-store, max-age=0, must-revalidate">>, ReqData0),
ReqData2 = cowboy_req:set_resp_header(<<"pragma">>, <<"no-cache">>, ReqData1),
cowboy_req:set_resp_header(<<"expires">>, rabbit_data_coercion:to_binary(0), ReqData2).
38 changes: 38 additions & 0 deletions deps/rabbitmq_management/src/rabbit_mgmt_wm_version.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
%% 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) 2007-2024 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%%

-module(rabbit_mgmt_wm_version).

-export([init/2]).
-export([to_json/2, content_types_provided/2]).
-export([variances/2]).

-include_lib("rabbit_common/include/rabbit.hrl").
-include_lib("rabbitmq_management_agent/include/rabbit_mgmt_records.hrl").

%%--------------------------------------------------------------------

init(Req, _State) ->
{cowboy_rest, rabbit_mgmt_headers:set_no_cache_headers(
rabbit_mgmt_headers:set_common_permission_headers(Req, ?MODULE), ?MODULE),
#context{}}.

variances(Req, Context) ->
{[<<"accept-encoding">>, <<"origin">>], Req, Context}.

content_types_provided(ReqData, Context) ->
{rabbit_mgmt_util:responder_map(to_json), ReqData, Context}.

to_json(ReqData, Context) ->
Version = case rabbit:product_info() of
#{product_version := Value} -> Value;
#{product_base_version := Base} -> Base
end,
rabbit_mgmt_util:reply(list_to_binary(Version), ReqData, Context).

%%--------------------------------------------------------------------

15 changes: 11 additions & 4 deletions deps/rabbitmq_management/test/rabbit_mgmt_http_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ all() ->
].

groups() ->
[
[
{all_tests_with_prefix, [], some_tests() ++ all_tests()},
{all_tests_without_prefix, [], some_tests()},
%% We have several groups because their interference is
Expand Down Expand Up @@ -104,7 +104,6 @@ definitions_group4_tests() ->
definitions_vhost_test
].


all_tests() -> [
cli_redirect_test,
api_redirect_test,
Expand Down Expand Up @@ -201,8 +200,9 @@ all_tests() -> [
disabled_qq_replica_opers_test,
qq_status_test,
list_deprecated_features_test,
list_used_deprecated_features_test,
cluster_and_node_tags_test
list_used_deprecated_features_test,
cluster_and_node_tags_test,
version_test
].

%% -------------------------------------------------------------------
Expand Down Expand Up @@ -3749,6 +3749,13 @@ oauth_test(Config) ->
%% cleanup
rpc(Config, application, unset_env, [rabbitmq_management, oauth_enabled]).

version_test(Config) ->
ActualVersion = http_get(Config, "/version"),
ct:log("ActualVersion : ~p", [ActualVersion]),
ExpectedVersion = rpc(Config, rabbit, base_product_version, []),
ct:log("ExpectedVersion : ~p", [ExpectedVersion]),
?assertEqual(ExpectedVersion, binary_to_list(ActualVersion)).

login_test(Config) ->
http_put(Config, "/users/myuser", [{password, <<"myuser">>},
{tags, <<"management">>}], {group, '2xx'}),
Expand Down
3 changes: 3 additions & 0 deletions selenium/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ not see any browser interaction, everything happens in the background, i.e. rabb

**The interactive mode** - This mode is convenient when we are still working on RabbitMQ source code and/or in the selenium tests. In this mode, you run RabbitMQ and tests directly from source to speed things up. The components, such as, UAA or keycloak, run in docker.

**IMPORTANT** - If you intend to switch between version of RabbitMQ, make sure
you run `./clean.sh` to clear any state left from the last test run.


## Run tests in headless-mode

Expand Down
2 changes: 1 addition & 1 deletion selenium/bin/components/keycloak
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ start_keycloak() {
--publish 8443:8443 \
--env KEYCLOAK_ADMIN=admin \
--env KEYCLOAK_ADMIN_PASSWORD=admin \
--mount type=bind,source=${MOUNT_KEYCLOAK_CONF_DIR},target=/opt/keycloak/data/import/ \
-v ${MOUNT_KEYCLOAK_CONF_DIR}:/opt/keycloak/data/import/ \
${KEYCLOAK_DOCKER_IMAGE} start-dev --import-realm \
--https-certificate-file=/opt/keycloak/data/import/server_keycloak_certificate.pem \
--https-certificate-key-file=/opt/keycloak/data/import/server_keycloak_key.pem
Expand Down
17 changes: 11 additions & 6 deletions selenium/bin/suite_template
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ teardown_local_others() {
if [[ $REQUIRED_COMPONENTS == "" ]]; then
print "There are no other components"
else
teardown_components
teardown_components true
fi
}
test_local() {
Expand Down Expand Up @@ -528,13 +528,18 @@ start_components() {
}

teardown_components() {
begin "Tear down ..."
skip_rabbitmq=${1:-false}

begin "Tear down ... "
for i in "${REQUIRED_COMPONENTS[@]}"
do
local component="$i"
stop="stop_$i"
type "$stop" &>/dev/null && $stop || kill_container_if_exist "$component"
print "Tear down $component"
if [[ $i != "rabbitmq" || ($i == "rabbitmq" && $skip_rabbitmq == false) ]]
then
local component="$i"
stop="stop_$i"
type "$stop" &>/dev/null && $stop || kill_container_if_exist "$component"
print "Tear down $component"
fi
done
end "Finished teardown"
}
Expand Down
3 changes: 3 additions & 0 deletions selenium/clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

rm -r $TMPDIR/rabbitmq-test-instances
2 changes: 1 addition & 1 deletion selenium/suites/authnz-mgt/oauth-and-basic-auth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

TEST_CASES_PATH=/oauth/with-basic-auth
TEST_CONFIG_PATH=/oauth
PROFILES="keycloak jwks keycloak-oauth-provider enable-basic-auth tls"
PROFILES="keycloak keycloak-oauth-provider keycloak-mgt-oauth-provider tls enable-basic-auth"

source $SCRIPT/../../bin/suite_template $@
runWith keycloak
7 changes: 3 additions & 4 deletions selenium/test/basic-auth/unauthorized.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ describe('An user without management tag', function () {
overview = new OverviewPage(driver)
captureScreen = captureScreensFor(driver, __filename)

assert.ok(!await login.isPopupWarningDisplayed())
await login.login('rabbit_no_management', 'rabbit_no_management')
await !overview.isLoaded()
//assert.ok(!await login.isPopupWarningDisplayed())
await login.login('rabbit_no_management', 'guest')
})

it('cannot log in into the management ui', async function () {
Expand All @@ -35,7 +34,7 @@ describe('An user without management tag', function () {

it('should get popup warning dialog', async function(){
assert.ok(login.isPopupWarningDisplayed())
assert.equal('Not_Authorized', await login.getPopupWarning())
assert.equal('Not management user', await login.getPopupWarning())
})

describe("After clicking on popup warning dialog button", function() {
Expand Down
10 changes: 10 additions & 0 deletions selenium/test/mgt-only/imports/users.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
"vhosts": [
{
"name": "/"
},
{
"name": "other"
}
],
"permissions": [
Expand All @@ -59,6 +62,13 @@
"write": ".*",
"read": ".*"
},
{
"user": "guest",
"vhost": "other",
"configure": ".*",
"write": ".*",
"read": ".*"
},
{
"user": "management",
"vhost": "/",
Expand Down
Loading
Loading