From 8ada3b359ec37ce40f7624df7a432e5a8072ef39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20S=C3=A1nchez?= Date: Thu, 24 Mar 2022 18:00:28 +0100 Subject: [PATCH] [Security solution][Endpoint] Fix blocklist entries are allowed to be assigned per policy on basic license (#128472) * Hide assignment section on blocklsit form when no licensing and isGlobal. Also check for valid form when changing policy * Fix commented code * Don't reset filter when closing flyout * Fix policy selectio was cleaned when switching from by policy to global and went back to by policy --- .../components/artifact_flyout.tsx | 8 +- .../view/components/blocklist_form.tsx | 75 +++++++++++++------ 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx index ab893b57f16e8..4b126d6e747db 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx @@ -257,10 +257,10 @@ export const ArtifactFlyout = memo( } // `undefined` will cause params to be dropped from url - setUrlParams({ itemId: undefined, show: undefined }, true); + setUrlParams({ ...urlParams, itemId: undefined, show: undefined }, true); onClose(); - }, [isSubmittingData, onClose, setUrlParams]); + }, [isSubmittingData, onClose, setUrlParams, urlParams]); const handleFormComponentOnChange: ArtifactFormComponentProps['onChange'] = useCallback( ({ item: updatedItem, isValid }) => { @@ -285,12 +285,12 @@ export const ArtifactFlyout = memo( if (isMounted) { // Close the flyout // `undefined` will cause params to be dropped from url - setUrlParams({ itemId: undefined, show: undefined }, true); + setUrlParams({ ...urlParams, itemId: undefined, show: undefined }, true); onSuccess(); } }, - [isEditFlow, isMounted, labels, onSuccess, setUrlParams, toasts] + [isEditFlow, isMounted, labels, onSuccess, setUrlParams, toasts, urlParams] ); const handleSubmitClick = useCallback(() => { diff --git a/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx b/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx index 030538598c8ad..9a6be2814a396 100644 --- a/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx @@ -65,6 +65,7 @@ import { useLicense } from '../../../../../common/hooks/use_license'; import { isValidHash } from '../../../../../../common/endpoint/service/trusted_apps/validations'; import { isArtifactGlobal } from '../../../../../../common/endpoint/service/artifacts'; import type { PolicyData } from '../../../../../../common/endpoint/types'; +import { isGlobalPolicyEffected } from '../../../../components/effected_policy_select/utils'; interface BlocklistEntry { field: BlocklistConditionEntryField; @@ -106,14 +107,34 @@ export const BlockListForm = memo( const warningsRef = useRef({}); const errorsRef = useRef({}); const [selectedPolicies, setSelectedPolicies] = useState([]); + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const isGlobal = useMemo(() => isArtifactGlobal(item as ExceptionListItemSchema), [item]); + const [wasByPolicy, setWasByPolicy] = useState(!isGlobalPolicyEffected(item.tags)); + const [hasFormChanged, setHasFormChanged] = useState(false); + + const showAssignmentSection = useMemo(() => { + return ( + isPlatinumPlus || + (mode === 'edit' && (!isGlobal || (wasByPolicy && isGlobal && hasFormChanged))) + ); + }, [mode, isGlobal, hasFormChanged, isPlatinumPlus, wasByPolicy]); + + // set initial state of `wasByPolicy` that checks if the initial state of the exception was by policy or not + useEffect(() => { + if (!hasFormChanged && item.tags) { + setWasByPolicy(!isGlobalPolicyEffected(item.tags)); + } + }, [item.tags, hasFormChanged]); // select policies if editing useEffect(() => { + if (hasFormChanged) return; const policyIds = item.tags?.map((tag) => tag.split(':')[1]) ?? []; if (!policyIds.length) return; const policiesData = policies.filter((policy) => policyIds.includes(policy.id)); + setSelectedPolicies(policiesData); - }, [item.tags, policies]); + }, [hasFormChanged, item.tags, policies]); const blocklistEntry = useMemo((): BlocklistEntry => { if (!item.entries.length) { @@ -248,6 +269,7 @@ export const BlockListForm = memo( isValid: isValid(errorsRef.current), item: nextItem, }); + setHasFormChanged(true); }, [validateValues, onChange, item] ); @@ -261,6 +283,7 @@ export const BlockListForm = memo( description: event.target.value, }, }); + setHasFormChanged(true); }, [onChange, item] ); @@ -286,6 +309,7 @@ export const BlockListForm = memo( isValid: isValid(errorsRef.current), item: nextItem, }); + setHasFormChanged(true); }, [validateValues, blocklistEntry, onChange, item] ); @@ -302,6 +326,7 @@ export const BlockListForm = memo( isValid: isValid(errorsRef.current), item: nextItem, }); + setHasFormChanged(true); }, [validateValues, onChange, item, blocklistEntry] ); @@ -320,6 +345,7 @@ export const BlockListForm = memo( isValid: isValid(errorsRef.current), item: nextItem, }); + setHasFormChanged(true); }, [validateValues, onChange, item, blocklistEntry] ); @@ -341,6 +367,7 @@ export const BlockListForm = memo( isValid: isValid(errorsRef.current), item: nextItem, }); + setHasFormChanged(true); }, [validateValues, onChange, item, blocklistEntry] ); @@ -351,16 +378,20 @@ export const BlockListForm = memo( ? [GLOBAL_ARTIFACT_TAG] : change.selected.map((policy) => `${BY_POLICY_ARTIFACT_TAG_PREFIX}${policy.id}`); - setSelectedPolicies(change.selected); + const nextItem = { ...item, tags }; + + // Preserve old selected policies when switching to global + if (!change.isGlobal) { + setSelectedPolicies(change.selected); + } + validateValues(nextItem); onChange({ isValid: isValid(errorsRef.current), - item: { - ...item, - tags, - }, + item: nextItem, }); + setHasFormChanged(true); }, - [onChange, item] + [validateValues, onChange, item] ); return ( @@ -461,20 +492,22 @@ export const BlockListForm = memo( /> - <> - - - - - + {showAssignmentSection && ( + <> + + + + + + )} ); }