mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Fleet] Add cypress test for subfeature privileges (#179781)
This commit is contained in:
parent
9215efb6aa
commit
8abdfb4401
12 changed files with 151 additions and 48 deletions
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 { FLEET } from '../tasks/navigation';
|
||||
import {
|
||||
deleteUsers,
|
||||
FleetAgentsReadIntegrNoneRole,
|
||||
FleetAgentsReadIntegrNoneUser,
|
||||
createUsersAndRoles,
|
||||
} from '../tasks/privileges';
|
||||
import { login, loginWithUserAndWaitForPage, logout } from '../tasks/login';
|
||||
|
||||
import {
|
||||
MISSING_PRIVILEGES,
|
||||
AGENTS_TAB,
|
||||
ADD_AGENT_BUTTON,
|
||||
ADD_FLEET_SERVER_HEADER,
|
||||
AGENT_POLICIES_TAB,
|
||||
SETTINGS_TAB,
|
||||
UNINSTALL_TOKENS_TAB,
|
||||
} from '../screens/fleet';
|
||||
|
||||
const rolesToCreate = [FleetAgentsReadIntegrNoneRole];
|
||||
const usersToCreate = [FleetAgentsReadIntegrNoneUser];
|
||||
|
||||
describe('When the user has Fleet Agents Read built-in role', () => {
|
||||
before(() => {
|
||||
createUsersAndRoles(usersToCreate, rolesToCreate);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
logout();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
deleteUsers(usersToCreate);
|
||||
});
|
||||
|
||||
describe('Fleet', () => {
|
||||
it('is accessible but user cannot perform any write actions on agent tabs', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, FleetAgentsReadIntegrNoneUser);
|
||||
cy.getBySel(AGENTS_TAB).should('exist');
|
||||
cy.getBySel(MISSING_PRIVILEGES.TITLE).should('not.exist');
|
||||
cy.getBySel(ADD_AGENT_BUTTON).should('not.exist');
|
||||
cy.getBySel(ADD_FLEET_SERVER_HEADER).should('not.exist');
|
||||
});
|
||||
|
||||
it('is accessible and user only see agents tab', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, FleetAgentsReadIntegrNoneUser);
|
||||
|
||||
cy.getBySel(AGENTS_TAB).should('exist');
|
||||
cy.getBySel(AGENT_POLICIES_TAB).should('not.exist');
|
||||
cy.getBySel(SETTINGS_TAB).should('not.exist');
|
||||
cy.getBySel(UNINSTALL_TOKENS_TAB).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -11,11 +11,7 @@ import { login, loginWithUserAndWaitForPage, logout } from '../tasks/login';
|
|||
|
||||
import { getIntegrationCard } from '../screens/integrations';
|
||||
|
||||
import {
|
||||
FLEET_SERVER_MISSING_PRIVILEGES,
|
||||
ADD_AGENT_BUTTON_TOP,
|
||||
AGENT_FLYOUT,
|
||||
} from '../screens/fleet';
|
||||
import { LANDING_PAGE_ADD_FLEET_SERVER_BUTTON } from '../screens/fleet';
|
||||
import { ADD_INTEGRATION_POLICY_BTN } from '../screens/integrations';
|
||||
import { scrollToIntegration } from '../tasks/integrations';
|
||||
|
||||
|
@ -44,18 +40,9 @@ describe('When the user has Editor built-in role', () => {
|
|||
navigateTo(FLEET);
|
||||
});
|
||||
|
||||
describe('When there are no agent policies', () => {
|
||||
it('If fleet server is not set up, Fleet shows a callout', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, BuiltInEditorUser);
|
||||
cy.getBySel(FLEET_SERVER_MISSING_PRIVILEGES.MESSAGE).should(
|
||||
'contain',
|
||||
'Fleet Server needs to be set up.'
|
||||
);
|
||||
|
||||
cy.getBySel(ADD_AGENT_BUTTON_TOP).click();
|
||||
cy.getBySel(AGENT_FLYOUT.MANAGED_TAB).click();
|
||||
cy.getBySel(FLEET_SERVER_MISSING_PRIVILEGES.PROMPT).should('exist');
|
||||
});
|
||||
it('It should not show a callout', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, BuiltInEditorUser);
|
||||
cy.getBySel(LANDING_PAGE_ADD_FLEET_SERVER_BUTTON).should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -35,12 +35,8 @@ describe('When the user has All privilege for Fleet but None for integrations',
|
|||
deleteUsersAndRoles(usersToCreate, rolesToCreate);
|
||||
});
|
||||
|
||||
it('Fleet access is blocked with a callout', () => {
|
||||
it('Fleet is accessible', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, FleetAllIntegrNoneUser);
|
||||
cy.getBySel(MISSING_PRIVILEGES.TITLE).should('have.text', 'Permission denied');
|
||||
cy.getBySel(MISSING_PRIVILEGES.MESSAGE).should(
|
||||
'contain',
|
||||
'You are not authorized to access Fleet.'
|
||||
);
|
||||
cy.getBySel(MISSING_PRIVILEGES.TITLE).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,8 +18,6 @@ import { cleanupAgentPolicies, unenrollAgent } from '../tasks/cleanup';
|
|||
import { getIntegrationCard } from '../screens/integrations';
|
||||
|
||||
import {
|
||||
FLEET_SERVER_MISSING_PRIVILEGES,
|
||||
ADD_AGENT_BUTTON_TOP,
|
||||
AGENT_POLICIES_TAB,
|
||||
AGENT_POLICY_SAVE_INTEGRATION,
|
||||
ADD_PACKAGE_POLICY_BTN,
|
||||
|
@ -68,18 +66,6 @@ describe('When the user has All privilege for Fleet but Read for integrations',
|
|||
});
|
||||
});
|
||||
|
||||
describe('When there are no agent policies', () => {
|
||||
it('If fleet server is not set up, Fleet shows a callout', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, FleetAllIntegrReadUser);
|
||||
cy.getBySel(FLEET_SERVER_MISSING_PRIVILEGES.TITLE).should('have.text', 'Permission denied');
|
||||
cy.getBySel(FLEET_SERVER_MISSING_PRIVILEGES.MESSAGE).should(
|
||||
'contain',
|
||||
'Fleet Server needs to be set up.'
|
||||
);
|
||||
cy.getBySel(ADD_AGENT_BUTTON_TOP).should('not.be.disabled');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Integrations', () => {
|
||||
it('are visible but cannot be added', () => {
|
||||
loginWithUserAndWaitForPage(INTEGRATIONS, FleetAllIntegrReadUser);
|
||||
|
|
|
@ -11,9 +11,20 @@ import { login, loginWithUserAndWaitForPage, logout } from '../tasks/login';
|
|||
|
||||
import { getIntegrationCard } from '../screens/integrations';
|
||||
|
||||
import { MISSING_PRIVILEGES } from '../screens/fleet';
|
||||
import {
|
||||
MISSING_PRIVILEGES,
|
||||
AGENTS_TAB,
|
||||
ADD_AGENT_BUTTON,
|
||||
ADD_FLEET_SERVER_HEADER,
|
||||
AGENT_POLICIES_TAB,
|
||||
ADD_AGENT_POLICY_BTN,
|
||||
SETTINGS_TAB,
|
||||
SETTINGS_OUTPUTS,
|
||||
SETTINGS_FLEET_SERVER_HOSTS,
|
||||
} from '../screens/fleet';
|
||||
import { ADD_INTEGRATION_POLICY_BTN } from '../screens/integrations';
|
||||
import { scrollToIntegration } from '../tasks/integrations';
|
||||
import { navigateToTab } from '../tasks/fleet';
|
||||
|
||||
const usersToCreate = [BuiltInViewerUser];
|
||||
|
||||
|
@ -36,13 +47,29 @@ describe('When the user has Viewer built-in role', () => {
|
|||
});
|
||||
|
||||
describe('Fleet', () => {
|
||||
it('is blocked with a callout', () => {
|
||||
it('is accessible but user cannot perform any write actions on agent tabs', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, BuiltInViewerUser);
|
||||
cy.getBySel(MISSING_PRIVILEGES.TITLE).should('have.text', 'Permission denied');
|
||||
cy.getBySel(MISSING_PRIVILEGES.MESSAGE).should(
|
||||
'contain',
|
||||
'You are not authorized to access Fleet.'
|
||||
);
|
||||
cy.getBySel(AGENTS_TAB).should('exist');
|
||||
cy.getBySel(MISSING_PRIVILEGES.TITLE).should('not.exist');
|
||||
cy.getBySel(ADD_AGENT_BUTTON).should('not.exist');
|
||||
cy.getBySel(ADD_FLEET_SERVER_HEADER).should('not.exist');
|
||||
});
|
||||
|
||||
it('is accessible but user cannot perform any write actions on agent policies tabs', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, BuiltInViewerUser);
|
||||
navigateToTab(AGENT_POLICIES_TAB);
|
||||
|
||||
// Not write actions
|
||||
cy.getBySel(ADD_AGENT_POLICY_BTN).should('not.be.enabled');
|
||||
});
|
||||
|
||||
it('is accessible but user cannot perform any write actions on settings tabs', () => {
|
||||
loginWithUserAndWaitForPage(FLEET, BuiltInViewerUser);
|
||||
navigateToTab(SETTINGS_TAB);
|
||||
|
||||
// Not write actions
|
||||
cy.getBySel(SETTINGS_OUTPUTS.ADD_BTN).should('not.exist');
|
||||
cy.getBySel(SETTINGS_FLEET_SERVER_HOSTS.ADD_BUTTON).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ export const PACKAGE_POLICY_TABLE_LINK = 'PackagePoliciesTableLink';
|
|||
export const ADD_PACKAGE_POLICY_BTN = 'addPackagePolicyButton';
|
||||
export const GENERATE_FLEET_SERVER_POLICY_BUTTON = 'generateFleetServerPolicyButton';
|
||||
export const ADD_FLEET_SERVER_HEADER = 'addFleetServerHeader';
|
||||
export const ADD_AGENT_POLICY_BTN = 'createAgentPolicyButton';
|
||||
|
||||
export const PLATFORM_TYPE_LINUX_BUTTON = 'platformTypeLinux';
|
||||
export const ADVANCED_FLEET_SERVER_ADD_HOST_BUTTON = 'fleetServerAddHostBtn';
|
||||
|
|
|
@ -133,6 +133,33 @@ export const FleetAllIntegrNoneUser: User = {
|
|||
password: 'password',
|
||||
roles: [FleetAllIntegrNoneRole.name],
|
||||
};
|
||||
export const FleetAgentsReadIntegrNoneRole: Role = {
|
||||
name: 'fleet_agents_read_int_none_role',
|
||||
privileges: {
|
||||
elasticsearch: {
|
||||
indices: [
|
||||
{
|
||||
names: ['*'],
|
||||
privileges: ['all'],
|
||||
},
|
||||
],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
feature: {
|
||||
fleetv2: ['minimal_read', 'agents_read'],
|
||||
fleet: ['none'],
|
||||
},
|
||||
spaces: ['*'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export const FleetAgentsReadIntegrNoneUser: User = {
|
||||
username: 'fleet_agents_read_int_none_role',
|
||||
password: 'password',
|
||||
roles: [FleetAgentsReadIntegrNoneRole.name],
|
||||
};
|
||||
export const FleetNoneIntegrAllRole: Role = {
|
||||
name: 'fleet_none_int_all_role',
|
||||
privileges: {
|
||||
|
|
|
@ -35,6 +35,7 @@ describe('AppRoutes', () => {
|
|||
fleet: {
|
||||
readAgents: true,
|
||||
},
|
||||
integrations: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -44,6 +45,7 @@ describe('AppRoutes', () => {
|
|||
'You are not authorized to access that page. It requires the Agents Read Kibana privilege for Fleet.',
|
||||
authz: {
|
||||
fleet: {},
|
||||
integrations: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -54,6 +56,7 @@ describe('AppRoutes', () => {
|
|||
fleet: {
|
||||
readAgentPolicies: true,
|
||||
},
|
||||
integrations: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -63,6 +66,7 @@ describe('AppRoutes', () => {
|
|||
'You are not authorized to access that page. It requires the Agent policies Read Kibana privilege for Fleet.',
|
||||
authz: {
|
||||
fleet: {},
|
||||
integrations: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -73,6 +77,7 @@ describe('AppRoutes', () => {
|
|||
fleet: {
|
||||
readSettings: true,
|
||||
},
|
||||
integrations: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -82,6 +87,7 @@ describe('AppRoutes', () => {
|
|||
'You are not authorized to access that page. It requires the Settings Read Kibana privilege for Fleet.',
|
||||
authz: {
|
||||
fleet: {},
|
||||
integrations: {},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
@ -49,7 +49,9 @@ jest.mock('../../../hooks', () => ({
|
|||
sendGetAgentStatus: jest.fn(),
|
||||
sendGetAgentPolicies: jest.fn().mockResolvedValue({ data: { items: [] } }),
|
||||
sendGetAgentTags: jest.fn().mockReturnValue({ data: { items: ['tag1', 'tag2'] } }),
|
||||
useAuthz: jest.fn().mockReturnValue({ fleet: { all: true, allAgents: true, readAgents: true } }),
|
||||
useAuthz: jest
|
||||
.fn()
|
||||
.mockReturnValue({ fleet: { all: true, allAgents: true, readAgents: true }, integrations: {} }),
|
||||
useStartServices: jest.fn().mockReturnValue({
|
||||
notifications: {
|
||||
toasts: {
|
||||
|
|
|
@ -95,6 +95,9 @@ describe('useFleetServerUnhealthy', () => {
|
|||
allAgents: true,
|
||||
readAgentPolicies: true,
|
||||
},
|
||||
integrations: {
|
||||
readIntegrationPolicies: true,
|
||||
},
|
||||
} as any);
|
||||
});
|
||||
it('should return isUnHealthy:false with an online fleet slerver', async () => {
|
||||
|
|
|
@ -70,12 +70,12 @@ export function useFleetServerUnhealthy() {
|
|||
}, [notifications.toasts]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!authz.fleet.allAgents || !authz.fleet.readAgentPolicies) {
|
||||
if (!authz.fleet.allAgents || !authz.integrations.readIntegrationPolicies) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
fetchData();
|
||||
}, [fetchData, authz.fleet.allAgents, authz.fleet.readAgentPolicies]);
|
||||
}, [fetchData, authz.fleet.allAgents, authz.integrations.readIntegrationPolicies]);
|
||||
|
||||
return {
|
||||
isLoading,
|
||||
|
|
|
@ -41,7 +41,10 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
|||
`--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`,
|
||||
|
||||
// add feature flags here
|
||||
`--xpack.fleet.enableExperimental=${JSON.stringify(['agentTamperProtectionEnabled'])}`,
|
||||
`--xpack.fleet.enableExperimental=${JSON.stringify([
|
||||
'agentTamperProtectionEnabled',
|
||||
'subfeaturePrivileges',
|
||||
])}`,
|
||||
|
||||
`--logging.loggers=${JSON.stringify([
|
||||
...getKibanaCliLoggers(xpackFunctionalTestsConfig.get('kbnTestServer.serverArgs')),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue