Skip to content

Commit a0a4c3d

Browse files
MarcialRosalesmergify[bot]
authored andcommitted
Test login preferences
(cherry picked from commit 764e684)
1 parent 39fbf91 commit a0a4c3d

File tree

6 files changed

+123
-17
lines changed

6 files changed

+123
-17
lines changed

deps/rabbitmq_management/src/rabbit_mgmt_login.erl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ login(<<"POST">>, Req0, State) ->
5252
AccessToken -> handleAccessToken(Req0, AccessToken, State)
5353
end;
5454

55-
login(<<"GET">>, Req, State) ->
55+
login(<<"GET">>, Req, State) ->
5656
Auth = case rabbit_mgmt_util:qs_val(?MANAGEMENT_LOGIN_STRICT_AUTH_MECHANISM, Req) of
5757
undefined ->
5858
case rabbit_mgmt_util:qs_val(?MANAGEMENT_LOGIN_PREFERRED_AUTH_MECHANISM, Req) of
@@ -61,6 +61,7 @@ login(<<"GET">>, Req, State) ->
6161
end;
6262
Val -> validate_auth_mechanism({?MANAGEMENT_LOGIN_STRICT_AUTH_MECHANISM, Val})
6363
end,
64+
?LOG_DEBUG("/login GET with auth: ~p", [Auth]),
6465
case Auth of
6566
undefined ->
6667
case rabbit_mgmt_util:qs_val(?OAUTH2_ACCESS_TOKEN, Req) of

deps/rabbitmq_management/src/rabbit_mgmt_oauth_bootstrap.erl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ get_auth_mechanism(Req) ->
8282

8383
get_auth_mechanism_from_cookies(Req) ->
8484
Cookies = cowboy_req:parse_cookies(Req),
85+
?LOG_DEBUG("get_auth_mechanism_from_cookies: ~p", [Cookies]),
8586
case proplists:get_value(?MANAGEMENT_LOGIN_STRICT_AUTH_MECHANISM, Cookies) of
8687
undefined ->
8788
case proplists:get_value(?MANAGEMENT_LOGIN_PREFERRED_AUTH_MECHANISM, Cookies) of
@@ -114,9 +115,14 @@ set_token_auth(AuthSettings, Req0) ->
114115
["set_token_auth('", Token, "');"]
115116
};
116117
_ ->
117-
Cookies = cowboy_req:parse_cookies(Req0),
118-
case lists:keyfind(?OAUTH2_ACCESS_TOKEN, 1, Cookies) of
119-
{_, Token} ->
118+
Cookies = cowboy_req:parse_cookies(Req0),
119+
?LOG_DEBUG("set_token_auth: ~p", [Cookies]),
120+
case proplists:get_value(?OAUTH2_ACCESS_TOKEN, Cookies) of
121+
undefined -> {
122+
Req0,
123+
[]
124+
};
125+
Token ->
120126
{
121127
cowboy_req:set_resp_cookie(
122128
?OAUTH2_ACCESS_TOKEN, <<"">>, Req0, #{
@@ -126,11 +132,7 @@ set_token_auth(AuthSettings, Req0) ->
126132
same_site => strict
127133
}),
128134
["set_token_auth('", Token, "');"]
129-
};
130-
false -> {
131-
Req0,
132-
[]
133-
}
135+
}
134136
end
135137
end;
136138
false -> {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const { By, Key, until, Builder } = require('selenium-webdriver')
2+
require('chromedriver')
3+
const assert = require('assert')
4+
const { buildDriver, goToHome, goToLogin, captureScreensFor, teardown, findOption } = require('../../utils')
5+
6+
const SSOHomePage = require('../../pageobjects/SSOHomePage')
7+
8+
describe('Given two oauth resources and basic auth enabled, an unauthenticated user', function () {
9+
let driver;
10+
let captureScreen;
11+
let login;
12+
13+
before(async function () {
14+
this.driver = buildDriver();
15+
this.captureScreen = captureScreensFor(this.driver, __filename);
16+
17+
login = async (key, value) => {
18+
await goToLogin(this.driver, key, value);
19+
const homePage = new SSOHomePage(this.driver);
20+
await homePage.isLoaded();
21+
return homePage;
22+
}
23+
})
24+
25+
it('can preselect rabbit_dev oauth2 resource', async function () {
26+
const homePage = await login("preferred_auth_mechanism", "oauth2:rabbit_dev");
27+
28+
const oauth2Section = await homePage.isOAuth2SectionVisible();
29+
assert.ok((await oauth2Section.getAttribute("class")).includes("section-visible"))
30+
const basicSection = await homePage.isBasicAuthSectionVisible();
31+
assert.ok((await basicSection.getAttribute("class")).includes("section-invisible"))
32+
33+
resources = await homePage.getOAuthResourceOptions();
34+
const option = findOption("rabbit_dev", resources);
35+
assert.ok(option);
36+
assert.ok(option.selected);
37+
38+
})
39+
it('can preselect rabbit_prod oauth2 resource', async function () {
40+
const homePage = await login("preferred_auth_mechanism", "oauth2:rabbit_prod");
41+
42+
const oauth2Section = await homePage.isOAuth2SectionVisible();
43+
assert.ok((await oauth2Section.getAttribute("class")).includes("section-visible"))
44+
const basicSection = await homePage.isBasicAuthSectionVisible();
45+
assert.ok((await basicSection.getAttribute("class")).includes("section-invisible"))
46+
47+
resources = await homePage.getOAuthResourceOptions();
48+
const option = findOption("rabbit_prod", resources);
49+
assert.ok(option);
50+
assert.ok(option.selected);
51+
52+
})
53+
54+
it('can preselect basic auth', async function () {
55+
const homePage = await login("preferred_auth_mechanism", "basic");
56+
57+
const oauth2Section = await homePage.isOAuth2SectionVisible();
58+
assert.ok((await oauth2Section.getAttribute("class")).includes("section-invisible"))
59+
const basicSection = await homePage.isBasicAuthSectionVisible();
60+
assert.ok((await basicSection.getAttribute("class")).includes("section-visible"))
61+
})
62+
63+
after(async function () {
64+
await teardown(this.driver, this, this.captureScreen);
65+
})
66+
})

selenium/test/pageobjects/BasePage.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ module.exports = class BasePage {
131131
for (const index in optionList) {
132132
const t = await optionList[index].getText()
133133
const v = await optionList[index].getAttribute('value')
134-
table_model.push({"text":t, "value": v})
134+
const s = await optionList[index].getAttribute('selected')
135+
table_model.push({"text": t, "value": v, "selected" : s !== undefined})
135136
}
136137

137138
return table_model
@@ -300,13 +301,14 @@ module.exports = class BasePage {
300301

301302
async isDisplayed(locator) {
302303
try {
303-
let element = await driver.findElement(locator)
304+
let element = await this.driver.findElement(locator)
304305

305306
return this.driver.wait(until.elementIsVisible(element), this.timeout,
306307
'Timed out after [timeout=' + this.timeout + ';polling=' + this.polling + '] awaiting till visible ' + element,
307308
this.polling / 2)
308309
}catch(error) {
309-
return Promise.resolve(false)
310+
console.log("isDisplayed failed due to " + error);
311+
return Promise.resolve(false);
310312
}
311313
}
312314

selenium/test/pageobjects/SSOHomePage.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ module.exports = class SSOHomePage extends BasePage {
7474
async isOAuth2SectionVisible() {
7575
return this.isDisplayed(SECTION_LOGIN_WITH_OAUTH)
7676
}
77+
7778
async getOAuth2Section() {
7879
return this.waitForDisplayed(SECTION_LOGIN_WITH_OAUTH)
7980
}

selenium/test/utils.js

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ class CaptureScreenshot {
3939
const screenshotsSubDir = path.join(screenshotsDir, this.test)
4040
if (!fs.existsSync(screenshotsSubDir)) {
4141
await fsp.mkdir(screenshotsSubDir)
42-
}
42+
}
4343
const dest = path.join(screenshotsSubDir, name + '.png')
44+
console.log("screenshot saved to " + dest)
4445
await fsp.writeFile(dest, image, 'base64')
4546
}
4647
}
@@ -122,8 +123,31 @@ module.exports = {
122123
return d.driver.get(d.baseUrl)
123124
},
124125

125-
goToLogin: (d, token) => {
126-
return d.driver.get(d.baseUrl + '#/login?access_token=' + token)
126+
/**
127+
* For instance,
128+
* goToLogin(d, access_token, myAccessToken)
129+
* or
130+
* goToLogin(d, preferred_auth_mechanism, "oauth2:my-resource")
131+
*/
132+
goToLogin: (d, ...keyValuePairs) => {
133+
const params = [];
134+
for (let i = 0; i < keyValuePairs.length; i += 2) {
135+
const key = keyValuePairs[i];
136+
const value = keyValuePairs[i + 1];
137+
138+
if (key !== undefined) {
139+
// URL-encode both key and value
140+
const encodedKey = encodeURIComponent(key);
141+
const encodedValue = encodeURIComponent(value || '');
142+
params.push(`${encodedKey}=${encodedValue}`);
143+
}
144+
}
145+
// Build query string: "key1=value1&key2=value2"
146+
const queryString = params.join('&');
147+
148+
const url = d.baseUrl + '/login?' + queryString;
149+
console.log("Navigating to " + url);
150+
return d.driver.get(url);
127151
},
128152

129153
goToConnections: (d) => {
@@ -263,8 +287,15 @@ module.exports = {
263287
&& actualOption.text == expectedOptions[i].text))
264288
}
265289
},
290+
findOption: (value, options) => {
291+
for (let i = 0; i < options.length; i++) {
292+
if (options[i].value === value) return options[i];
293+
}
294+
return undefined;
295+
},
266296

267297
teardown: async (d, test, captureScreen = null) => {
298+
268299
driver = d.driver
269300
driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) {
270301
entries.forEach(function(entry) {
@@ -274,8 +305,11 @@ module.exports = {
274305
if (test.currentTest) {
275306
if (test.currentTest.isPassed()) {
276307
driver.executeScript('lambda-status=passed')
277-
} else {
278-
if (captureScreen != null) await captureScreen.shot('after-failed')
308+
} else {
309+
if (captureScreen != null) {
310+
console.log("Teardown failed . capture...");
311+
await captureScreen.shot('after-failed');
312+
}
279313
driver.executeScript('lambda-status=failed')
280314
}
281315
}

0 commit comments

Comments
 (0)