From c52c5fabf669c66f3db9001f6eb7ba1ef378aa6a Mon Sep 17 00:00:00 2001
From: Georgii Gorbachev
Date: Wed, 6 Jan 2021 00:50:42 +0100
Subject: [PATCH] [SecuritySolution][Detections] Fix "Closing a signal silently
fails with reduced privileges" (#86908)
## Summary
This PR introduces the following changes. If the user has insufficient write privileges on the signals index:
- we disable the status-changing actions on detection alerts ("Open alert", "Close Alert", "Mark in progress") in the context menu of an alert in alerts table
- we make sure to show the corresponding callout that tells about read-only access to detection alerts
- in the callout we provide links to docs for understanding why/how to fix
---
.../components/links_to_docs/doc_link.tsx | 33 +++++++++++++
.../links_to_docs/external_link.tsx | 25 ++++++++++
.../common/components/links_to_docs/index.tsx | 7 +++
.../links_to_docs/links_components.tsx | 23 +++++++++
.../links_to_docs/links_translations.ts | 34 ++++++++++++++
.../timeline_actions/alert_context_menu.tsx | 8 ++--
.../read_only_alerts_callout/index.tsx | 6 +--
.../read_only_alerts_callout/translations.ts | 22 ---------
.../read_only_alerts_callout/translations.tsx | 47 +++++++++++++++++++
.../read_only_rules_callout/index.tsx | 2 +-
.../read_only_rules_callout/translations.ts | 22 ---------
.../read_only_rules_callout/translations.tsx | 47 +++++++++++++++++++
.../components/user_info/index.test.tsx | 1 +
.../detections/components/user_info/index.tsx | 28 +++++++++++
.../alerts/use_privilege_user.test.tsx | 3 ++
.../alerts/use_privilege_user.tsx | 11 ++---
.../translations/translations/ja-JP.json | 6 +--
.../translations/translations/zh-CN.json | 6 +--
18 files changed, 265 insertions(+), 66 deletions(-)
create mode 100644 x-pack/plugins/security_solution/public/common/components/links_to_docs/doc_link.tsx
create mode 100644 x-pack/plugins/security_solution/public/common/components/links_to_docs/external_link.tsx
create mode 100644 x-pack/plugins/security_solution/public/common/components/links_to_docs/index.tsx
create mode 100644 x-pack/plugins/security_solution/public/common/components/links_to_docs/links_components.tsx
create mode 100644 x-pack/plugins/security_solution/public/common/components/links_to_docs/links_translations.ts
delete mode 100644 x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/translations.ts
create mode 100644 x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/translations.tsx
delete mode 100644 x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/translations.ts
create mode 100644 x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/translations.tsx
diff --git a/x-pack/plugins/security_solution/public/common/components/links_to_docs/doc_link.tsx b/x-pack/plugins/security_solution/public/common/components/links_to_docs/doc_link.tsx
new file mode 100644
index 0000000000000..f02e4390db02f
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/common/components/links_to_docs/doc_link.tsx
@@ -0,0 +1,33 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React, { FC, memo } from 'react';
+import { useKibana } from '../../lib/kibana';
+import { ExternalLink } from './external_link';
+import { COMMON_ARIA_LABEL_ENDING } from './links_translations';
+
+interface DocLinkProps {
+ guidePath?: string;
+ docPath: string;
+ linkText: string;
+}
+
+const DocLink: FC = ({ guidePath = 'security', docPath, linkText }) => {
+ const { services } = useKibana();
+ const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = services.docLinks;
+
+ const url = `${ELASTIC_WEBSITE_URL}guide/en/${guidePath}/${DOC_LINK_VERSION}/${docPath}`;
+ const ariaLabel = `${linkText} - ${COMMON_ARIA_LABEL_ENDING}`;
+
+ return ;
+};
+
+/**
+ * A simple text link to documentation.
+ */
+const DocLinkWrapper = memo(DocLink);
+
+export { DocLinkWrapper as DocLink };
diff --git a/x-pack/plugins/security_solution/public/common/components/links_to_docs/external_link.tsx b/x-pack/plugins/security_solution/public/common/components/links_to_docs/external_link.tsx
new file mode 100644
index 0000000000000..f83c6f8fe31e4
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/common/components/links_to_docs/external_link.tsx
@@ -0,0 +1,25 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React, { FC } from 'react';
+import { EuiLink } from '@elastic/eui';
+
+interface ExternalLinkProps {
+ url: string;
+ text: string;
+ ariaLabel?: string;
+}
+
+/**
+ * A simplistic text link for opening external urls in a new browser tab.
+ */
+export const ExternalLink: FC = ({ url, text, ariaLabel }) => {
+ return (
+
+ {text}
+
+ );
+};
diff --git a/x-pack/plugins/security_solution/public/common/components/links_to_docs/index.tsx b/x-pack/plugins/security_solution/public/common/components/links_to_docs/index.tsx
new file mode 100644
index 0000000000000..f681783cb78fa
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/common/components/links_to_docs/index.tsx
@@ -0,0 +1,7 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+export * from './links_components';
diff --git a/x-pack/plugins/security_solution/public/common/components/links_to_docs/links_components.tsx b/x-pack/plugins/security_solution/public/common/components/links_to_docs/links_components.tsx
new file mode 100644
index 0000000000000..362f6b25c1103
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/common/components/links_to_docs/links_components.tsx
@@ -0,0 +1,23 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { DocLink } from './doc_link';
+import * as i18n from './links_translations';
+
+export const SecuritySolutionRequirementsLink = () => (
+
+);
+
+export const DetectionsRequirementsLink = () => (
+
+);
diff --git a/x-pack/plugins/security_solution/public/common/components/links_to_docs/links_translations.ts b/x-pack/plugins/security_solution/public/common/components/links_to_docs/links_translations.ts
new file mode 100644
index 0000000000000..5ab0032b9b9a7
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/common/components/links_to_docs/links_translations.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+
+/**
+ * If a link's text is "Docs", its aria-label will be set to
+ * "Docs - ${COMMON_ARIA_LABEL_ENDING}".
+ */
+export const COMMON_ARIA_LABEL_ENDING = i18n.translate(
+ 'xpack.securitySolution.documentationLinks.ariaLabelEnding',
+ {
+ defaultMessage: 'click to open documentation in a new tab',
+ }
+);
+
+export const SOLUTION_REQUIREMENTS_LINK_PATH = 'sec-requirements.html';
+export const SOLUTION_REQUIREMENTS_LINK_TEXT = i18n.translate(
+ 'xpack.securitySolution.documentationLinks.solutionRequirements.text',
+ {
+ defaultMessage: 'Elastic Security system requirements',
+ }
+);
+
+export const DETECTIONS_REQUIREMENTS_LINK_PATH = 'detections-permissions-section.html';
+export const DETECTIONS_REQUIREMENTS_LINK_TEXT = i18n.translate(
+ 'xpack.securitySolution.documentationLinks.detectionsRequirements.text',
+ {
+ defaultMessage: 'Detections prerequisites and requirements',
+ }
+);
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx
index ccdc2b5022070..614b39d280ae4 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx
@@ -98,7 +98,7 @@ const AlertContextMenuComponent: React.FC = ({
setPopover(false);
}, []);
const [exceptionModalType, setOpenAddExceptionModal] = useState(null);
- const [{ canUserCRUD, hasIndexWrite }] = useUserData();
+ const [{ canUserCRUD, hasIndexWrite, hasIndexUpdateDelete }] = useUserData();
const isEndpointAlert = useMemo((): boolean => {
if (ecsRowData == null) {
@@ -218,7 +218,7 @@ const AlertContextMenuComponent: React.FC = ({
data-test-subj="open-alert-status"
id={FILTER_OPEN}
onClick={openAlertActionOnClick}
- disabled={!canUserCRUD || !hasIndexWrite}
+ disabled={!canUserCRUD || !hasIndexUpdateDelete}
>
{i18n.ACTION_OPEN_ALERT}
@@ -251,7 +251,7 @@ const AlertContextMenuComponent: React.FC = ({
data-test-subj="close-alert-status"
id={FILTER_CLOSED}
onClick={closeAlertActionClick}
- disabled={!canUserCRUD || !hasIndexWrite}
+ disabled={!canUserCRUD || !hasIndexUpdateDelete}
>
{i18n.ACTION_CLOSE_ALERT}
@@ -284,7 +284,7 @@ const AlertContextMenuComponent: React.FC = ({
data-test-subj="in-progress-alert-status"
id={FILTER_IN_PROGRESS}
onClick={inProgressAlertActionClick}
- disabled={!canUserCRUD || !hasIndexWrite}
+ disabled={!canUserCRUD || !hasIndexUpdateDelete}
>
{i18n.ACTION_IN_PROGRESS_ALERT}
diff --git a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/index.tsx b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/index.tsx
index 8ba04e5fdd7de..a2bc18c1aa3f2 100644
--- a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/index.tsx
@@ -14,16 +14,16 @@ const readOnlyAccessToAlertsMessage: CallOutMessage = {
type: 'primary',
id: 'read-only-access-to-alerts',
title: i18n.READ_ONLY_ALERTS_CALLOUT_TITLE,
- description: {i18n.READ_ONLY_ALERTS_CALLOUT_MSG}
,
+ description: i18n.readOnlyAlertsCallOutBody(),
};
const ReadOnlyAlertsCallOutComponent = () => {
- const [{ hasIndexWrite }] = useUserData();
+ const [{ hasIndexUpdateDelete }] = useUserData();
return (
);
diff --git a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/translations.ts b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/translations.ts
deleted file mode 100644
index aabd9e44dfff8..0000000000000
--- a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/translations.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-
-export const READ_ONLY_ALERTS_CALLOUT_TITLE = i18n.translate(
- 'xpack.securitySolution.detectionEngine.readOnlyAlertsCallOutTitle',
- {
- defaultMessage: 'You cannot change alert states',
- }
-);
-
-export const READ_ONLY_ALERTS_CALLOUT_MSG = i18n.translate(
- 'xpack.securitySolution.detectionEngine.readOnlyAlertsCallOutMsg',
- {
- defaultMessage:
- 'You only have permissions to view alerts. If you need to update alert states (open or close alerts), contact your Kibana administrator.',
- }
-);
diff --git a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/translations.tsx b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/translations.tsx
new file mode 100644
index 0000000000000..451748ff7be68
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_alerts_callout/translations.tsx
@@ -0,0 +1,47 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+import {
+ SecuritySolutionRequirementsLink,
+ DetectionsRequirementsLink,
+} from '../../../../common/components/links_to_docs';
+
+export const READ_ONLY_ALERTS_CALLOUT_TITLE = i18n.translate(
+ 'xpack.securitySolution.detectionEngine.readOnlyAlertsCallOut.messageTitle',
+ {
+ defaultMessage: 'You cannot change alert states',
+ }
+);
+
+export const readOnlyAlertsCallOutBody = () => (
+
+
+
+ ),
+ docs: (
+
+ ),
+ }}
+ />
+);
diff --git a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/index.tsx b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/index.tsx
index e25812acbea92..d593b5f696970 100644
--- a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/index.tsx
@@ -14,7 +14,7 @@ const readOnlyAccessToRulesMessage: CallOutMessage = {
type: 'primary',
id: 'read-only-access-to-rules',
title: i18n.READ_ONLY_RULES_CALLOUT_TITLE,
- description: {i18n.READ_ONLY_RULES_CALLOUT_MSG}
,
+ description: i18n.readOnlyRulesCallOutBody(),
};
const ReadOnlyRulesCallOutComponent = () => {
diff --git a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/translations.ts b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/translations.ts
deleted file mode 100644
index a0c971df37a2e..0000000000000
--- a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/translations.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-
-export const READ_ONLY_RULES_CALLOUT_TITLE = i18n.translate(
- 'xpack.securitySolution.detectionEngine.readOnlyRulesCallOutTitle',
- {
- defaultMessage: 'Rule permissions required',
- }
-);
-
-export const READ_ONLY_RULES_CALLOUT_MSG = i18n.translate(
- 'xpack.securitySolution.detectionEngine.readOnlyRulesCallOutMsg',
- {
- defaultMessage:
- 'You are currently missing the required permissions to create/edit detection engine rule. Please contact your administrator for further assistance.',
- }
-);
diff --git a/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/translations.tsx b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/translations.tsx
new file mode 100644
index 0000000000000..93ac43173935d
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/detections/components/callouts/read_only_rules_callout/translations.tsx
@@ -0,0 +1,47 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+import {
+ SecuritySolutionRequirementsLink,
+ DetectionsRequirementsLink,
+} from '../../../../common/components/links_to_docs';
+
+export const READ_ONLY_RULES_CALLOUT_TITLE = i18n.translate(
+ 'xpack.securitySolution.detectionEngine.readOnlyRulesCallOut.messageTitle',
+ {
+ defaultMessage: 'Rule permissions required',
+ }
+);
+
+export const readOnlyRulesCallOutBody = () => (
+
+
+
+ ),
+ docs: (
+
+ ),
+ }}
+ />
+);
diff --git a/x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx
index e87303efbe526..ffbdd74f0485c 100644
--- a/x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx
@@ -38,6 +38,7 @@ describe('useUserInfo', () => {
hasEncryptionKey: null,
hasIndexManage: null,
hasIndexWrite: null,
+ hasIndexUpdateDelete: null,
isAuthenticated: null,
isSignalIndexExists: null,
loading: true,
diff --git a/x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx b/x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx
index 3b0976f459324..8592de826a200 100644
--- a/x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx
@@ -15,6 +15,7 @@ export interface State {
canUserCRUD: boolean | null;
hasIndexManage: boolean | null;
hasIndexWrite: boolean | null;
+ hasIndexUpdateDelete: boolean | null;
isSignalIndexExists: boolean | null;
isAuthenticated: boolean | null;
hasEncryptionKey: boolean | null;
@@ -27,6 +28,7 @@ export const initialState: State = {
canUserCRUD: null,
hasIndexManage: null,
hasIndexWrite: null,
+ hasIndexUpdateDelete: null,
isSignalIndexExists: null,
isAuthenticated: null,
hasEncryptionKey: null,
@@ -45,6 +47,10 @@ export type Action =
type: 'updateHasIndexWrite';
hasIndexWrite: boolean | null;
}
+ | {
+ type: 'updateHasIndexUpdateDelete';
+ hasIndexUpdateDelete: boolean | null;
+ }
| {
type: 'updateIsSignalIndexExists';
isSignalIndexExists: boolean | null;
@@ -90,6 +96,12 @@ export const userInfoReducer = (state: State, action: Action): State => {
hasIndexWrite: action.hasIndexWrite,
};
}
+ case 'updateHasIndexUpdateDelete': {
+ return {
+ ...state,
+ hasIndexUpdateDelete: action.hasIndexUpdateDelete,
+ };
+ }
case 'updateIsSignalIndexExists': {
return {
...state,
@@ -151,6 +163,7 @@ export const useUserInfo = (): State => {
canUserCRUD,
hasIndexManage,
hasIndexWrite,
+ hasIndexUpdateDelete,
isSignalIndexExists,
isAuthenticated,
hasEncryptionKey,
@@ -166,6 +179,7 @@ export const useUserInfo = (): State => {
hasEncryptionKey: isApiEncryptionKey,
hasIndexManage: hasApiIndexManage,
hasIndexWrite: hasApiIndexWrite,
+ hasIndexUpdateDelete: hasApiIndexUpdateDelete,
} = usePrivilegeUser();
const {
loading: indexNameLoading,
@@ -197,6 +211,19 @@ export const useUserInfo = (): State => {
}
}, [dispatch, loading, hasIndexWrite, hasApiIndexWrite]);
+ useEffect(() => {
+ if (
+ !loading &&
+ hasIndexUpdateDelete !== hasApiIndexUpdateDelete &&
+ hasApiIndexUpdateDelete != null
+ ) {
+ dispatch({
+ type: 'updateHasIndexUpdateDelete',
+ hasIndexUpdateDelete: hasApiIndexUpdateDelete,
+ });
+ }
+ }, [dispatch, loading, hasIndexUpdateDelete, hasApiIndexUpdateDelete]);
+
useEffect(() => {
if (
!loading &&
@@ -272,6 +299,7 @@ export const useUserInfo = (): State => {
canUserCRUD,
hasIndexManage,
hasIndexWrite,
+ hasIndexUpdateDelete,
signalIndexName,
signalIndexMappingOutdated,
};
diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_privilege_user.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_privilege_user.test.tsx
index c248223c6b81b..fca4714b922f7 100644
--- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_privilege_user.test.tsx
+++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_privilege_user.test.tsx
@@ -21,6 +21,7 @@ describe('usePrivilegeUser', () => {
hasEncryptionKey: null,
hasIndexManage: null,
hasIndexWrite: null,
+ hasIndexUpdateDelete: null,
isAuthenticated: null,
loading: true,
});
@@ -38,6 +39,7 @@ describe('usePrivilegeUser', () => {
hasEncryptionKey: true,
hasIndexManage: true,
hasIndexWrite: true,
+ hasIndexUpdateDelete: true,
isAuthenticated: true,
loading: false,
});
@@ -59,6 +61,7 @@ describe('usePrivilegeUser', () => {
hasEncryptionKey: false,
hasIndexManage: false,
hasIndexWrite: false,
+ hasIndexUpdateDelete: false,
isAuthenticated: false,
loading: false,
});
diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_privilege_user.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_privilege_user.tsx
index dda9b50239cde..f8a61faee2914 100644
--- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_privilege_user.tsx
+++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_privilege_user.tsx
@@ -16,6 +16,7 @@ export interface ReturnPrivilegeUser {
hasEncryptionKey: boolean | null;
hasIndexManage: boolean | null;
hasIndexWrite: boolean | null;
+ hasIndexUpdateDelete: boolean | null;
}
/**
* Hook to get user privilege from
@@ -23,16 +24,12 @@ export interface ReturnPrivilegeUser {
*/
export const usePrivilegeUser = (): ReturnPrivilegeUser => {
const [loading, setLoading] = useState(true);
- const [privilegeUser, setPrivilegeUser] = useState<
- Pick<
- ReturnPrivilegeUser,
- 'isAuthenticated' | 'hasEncryptionKey' | 'hasIndexManage' | 'hasIndexWrite'
- >
- >({
+ const [privilegeUser, setPrivilegeUser] = useState>({
isAuthenticated: null,
hasEncryptionKey: null,
hasIndexManage: null,
hasIndexWrite: null,
+ hasIndexUpdateDelete: null,
});
const [, dispatchToaster] = useStateToaster();
@@ -59,6 +56,7 @@ export const usePrivilegeUser = (): ReturnPrivilegeUser => {
privilege.index[indexName].create_doc ||
privilege.index[indexName].index ||
privilege.index[indexName].write,
+ hasIndexUpdateDelete: privilege.index[indexName].write,
});
}
}
@@ -69,6 +67,7 @@ export const usePrivilegeUser = (): ReturnPrivilegeUser => {
hasEncryptionKey: false,
hasIndexManage: false,
hasIndexWrite: false,
+ hasIndexUpdateDelete: false,
});
errorToToaster({ title: i18n.PRIVILEGE_FETCH_FAILURE, error, dispatchToaster });
}
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 243cf34e1f22e..4c3e396f88341 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -16843,8 +16843,7 @@
"xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutMsg": "Kibanaを起動するごとに保存されたオブジェクトの新しい暗号化キーを作成します。永続キーがないと、Kibanaの再起動後にルールを削除または修正することができません。永続キーを設定するには、kibana.ymlファイルに32文字以上のテキスト値を付けてxpack.encryptedSavedObjects.encryptionKey設定を追加してください。",
"xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutTitle": "API統合キーが必要です",
"xpack.securitySolution.detectionEngine.noIndexTitle": "検出エンジンを設定しましょう",
- "xpack.securitySolution.detectionEngine.readOnlyAlertsCallOutMsg": "アラートを表示する権限のみが付与されています。アラート状態を更新(アラートを開く、アラートを閉じる)必要がある場合は、Kibana管理者に連絡してください。",
- "xpack.securitySolution.detectionEngine.readOnlyAlertsCallOutTitle": "アラート状態を変更することはできません",
+ "xpack.securitySolution.detectionEngine.readOnlyAlertsCallOut.messageTitle": "アラート状態を変更することはできません",
"xpack.securitySolution.detectionEngine.pageTitle": "検出エンジン",
"xpack.securitySolution.detectionEngine.panelSubtitleShowing": "表示中",
"xpack.securitySolution.detectionEngine.queryPreview.queryGraphCountLabel": "カウント",
@@ -16859,8 +16858,7 @@
"xpack.securitySolution.detectionEngine.queryPreview.queryPreviewGraphTitle": "{hits} {hits, plural, =1 {ヒット} other {ヒット}}",
"xpack.securitySolution.detectionEngine.queryPreview.queryPreviewHelpText": "クエリ結果をプレビューするデータのタイムフレームを選択します",
"xpack.securitySolution.detectionEngine.queryPreview.queryPreviewLabel": "クイッククエリプレビュー",
- "xpack.securitySolution.detectionEngine.readOnlyRulesCallOutMsg": "現在、検出エンジンルールを作成/編集するための必要な権限がありません。サポートについては、管理者にお問い合わせください。",
- "xpack.securitySolution.detectionEngine.readOnlyRulesCallOutTitle": "ルールアクセス権が必要です",
+ "xpack.securitySolution.detectionEngine.readOnlyRulesCallOut.messageTitle": "ルールアクセス権が必要です",
"xpack.securitySolution.detectionEngine.rule.editRule.errorMsgDescription": "{countError, plural, one {このタブ} other {これらのタブ}}に無効な入力があります: {tabHasError}",
"xpack.securitySolution.detectionEngine.ruleDescription.mlJobStartedDescription": "開始",
"xpack.securitySolution.detectionEngine.ruleDescription.mlJobStoppedDescription": "停止",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 6e95db4447bef..713bfe675e4cb 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -16860,8 +16860,7 @@
"xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutMsg": "每次启动 Kibana,都会为已保存对象生成新的加密密钥。没有持久性密钥,在 Kibana 重新启动后,将无法删除或修改规则。要设置持久性密钥,请将文本值为 32 个或更多任意字符的 xpack.encryptedSavedObjects.encryptionKey 设置添加到 kibana.yml 文件。",
"xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutTitle": "需要 API 集成密钥",
"xpack.securitySolution.detectionEngine.noIndexTitle": "让我们来设置您的检测引擎",
- "xpack.securitySolution.detectionEngine.readOnlyAlertsCallOutMsg": "您仅有权查看告警。如果您需要更新告警状态(打开或关闭告警),请联系您的 Kibana 管理员。",
- "xpack.securitySolution.detectionEngine.readOnlyAlertsCallOutTitle": "您无法更改告警状态",
+ "xpack.securitySolution.detectionEngine.readOnlyAlertsCallOut.messageTitle": "您无法更改告警状态",
"xpack.securitySolution.detectionEngine.pageTitle": "检测引擎",
"xpack.securitySolution.detectionEngine.panelSubtitleShowing": "正在显示",
"xpack.securitySolution.detectionEngine.queryPreview.queryGraphCountLabel": "计数",
@@ -16876,8 +16875,7 @@
"xpack.securitySolution.detectionEngine.queryPreview.queryPreviewGraphTitle": "{hits} 个{hits, plural, =1 {命中} other {命中}}",
"xpack.securitySolution.detectionEngine.queryPreview.queryPreviewHelpText": "选择数据的时间范围以预览查询结果",
"xpack.securitySolution.detectionEngine.queryPreview.queryPreviewLabel": "快速查询预览",
- "xpack.securitySolution.detectionEngine.readOnlyRulesCallOutMsg": "您当前缺少所需的权限,无法创建/编辑检测引擎规则。有关进一步帮助,请联系您的管理员。",
- "xpack.securitySolution.detectionEngine.readOnlyRulesCallOutTitle": "需要规则权限",
+ "xpack.securitySolution.detectionEngine.readOnlyRulesCallOut.messageTitle": "需要规则权限",
"xpack.securitySolution.detectionEngine.rule.editRule.errorMsgDescription": "您在{countError, plural, one {以下选项卡} other {以下选项卡}}中的输入无效:{tabHasError}",
"xpack.securitySolution.detectionEngine.ruleDescription.mlJobStartedDescription": "已启动",
"xpack.securitySolution.detectionEngine.ruleDescription.mlJobStoppedDescription": "已停止",