From 7468e6cf0231e907b6a308cdad951e0296b7165d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20=C3=81brah=C3=A1m?= Date: Thu, 21 Nov 2024 17:11:11 +0100 Subject: [PATCH] wip --- .../endpoint/service/authz/authz.test.ts | 75 +++++++++++-------- .../common/endpoint/service/authz/authz.ts | 16 +++- .../common/endpoint/types/authz.ts | 2 + .../components/management_empty_state.tsx | 12 ++- .../management/cypress/cypress_base.config.ts | 4 +- .../pages/endpoint_hosts/view/index.test.tsx | 2 +- 6 files changed, 71 insertions(+), 40 deletions(-) diff --git a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts index 52adbc464ce43..3c9e991e54efe 100644 --- a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts @@ -96,48 +96,60 @@ describe('Endpoint Authz service', () => { ); }); - it('should not give canAccessFleet if `fleet.all` is false', () => { - fleetAuthz.fleet.all = false; - expect(calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canAccessFleet).toBe( - false - ); - }); + describe('Fleet', () => { + [true, false].forEach((value) => { + it(`should set canAccessFleet to ${value} if \`fleet.all\` is ${value}`, () => { + fleetAuthz.fleet.all = value; + expect(calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canAccessFleet).toBe( + value + ); + }); - it('should not give canReadFleetAgents if `fleet.readAgents` is false', () => { - fleetAuthz.fleet.readAgents = false; - expect(calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canReadFleetAgents).toBe( - false - ); - }); + it(`should set canReadFleetAgents to ${value} if \`fleet.readAgents\` is ${value}`, () => { + fleetAuthz.fleet.readAgents = value; + expect( + calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canReadFleetAgents + ).toBe(value); + }); - it('should not give canWriteFleetAgents if `fleet.allAgents` is false', () => { - fleetAuthz.fleet.allAgents = false; - expect( - calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canWriteFleetAgents - ).toBe(false); - }); + it(`should set canWriteFleetAgents to ${value} if \`fleet.allAgents\` is ${value}`, () => { + fleetAuthz.fleet.allAgents = value; + expect( + calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canWriteFleetAgents + ).toBe(value); + }); - it('should not give canReadFleetAgentPolicies if `fleet.readAgentPolicies` is false', () => { - fleetAuthz.fleet.readAgentPolicies = false; - expect( - calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canReadFleetAgentPolicies - ).toBe(false); + it(`should set canReadFleetAgentPolicies to ${value} if \`fleet.readAgentPolicies\` is ${value}`, () => { + fleetAuthz.fleet.readAgentPolicies = value; + expect( + calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canReadFleetAgentPolicies + ).toBe(value); + }); + + it(`should set canAccessFleet to ${value} if \`fleet.all\` is ${value}`, () => { + fleetAuthz.fleet.all = value; + expect(calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canAccessFleet).toBe( + value + ); + }); + + it(`should set canWriteIntegrationPolicies to ${value} if \`integrations.writeIntegrationPolicies\` is ${value}`, () => { + fleetAuthz.integrations.writeIntegrationPolicies = value; + expect( + calculateEndpointAuthz(licenseService, fleetAuthz, userRoles) + .canWriteIntegrationPolicies + ).toBe(value); + }); + }); }); - it('should not give canAccessEndpointManagement if not superuser', () => { + it('should set canAccessEndpointManagement if not superuser', () => { userRoles = []; expect( calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canAccessEndpointManagement ).toBe(false); }); - it('should give canAccessFleet if `fleet.all` is true', () => { - fleetAuthz.fleet.all = true; - expect(calculateEndpointAuthz(licenseService, fleetAuthz, userRoles).canAccessFleet).toBe( - true - ); - }); - it('should give canAccessEndpointManagement if superuser', () => { userRoles = ['superuser']; expect( @@ -308,6 +320,7 @@ describe('Endpoint Authz service', () => { canReadFleetAgentPolicies: false, canReadFleetAgents: false, canWriteFleetAgents: false, + canWriteIntegrationPolicies: false, canAccessEndpointActionsLogManagement: false, canAccessEndpointManagement: false, canCreateArtifactsByPolicy: false, diff --git a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts index 574e7bd6106ef..4c599e58af8b3 100644 --- a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts +++ b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts @@ -100,10 +100,16 @@ export const calculateEndpointAuthz = ( const authz: EndpointAuthz = { canWriteSecuritySolution, canReadSecuritySolution, + + // --------------------------------------------------------- + // Coming from Fleet authz + // --------------------------------------------------------- canAccessFleet: fleetAuthz?.fleet.all ?? false, canReadFleetAgentPolicies: fleetAuthz?.fleet.readAgentPolicies ?? false, canWriteFleetAgents: fleetAuthz?.fleet.allAgents ?? false, canReadFleetAgents: fleetAuthz?.fleet.readAgents ?? false, + canWriteIntegrationPolicies: fleetAuthz?.integrations.writeIntegrationPolicies ?? false, + canAccessEndpointManagement: hasEndpointManagementAccess, // TODO: is this one deprecated? it is the only place we need to check for superuser. canCreateArtifactsByPolicy: isPlatinumPlusLicense, canWriteEndpointList, @@ -167,6 +173,7 @@ export const getEndpointAuthzInitialState = (): EndpointAuthz => { canReadFleetAgentPolicies: false, canReadFleetAgents: false, canWriteFleetAgents: false, + canWriteIntegrationPolicies: false, canAccessEndpointActionsLogManagement: false, canAccessEndpointManagement: false, canCreateArtifactsByPolicy: false, @@ -209,13 +216,14 @@ export const getEndpointAuthzInitialState = (): EndpointAuthz => { * @param capabilities Capabilities from coreStart.application */ export const canFetchAgentPolicies = (capabilities: Capabilities): boolean => { - const canReadPolicyManagement = capabilities.siem.readPolicyManagement as boolean; + const canReadPolicyManagement = (capabilities.siem?.readPolicyManagement ?? false) as boolean; const fleetv2 = capabilities.fleetv2; - const canReadFleetAgentPolicies = (fleetv2.read && - (fleetv2.agent_policies_read === true || fleetv2.agent_policies_read === undefined)) as boolean; + const canReadFleetAgentPolicies = (fleetv2?.read && + (fleetv2?.agent_policies_read === true || + fleetv2?.agent_policies_read === undefined)) as boolean; - const canReadIntegrations = capabilities.fleet.read as boolean; + const canReadIntegrations = capabilities.fleet?.read as boolean; return canReadPolicyManagement || (canReadFleetAgentPolicies && canReadIntegrations); }; diff --git a/x-pack/plugins/security_solution/common/endpoint/types/authz.ts b/x-pack/plugins/security_solution/common/endpoint/types/authz.ts index 6a326479ce8ae..fd0cfb470682b 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/authz.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/authz.ts @@ -22,6 +22,8 @@ export interface EndpointAuthz { canReadFleetAgents: boolean; /** If the user has permissions to write Fleet Agents */ canWriteFleetAgents: boolean; + /** If the user has permissions to write Integration policies */ + canWriteIntegrationPolicies: boolean; /** If the user has permissions to access Endpoint management (includes check to ensure they also have access to fleet) */ canAccessEndpointManagement: boolean; /** If the user has permissions to access Actions Log management and also has a platinum license (used for endpoint details flyout) */ diff --git a/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx b/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx index 2408dad4f39f3..7a1bdfa864c34 100644 --- a/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx +++ b/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx @@ -74,7 +74,11 @@ const PolicyEmptyState = React.memo<{ policyEntryPoint?: boolean; }>(({ loading, onActionClick, actionDisabled, policyEntryPoint = false }) => { const docLinks = useKibana().services.docLinks; - const { canAccessFleet, loading: authzLoading } = useUserPrivileges().endpointPrivileges; + const { + canAccessFleet, + canWriteIntegrationPolicies, + loading: authzLoading, + } = useUserPrivileges().endpointPrivileges; return (
@@ -134,7 +138,7 @@ const PolicyEmptyState = React.memo<{ {authzLoading && } - {!authzLoading && canAccessFleet && ( + {!authzLoading && canAccessFleet && canWriteIntegrationPolicies && ( <> @@ -156,7 +160,9 @@ const PolicyEmptyState = React.memo<{ )} - {!authzLoading && !canAccessFleet && } + {!authzLoading && !(canAccessFleet && canWriteIntegrationPolicies) && ( + + )} diff --git a/x-pack/plugins/security_solution/public/management/cypress/cypress_base.config.ts b/x-pack/plugins/security_solution/public/management/cypress/cypress_base.config.ts index c8aa2b347b82b..10d4d4dc047cf 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/cypress_base.config.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/cypress_base.config.ts @@ -77,7 +77,9 @@ export const getCypressBaseConfig = ( // baseUrl: To override, set Env. variable `CYPRESS_BASE_URL` baseUrl: 'http://localhost:5601', supportFile: 'public/management/cypress/support/e2e.ts', - specPattern: 'public/management/cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', + // x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint_list/endpoints_rbac_mocked_data.cy.ts + specPattern: + 'public/management/cypress/e2e/endpoint_list/endpoints_rbac_mocked_data.cy.{js,jsx,ts,tsx}', experimentalRunAllSpecs: true, experimentalMemoryManagement: true, experimentalInteractiveRunEvents: true, diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index d0b05404dc16d..f98dc86c13de4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -1462,7 +1462,7 @@ describe('when on the endpoint list page', () => { const onboardingSteps = await renderResult.findByTestId('onboardingSteps'); expect(onboardingSteps).toBeInTheDocument(); }); - it('user has endpoint list ALL/READ and fleet NONE and can view a modified onboarding screen with no actions link to fleet', async () => { + it.only('user has endpoint list ALL/READ and fleet NONE and can view a modified onboarding screen with no actions link to fleet', async () => { mockUserPrivileges.mockReturnValue({ ...initialUserPrivilegesState(), endpointPrivileges: getEndpointPrivilegesInitialStateMock({