Skip to content

Commit

Permalink
[ftr] enable mock-idp-plugin for stateful (deployment-agnostic) tests (
Browse files Browse the repository at this point in the history
…#192279)

## Summary

closes #190221

This PR enables `mock-idp-plugin` when Kibana is started with stateful
FTR config for deployment-agnostic tests:

```
 node scripts/functional_tests_server --config=x-pack/test/api_integration/deployment_agnostic/configs/stateful/platform.stateful.config.ts
```

<img width="1574" alt="image"
src="https://github.com/user-attachments/assets/494e89ee-cd65-4dde-86da-a5e2c28ec40d">

You can pick up one of the the role defined for stateful SAML
authentication in
https://github.com/elastic/kibana/blob/main/packages/kbn-es/src/stateful_resources/roles.yml

Note: this plugin is only enabled locally for a better manual testing
experience, it is **not loaded on CI**

It is done to unify DevEx when folks work on deployment-agnostic tests
and would like to confirm the functionality under the same role for both
stateful and serverless deployments.

Thanks @azasypkin for the help, again :)

How to test:
- start the servers using
`x-pack/test/api_integration/deployment_agnostic/configs/stateful/platform.stateful.config.ts`
config and go to `http://localhost:5620`
- try to login with different roles, make sure valid role is applied in
top right profile menu

(cherry picked from commit a94a4db)
  • Loading branch information
dmlemeshko committed Sep 23, 2024
1 parent b9761fb commit 509a1fe
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/kbn-mock-idp-plugin/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const config = {
// The plugin should only be enabled in Serverless.
enabled: offeringBasedSchema({
serverless: schema.boolean({ defaultValue: true }),
traditional: schema.boolean({ defaultValue: false }),
options: { defaultValue: false },
}),
}),
Expand Down
37 changes: 21 additions & 16 deletions packages/kbn-mock-idp-plugin/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import type { PluginInitializer, Plugin } from '@kbn/core-plugins-server';
import { schema } from '@kbn/config-schema';
import type { TypeOf } from '@kbn/config-schema';
import { MOCK_IDP_LOGIN_PATH, MOCK_IDP_LOGOUT_PATH, createSAMLResponse } from '@kbn/mock-idp-utils';
import { SERVERLESS_ROLES_ROOT_PATH, readRolesFromResource } from '@kbn/es';
import {
SERVERLESS_ROLES_ROOT_PATH,
STATEFUL_ROLES_ROOT_PATH,
readRolesFromResource,
} from '@kbn/es';
import { resolve } from 'path';
import { CloudSetup } from '@kbn/cloud-plugin/server';

Expand Down Expand Up @@ -42,6 +46,11 @@ const readServerlessRoles = (projectType: string) => {
}
};

const readStatefulRoles = () => {
const rolesResourcePath = resolve(STATEFUL_ROLES_ROOT_PATH, 'roles.yml');
return readRolesFromResource(rolesResourcePath);
};

export type CreateSAMLResponseParams = TypeOf<typeof createSAMLResponseSchema>;

export const plugin: PluginInitializer<
Expand Down Expand Up @@ -73,22 +82,18 @@ export const plugin: PluginInitializer<
options: { authRequired: false },
},
(context, request, response) => {
const projectType = plugins.cloud.serverless?.projectType;
if (!projectType) {
return response.customError({ statusCode: 500, body: 'projectType is not defined' });
} else {
try {
if (roles.length === 0) {
roles.push(...readServerlessRoles(projectType));
}
return response.ok({
body: {
roles,
},
});
} catch (err) {
return response.customError({ statusCode: 500, body: err.message });
try {
if (roles.length === 0) {
const projectType = plugins.cloud?.serverless?.projectType;
roles.push(...(projectType ? readServerlessRoles(projectType) : readStatefulRoles()));
}
return response.ok({
body: {
roles,
},
});
} catch (err) {
return response.customError({ statusCode: 500, body: err.message });
}
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,19 @@ export function createStatefulTestConfig<T extends DeploymentAgnosticCommonServi
);
}

// if config is executed on CI or locally
const isRunOnCI = process.env.CI;

const xPackAPITestsConfig = await readConfigFile(require.resolve('../../config.ts'));

// TODO: move to kbn-es because currently metadata file has hardcoded entityID and Location
const idpPath = require.resolve(
'@kbn/security-api-integration-helpers/saml/idp_metadata_mock_idp.xml'
);
const samlIdPPlugin = path.resolve(
__dirname,
'../../../security_api_integration/plugins/saml_provider'
);

const servers = {
kibana: {
Expand Down Expand Up @@ -98,6 +105,17 @@ export function createStatefulTestConfig<T extends DeploymentAgnosticCommonServi
...xPackAPITestsConfig.get('kbnTestServer'),
serverArgs: [
...xPackAPITestsConfig.get('kbnTestServer.serverArgs'),
// if the config is run locally, explicitly enable mock-idp-plugin for UI role selector
...(isRunOnCI ? [] : ['--mock_idp_plugin.enabled=true']),
// This ensures that we register the Security SAML API endpoints.
// In the real world the SAML config is injected by control plane.
`--plugin-path=${samlIdPPlugin}`,
'--xpack.cloud.id=ftr_fake_cloud_id',
// Ensure that SAML is used as the default authentication method whenever a user navigates to Kibana. In other
// words, Kibana should attempt to authenticate the user using the provider with the lowest order if the Login
// Selector is disabled (replicating Serverless configuration). By declaring `cloud-basic` with a higher
// order, we indicate that basic authentication can still be used, but only if explicitly requested when the
// user navigates to `/login` page directly and enters username and password in the login form.
'--xpack.security.authc.selector.enabled=false',
`--xpack.security.authc.providers=${JSON.stringify({
saml: { 'cloud-saml-kibana': { order: 0, realm: MOCK_IDP_REALM_NAME } },
Expand Down

0 comments on commit 509a1fe

Please sign in to comment.