Skip to content

Commit

Permalink
[8.x] [kbn-test] validate isCloud by checking kbnHost (#198025) (#198718
Browse files Browse the repository at this point in the history
)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[kbn-test] validate isCloud by checking kbnHost
(#198025)](#198025)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Dzmitry
Lemechko","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-11-01T19:10:28Z","message":"[kbn-test]
validate isCloud by checking kbnHost (#198025)\n\n##
Summary\r\n\r\nRecently we had issues investigating SAML auth failures
against MKI. The\r\nissue was caused by missing `TEST_CLOUD` env var
that led to `isCloud`\r\nproperty to be set to false.\r\n\r\nThis PR
adds `isCloud` validation by checking if `kbnHost` is pointing\r\nto
Cloud instance and throwing error about misconfiguration\r\n\r\n**How to
test:**\r\n\r\nTry to run FTR tests against MKI without defining
`TEST_CLOUD` env var\r\n\r\n---------\r\n\r\nCo-authored-by: Aleh
Zasypkin
<[email protected]>","sha":"413f7c10b69aa01394beeeb1760a9b085d06d1e4","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","FTR","backport:version","v8.17.0"],"title":"[kbn-test]
validate isCloud by checking
kbnHost","number":198025,"url":"https://github.com/elastic/kibana/pull/198025","mergeCommit":{"message":"[kbn-test]
validate isCloud by checking kbnHost (#198025)\n\n##
Summary\r\n\r\nRecently we had issues investigating SAML auth failures
against MKI. The\r\nissue was caused by missing `TEST_CLOUD` env var
that led to `isCloud`\r\nproperty to be set to false.\r\n\r\nThis PR
adds `isCloud` validation by checking if `kbnHost` is pointing\r\nto
Cloud instance and throwing error about misconfiguration\r\n\r\n**How to
test:**\r\n\r\nTry to run FTR tests against MKI without defining
`TEST_CLOUD` env var\r\n\r\n---------\r\n\r\nCo-authored-by: Aleh
Zasypkin
<[email protected]>","sha":"413f7c10b69aa01394beeeb1760a9b085d06d1e4"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/198025","number":198025,"mergeCommit":{"message":"[kbn-test]
validate isCloud by checking kbnHost (#198025)\n\n##
Summary\r\n\r\nRecently we had issues investigating SAML auth failures
against MKI. The\r\nissue was caused by missing `TEST_CLOUD` env var
that led to `isCloud`\r\nproperty to be set to false.\r\n\r\nThis PR
adds `isCloud` validation by checking if `kbnHost` is pointing\r\nto
Cloud instance and throwing error about misconfiguration\r\n\r\n**How to
test:**\r\n\r\nTry to run FTR tests against MKI without defining
`TEST_CLOUD` env var\r\n\r\n---------\r\n\r\nCo-authored-by: Aleh
Zasypkin
<[email protected]>","sha":"413f7c10b69aa01394beeeb1760a9b085d06d1e4"}},{"branch":"8.x","label":"v8.17.0","branchLabelMappingKey":"^v8.17.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Dzmitry Lemechko <[email protected]>
  • Loading branch information
kibanamachine and dmlemeshko authored Nov 1, 2024
1 parent 273a1ee commit 1b1faa1
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 13 deletions.
26 changes: 15 additions & 11 deletions packages/kbn-test/src/auth/saml_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import { createSAMLResponse as createMockedSAMLResponse } from '@kbn/mock-idp-utils';
import { ToolingLog } from '@kbn/tooling-log';
import axios, { AxiosResponse } from 'axios';
import util from 'util';
import * as cheerio from 'cheerio';
import { Cookie, parse as parseCookie } from 'tough-cookie';
import Url from 'url';
Expand Down Expand Up @@ -253,23 +254,26 @@ export const finishSAMLHandshake = async ({
}) => {
const encodedResponse = encodeURIComponent(samlResponse);
const url = kbnHost + '/api/security/saml/callback';
const request = {
url,
method: 'post',
data: `SAMLResponse=${encodedResponse}`,
headers: {
'content-type': 'application/x-www-form-urlencoded',
...(sid ? { Cookie: `sid=${sid}` } : {}),
},
validateStatus: () => true,
maxRedirects: 0,
};
let authResponse: AxiosResponse;

try {
authResponse = await axios.request({
url,
method: 'post',
data: `SAMLResponse=${encodedResponse}`,
headers: {
'content-type': 'application/x-www-form-urlencoded',
...(sid ? { Cookie: `sid=${sid}` } : {}),
},
validateStatus: () => true,
maxRedirects: 0,
});
authResponse = await axios.request(request);
} catch (ex) {
log.error('Failed to call SAML callback');
cleanException(url, ex);
// Logging the `Cookie: sid=xxxx` header is safe here since it’s an intermediate, non-authenticated cookie that cannot be reused if leaked.
log.error(`Request sent: ${util.inspect(request)}`);
throw ex;
}

Expand Down
29 changes: 28 additions & 1 deletion packages/kbn-test/src/auth/session_manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ describe('SamlSessionManager', () => {
describe('for cloud session', () => {
const hostOptions = {
protocol: 'https' as 'http' | 'https',
hostname: 'cloud',
hostname: 'my-test-deployment.test.elastic.cloud',
username: 'elastic',
password: 'changeme',
};
Expand Down Expand Up @@ -328,4 +328,31 @@ describe('SamlSessionManager', () => {
expect(createCloudSAMLSessionMock.mock.calls).toHaveLength(0);
});
});

describe(`for cloud session with 'isCloud' set to false`, () => {
const hostOptions = {
protocol: 'http' as 'http' | 'https',
hostname: 'my-test-deployment.test.elastic.cloud',
username: 'elastic',
password: 'changeme',
};
const samlSessionManagerOptions = {
hostOptions,
isCloud: false,
log,
cloudUsersFilePath,
};

beforeEach(() => {
jest.resetAllMocks();
});

test('should throw an error when kbnHost points to a Cloud instance', () => {
const kbnHost = `${hostOptions.protocol}://${hostOptions.hostname}`;
expect(() => new SamlSessionManager(samlSessionManagerOptions)).toThrow(
`SamlSessionManager: 'isCloud' was set to false, but 'kbnHost' appears to be a Cloud instance: ${kbnHost}
Set env variable 'TEST_CLOUD=1' to run FTR against your Cloud deployment`
);
});
});
});
18 changes: 17 additions & 1 deletion packages/kbn-test/src/auth/session_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ export class SamlSessionManager {
private readonly cloudUsersFilePath: string;

constructor(options: SamlSessionManagerOptions) {
this.isCloud = options.isCloud;
this.log = options.log;
const hostOptionsWithoutAuth = {
protocol: options.hostOptions.protocol,
hostname: options.hostOptions.hostname,
port: options.hostOptions.port,
};
this.kbnHost = Url.format(hostOptionsWithoutAuth);
this.isCloud = options.isCloud;
this.kbnClient = new KbnClient({
log: this.log,
url: Url.format({
Expand All @@ -73,6 +73,22 @@ export class SamlSessionManager {
this.sessionCache = new Map<Role, Session>();
this.roleToUserMap = new Map<Role, User>();
this.supportedRoles = options.supportedRoles;
this.validateCloudSetting();
}

/**
* Validates if the 'kbnHost' points to Cloud, even if 'isCloud' was set to false
*/
private validateCloudSetting() {
const cloudSubDomains = ['elastic.cloud', 'foundit.no', 'cloud.es.io', 'elastic-cloud.com'];
const isCloudHost = cloudSubDomains.some((domain) => this.kbnHost.endsWith(domain));

if (!this.isCloud && isCloudHost) {
throw new Error(
`SamlSessionManager: 'isCloud' was set to false, but 'kbnHost' appears to be a Cloud instance: ${this.kbnHost}
Set env variable 'TEST_CLOUD=1' to run FTR against your Cloud deployment`
);
}
}

/**
Expand Down

0 comments on commit 1b1faa1

Please sign in to comment.