mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Search][Onboarding] Empty State page endpoints (#191229)
## Summary This PR introduces two endpoints for the `search_indices` plugin that will be used by the start (empty state) page to determine if the user has an indices and what their permissions are. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
9ea2adb7ae
commit
486df8cf5e
17 changed files with 623 additions and 3 deletions
|
@ -7,3 +7,5 @@
|
|||
|
||||
export const PLUGIN_ID = 'searchIndices';
|
||||
export const PLUGIN_NAME = 'searchIndices';
|
||||
|
||||
export type { IndicesStatusResponse, UserStartPrivilegesResponse } from './types';
|
||||
|
|
17
x-pack/plugins/search_indices/common/types.ts
Normal file
17
x-pack/plugins/search_indices/common/types.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export interface IndicesStatusResponse {
|
||||
indexNames: string[];
|
||||
}
|
||||
|
||||
export interface UserStartPrivilegesResponse {
|
||||
privileges: {
|
||||
canCreateApiKeys: boolean;
|
||||
canCreateIndex: boolean;
|
||||
};
|
||||
}
|
231
x-pack/plugins/search_indices/server/lib/status.test.ts
Normal file
231
x-pack/plugins/search_indices/server/lib/status.test.ts
Normal file
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type {
|
||||
IndicesGetResponse,
|
||||
SecurityHasPrivilegesResponse,
|
||||
} from '@elastic/elasticsearch/lib/api/types';
|
||||
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import { fetchIndicesStatus, fetchUserStartPrivileges } from './status';
|
||||
|
||||
const mockLogger = {
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
};
|
||||
const logger: Logger = mockLogger as unknown as Logger;
|
||||
|
||||
const mockClient = {
|
||||
indices: {
|
||||
get: jest.fn(),
|
||||
},
|
||||
security: {
|
||||
hasPrivileges: jest.fn(),
|
||||
},
|
||||
};
|
||||
const client = mockClient as unknown as ElasticsearchClient;
|
||||
|
||||
describe('status api lib', function () {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('fetchIndicesStatus', function () {
|
||||
it('should return results from get', async () => {
|
||||
const mockResult: IndicesGetResponse = {};
|
||||
mockClient.indices.get.mockResolvedValue(mockResult);
|
||||
|
||||
await expect(fetchIndicesStatus(client, logger)).resolves.toEqual({ indexNames: [] });
|
||||
expect(mockClient.indices.get).toHaveBeenCalledTimes(1);
|
||||
expect(mockClient.indices.get).toHaveBeenCalledWith({
|
||||
expand_wildcards: ['open'],
|
||||
features: ['settings'],
|
||||
index: '*',
|
||||
});
|
||||
});
|
||||
it('should return index names', async () => {
|
||||
const mockResult: IndicesGetResponse = {
|
||||
'unit-test-index': {
|
||||
settings: {},
|
||||
},
|
||||
};
|
||||
mockClient.indices.get.mockResolvedValue(mockResult);
|
||||
|
||||
await expect(fetchIndicesStatus(client, logger)).resolves.toEqual({
|
||||
indexNames: ['unit-test-index'],
|
||||
});
|
||||
});
|
||||
it('should not return hidden indices', async () => {
|
||||
const mockResult: IndicesGetResponse = {
|
||||
'unit-test-index': {
|
||||
settings: {},
|
||||
},
|
||||
'hidden-index': {
|
||||
settings: {
|
||||
index: {
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
mockClient.indices.get.mockResolvedValue(mockResult);
|
||||
|
||||
await expect(fetchIndicesStatus(client, logger)).resolves.toEqual({
|
||||
indexNames: ['unit-test-index'],
|
||||
});
|
||||
|
||||
mockResult['hidden-index']!.settings!.index!.hidden = 'true';
|
||||
await expect(fetchIndicesStatus(client, logger)).resolves.toEqual({
|
||||
indexNames: ['unit-test-index'],
|
||||
});
|
||||
});
|
||||
it('should not return closed indices', async () => {
|
||||
const mockResult: IndicesGetResponse = {
|
||||
'unit-test-index': {
|
||||
settings: {},
|
||||
},
|
||||
'closed-index': {
|
||||
settings: {
|
||||
index: {
|
||||
verified_before_close: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
mockClient.indices.get.mockResolvedValue(mockResult);
|
||||
|
||||
await expect(fetchIndicesStatus(client, logger)).resolves.toEqual({
|
||||
indexNames: ['unit-test-index'],
|
||||
});
|
||||
|
||||
mockResult['closed-index']!.settings!.index!.verified_before_close = 'true';
|
||||
await expect(fetchIndicesStatus(client, logger)).resolves.toEqual({
|
||||
indexNames: ['unit-test-index'],
|
||||
});
|
||||
});
|
||||
it('should raise exceptions', async () => {
|
||||
const error = new Error('boom');
|
||||
mockClient.indices.get.mockRejectedValue(error);
|
||||
|
||||
await expect(fetchIndicesStatus(client, logger)).rejects.toThrow(error);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchUserStartPrivileges', function () {
|
||||
it('should return privileges true', async () => {
|
||||
const result: SecurityHasPrivilegesResponse = {
|
||||
application: {},
|
||||
cluster: {
|
||||
manage_api_key: true,
|
||||
},
|
||||
has_all_requested: true,
|
||||
index: {
|
||||
'test-index-name': {
|
||||
create_index: true,
|
||||
},
|
||||
},
|
||||
username: 'unit-test',
|
||||
};
|
||||
mockClient.security.hasPrivileges.mockResolvedValue(result);
|
||||
|
||||
await expect(fetchUserStartPrivileges(client, logger)).resolves.toEqual({
|
||||
privileges: {
|
||||
canCreateIndex: true,
|
||||
canCreateApiKeys: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockClient.security.hasPrivileges).toHaveBeenCalledTimes(1);
|
||||
expect(mockClient.security.hasPrivileges).toHaveBeenCalledWith({
|
||||
cluster: ['manage_api_key'],
|
||||
index: [
|
||||
{
|
||||
names: ['test-index-name'],
|
||||
privileges: ['create_index'],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
it('should return privileges false', async () => {
|
||||
const result: SecurityHasPrivilegesResponse = {
|
||||
application: {},
|
||||
cluster: {
|
||||
manage_api_key: false,
|
||||
},
|
||||
has_all_requested: false,
|
||||
index: {
|
||||
'test-index-name': {
|
||||
create_index: false,
|
||||
},
|
||||
},
|
||||
username: 'unit-test',
|
||||
};
|
||||
mockClient.security.hasPrivileges.mockResolvedValue(result);
|
||||
|
||||
await expect(fetchUserStartPrivileges(client, logger)).resolves.toEqual({
|
||||
privileges: {
|
||||
canCreateIndex: false,
|
||||
canCreateApiKeys: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
it('should return mixed privileges', async () => {
|
||||
const result: SecurityHasPrivilegesResponse = {
|
||||
application: {},
|
||||
cluster: {
|
||||
manage_api_key: false,
|
||||
},
|
||||
has_all_requested: false,
|
||||
index: {
|
||||
'test-index-name': {
|
||||
create_index: true,
|
||||
},
|
||||
},
|
||||
username: 'unit-test',
|
||||
};
|
||||
mockClient.security.hasPrivileges.mockResolvedValue(result);
|
||||
|
||||
await expect(fetchUserStartPrivileges(client, logger)).resolves.toEqual({
|
||||
privileges: {
|
||||
canCreateIndex: true,
|
||||
canCreateApiKeys: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
it('should handle malformed responses', async () => {
|
||||
const result: SecurityHasPrivilegesResponse = {
|
||||
application: {},
|
||||
cluster: {},
|
||||
has_all_requested: true,
|
||||
index: {
|
||||
'test-index-name': {
|
||||
create_index: true,
|
||||
},
|
||||
},
|
||||
username: 'unit-test',
|
||||
};
|
||||
mockClient.security.hasPrivileges.mockResolvedValue(result);
|
||||
|
||||
await expect(fetchUserStartPrivileges(client, logger)).resolves.toEqual({
|
||||
privileges: {
|
||||
canCreateIndex: true,
|
||||
canCreateApiKeys: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
it('should default privileges on exceptions', async () => {
|
||||
mockClient.security.hasPrivileges.mockRejectedValue(new Error('Boom!!'));
|
||||
|
||||
await expect(fetchUserStartPrivileges(client, logger)).resolves.toEqual({
|
||||
privileges: {
|
||||
canCreateIndex: false,
|
||||
canCreateApiKeys: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
70
x-pack/plugins/search_indices/server/lib/status.ts
Normal file
70
x-pack/plugins/search_indices/server/lib/status.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
|
||||
import type { IndicesStatusResponse, UserStartPrivilegesResponse } from '../../common/types';
|
||||
|
||||
import { isHidden, isClosed } from '../utils/index_utils';
|
||||
|
||||
export async function fetchIndicesStatus(
|
||||
client: ElasticsearchClient,
|
||||
logger: Logger
|
||||
): Promise<IndicesStatusResponse> {
|
||||
const indexMatches = await client.indices.get({
|
||||
expand_wildcards: ['open'],
|
||||
// for better performance only compute settings of indices but not mappings
|
||||
features: ['settings'],
|
||||
index: '*',
|
||||
});
|
||||
|
||||
const indexNames = Object.keys(indexMatches).filter(
|
||||
(indexName) =>
|
||||
indexMatches[indexName] &&
|
||||
!isHidden(indexMatches[indexName]) &&
|
||||
!isClosed(indexMatches[indexName])
|
||||
);
|
||||
|
||||
return {
|
||||
indexNames,
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchUserStartPrivileges(
|
||||
client: ElasticsearchClient,
|
||||
logger: Logger,
|
||||
indexName: string = 'test-index-name'
|
||||
): Promise<UserStartPrivilegesResponse> {
|
||||
try {
|
||||
const securityCheck = await client.security.hasPrivileges({
|
||||
cluster: ['manage_api_key'],
|
||||
index: [
|
||||
{
|
||||
names: [indexName],
|
||||
privileges: ['create_index'],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return {
|
||||
privileges: {
|
||||
canCreateIndex: securityCheck?.index?.[indexName]?.create_index ?? false,
|
||||
canCreateApiKeys: securityCheck?.cluster?.manage_api_key ?? false,
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
logger.error(`Error checking user privileges for searchIndices elasticsearch start`);
|
||||
logger.error(e);
|
||||
return {
|
||||
privileges: {
|
||||
canCreateIndex: false,
|
||||
canCreateApiKeys: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ export class SearchIndicesPlugin
|
|||
const router = core.http.createRouter();
|
||||
|
||||
// Register server side APIs
|
||||
defineRoutes(router);
|
||||
defineRoutes(router, this.logger);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -6,5 +6,10 @@
|
|||
*/
|
||||
|
||||
import type { IRouter } from '@kbn/core/server';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
|
||||
export function defineRoutes(router: IRouter) {}
|
||||
import { registerStatusRoutes } from './status';
|
||||
|
||||
export function defineRoutes(router: IRouter, logger: Logger) {
|
||||
registerStatusRoutes(router, logger);
|
||||
}
|
||||
|
|
53
x-pack/plugins/search_indices/server/routes/status.ts
Normal file
53
x-pack/plugins/search_indices/server/routes/status.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IRouter } from '@kbn/core/server';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
|
||||
import { fetchIndicesStatus, fetchUserStartPrivileges } from '../lib/status';
|
||||
|
||||
export function registerStatusRoutes(router: IRouter, logger: Logger) {
|
||||
router.get(
|
||||
{
|
||||
path: '/internal/search_indices/status',
|
||||
validate: {},
|
||||
options: {
|
||||
access: 'internal',
|
||||
},
|
||||
},
|
||||
async (context, _request, response) => {
|
||||
const core = await context.core;
|
||||
const client = core.elasticsearch.client.asCurrentUser;
|
||||
const body = await fetchIndicesStatus(client, logger);
|
||||
|
||||
return response.ok({
|
||||
body,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
{
|
||||
path: '/internal/search_indices/start_privileges',
|
||||
validate: {},
|
||||
options: {
|
||||
access: 'internal',
|
||||
},
|
||||
},
|
||||
async (context, _request, response) => {
|
||||
const core = await context.core;
|
||||
const client = core.elasticsearch.client.asCurrentUser;
|
||||
const body = await fetchUserStartPrivileges(client, logger);
|
||||
|
||||
return response.ok({
|
||||
body,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
109
x-pack/plugins/search_indices/server/utils/index_utils.test.ts
Normal file
109
x-pack/plugins/search_indices/server/utils/index_utils.test.ts
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { isClosed, isHidden } from './index_utils';
|
||||
|
||||
describe('index utils', function () {
|
||||
describe('isClosed', function () {
|
||||
it('handles boolean values', () => {
|
||||
expect(
|
||||
isClosed({
|
||||
settings: {
|
||||
index: {
|
||||
verified_before_close: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
).toBe(true);
|
||||
expect(
|
||||
isClosed({
|
||||
settings: {
|
||||
index: {
|
||||
verified_before_close: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
it('handles string values', () => {
|
||||
expect(
|
||||
isClosed({
|
||||
settings: {
|
||||
index: {
|
||||
verified_before_close: 'true',
|
||||
},
|
||||
},
|
||||
})
|
||||
).toBe(true);
|
||||
expect(
|
||||
isClosed({
|
||||
settings: {
|
||||
index: {
|
||||
verified_before_close: 'false',
|
||||
},
|
||||
},
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
it('handles undefined index settings', () => {
|
||||
expect(
|
||||
isClosed({
|
||||
settings: {},
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('isHidden', function () {
|
||||
it('handles boolean values', () => {
|
||||
expect(
|
||||
isHidden({
|
||||
settings: {
|
||||
index: {
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
).toBe(true);
|
||||
expect(
|
||||
isHidden({
|
||||
settings: {
|
||||
index: {
|
||||
hidden: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
it('handles string values', () => {
|
||||
expect(
|
||||
isHidden({
|
||||
settings: {
|
||||
index: {
|
||||
hidden: 'true',
|
||||
},
|
||||
},
|
||||
})
|
||||
).toBe(true);
|
||||
expect(
|
||||
isHidden({
|
||||
settings: {
|
||||
index: {
|
||||
hidden: 'false',
|
||||
},
|
||||
},
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
it('handles undefined index settings', () => {
|
||||
expect(
|
||||
isHidden({
|
||||
settings: {},
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
19
x-pack/plugins/search_indices/server/utils/index_utils.ts
Normal file
19
x-pack/plugins/search_indices/server/utils/index_utils.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IndicesIndexState } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
export function isHidden(index: IndicesIndexState): boolean {
|
||||
return index.settings?.index?.hidden === true || index.settings?.index?.hidden === 'true';
|
||||
}
|
||||
|
||||
export function isClosed(index: IndicesIndexState): boolean {
|
||||
return (
|
||||
index.settings?.index?.verified_before_close === true ||
|
||||
index.settings?.index?.verified_before_close === 'true'
|
||||
);
|
||||
}
|
|
@ -14,6 +14,8 @@
|
|||
"@kbn/core",
|
||||
"@kbn/navigation-plugin",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/core-elasticsearch-server",
|
||||
"@kbn/logging",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -18,7 +18,10 @@ export default createTestConfig({
|
|||
},
|
||||
suiteTags: { exclude: ['skipSvlSearch'] },
|
||||
// add feature flags
|
||||
kbnServerArgs: ['--xpack.security.roleManagementEnabled=true'],
|
||||
kbnServerArgs: [
|
||||
'--xpack.security.roleManagementEnabled=true',
|
||||
`--xpack.searchIndices.enabled=true`, // global empty state FF
|
||||
],
|
||||
// load tests in the index file
|
||||
testFiles: [require.resolve('./index.feature_flags.ts')],
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context';
|
|||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Serverless search API - feature flags', function () {
|
||||
loadTestFile(require.resolve('./search_indices'));
|
||||
loadTestFile(require.resolve('./platform_security'));
|
||||
loadTestFile(require.resolve('../common/platform_security/roles_routes_feature_flag.ts'));
|
||||
});
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('search indices APIs', function () {
|
||||
loadTestFile(require.resolve('./status'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from 'expect';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const svlCommonApi = getService('svlCommonApi');
|
||||
const svlUserManager = getService('svlUserManager');
|
||||
const supertestWithoutAuth = getService('supertestWithoutAuth');
|
||||
let credentials: { Cookie: string };
|
||||
|
||||
describe('search_indices Status APIs', function () {
|
||||
describe('indices status', function () {
|
||||
before(async () => {
|
||||
// get auth header for Viewer role
|
||||
credentials = await svlUserManager.getM2MApiCredentialsWithRoleScope('developer');
|
||||
});
|
||||
it('returns list of index names', async () => {
|
||||
const { body } = await supertestWithoutAuth
|
||||
.get('/internal/search_indices/status')
|
||||
.set(svlCommonApi.getInternalRequestHeader())
|
||||
.set(credentials)
|
||||
.expect(200);
|
||||
|
||||
expect(body.indexNames).toBeDefined();
|
||||
expect(Array.isArray(body.indexNames)).toBe(true);
|
||||
});
|
||||
});
|
||||
describe('user privileges', function () {
|
||||
// GET /internal/search_indices/start_privileges
|
||||
describe('developer', function () {
|
||||
before(async () => {
|
||||
// get auth header for Viewer role
|
||||
credentials = await svlUserManager.getM2MApiCredentialsWithRoleScope('developer');
|
||||
});
|
||||
|
||||
it('returns expected privileges', async () => {
|
||||
const { body } = await supertestWithoutAuth
|
||||
.get('/internal/search_indices/start_privileges')
|
||||
.set(svlCommonApi.getInternalRequestHeader())
|
||||
.set(credentials)
|
||||
.expect(200);
|
||||
|
||||
expect(body).toEqual({
|
||||
privileges: {
|
||||
canCreateApiKeys: true,
|
||||
canCreateIndex: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('viewer', function () {
|
||||
before(async () => {
|
||||
// get auth header for Viewer role
|
||||
credentials = await svlUserManager.getM2MApiCredentialsWithRoleScope('viewer');
|
||||
});
|
||||
|
||||
it('returns expected privileges', async () => {
|
||||
const { body } = await supertestWithoutAuth
|
||||
.get('/internal/search_indices/start_privileges')
|
||||
.set(svlCommonApi.getInternalRequestHeader())
|
||||
.set(credentials)
|
||||
.expect(200);
|
||||
|
||||
expect(body).toEqual({
|
||||
privileges: {
|
||||
canCreateApiKeys: false,
|
||||
canCreateIndex: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -25,6 +25,7 @@ export default createTestConfig({
|
|||
`--xpack.cloud.organization_url='/account/members'`,
|
||||
`--xpack.security.roleManagementEnabled=true`,
|
||||
`--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities
|
||||
`--xpack.searchIndices.enabled=true`, // global empty state FF
|
||||
],
|
||||
// load tests in the index file
|
||||
testFiles: [require.resolve('./index.feature_flags.ts')],
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({}: FtrProviderContext) {
|
||||
describe('Elasticsearch Start [Onboarding Empty State]', function () {});
|
||||
}
|
|
@ -10,6 +10,7 @@ import { FtrProviderContext } from '../../ftr_provider_context';
|
|||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('serverless search UI - feature flags', function () {
|
||||
// add tests that require feature flags, defined in config.feature_flags.ts
|
||||
loadTestFile(require.resolve('./elasticsearch_start.ts'));
|
||||
loadTestFile(require.resolve('../common/platform_security/navigation/management_nav_cards.ts'));
|
||||
loadTestFile(require.resolve('../common/platform_security/roles.ts'));
|
||||
loadTestFile(require.resolve('../common/spaces/spaces_selection_enabled.ts'));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue