Skip to content

Commit

Permalink
do not show Endpoint onboarding without integration policy write priv…
Browse files Browse the repository at this point in the history
…ilege
  • Loading branch information
gergoabraham committed Nov 22, 2024
1 parent 47f9d94 commit 63ca011
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -308,6 +320,7 @@ describe('Endpoint Authz service', () => {
canReadFleetAgentPolicies: false,
canReadFleetAgents: false,
canWriteFleetAgents: false,
canWriteIntegrationPolicies: false,
canAccessEndpointActionsLogManagement: false,
canAccessEndpointManagement: false,
canCreateArtifactsByPolicy: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,19 @@ 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,

// ---------------------------------------------------------
// Endpoint & policy management
// ---------------------------------------------------------
canAccessEndpointManagement: hasEndpointManagementAccess, // TODO: is this one deprecated? it is the only place we need to check for superuser.
canCreateArtifactsByPolicy: isPlatinumPlusLicense,
canWriteEndpointList,
Expand Down Expand Up @@ -167,6 +176,7 @@ export const getEndpointAuthzInitialState = (): EndpointAuthz => {
canReadFleetAgentPolicies: false,
canReadFleetAgents: false,
canWriteFleetAgents: false,
canWriteIntegrationPolicies: false,
canAccessEndpointActionsLogManagement: false,
canAccessEndpointManagement: false,
canCreateArtifactsByPolicy: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div data-test-subj="emptyPolicyTable">
Expand Down Expand Up @@ -134,7 +138,7 @@ const PolicyEmptyState = React.memo<{

{authzLoading && <EuiSkeletonText lines={1} />}

{!authzLoading && canAccessFleet && (
{!authzLoading && canAccessFleet && canWriteIntegrationPolicies && (
<>
<EuiSpacer size="s" />
<EuiFlexGroup>
Expand All @@ -156,7 +160,9 @@ const PolicyEmptyState = React.memo<{
</>
)}

{!authzLoading && !canAccessFleet && <MissingFleetAccessInfo />}
{!authzLoading && !(canAccessFleet && canWriteIntegrationPolicies) && (
<MissingFleetAccessInfo />
)}
</EuiFlexItem>

<EuiFlexItem grow={2}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ describe('When on the policy list page', () => {

beforeEach(() => {
useUserPrivilegesMock.mockReturnValue({
endpointPrivileges: { canReadEndpointList: true, canAccessFleet: true, loading: false },
endpointPrivileges: {
canReadEndpointList: true,
canAccessFleet: true,
canWriteIntegrationPolicies: true,
loading: false,
},
});

mockedContext = createAppRootMockRenderer();
Expand Down Expand Up @@ -75,28 +80,61 @@ describe('When on the policy list page', () => {
count: 0,
})
);
render();
await waitFor(() => {
expect(getPackagePolicies).toHaveBeenCalled();
});
});

afterEach(() => {
getPackagePolicies.mockReset();
});
it('should show the empty page', async () => {
await waitFor(() => {
expect(renderResult.getByTestId('emptyPolicyTable')).toBeTruthy();
});
});
it('should show instruction text and a button to add the Endpoint Security integration', async () => {

it('should show the empty page with onboarding instructions', async () => {
render();

await waitFor(() => {
expect(renderResult.getByTestId('emptyPolicyTable')).toBeInTheDocument();
expect(renderResult.getByTestId('policyOnboardingInstructions')).toBeInTheDocument();
expect(
renderResult.getByText(
'From this page, you can view and manage the Elastic Defend integration policies in your environment running Elastic Defend.'
)
).toBeTruthy();
).toBeInTheDocument();
});
});

expect(renderResult.getByTestId('onboardingStartButton')).toBeTruthy();
it('should show onboarding button with fleet access and integrations write privilege', async () => {
useUserPrivilegesMock.mockReturnValue({
endpointPrivileges: { canAccessFleet: true, canWriteIntegrationPolicies: true },
});
render();

await waitFor(() => {
expect(renderResult.getByTestId('policyOnboardingInstructions')).toBeInTheDocument();
expect(renderResult.getByTestId('onboardingStartButton')).toBeInTheDocument();
});
});

it('should not show onboarding button with integrations write privilege but without fleet access', async () => {
useUserPrivilegesMock.mockReturnValue({
endpointPrivileges: { canAccessFleet: false, canWriteIntegrationPolicies: true },
});

render();

await waitFor(() => {
expect(renderResult.getByTestId('policyOnboardingInstructions')).toBeInTheDocument();
expect(renderResult.queryByTestId('onboardingStartButton')).not.toBeInTheDocument();
});
});

it('should not show onboarding button with fleet access but without integrations write privilege', async () => {
useUserPrivilegesMock.mockReturnValue({
endpointPrivileges: { canAccessFleet: true, canWriteIntegrationPolicies: false },
});

render();

await waitFor(() => {
expect(renderResult.getByTestId('policyOnboardingInstructions')).toBeInTheDocument();
expect(renderResult.queryByTestId('onboardingStartButton')).not.toBeInTheDocument();
});
});
});
Expand Down

0 comments on commit 63ca011

Please sign in to comment.