-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Synthetics] Restrict user with limited Fleet permissions to manipula…
…te monitors (#150402) Closes #137471 ## Summary Adds checks at various points (add, edit, delete, enable, disable actions) and asserts if user has the necessary Synthetics and Fleet (Integrations Read/Write) permissions. - A user with no `capabilities.uptime.save` permission won't be able to edit, delete, enable or disable a monitor on Overview, Management and Details page. - A user with no `fleet.authz.integrations.writeIntegrationPolicies` permission won't be able to create, update, enable or disable a monitor with at least one Private Location selected. - A user with no `fleet.authz.integrations.writeIntegrationPolicies` permission won't be able to create or delete a Private Location from Synthetics -> Settings. Action buttons and menu items will be disabled, with a tooltip conveying the reason why the button is disabled. ### Testing 1. Setup Kibana and Synthetics and so that you are able to create monitors with both public and private locations. 2. Create a few monitors using a user having both synthetics and fleet permissions. 3. Test different actions (create, edit, delete, enable, disable) with a user having no synthetics permissions. 3. Test different actions with a user having synthetics permissions but no fleet permissions. ![Screenshot 2023-02-07 at 02 25 53](https://user-images.githubusercontent.com/2748376/217142767-0b82abc2-656c-4f65-9dae-cddaaaac5688.png) ![Screenshot 2023-02-07 at 04 10 43](https://user-images.githubusercontent.com/2748376/217142783-6958836d-11cc-4e82-9879-fc4031f13567.png) v87 ![Screenshot 2023-02-07 at 04 13 06](https://user-images.githubusercontent.com/2748376/217142785-30bf45c8-1e19-4522-af8e-bed32f6948ba.png) ![Screenshot 2023-02-07 at 04 13 23](https://user-images.githubusercontent.com/2748376/217142793-c09a0273-1829-418a-9126-7da296c223ae.png) --------- Co-authored-by: shahzad31 <[email protected]> Co-authored-by: Kibana Machine <[email protected]>
- Loading branch information
1 parent
d0b0985
commit 4308929
Showing
19 changed files
with
391 additions
and
166 deletions.
There are no files selected for viewing
109 changes: 109 additions & 0 deletions
109
...ck/plugins/synthetics/public/apps/synthetics/components/common/components/permissions.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 React, { ReactNode } from 'react'; | ||
import { EuiCallOut, EuiToolTip } from '@elastic/eui'; | ||
import { i18n } from '@kbn/i18n'; | ||
|
||
export const FleetPermissionsCallout = () => { | ||
return ( | ||
<EuiCallOut title={NEED_PERMISSIONS} color="warning" iconType="help"> | ||
<p>{NEED_FLEET_READ_AGENT_POLICIES_PERMISSION}</p> | ||
</EuiCallOut> | ||
); | ||
}; | ||
|
||
/** | ||
* If any of the canEditSynthetics or canUpdatePrivateMonitor is false, then wrap the children with a tooltip | ||
* so that a reason can be conveyed to the user explaining why the action is disabled. | ||
*/ | ||
export const NoPermissionsTooltip = ({ | ||
canEditSynthetics = true, | ||
canUpdatePrivateMonitor = true, | ||
canAddPrivateMonitor = true, | ||
children, | ||
}: { | ||
canEditSynthetics?: boolean; | ||
canUpdatePrivateMonitor?: boolean; | ||
canAddPrivateMonitor?: boolean; | ||
children: ReactNode; | ||
}) => { | ||
const disabledMessage = getRestrictionReasonLabel( | ||
canEditSynthetics, | ||
canUpdatePrivateMonitor, | ||
canAddPrivateMonitor | ||
); | ||
if (disabledMessage) { | ||
return ( | ||
<EuiToolTip content={disabledMessage}> | ||
<span>{children}</span> | ||
</EuiToolTip> | ||
); | ||
} | ||
|
||
return <>{children}</>; | ||
}; | ||
|
||
function getRestrictionReasonLabel( | ||
canEditSynthetics = true, | ||
canUpdatePrivateMonitor = true, | ||
canAddPrivateMonitor = true | ||
): string | undefined { | ||
return !canEditSynthetics | ||
? CANNOT_PERFORM_ACTION_SYNTHETICS | ||
: !canUpdatePrivateMonitor | ||
? CANNOT_PERFORM_ACTION_FLEET | ||
: !canAddPrivateMonitor | ||
? PRIVATE_LOCATIONS_NOT_ALLOWED_MESSAGE | ||
: undefined; | ||
} | ||
|
||
export const NEED_PERMISSIONS = i18n.translate( | ||
'xpack.synthetics.monitorManagement.needPermissions', | ||
{ | ||
defaultMessage: 'Need permissions', | ||
} | ||
); | ||
|
||
export const NEED_FLEET_READ_AGENT_POLICIES_PERMISSION = i18n.translate( | ||
'xpack.synthetics.monitorManagement.needFleetReadAgentPoliciesPermission', | ||
{ | ||
defaultMessage: | ||
'You are not authorized to access Fleet. Fleet permissions are required to create new private locations.', | ||
} | ||
); | ||
|
||
export const CANNOT_SAVE_INTEGRATION_LABEL = i18n.translate( | ||
'xpack.synthetics.monitorManagement.cannotSaveIntegration', | ||
{ | ||
defaultMessage: | ||
'You are not authorized to update integrations. Integrations write permissions are required.', | ||
} | ||
); | ||
|
||
const CANNOT_PERFORM_ACTION_FLEET = i18n.translate( | ||
'xpack.synthetics.monitorManagement.noFleetPermission', | ||
{ | ||
defaultMessage: | ||
'You are not authorized to perform this action. Integrations write permissions are required.', | ||
} | ||
); | ||
|
||
const CANNOT_PERFORM_ACTION_SYNTHETICS = i18n.translate( | ||
'xpack.synthetics.monitorManagement.noSyntheticsPermissions', | ||
{ | ||
defaultMessage: 'You do not have sufficient permissions to perform this action.', | ||
} | ||
); | ||
|
||
const PRIVATE_LOCATIONS_NOT_ALLOWED_MESSAGE = i18n.translate( | ||
'xpack.synthetics.monitorManagement.privateLocationsNotAllowedMessage', | ||
{ | ||
defaultMessage: | ||
'You do not have permission to add monitors to private locations. Contact your administrator to request access.', | ||
} | ||
); |
33 changes: 0 additions & 33 deletions
33
x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/edit_monitor.tsx
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
...s/public/apps/synthetics/components/monitor_details/monitor_summary/edit_monitor_link.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React from 'react'; | ||
import { useParams } from 'react-router-dom'; | ||
import { i18n } from '@kbn/i18n'; | ||
import { EuiButton } from '@elastic/eui'; | ||
|
||
import { EncryptedSyntheticsMonitor } from '../../../../../../common/runtime_types'; | ||
import { useCanEditSynthetics } from '../../../../../hooks/use_capabilities'; | ||
import { useSyntheticsSettingsContext } from '../../../contexts'; | ||
import { useCanUpdatePrivateMonitor } from '../../../hooks'; | ||
import { NoPermissionsTooltip } from '../../common/components/permissions'; | ||
import { useSelectedMonitor } from '../hooks/use_selected_monitor'; | ||
|
||
export const EditMonitorLink = () => { | ||
const { basePath } = useSyntheticsSettingsContext(); | ||
|
||
const { monitorId } = useParams<{ monitorId: string }>(); | ||
const { monitor } = useSelectedMonitor(); | ||
|
||
const canEditSynthetics = useCanEditSynthetics(); | ||
const canUpdatePrivateMonitor = useCanUpdatePrivateMonitor(monitor as EncryptedSyntheticsMonitor); | ||
const isLinkDisabled = !canEditSynthetics || !canUpdatePrivateMonitor; | ||
const linkProps = isLinkDisabled | ||
? { disabled: true } | ||
: { href: `${basePath}/app/synthetics/edit-monitor/${monitorId}` }; | ||
|
||
return ( | ||
<NoPermissionsTooltip | ||
canEditSynthetics={canEditSynthetics} | ||
canUpdatePrivateMonitor={canUpdatePrivateMonitor} | ||
> | ||
<EuiButton fill iconType="pencil" iconSide="left" {...linkProps}> | ||
{EDIT_MONITOR} | ||
</EuiButton> | ||
</NoPermissionsTooltip> | ||
); | ||
}; | ||
|
||
const EDIT_MONITOR = i18n.translate('xpack.synthetics.monitorSummary.editMonitor', { | ||
defaultMessage: 'Edit monitor', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.