mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Cases] User profile hooks (#137830)
* Refactoring services, auth * Adding suggest api and tests * Working integration tests * Switching suggest api tags * Adding tests for size and owner * Adding api tag tests * Addressing feedback * Create suggest query * Add tests * Add security as dependency and fix types * Add bulk get profiles query * Rename folder * Revert security solution optional * PR feedback * Reduce size * Make security required * Fix tests * Do not retry suggestions Co-authored-by: Jonathan Buttner <jonathan.buttner@elastic.co> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
025f6f3ccd
commit
c3a55d1aa8
16 changed files with 468 additions and 11 deletions
|
@ -157,3 +157,9 @@ export const READ_CASES_CAPABILITY = 'read_cases' as const;
|
|||
export const UPDATE_CASES_CAPABILITY = 'update_cases' as const;
|
||||
export const DELETE_CASES_CAPABILITY = 'delete_cases' as const;
|
||||
export const PUSH_CASES_CAPABILITY = 'push_cases' as const;
|
||||
|
||||
/**
|
||||
* User profiles
|
||||
*/
|
||||
|
||||
export const DEFAULT_USER_SIZE = 10;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
"kibanaVersion":"kibana",
|
||||
"optionalPlugins":[
|
||||
"home",
|
||||
"security",
|
||||
"taskManager",
|
||||
"usageCollection"
|
||||
],
|
||||
|
@ -30,7 +29,8 @@
|
|||
"kibanaUtils",
|
||||
"triggersActionsUi",
|
||||
"management",
|
||||
"spaces"
|
||||
"spaces",
|
||||
"security"
|
||||
],
|
||||
"requiredBundles": [
|
||||
"savedObjects"
|
||||
|
|
|
@ -16,3 +16,11 @@ export const CASE_LIST_CACHE_KEY = 'case-list';
|
|||
export const CASE_CONNECTORS_CACHE_KEY = 'case-connectors';
|
||||
export const CASE_LICENSE_CACHE_KEY = 'case-license-action';
|
||||
export const CASE_TAGS_CACHE_KEY = 'case-tags';
|
||||
|
||||
/**
|
||||
* User profiles
|
||||
*/
|
||||
|
||||
export const USER_PROFILES_CACHE_KEY = 'user-profiles';
|
||||
export const USER_PROFILES_SUGGEST_CACHE_KEY = 'suggest';
|
||||
export const USER_PROFILES_BULK_GET_CACHE_KEY = 'bulk-get';
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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 { UserProfile } from '@kbn/security-plugin/common';
|
||||
import { userProfiles } from '../api.mock';
|
||||
|
||||
export const suggestUserProfiles = async (): Promise<UserProfile[]> =>
|
||||
Promise.resolve(userProfiles);
|
||||
|
||||
export const bulkGetUserProfiles = async (): Promise<UserProfile[]> =>
|
||||
Promise.resolve(userProfiles);
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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 { UserProfile } from '@kbn/security-plugin/common';
|
||||
|
||||
export const userProfiles: UserProfile[] = [
|
||||
{
|
||||
uid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
|
||||
data: {},
|
||||
user: {
|
||||
username: 'damaged_raccoon',
|
||||
email: 'damaged_raccoon@elastic.co',
|
||||
full_name: 'Damaged Raccoon',
|
||||
},
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
uid: 'u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0',
|
||||
data: {},
|
||||
user: {
|
||||
username: 'physical_dinosaur',
|
||||
email: 'physical_dinosaur@elastic.co',
|
||||
full_name: 'Physical Dinosaur',
|
||||
},
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
uid: 'u_9xDEQqUqoYCnFnPPLq5mIRHKL8gBTo_NiKgOnd5gGk0_0',
|
||||
data: {},
|
||||
user: {
|
||||
username: 'wet_dingo',
|
||||
email: 'wet_dingo@elastic.co',
|
||||
full_name: 'Wet Dingo',
|
||||
},
|
||||
enabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
export const userProfilesIds = userProfiles.map((profile) => profile.uid);
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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 { GENERAL_CASES_OWNER } from '../../../common/constants';
|
||||
import { createStartServicesMock } from '../../common/lib/kibana/kibana_react.mock';
|
||||
import { bulkGetUserProfiles, suggestUserProfiles } from './api';
|
||||
import { userProfiles, userProfilesIds } from './api.mock';
|
||||
|
||||
describe('User profiles API', () => {
|
||||
describe('suggestUserProfiles', () => {
|
||||
const abortCtrl = new AbortController();
|
||||
const { http } = createStartServicesMock();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
http.post = jest.fn().mockResolvedValue(userProfiles);
|
||||
});
|
||||
|
||||
it('returns the user profiles correctly', async () => {
|
||||
const res = await suggestUserProfiles({
|
||||
http,
|
||||
name: 'elastic',
|
||||
owner: [GENERAL_CASES_OWNER],
|
||||
signal: abortCtrl.signal,
|
||||
});
|
||||
|
||||
expect(res).toEqual(userProfiles);
|
||||
});
|
||||
|
||||
it('calls http.post correctly', async () => {
|
||||
await suggestUserProfiles({
|
||||
http,
|
||||
name: 'elastic',
|
||||
owner: [GENERAL_CASES_OWNER],
|
||||
signal: abortCtrl.signal,
|
||||
});
|
||||
|
||||
expect(http.post).toHaveBeenCalledWith('/internal/cases/_suggest_user_profiles', {
|
||||
body: '{"name":"elastic","size":10,"owner":["cases"]}',
|
||||
signal: abortCtrl.signal,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulkGetUserProfiles', () => {
|
||||
const { security } = createStartServicesMock();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
security.userProfiles.bulkGet = jest.fn().mockResolvedValue(userProfiles);
|
||||
});
|
||||
|
||||
it('returns the user profiles correctly', async () => {
|
||||
const res = await bulkGetUserProfiles({
|
||||
security,
|
||||
uids: userProfilesIds,
|
||||
});
|
||||
|
||||
expect(res).toEqual(userProfiles);
|
||||
});
|
||||
|
||||
it('calls http.post correctly', async () => {
|
||||
await bulkGetUserProfiles({
|
||||
security,
|
||||
uids: userProfilesIds,
|
||||
});
|
||||
|
||||
expect(security.userProfiles.bulkGet).toHaveBeenCalledWith({
|
||||
dataPath: 'avatar',
|
||||
uids: new Set([
|
||||
'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
|
||||
'u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0',
|
||||
'u_9xDEQqUqoYCnFnPPLq5mIRHKL8gBTo_NiKgOnd5gGk0_0',
|
||||
]),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
46
x-pack/plugins/cases/public/containers/user_profiles/api.ts
Normal file
46
x-pack/plugins/cases/public/containers/user_profiles/api.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 { HttpStart } from '@kbn/core/public';
|
||||
import { UserProfile } from '@kbn/security-plugin/common';
|
||||
import { SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||
import { INTERNAL_SUGGEST_USER_PROFILES_URL, DEFAULT_USER_SIZE } from '../../../common/constants';
|
||||
|
||||
export interface SuggestUserProfilesArgs {
|
||||
http: HttpStart;
|
||||
name: string;
|
||||
owner: string[];
|
||||
signal: AbortSignal;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export const suggestUserProfiles = async ({
|
||||
http,
|
||||
name,
|
||||
size = DEFAULT_USER_SIZE,
|
||||
owner,
|
||||
signal,
|
||||
}: SuggestUserProfilesArgs): Promise<UserProfile[]> => {
|
||||
const response = await http.post<UserProfile[]>(INTERNAL_SUGGEST_USER_PROFILES_URL, {
|
||||
body: JSON.stringify({ name, size, owner }),
|
||||
signal,
|
||||
});
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
export interface BulkGetUserProfilesArgs {
|
||||
security: SecurityPluginStart;
|
||||
uids: string[];
|
||||
}
|
||||
|
||||
export const bulkGetUserProfiles = async ({
|
||||
security,
|
||||
uids,
|
||||
}: BulkGetUserProfilesArgs): Promise<UserProfile[]> => {
|
||||
return security.userProfiles.bulkGet({ uids: new Set(uids), dataPath: 'avatar' });
|
||||
};
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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 { renderHook } from '@testing-library/react-hooks';
|
||||
import { useToasts } from '../../common/lib/kibana';
|
||||
import { AppMockRenderer, createAppMockRenderer } from '../../common/mock';
|
||||
import * as api from './api';
|
||||
import { useBulkGetUserProfiles } from './use_bulk_get_user_profiles';
|
||||
import { userProfilesIds } from './api.mock';
|
||||
|
||||
jest.mock('../../common/lib/kibana');
|
||||
jest.mock('./api');
|
||||
|
||||
describe('useBulkGetUserProfiles', () => {
|
||||
const props = {
|
||||
uids: userProfilesIds,
|
||||
};
|
||||
|
||||
const addSuccess = jest.fn();
|
||||
(useToasts as jest.Mock).mockReturnValue({ addSuccess, addError: jest.fn() });
|
||||
|
||||
let appMockRender: AppMockRenderer;
|
||||
|
||||
beforeEach(() => {
|
||||
appMockRender = createAppMockRenderer();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('calls bulkGetUserProfiles with correct arguments', async () => {
|
||||
const spyOnSuggestUserProfiles = jest.spyOn(api, 'bulkGetUserProfiles');
|
||||
|
||||
const { result, waitFor } = renderHook(() => useBulkGetUserProfiles(props), {
|
||||
wrapper: appMockRender.AppWrapper,
|
||||
});
|
||||
|
||||
await waitFor(() => result.current.isSuccess);
|
||||
|
||||
expect(spyOnSuggestUserProfiles).toBeCalledWith({
|
||||
...props,
|
||||
security: expect.anything(),
|
||||
});
|
||||
});
|
||||
|
||||
it('shows a toast error message when an error occurs in the response', async () => {
|
||||
const spyOnSuggestUserProfiles = jest.spyOn(api, 'bulkGetUserProfiles');
|
||||
|
||||
spyOnSuggestUserProfiles.mockImplementation(() => {
|
||||
throw new Error('Something went wrong');
|
||||
});
|
||||
|
||||
const addError = jest.fn();
|
||||
(useToasts as jest.Mock).mockReturnValue({ addSuccess, addError });
|
||||
|
||||
const { result, waitFor } = renderHook(() => useBulkGetUserProfiles(props), {
|
||||
wrapper: appMockRender.AppWrapper,
|
||||
});
|
||||
|
||||
await waitFor(() => result.current.isError);
|
||||
|
||||
expect(addError).toHaveBeenCalled();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 { useQuery, UseQueryResult } from 'react-query';
|
||||
import { UserProfile } from '@kbn/security-plugin/common';
|
||||
import * as i18n from '../translations';
|
||||
import { useKibana, useToasts } from '../../common/lib/kibana';
|
||||
import { ServerError } from '../../types';
|
||||
import { USER_PROFILES_CACHE_KEY, USER_PROFILES_BULK_GET_CACHE_KEY } from '../constants';
|
||||
import { bulkGetUserProfiles } from './api';
|
||||
|
||||
export const useBulkGetUserProfiles = ({ uids }: { uids: string[] }) => {
|
||||
const { security } = useKibana().services;
|
||||
|
||||
const toasts = useToasts();
|
||||
|
||||
return useQuery<UserProfile[], ServerError>(
|
||||
[USER_PROFILES_CACHE_KEY, USER_PROFILES_BULK_GET_CACHE_KEY, uids],
|
||||
() => {
|
||||
return bulkGetUserProfiles({ security, uids });
|
||||
},
|
||||
{
|
||||
onError: (error: ServerError) => {
|
||||
if (error.name !== 'AbortError') {
|
||||
toasts.addError(
|
||||
error.body && error.body.message ? new Error(error.body.message) : error,
|
||||
{
|
||||
title: i18n.ERROR_TITLE,
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export type UseSuggestUserProfiles = UseQueryResult<UserProfile[], ServerError>;
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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 { GENERAL_CASES_OWNER } from '../../../common/constants';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { useToasts } from '../../common/lib/kibana';
|
||||
import { AppMockRenderer, createAppMockRenderer } from '../../common/mock';
|
||||
import * as api from './api';
|
||||
import { useSuggestUserProfiles } from './use_suggest_user_profiles';
|
||||
|
||||
jest.mock('../../common/lib/kibana');
|
||||
jest.mock('./api');
|
||||
|
||||
describe('useSuggestUserProfiles', () => {
|
||||
const props = {
|
||||
name: 'elastic',
|
||||
owner: [GENERAL_CASES_OWNER],
|
||||
};
|
||||
|
||||
const addSuccess = jest.fn();
|
||||
(useToasts as jest.Mock).mockReturnValue({ addSuccess, addError: jest.fn() });
|
||||
|
||||
let appMockRender: AppMockRenderer;
|
||||
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
appMockRender = createAppMockRenderer();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('calls suggestUserProfiles with correct arguments', async () => {
|
||||
const spyOnSuggestUserProfiles = jest.spyOn(api, 'suggestUserProfiles');
|
||||
|
||||
const { result, waitFor } = renderHook(() => useSuggestUserProfiles(props), {
|
||||
wrapper: appMockRender.AppWrapper,
|
||||
});
|
||||
|
||||
jest.advanceTimersByTime(500);
|
||||
await waitFor(() => result.current.isSuccess);
|
||||
|
||||
expect(spyOnSuggestUserProfiles).toBeCalledWith({
|
||||
...props,
|
||||
size: 10,
|
||||
http: expect.anything(),
|
||||
signal: expect.anything(),
|
||||
});
|
||||
});
|
||||
|
||||
it('shows a toast error message when an error occurs in the response', async () => {
|
||||
const spyOnSuggestUserProfiles = jest.spyOn(api, 'suggestUserProfiles');
|
||||
|
||||
spyOnSuggestUserProfiles.mockImplementation(() => {
|
||||
throw new Error('Something went wrong');
|
||||
});
|
||||
|
||||
const addError = jest.fn();
|
||||
(useToasts as jest.Mock).mockReturnValue({ addSuccess, addError });
|
||||
|
||||
const { result, waitFor } = renderHook(() => useSuggestUserProfiles(props), {
|
||||
wrapper: appMockRender.AppWrapper,
|
||||
});
|
||||
|
||||
jest.advanceTimersByTime(500);
|
||||
await waitFor(() => result.current.isError);
|
||||
|
||||
expect(addError).toHaveBeenCalled();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 { useState } from 'react';
|
||||
import { useQuery, UseQueryResult } from 'react-query';
|
||||
import useDebounce from 'react-use/lib/useDebounce';
|
||||
import { UserProfile } from '@kbn/security-plugin/common';
|
||||
import { DEFAULT_USER_SIZE } from '../../../common/constants';
|
||||
import * as i18n from '../translations';
|
||||
import { useKibana, useToasts } from '../../common/lib/kibana';
|
||||
import { ServerError } from '../../types';
|
||||
import { USER_PROFILES_CACHE_KEY, USER_PROFILES_SUGGEST_CACHE_KEY } from '../constants';
|
||||
import { suggestUserProfiles, SuggestUserProfilesArgs } from './api';
|
||||
|
||||
const DEBOUNCE_MS = 500;
|
||||
|
||||
export const useSuggestUserProfiles = ({
|
||||
name,
|
||||
owner,
|
||||
size = DEFAULT_USER_SIZE,
|
||||
}: Omit<SuggestUserProfilesArgs, 'signal' | 'http'>) => {
|
||||
const { http } = useKibana().services;
|
||||
const [debouncedName, setDebouncedName] = useState(name);
|
||||
|
||||
useDebounce(() => setDebouncedName(name), DEBOUNCE_MS, [name]);
|
||||
|
||||
const toasts = useToasts();
|
||||
|
||||
return useQuery<UserProfile[], ServerError>(
|
||||
[
|
||||
USER_PROFILES_CACHE_KEY,
|
||||
USER_PROFILES_SUGGEST_CACHE_KEY,
|
||||
{ name: debouncedName, owner, size },
|
||||
],
|
||||
() => {
|
||||
const abortCtrlRef = new AbortController();
|
||||
return suggestUserProfiles({
|
||||
http,
|
||||
name: debouncedName,
|
||||
owner,
|
||||
size,
|
||||
signal: abortCtrlRef.signal,
|
||||
});
|
||||
},
|
||||
{
|
||||
retry: false,
|
||||
onError: (error: ServerError) => {
|
||||
if (error.name !== 'AbortError') {
|
||||
toasts.addError(
|
||||
error.body && error.body.message ? new Error(error.body.message) : error,
|
||||
{
|
||||
title: i18n.ERROR_TITLE,
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export type UseSuggestUserProfiles = UseQueryResult<UserProfile[], ServerError>;
|
|
@ -15,7 +15,7 @@ import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
|
|||
import type { ManagementSetup, ManagementAppMountParams } from '@kbn/management-plugin/public';
|
||||
import type { FeaturesPluginStart } from '@kbn/features-plugin/public';
|
||||
import type { LensPublicStart } from '@kbn/lens-plugin/public';
|
||||
import type { SecurityPluginSetup } from '@kbn/security-plugin/public';
|
||||
import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||
import type { SpacesPluginStart } from '@kbn/spaces-plugin/public';
|
||||
import type { TriggersAndActionsUIPublicPluginStart as TriggersActionsStart } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import type { DistributiveOmit } from '@elastic/eui';
|
||||
|
@ -57,6 +57,7 @@ export interface CasesPluginStart {
|
|||
storage: Storage;
|
||||
triggersActionsUi: TriggersActionsStart;
|
||||
features: FeaturesPluginStart;
|
||||
security: SecurityPluginStart;
|
||||
spaces?: SpacesPluginStart;
|
||||
}
|
||||
|
||||
|
@ -66,10 +67,7 @@ export interface CasesPluginStart {
|
|||
* Leaving it out currently in lieu of RBAC changes
|
||||
*/
|
||||
|
||||
export type StartServices = CoreStart &
|
||||
CasesPluginStart & {
|
||||
security: SecurityPluginSetup;
|
||||
};
|
||||
export type StartServices = CoreStart & CasesPluginStart;
|
||||
|
||||
export interface RenderAppProps {
|
||||
mountParams: ManagementAppMountParams;
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
"triggersActionsUi",
|
||||
"inspector",
|
||||
"unifiedSearch",
|
||||
"sharedUX"
|
||||
"sharedUX",
|
||||
"security"
|
||||
],
|
||||
"ui": true,
|
||||
"server": true,
|
||||
|
|
|
@ -37,6 +37,7 @@ import {
|
|||
ActionTypeRegistryContract,
|
||||
RuleTypeRegistryContract,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||
import { observabilityAppId, observabilityFeatureId, casesPath } from '../common';
|
||||
import { createLazyObservabilityPageTemplate } from './components/shared';
|
||||
import { registerDataHandler } from './data_handler';
|
||||
|
@ -51,6 +52,7 @@ import { getExploratoryViewEmbeddable } from './components/shared/exploratory_vi
|
|||
import { createExploratoryViewUrl } from './components/shared/exploratory_view/configurations/exploratory_view_url';
|
||||
import { createUseRulesLink } from './hooks/create_use_rules_link';
|
||||
import getAppDataView from './utils/observability_data_views/get_app_data_view';
|
||||
|
||||
export type ObservabilityPublicSetup = ReturnType<Plugin['setup']>;
|
||||
|
||||
export interface ObservabilityPublicPluginsSetup {
|
||||
|
@ -73,6 +75,7 @@ export interface ObservabilityPublicPluginsStart {
|
|||
sharedUX: SharedUXPluginStart;
|
||||
ruleTypeRegistry: RuleTypeRegistryContract;
|
||||
actionTypeRegistry: ActionTypeRegistryContract;
|
||||
security: SecurityPluginStart;
|
||||
}
|
||||
|
||||
export type ObservabilityPublicStart = ReturnType<Plugin['start']>;
|
||||
|
|
|
@ -137,7 +137,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
apm,
|
||||
savedObjectsTagging: savedObjectsTaggingOss.getTaggingApi(),
|
||||
storage: this.storage,
|
||||
security: plugins.security,
|
||||
security: startPluginsDeps.security,
|
||||
};
|
||||
return services;
|
||||
})();
|
||||
|
|
|
@ -23,7 +23,7 @@ import type {
|
|||
TriggersAndActionsUIPublicPluginStart as TriggersActionsStart,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import type { CasesUiStart } from '@kbn/cases-plugin/public';
|
||||
import type { SecurityPluginSetup } from '@kbn/security-plugin/public';
|
||||
import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public';
|
||||
import type { TimelinesUIStart } from '@kbn/timelines-plugin/public';
|
||||
import type { SessionViewStart } from '@kbn/session-view-plugin/public';
|
||||
import type { KubernetesSecurityStart } from '@kbn/kubernetes-security-plugin/public';
|
||||
|
@ -87,7 +87,7 @@ export interface StartPlugins {
|
|||
spaces?: SpacesPluginStart;
|
||||
dataViewFieldEditor: IndexPatternFieldEditorStart;
|
||||
osquery?: OsqueryPluginStart;
|
||||
security: SecurityPluginSetup;
|
||||
security: SecurityPluginStart;
|
||||
cloudSecurityPosture: CspClientPluginStart;
|
||||
threatIntelligence: ThreatIntelligencePluginStart;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue