mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Serverless] Disable Login Selector and push Basic
authentication providder down the authentication chain. (#165810)
## Summary Since we're planning to disable login selector in MKI soon, we should adapt our tests for this new configuration. This PR disables Login Selector and pushes `Basic` authentication providder down the authentication chain in Serverless tests.
This commit is contained in:
parent
b35328f2b2
commit
7aa307476c
30 changed files with 300 additions and 231 deletions
|
@ -5,13 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-nodejs-modules */
|
||||
|
||||
import * as yaml from 'js-yaml';
|
||||
import type { UrlObject } from 'url';
|
||||
import Url from 'url';
|
||||
import type { Role } from '@kbn/security-plugin/common';
|
||||
import { isLocalhost } from '../../../../scripts/endpoint/common/is_localhost';
|
||||
import type { LoginState } from '@kbn/security-plugin/common/login_state';
|
||||
import { getWithResponseActionsRole } from '../../../../scripts/endpoint/common/roles_users/with_response_actions_role';
|
||||
import { getNoResponseActionsRole } from '../../../../scripts/endpoint/common/roles_users/without_response_actions_role';
|
||||
import { request } from './common';
|
||||
|
@ -90,35 +86,6 @@ const ELASTICSEARCH_PASSWORD = 'ELASTICSEARCH_PASSWORD';
|
|||
const KIBANA_USERNAME = 'KIBANA_USERNAME';
|
||||
const KIBANA_PASSWORD = 'KIBANA_PASSWORD';
|
||||
|
||||
/**
|
||||
* The Kibana server endpoint used for authentication
|
||||
*/
|
||||
const LOGIN_API_ENDPOINT = '/internal/security/login';
|
||||
|
||||
/**
|
||||
* cy.visit will default to the baseUrl which uses the default kibana test user
|
||||
* This function will override that functionality in cy.visit by building the baseUrl
|
||||
* directly from the environment variables set up in x-pack/test/security_solution_cypress/runner.ts
|
||||
*
|
||||
* @param role string role/user to log in with
|
||||
* @param route string route to visit
|
||||
*/
|
||||
export const getUrlWithRoute = (role: string, route: string) => {
|
||||
const url = Cypress.config().baseUrl;
|
||||
const kibana = new URL(String(url));
|
||||
const theUrl = `${Url.format({
|
||||
auth: `${role}:changeme`,
|
||||
username: role,
|
||||
password: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
protocol: kibana.protocol.replace(':', ''),
|
||||
hostname: kibana.hostname,
|
||||
port: kibana.port,
|
||||
} as UrlObject)}${route.startsWith('/') ? '' : '/'}${route}`;
|
||||
cy.log(`origin: ${theUrl}`);
|
||||
|
||||
return theUrl;
|
||||
};
|
||||
|
||||
export const createCustomRoleAndUser = (role: string, rolePrivileges: Omit<Role, 'name'>) => {
|
||||
// post the role
|
||||
request({
|
||||
|
@ -139,31 +106,44 @@ export const createCustomRoleAndUser = (role: string, rolePrivileges: Omit<Role,
|
|||
});
|
||||
};
|
||||
|
||||
export const loginWithRole = async (role: ROLE) => {
|
||||
const loginWithUsernameAndPassword = (username: string, password: string) => {
|
||||
const baseUrl = Cypress.config().baseUrl;
|
||||
if (!baseUrl) {
|
||||
throw Error(`Cypress config baseUrl not set!`);
|
||||
}
|
||||
|
||||
// Programmatically authenticate without interacting with the Kibana login page.
|
||||
const headers = { 'kbn-xsrf': 'cypress-creds' };
|
||||
request<LoginState>({ headers, url: `${baseUrl}/internal/security/login_state` }).then(
|
||||
(loginState) => {
|
||||
const basicProvider = loginState.body.selector.providers.find(
|
||||
(provider) => provider.type === 'basic'
|
||||
);
|
||||
return request({
|
||||
url: `${baseUrl}/internal/security/login`,
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: {
|
||||
providerType: basicProvider.type,
|
||||
providerName: basicProvider.name,
|
||||
currentURL: '/',
|
||||
params: { username, password },
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export const loginWithRole = (role: ROLE) => {
|
||||
loginWithCustomRole(role, rolesMapping[role]);
|
||||
};
|
||||
|
||||
export const loginWithCustomRole = async (role: string, rolePrivileges: Omit<Role, 'name'>) => {
|
||||
export const loginWithCustomRole = (role: string, rolePrivileges: Omit<Role, 'name'>) => {
|
||||
createCustomRoleAndUser(role, rolePrivileges);
|
||||
const theUrl = new URL(String(Cypress.config().baseUrl));
|
||||
theUrl.username = role;
|
||||
theUrl.password = Cypress.env(ELASTICSEARCH_PASSWORD);
|
||||
|
||||
cy.log(`origin: ${theUrl}`);
|
||||
request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username: role,
|
||||
password: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
},
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'cypress-creds-via-config' },
|
||||
method: 'POST',
|
||||
url: getUrlWithRoute(role, LOGIN_API_ENDPOINT),
|
||||
});
|
||||
cy.log(`origin: ${Cypress.config().baseUrl}`);
|
||||
|
||||
loginWithUsernameAndPassword(role, Cypress.env(ELASTICSEARCH_PASSWORD));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -199,14 +179,6 @@ const credentialsProvidedByEnvironment = (): boolean =>
|
|||
* Kibana's `/internal/security/login` endpoint, bypassing the login page (for speed).
|
||||
*/
|
||||
const loginViaEnvironmentCredentials = () => {
|
||||
const url = Cypress.config().baseUrl;
|
||||
|
||||
if (!url) {
|
||||
throw Error(`Cypress config baseUrl not set!`);
|
||||
}
|
||||
|
||||
const urlObj = new URL(url);
|
||||
|
||||
let username: string;
|
||||
let password: string;
|
||||
let usernameEnvVar: string;
|
||||
|
@ -228,21 +200,7 @@ const loginViaEnvironmentCredentials = () => {
|
|||
`Authenticating user [${username}] retrieved via environment credentials from the \`CYPRESS_${usernameEnvVar}\` and \`CYPRESS_${passwordEnvVar}\` environment variables`
|
||||
);
|
||||
|
||||
// programmatically authenticate without interacting with the Kibana login page
|
||||
request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: url && !isLocalhost(urlObj.hostname) ? 'cloud-basic' : 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username,
|
||||
password,
|
||||
},
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'cypress-creds-via-env' },
|
||||
method: 'POST',
|
||||
url: `${url}${LOGIN_API_ENDPOINT}`,
|
||||
});
|
||||
loginWithUsernameAndPassword(username, password);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -258,22 +216,10 @@ const loginViaConfig = () => {
|
|||
// read the login details from `kibana.dev.yaml`
|
||||
cy.readFile(KIBANA_DEV_YML_PATH).then((kibanaDevYml) => {
|
||||
const config = yaml.safeLoad(kibanaDevYml);
|
||||
|
||||
// programmatically authenticate without interacting with the Kibana login page
|
||||
request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username: Cypress.env(ELASTICSEARCH_USERNAME),
|
||||
password: config.elasticsearch.password,
|
||||
},
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'cypress-creds-via-config' },
|
||||
method: 'POST',
|
||||
url: `${Cypress.config().baseUrl}${LOGIN_API_ENDPOINT}`,
|
||||
});
|
||||
loginWithUsernameAndPassword(
|
||||
Cypress.env(ELASTICSEARCH_USERNAME),
|
||||
config.elasticsearch.password
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -295,18 +295,37 @@ export class SecurityPageObject extends FtrService {
|
|||
return user as AuthenticatedUser;
|
||||
}
|
||||
|
||||
async forceLogout() {
|
||||
async forceLogout(
|
||||
{ waitForLoginPage }: { waitForLoginPage: boolean } = { waitForLoginPage: true }
|
||||
) {
|
||||
this.log.debug('SecurityPage.forceLogout');
|
||||
if (await this.find.existsByDisplayedByCssSelector('.login-form', 100)) {
|
||||
this.log.debug('Already on the login page, not forcing anything');
|
||||
return;
|
||||
}
|
||||
|
||||
this.log.debug('Redirecting to /logout to force the logout');
|
||||
this.log.debug(`Redirecting to ${this.deployment.getHostPort()}/logout to force the logout`);
|
||||
const url = this.deployment.getHostPort() + '/logout';
|
||||
await this.browser.get(url);
|
||||
this.log.debug('Waiting on the login form to appear');
|
||||
await this.waitForLoginPage();
|
||||
|
||||
// After logging out, the user can be redirected to various locations depending on the context. By default, we
|
||||
// expect the user to be redirected to the login page. However, if the login page is not available for some reason,
|
||||
// we should simply wait until the user is redirected *elsewhere*.
|
||||
if (waitForLoginPage) {
|
||||
this.log.debug('Waiting on the login form to appear');
|
||||
await this.waitForLoginPage();
|
||||
} else {
|
||||
this.log.debug('Waiting for logout to complete');
|
||||
await this.retry.waitFor('Waiting for logout to complete', async () => {
|
||||
// There are cases when browser/Kibana would like users to confirm that they want to navigate away from the
|
||||
// current page and lose the state (e.g. unsaved changes) via native alert dialog.
|
||||
const alert = await this.browser.getAlert();
|
||||
if (alert?.accept) {
|
||||
await alert.accept();
|
||||
}
|
||||
return !(await this.browser.getCurrentUrl()).includes('/logout');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async clickRolesSection() {
|
||||
|
|
|
@ -12,6 +12,7 @@ import Url from 'url';
|
|||
|
||||
import type { ROLES } from '@kbn/security-solution-plugin/common/test';
|
||||
import { NEW_FEATURES_TOUR_STORAGE_KEYS } from '@kbn/security-solution-plugin/common/constants';
|
||||
import { LoginState } from '@kbn/security-plugin/common/login_state';
|
||||
import {
|
||||
hostDetailsUrl,
|
||||
LOGOUT_URL,
|
||||
|
@ -50,11 +51,6 @@ const ELASTICSEARCH_USERNAME = 'ELASTICSEARCH_USERNAME';
|
|||
*/
|
||||
const ELASTICSEARCH_PASSWORD = 'ELASTICSEARCH_PASSWORD';
|
||||
|
||||
/**
|
||||
* The Kibana server endpoint used for authentication
|
||||
*/
|
||||
const LOGIN_API_ENDPOINT = '/internal/security/login';
|
||||
|
||||
/**
|
||||
* cy.visit will default to the baseUrl which uses the default kibana test user
|
||||
* This function will override that functionality in cy.visit by building the baseUrl
|
||||
|
@ -141,53 +137,46 @@ export const deleteRoleAndUser = (role: ROLES) => {
|
|||
});
|
||||
};
|
||||
|
||||
const loginWithUsernameAndPassword = (username: string, password: string) => {
|
||||
const baseUrl = Cypress.config().baseUrl;
|
||||
if (!baseUrl) {
|
||||
throw Error(`Cypress config baseUrl not set!`);
|
||||
}
|
||||
|
||||
const headers = { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' };
|
||||
// programmatically authenticate without interacting with the Kibana login page
|
||||
cy.request<LoginState>({ headers, url: `${baseUrl}/internal/security/login_state` }).then(
|
||||
(loginState) => {
|
||||
const basicProvider = loginState.body.selector.providers.find(
|
||||
(provider) => provider.type === 'basic'
|
||||
);
|
||||
return cy.request({
|
||||
url: `${baseUrl}/internal/security/login`,
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: {
|
||||
providerType: basicProvider.type,
|
||||
providerName: basicProvider.name,
|
||||
currentURL: '/',
|
||||
params: { username, password },
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export const loginWithUser = (user: User) => {
|
||||
cy.session(user, () => {
|
||||
cy.request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username: user.username,
|
||||
password: user.password,
|
||||
},
|
||||
},
|
||||
headers: {
|
||||
'kbn-xsrf': 'cypress-creds-via-config',
|
||||
'x-elastic-internal-origin': 'security-solution',
|
||||
},
|
||||
method: 'POST',
|
||||
url: constructUrlWithUser(user, LOGIN_API_ENDPOINT),
|
||||
});
|
||||
loginWithUsernameAndPassword(user.username, user.password);
|
||||
});
|
||||
};
|
||||
|
||||
const loginWithRole = async (role: ROLES) => {
|
||||
const loginWithRole = (role: ROLES) => {
|
||||
postRoleAndUser(role);
|
||||
const theUrl = new URL(String(Cypress.config().baseUrl));
|
||||
theUrl.username = role;
|
||||
theUrl.password = Cypress.env(ELASTICSEARCH_PASSWORD);
|
||||
|
||||
cy.log(`origin: ${theUrl}`);
|
||||
cy.log(`origin: ${Cypress.config().baseUrl}`);
|
||||
cy.session(role, () => {
|
||||
cy.request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username: role,
|
||||
password: 'changeme',
|
||||
},
|
||||
},
|
||||
headers: {
|
||||
'kbn-xsrf': 'cypress-creds-via-config',
|
||||
'x-elastic-internal-origin': 'security-solution',
|
||||
},
|
||||
method: 'POST',
|
||||
url: getUrlWithRoute(role, LOGIN_API_ENDPOINT),
|
||||
});
|
||||
loginWithUsernameAndPassword(role, 'changeme');
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -231,24 +220,7 @@ const loginViaEnvironmentCredentials = () => {
|
|||
const password = Cypress.env(ELASTICSEARCH_PASSWORD);
|
||||
|
||||
cy.session([username, password], () => {
|
||||
// programmatically authenticate without interacting with the Kibana login page
|
||||
cy.request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username,
|
||||
password,
|
||||
},
|
||||
},
|
||||
headers: {
|
||||
'kbn-xsrf': 'cypress-creds-via-env',
|
||||
'x-elastic-internal-origin': 'security-solution',
|
||||
},
|
||||
method: 'POST',
|
||||
url: `${Cypress.config().baseUrl}${LOGIN_API_ENDPOINT}`,
|
||||
});
|
||||
loginWithUsernameAndPassword(username, password);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -264,26 +236,8 @@ const loginViaConfig = () => {
|
|||
|
||||
// read the login details from `kibana.dev.yaml`
|
||||
cy.readFile(KIBANA_DEV_YML_PATH).then((kibanaDevYml) => {
|
||||
const config = yaml.safeLoad(kibanaDevYml);
|
||||
|
||||
// programmatically authenticate without interacting with the Kibana login page
|
||||
cy.request({
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username: config.elasticsearch.username,
|
||||
password: config.elasticsearch.password,
|
||||
},
|
||||
},
|
||||
headers: {
|
||||
'kbn-xsrf': 'cypress-creds-via-config',
|
||||
'x-elastic-internal-origin': 'security-solution',
|
||||
},
|
||||
method: 'POST',
|
||||
url: `${Cypress.config().baseUrl}${LOGIN_API_ENDPOINT}`,
|
||||
});
|
||||
const { username, password } = yaml.safeLoad(kibanaDevYml);
|
||||
loginWithUsernameAndPassword(username, password);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"@kbn/expandable-flyout",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/lists-plugin",
|
||||
"@kbn/securitysolution-list-constants"
|
||||
"@kbn/securitysolution-list-constants",
|
||||
"@kbn/security-plugin"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -68,6 +68,9 @@ export function createTestConfig(options: CreateTestConfigOptions) {
|
|||
advancedSettings: {
|
||||
pathname: '/app/management/kibana/settings',
|
||||
},
|
||||
login: {
|
||||
pathname: '/login',
|
||||
},
|
||||
},
|
||||
// choose where screenshots should be saved
|
||||
screenshots: {
|
||||
|
|
|
@ -7,10 +7,21 @@
|
|||
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
|
||||
export function SvlCommonPageProvider({ getService }: FtrProviderContext) {
|
||||
export function SvlCommonPageProvider({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const config = getService('config');
|
||||
const pageObjects = getPageObjects(['security']);
|
||||
|
||||
return {
|
||||
async login() {
|
||||
await pageObjects.security.forceLogout({ waitForLoginPage: false });
|
||||
return await pageObjects.security.login(config.get('servers.kibana.username'));
|
||||
},
|
||||
|
||||
async forceLogout() {
|
||||
await pageObjects.security.forceLogout({ waitForLoginPage: false });
|
||||
},
|
||||
|
||||
async assertProjectHeaderExists() {
|
||||
await testSubjects.existOrFail('kibanaProjectHeader');
|
||||
},
|
||||
|
|
|
@ -24,15 +24,19 @@ async function clearAllApiKeys(esClient: Client, logger: ToolingLog) {
|
|||
}
|
||||
|
||||
export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
||||
const pageObjects = getPageObjects(['common', 'apiKeys']);
|
||||
const pageObjects = getPageObjects(['common', 'svlCommonPage', 'apiKeys']);
|
||||
const browser = getService('browser');
|
||||
const es = getService('es');
|
||||
const log = getService('log');
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/165553
|
||||
describe.skip('API keys', () => {
|
||||
describe('API keys', () => {
|
||||
before(async () => {
|
||||
await pageObjects.svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await clearAllApiKeys(es, log);
|
||||
await pageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('should create and delete API keys correctly', async () => {
|
||||
|
|
|
@ -12,6 +12,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
const dashboard = getPageObject('dashboard');
|
||||
const lens = getPageObject('lens');
|
||||
const svlCommonNavigation = getPageObject('svlCommonNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
const svlObltNavigation = getService('svlObltNavigation');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
@ -22,6 +23,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
describe('Cases persistable attachments', () => {
|
||||
describe('lens visualization', () => {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional');
|
||||
await kibanaServer.importExport.load(
|
||||
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
|
||||
|
@ -45,6 +47,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
await kibanaServer.importExport.unload(
|
||||
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
|
||||
);
|
||||
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('adds lens visualization to a new case', async () => {
|
||||
|
|
|
@ -11,6 +11,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
|
|||
export default ({ getPageObject, getService }: FtrProviderContext) => {
|
||||
const common = getPageObject('common');
|
||||
const svlCommonNavigation = getPageObject('svlCommonNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
const svlObltNavigation = getService('svlObltNavigation');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const cases = getService('cases');
|
||||
|
@ -18,6 +19,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
|
||||
describe('Configure Case', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
|
||||
await svlObltNavigation.navigateToLandingPage();
|
||||
|
||||
await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'observability-overview:cases' });
|
||||
|
@ -27,6 +30,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
|
||||
after(async () => {
|
||||
await cases.api.deleteAllCases();
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('Closure options', function () {
|
||||
|
|
|
@ -19,14 +19,20 @@ export default ({ getService, getPageObject }: FtrProviderContext) => {
|
|||
const find = getService('find');
|
||||
const cases = getService('cases');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
const config = getService('config');
|
||||
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await navigateToCasesApp(getPageObject, getService, owner);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await cases.api.deleteAllCases();
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('creates a case', async () => {
|
||||
|
|
|
@ -15,10 +15,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
const testSubjects = getService('testSubjects');
|
||||
const cases = getService('cases');
|
||||
const svlCommonNavigation = getPageObject('svlCommonNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
const svlObltNavigation = getService('svlObltNavigation');
|
||||
|
||||
describe('Cases list', () => {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
await svlObltNavigation.navigateToLandingPage();
|
||||
await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'observability-overview:cases' });
|
||||
});
|
||||
|
@ -26,6 +28,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
after(async () => {
|
||||
await cases.api.deleteAllCases();
|
||||
await cases.casesTable.waitForCasesToBeDeleted();
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('empty state', () => {
|
||||
|
|
|
@ -27,8 +27,17 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
const retry = getService('retry');
|
||||
const comboBox = getService('comboBox');
|
||||
const svlCommonNavigation = getPageObject('svlCommonNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
|
||||
describe('Case View', () => {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('page', () => {
|
||||
createOneCaseBeforeDeleteAllAfter(getPageObject, getService, owner);
|
||||
|
||||
|
|
|
@ -7,27 +7,36 @@
|
|||
import 'cypress-axe';
|
||||
import 'cypress-real-events/support';
|
||||
import URL from 'url';
|
||||
import { request } from '@kbn/security-solution-plugin/public/management/cypress/tasks/common';
|
||||
import { LoginState } from '@kbn/security-plugin/common/login_state';
|
||||
|
||||
Cypress.Commands.add('loginAsElasticUser', () => {
|
||||
const username = Cypress.env('username');
|
||||
const password = Cypress.env('password');
|
||||
const kibanaUrlWithoutAuth = Cypress.env('kibanaUrlWithoutAuth');
|
||||
const headers = { 'kbn-xsrf': 'e2e_test', 'x-elastic-internal-origin': 'kibana' };
|
||||
cy.log(`Logging in as ${username} on ${kibanaUrlWithoutAuth}`);
|
||||
cy.visit('/');
|
||||
cy.request({
|
||||
log: true,
|
||||
method: 'POST',
|
||||
url: `${kibanaUrlWithoutAuth}/internal/security/login`,
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: `${kibanaUrlWithoutAuth}/login`,
|
||||
params: { username, password },
|
||||
},
|
||||
headers: {
|
||||
'kbn-xsrf': 'e2e_test',
|
||||
'x-elastic-internal-origin': 'kibana',
|
||||
},
|
||||
cy.visit('/login');
|
||||
|
||||
cy.request<LoginState>({
|
||||
headers,
|
||||
url: `${kibanaUrlWithoutAuth}/internal/security/login_state`,
|
||||
}).then((loginState) => {
|
||||
const basicProvider = loginState.body.selector.providers.find(
|
||||
(provider) => provider.type === 'basic'
|
||||
);
|
||||
return request({
|
||||
headers,
|
||||
log: true,
|
||||
method: 'POST',
|
||||
url: `${kibanaUrlWithoutAuth}/internal/security/login`,
|
||||
body: {
|
||||
providerType: basicProvider.type,
|
||||
providerName: basicProvider.name,
|
||||
currentURL: `${kibanaUrlWithoutAuth}/login`,
|
||||
params: { username, password },
|
||||
},
|
||||
});
|
||||
});
|
||||
cy.visit('/');
|
||||
});
|
||||
|
|
|
@ -20,13 +20,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const browser = getService('browser');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const retry = getService('retry');
|
||||
const PageObjects = getPageObjects(['common', 'observabilityLogExplorer']);
|
||||
const PageObjects = getPageObjects(['common', 'observabilityLogExplorer', 'svlCommonPage']);
|
||||
|
||||
describe('Dataset Selector', () => {
|
||||
before(async () => {
|
||||
await PageObjects.svlCommonPage.login();
|
||||
await PageObjects.observabilityLogExplorer.removeInstalledPackages();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('without installed integrations or uncategorized data streams', () => {
|
||||
before(async () => {
|
||||
await PageObjects.observabilityLogExplorer.navigateTo();
|
||||
|
|
|
@ -8,16 +8,18 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
|
|||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const PageObjects = getPageObjects(['observabilityLogExplorer']);
|
||||
const PageObjects = getPageObjects(['observabilityLogExplorer', 'svlCommonPage']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
describe('Filter controls customization', () => {
|
||||
before('initialize tests', async () => {
|
||||
await PageObjects.svlCommonPage.login();
|
||||
await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover');
|
||||
});
|
||||
|
||||
after('clean up archives', async () => {
|
||||
await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover');
|
||||
await PageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('renders a filter controls section as part of the unified search bar', async () => {
|
||||
|
|
|
@ -15,8 +15,17 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
const lens = getPageObject('lens');
|
||||
const svlSearchNavigation = getService('svlSearchNavigation');
|
||||
const svlCommonNavigation = getPageObject('svlCommonNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
|
||||
describe('persistable attachment', () => {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('lens visualization', () => {
|
||||
before(async () => {
|
||||
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional');
|
||||
|
|
|
@ -16,6 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
'common',
|
||||
'header',
|
||||
'lens',
|
||||
'svlCommonPage',
|
||||
]);
|
||||
|
||||
const pieChart = getService('pieChart');
|
||||
|
@ -27,6 +28,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
|
||||
describe('Building a new dashboard', function () {
|
||||
before(async () => {
|
||||
await PageObjects.svlCommonPage.login();
|
||||
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional');
|
||||
await kibanaServer.importExport.load(
|
||||
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
|
||||
|
@ -42,6 +44,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await kibanaServer.importExport.unload(
|
||||
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
|
||||
);
|
||||
await PageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('can add a lens panel by value', async () => {
|
||||
|
|
|
@ -18,10 +18,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const kibanaServer = getService('kibanaServer');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
const PageObjects = getPageObjects(['common', 'settings', 'header', 'savedObjects', 'dashboard']);
|
||||
const PageObjects = getPageObjects([
|
||||
'common',
|
||||
'settings',
|
||||
'header',
|
||||
'savedObjects',
|
||||
'dashboard',
|
||||
'svlCommonPage',
|
||||
]);
|
||||
|
||||
describe('Importing an existing dashboard', () => {
|
||||
before(async () => {
|
||||
await PageObjects.svlCommonPage.login();
|
||||
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional');
|
||||
await kibanaServer.uiSettings.replace({});
|
||||
});
|
||||
|
@ -29,6 +37,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/logstash_functional');
|
||||
await kibanaServer.savedObjects.cleanStandardList();
|
||||
await PageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('should be able to import dashboard created in 8.11', async () => {
|
||||
|
|
|
@ -11,12 +11,18 @@ export default function ({ getPageObject, getService }: FtrProviderContext) {
|
|||
const svlSearchNavigation = getService('svlSearchNavigation');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const svlCommonNavigation = getPageObject('svlCommonNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
|
||||
describe('empty pages', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
await svlSearchNavigation.navigateToLandingPage();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('should show search specific empty page in discover', async () => {
|
||||
await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'discover' });
|
||||
await testSubjects.existOrFail('kbnOverviewElasticsearchGettingStarted');
|
||||
|
|
|
@ -7,14 +7,22 @@
|
|||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getPageObject, getService }: FtrProviderContext) {
|
||||
const svlSearchLandingPage = getPageObject('svlSearchLandingPage');
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
const pageObjects = getPageObjects(['svlSearchLandingPage', 'svlCommonPage']);
|
||||
const svlSearchNavigation = getService('svlSearchNavigation');
|
||||
|
||||
describe('landing page', function () {
|
||||
before(async () => {
|
||||
await pageObjects.svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await pageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('has serverless side nav', async () => {
|
||||
await svlSearchNavigation.navigateToLandingPage();
|
||||
await svlSearchLandingPage.assertSvlSearchSideNavExists();
|
||||
await pageObjects.svlSearchLandingPage.assertSvlSearchSideNavExists();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -12,14 +12,20 @@ export default function ({ getPageObject, getService }: FtrProviderContext) {
|
|||
const svlSearchLandingPage = getPageObject('svlSearchLandingPage');
|
||||
const svlSearchNavigation = getService('svlSearchNavigation');
|
||||
const svlCommonNavigation = getPageObject('svlCommonNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const browser = getService('browser');
|
||||
|
||||
describe('navigation', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
await svlSearchNavigation.navigateToLandingPage();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('navigate search sidenav & breadcrumbs', async () => {
|
||||
const expectNoPageReload = await svlCommonNavigation.createNoPageReloadCheck();
|
||||
|
||||
|
|
|
@ -13,9 +13,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
// const find = getService('find');
|
||||
// const testSubjects = getService('testSubjects');
|
||||
const screenshotDirectories = ['response_ops_docs', 'stack_connectors'];
|
||||
const pageObjects = getPageObjects(['common', 'header']);
|
||||
const pageObjects = getPageObjects(['common', 'header', 'svlCommonPage']);
|
||||
|
||||
describe('connectors', function () {
|
||||
before(async () => {
|
||||
await pageObjects.svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await pageObjects.svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('connectors list screenshot', async () => {
|
||||
await pageObjects.common.navigateToApp('connectors');
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { request } from '@kbn/security-solution-plugin/public/management/cypress/tasks/common';
|
||||
import { LoginState } from '@kbn/security-plugin/common/login_state';
|
||||
import type { ServerlessRoleName } from '../../../../../shared/lib';
|
||||
import { STANDARD_HTTP_HEADERS } from '../../../../../shared/lib/security/default_http_headers';
|
||||
|
||||
|
@ -20,30 +21,29 @@ const sendApiLoginRequest = (
|
|||
username: string,
|
||||
password: string
|
||||
): Cypress.Chainable<{ username: string; password: string }> => {
|
||||
const url = new URL(Cypress.config().baseUrl ?? '');
|
||||
url.pathname = '/internal/security/login';
|
||||
const baseUrl = Cypress.config().baseUrl;
|
||||
|
||||
cy.log(`Authenticating [${username}] via ${url.toString()}`);
|
||||
cy.log(`Authenticating [${username}] via ${baseUrl}`);
|
||||
|
||||
return request({
|
||||
headers: { ...STANDARD_HTTP_HEADERS },
|
||||
method: 'POST',
|
||||
url: url.toString(),
|
||||
body: {
|
||||
providerType: 'basic',
|
||||
providerName: 'basic',
|
||||
currentURL: '/',
|
||||
params: {
|
||||
username,
|
||||
password,
|
||||
},
|
||||
},
|
||||
}).then(() => {
|
||||
return {
|
||||
username,
|
||||
password,
|
||||
};
|
||||
});
|
||||
const headers = { ...STANDARD_HTTP_HEADERS };
|
||||
return request<LoginState>({ headers, url: `${baseUrl}/internal/security/login_state` })
|
||||
.then((loginState) => {
|
||||
const basicProvider = loginState.body.selector.providers.find(
|
||||
(provider) => provider.type === 'basic'
|
||||
);
|
||||
return request({
|
||||
url: `${baseUrl}/internal/security/login`,
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: {
|
||||
providerType: basicProvider.type,
|
||||
providerName: basicProvider.name,
|
||||
currentURL: '/',
|
||||
params: { username, password },
|
||||
},
|
||||
});
|
||||
})
|
||||
.then(() => ({ username, password }));
|
||||
};
|
||||
|
||||
interface CyLoginTask {
|
||||
|
|
|
@ -10,6 +10,7 @@ import { FtrProviderContext } from '../../../../ftr_provider_context';
|
|||
|
||||
export default ({ getPageObject, getService }: FtrProviderContext) => {
|
||||
const common = getPageObject('common');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
const svlSecNavigation = getService('svlSecNavigation');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const cases = getService('cases');
|
||||
|
@ -17,6 +18,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
|
||||
describe('Configure Case', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
|
||||
await svlSecNavigation.navigateToLandingPage();
|
||||
|
||||
await testSubjects.click('solutionSideNavItemLink-cases');
|
||||
|
@ -26,6 +29,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
|
||||
after(async () => {
|
||||
await cases.api.deleteAllCases();
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('Closure options', function () {
|
||||
|
|
|
@ -20,13 +20,19 @@ export default ({ getService, getPageObject }: FtrProviderContext) => {
|
|||
const cases = getService('cases');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const config = getService('config');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
|
||||
beforeEach(async () => {
|
||||
await navigateToCasesApp(getPageObject, getService, owner);
|
||||
});
|
||||
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await cases.api.deleteAllCases();
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('creates a case', async () => {
|
||||
|
|
|
@ -15,9 +15,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
const testSubjects = getService('testSubjects');
|
||||
const cases = getService('cases');
|
||||
const svlSecNavigation = getService('svlSecNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
|
||||
describe('Cases List', () => {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
|
||||
await svlSecNavigation.navigateToLandingPage();
|
||||
|
||||
await testSubjects.click('solutionSideNavItemLink-cases');
|
||||
|
@ -26,6 +29,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
after(async () => {
|
||||
await cases.api.deleteAllCases();
|
||||
await cases.casesTable.waitForCasesToBeDeleted();
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('empty state', () => {
|
||||
|
|
|
@ -27,8 +27,17 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
|
|||
const retry = getService('retry');
|
||||
const comboBox = getService('comboBox');
|
||||
const svlCommonNavigation = getPageObject('svlCommonNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
|
||||
describe('Case View', () => {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
describe('page', () => {
|
||||
createOneCaseBeforeDeleteAllAfter(getPageObject, getService, owner);
|
||||
|
||||
|
|
|
@ -10,8 +10,17 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
|
|||
export default function ({ getPageObject, getService }: FtrProviderContext) {
|
||||
const svlSecLandingPage = getPageObject('svlSecLandingPage');
|
||||
const svlSecNavigation = getService('svlSecNavigation');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
|
||||
describe('landing page', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('has serverless side nav', async () => {
|
||||
await svlSecNavigation.navigateToLandingPage();
|
||||
await svlSecLandingPage.assertSvlSecSideNavExists();
|
||||
|
|
|
@ -9,8 +9,17 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
|
|||
|
||||
export default function ({ getPageObject }: FtrProviderContext) {
|
||||
const PageObject = getPageObject('common');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
|
||||
describe('Management', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await svlCommonPage.forceLogout();
|
||||
});
|
||||
|
||||
it('redirects from common management url to security specific page', async () => {
|
||||
const SUB_URL = '';
|
||||
await PageObject.navigateToUrl('management', SUB_URL, {
|
||||
|
|
|
@ -119,13 +119,12 @@ export default async () => {
|
|||
])}`,
|
||||
// This ensures that we register the Security SAML API endpoints.
|
||||
// In the real world the SAML config is injected by control plane.
|
||||
// basic: { 'basic': { order: 0 } },
|
||||
`--plugin-path=${samlIdPPlugin}`,
|
||||
'--xpack.cloud.id=ftr_fake_cloud_id',
|
||||
'--xpack.security.authc.selector.enabled=false',
|
||||
`--xpack.security.authc.providers=${JSON.stringify({
|
||||
basic: { basic: { order: 0 } },
|
||||
saml: { 'cloud-saml-kibana': { order: 1, realm: 'cloud-saml-kibana' } },
|
||||
saml: { 'cloud-saml-kibana': { order: 0, realm: 'cloud-saml-kibana' } },
|
||||
basic: { 'cloud-basic': { order: 1 } },
|
||||
})}`,
|
||||
'--xpack.encryptedSavedObjects.encryptionKey="wuGNaIhoMpk5sO4UBxgr3NyW1sFcLgIf"',
|
||||
`--server.publicBaseUrl=${servers.kibana.protocol}://${servers.kibana.hostname}:${servers.kibana.port}`,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue