Insert control-cache headers to every resource and reload index.html
(cherry picked from commit ce760c688b)
# Conflicts:
# .github/workflows/test-management-ui-for-pr.yaml
# deps/rabbitmq_management/test/rabbit_mgmt_http_SUITE.erl
# selenium/test/multi-oauth/certs/server_rabbitmq_certificate.pem
# selenium/test/multi-oauth/certs/server_rabbitmq_key.pem
# selenium/test/multi-oauth/devkeycloak/server_devkeycloak.p12
# selenium/test/multi-oauth/devkeycloak/server_devkeycloak_certificate.pem
# selenium/test/multi-oauth/devkeycloak/server_devkeycloak_key.pem
# selenium/test/multi-oauth/prodkeycloak/server_prodkeycloak.p12
# selenium/test/multi-oauth/prodkeycloak/server_prodkeycloak_certificate.pem
# selenium/test/multi-oauth/prodkeycloak/server_prodkeycloak_key.pem
This commit is contained in:
parent
8e9c2a76c9
commit
914b0f10cb
|
|
@ -69,8 +69,9 @@ 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: |
|
||||
<<<<<<< HEAD
|
||||
RABBITMQ_DOCKER_IMAGE=bazel/packaging/docker-image:rabbitmq-amd64 \
|
||||
${SELENIUM_DIR}/run-suites.sh
|
||||
mkdir -p /tmp/full-suite
|
||||
|
|
@ -80,13 +81,25 @@ jobs:
|
|||
mkdir -p /tmp/full-suite/screens
|
||||
mv ${SELENIUM_DIR}/screens/* /tmp/full-suite/screens
|
||||
|
||||
=======
|
||||
IMAGE_TAG=$(find PACKAGES/rabbitmq-server-generic-unix-*.tar.xz | awk -F 'PACKAGES/rabbitmq-server-generic-unix-|.tar.xz' '{print $2}')
|
||||
RABBITMQ_DOCKER_IMAGE=pivotalrabbitmq/rabbitmq:$IMAGE_TAG \
|
||||
${SELENIUM_DIR}/run-suites.sh short-suite-management-ui
|
||||
mkdir -p /tmp/short-suite
|
||||
mv /tmp/selenium/* /tmp/short-suite
|
||||
|
||||
>>>>>>> ce760c688b (Insert control-cache headers to every resource and reload index.html)
|
||||
- name: Upload Test Artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4.3.2
|
||||
with:
|
||||
name: test-artifacts-${{ matrix.browser }}-${{ matrix.erlang_version }}
|
||||
path: |
|
||||
<<<<<<< HEAD
|
||||
/tmp/full-suite
|
||||
=======
|
||||
/tmp/short-suite
|
||||
>>>>>>> ce760c688b (Insert control-cache headers to every resource and reload index.html)
|
||||
|
||||
summary-selenium:
|
||||
needs:
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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, []}
|
||||
].
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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_version() of
|
||||
undefined -> rabbit:base_product_version();
|
||||
V -> V
|
||||
end,
|
||||
rabbit_mgmt_util:reply(list_to_binary(Version), ReqData, Context).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -104,7 +104,6 @@ definitions_group4_tests() ->
|
|||
definitions_vhost_test
|
||||
].
|
||||
|
||||
|
||||
all_tests() -> [
|
||||
cli_redirect_test,
|
||||
api_redirect_test,
|
||||
|
|
@ -202,7 +201,17 @@ all_tests() -> [
|
|||
qq_status_test,
|
||||
list_deprecated_features_test,
|
||||
list_used_deprecated_features_test,
|
||||
<<<<<<< HEAD
|
||||
cluster_and_node_tags_test
|
||||
=======
|
||||
connections_amqpl,
|
||||
connections_amqp,
|
||||
amqp_sessions,
|
||||
amqpl_sessions,
|
||||
enable_plugin_amqp,
|
||||
cluster_and_node_tags_test,
|
||||
version_test
|
||||
>>>>>>> ce760c688b (Insert control-cache headers to every resource and reload index.html)
|
||||
].
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
|
|
@ -3749,6 +3758,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'}),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
rm -r $TMPDIR/rabbitmq-test-instances
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -1,32 +1,30 @@
|
|||
const { By, Key, until, Builder } = require('selenium-webdriver')
|
||||
require('chromedriver')
|
||||
const assert = require('assert')
|
||||
const { buildDriver, goToHome, captureScreensFor, teardown, idpLoginPage } = require('../../utils')
|
||||
const { buildDriver, goToHome, captureScreensFor, teardown, delay } = require('../../utils')
|
||||
|
||||
const SSOHomePage = require('../../pageobjects/SSOHomePage')
|
||||
const OverviewPage = require('../../pageobjects/OverviewPage')
|
||||
|
||||
describe('When basic authentication is enabled but UAA is down', function () {
|
||||
let homePage
|
||||
let idpLogin
|
||||
let overview
|
||||
let captureScreen
|
||||
|
||||
before(async function () {
|
||||
driver = buildDriver()
|
||||
await goToHome(driver)
|
||||
homePage = new SSOHomePage(driver)
|
||||
idpLogin = idpLoginPage(driver)
|
||||
homePage = new SSOHomePage(driver)
|
||||
overview = new OverviewPage(driver)
|
||||
captureScreen = captureScreensFor(driver, __filename)
|
||||
})
|
||||
|
||||
it('can log in with Basic Auth', async function () {
|
||||
await homePage.toggleBasicAuthSection()
|
||||
assert.ok(await homePage.isLoginButtonVisible)
|
||||
await homePage.basicAuthLogin('guest', 'guest')
|
||||
if (!await overview.isLoaded()) {
|
||||
throw new Error('Failed to login')
|
||||
}
|
||||
await overview.isLoaded()
|
||||
assert.equal(await overview.getUser(), 'User guest')
|
||||
await overview.logout()
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const { By, Key, until, Builder, Select } = require('selenium-webdriver')
|
||||
const { By, Key, until, Builder, Select, WebDriverError, NoSuchSessionError } = require('selenium-webdriver')
|
||||
|
||||
const MENU_TABS = By.css('div#menu ul#tabs')
|
||||
const USER = By.css('li#logout')
|
||||
|
|
@ -184,7 +184,9 @@ module.exports = class BasePage {
|
|||
'Timed out after [timeout=' + this.timeout + ';polling=' + this.polling + '] seconds locating ' + locator,
|
||||
this.polling)
|
||||
}catch(error) {
|
||||
console.error("Failed to locate element " + locator)
|
||||
if (!error.name.includes("NoSuchSessionError")) {
|
||||
console.error("Failed waitForLocated " + locator + " due to " + error)
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
|
@ -194,8 +196,10 @@ module.exports = class BasePage {
|
|||
return this.driver.wait(until.elementIsVisible(element), this.timeout,
|
||||
'Timed out after [timeout=' + this.timeout + ';polling=' + this.polling + '] awaiting till visible ' + element,
|
||||
this.polling)
|
||||
}catch(error) {
|
||||
console.error("Failed to find visible element " + element)
|
||||
}catch(error) {
|
||||
if (!error.name.includes("NoSuchSessionError")) {
|
||||
console.error("Failed to find visible element " + element + " due to " + error)
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
|
@ -206,7 +210,9 @@ module.exports = class BasePage {
|
|||
try {
|
||||
return this.waitForVisible(await this.waitForLocated(locator))
|
||||
}catch(error) {
|
||||
console.error("Failed to waitForDisplayed for locator " + locator)
|
||||
if (!error.name.includes("NoSuchSessionError")) {
|
||||
console.error("Failed to waitForDisplayed " + locator + " due to " + error)
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,8 +87,11 @@ module.exports = class SSOHomePage extends BasePage {
|
|||
|
||||
async basicAuthLogin (username, password) {
|
||||
await this.isLoaded()
|
||||
await this.waitForDisplayed(BASIC_AUTH_LOGIN_USERNAME)
|
||||
await this.sendKeys(BASIC_AUTH_LOGIN_USERNAME, username)
|
||||
await this.waitForDisplayed(BASIC_AUTH_LOGIN_PASSWORD)
|
||||
await this.sendKeys(BASIC_AUTH_LOGIN_PASSWORD, password)
|
||||
await this.waitForDisplayed(BASIC_AUTH_LOGIN_FORM)
|
||||
return this.submit(BASIC_AUTH_LOGIN_FORM)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue