mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[ML] Hide ML embeddables from the "Add panel" flyout when ML feature isn't available (#187639)
## Summary Fixes #187007 Hides ML embeddables from the "Add panel" flyout when 1. ML feature isn't available for the user role 2. ML is hidden in a current space ### How to test 1. Create a custom role with disabled ML privilege and assign it to a user  2. Remove ML feature visibility in a current space  ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
parent
43fca860ae
commit
7997d6fe33
6 changed files with 73 additions and 5 deletions
|
@ -69,9 +69,14 @@ export class DashboardAddPanelService extends FtrService {
|
|||
await this.testSubjects.click(`visType-${visType}`);
|
||||
}
|
||||
|
||||
async verifyEmbeddableFactoryGroupExists(groupId: string) {
|
||||
async verifyEmbeddableFactoryGroupExists(groupId: string, expectExist: boolean = true) {
|
||||
this.log.debug('DashboardAddPanel.verifyEmbeddableFactoryGroupExists');
|
||||
await this.testSubjects.existOrFail(`dashboardEditorMenu-${groupId}Group`);
|
||||
const testSubject = `dashboardEditorMenu-${groupId}Group`;
|
||||
if (expectExist) {
|
||||
await this.testSubjects.existOrFail(testSubject);
|
||||
} else {
|
||||
await this.testSubjects.missingOrFail(testSubject);
|
||||
}
|
||||
}
|
||||
|
||||
async clickAddNewEmbeddableLink(type: string) {
|
||||
|
|
|
@ -41,7 +41,9 @@ export class AiopsPlugin
|
|||
{ registerChangePointChartsAttachment },
|
||||
[coreStart, pluginStart],
|
||||
]) => {
|
||||
if (license.hasAtLeast('platinum')) {
|
||||
const { canUseAiops } = coreStart.application.capabilities.ml;
|
||||
|
||||
if (license.hasAtLeast('platinum') && canUseAiops) {
|
||||
if (embeddable) {
|
||||
registerEmbeddables(embeddable, core);
|
||||
}
|
||||
|
|
|
@ -269,7 +269,7 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
|||
);
|
||||
}
|
||||
|
||||
if (fullLicense) {
|
||||
if (fullLicense && mlCapabilities.canGetMlInfo) {
|
||||
registerMlUiActions(pluginsSetup.uiActions, core);
|
||||
|
||||
if (this.enabledFeatures.ad) {
|
||||
|
|
|
@ -10,8 +10,9 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
|
|||
import { USER } from '../../../services/ml/security_common';
|
||||
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects(['common', 'error']);
|
||||
const PageObjects = getPageObjects(['common', 'error', 'dashboard']);
|
||||
const ml = getService('ml');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
const testUsers = [{ user: USER.ML_UNAUTHORIZED, discoverAvailable: true }];
|
||||
|
||||
|
@ -56,5 +57,28 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('for user with no ML access and Kibana features access', function () {
|
||||
before(async () => {
|
||||
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote');
|
||||
await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp');
|
||||
await ml.securityUI.loginAs(USER.ML_DISABLED);
|
||||
await ml.api.cleanMlIndices();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
// NOTE: Logout needs to happen before anything else to avoid flaky behavior
|
||||
await ml.securityUI.logout();
|
||||
});
|
||||
|
||||
it('should not register ML embeddables in the dashboard', async () => {
|
||||
await ml.testExecution.logTestStep(
|
||||
'should not contain ML embeddable in the Add panel list'
|
||||
);
|
||||
await PageObjects.dashboard.navigateToApp();
|
||||
await PageObjects.dashboard.clickCreateDashboardPrompt();
|
||||
await ml.dashboardEmbeddables.assertMlSectionExists(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -114,6 +114,13 @@ export function MachineLearningDashboardEmbeddablesProvider(
|
|||
});
|
||||
},
|
||||
|
||||
async assertMlSectionExists(expectExist = true) {
|
||||
await retry.tryForTime(60 * 1000, async () => {
|
||||
await dashboardAddPanel.clickEditorMenuButton();
|
||||
await dashboardAddPanel.verifyEmbeddableFactoryGroupExists('ml', expectExist);
|
||||
});
|
||||
},
|
||||
|
||||
async openAnomalyJobSelectionFlyout(
|
||||
mlEmbeddableType: 'ml_anomaly_swimlane' | 'ml_anomaly_charts' | 'ml_single_metric_viewer'
|
||||
) {
|
||||
|
|
|
@ -21,6 +21,7 @@ export enum USER {
|
|||
ML_VIEWER_SPACE1 = 'ft_ml_viewer_space1',
|
||||
ML_VIEWER_ALL_SPACES = 'ft_ml_viewer_all_spaces',
|
||||
ML_UNAUTHORIZED = 'ft_ml_unauthorized',
|
||||
ML_DISABLED = 'ft_ml_disabled',
|
||||
}
|
||||
|
||||
export function MachineLearningSecurityCommonProvider({ getService }: FtrProviderContext) {
|
||||
|
@ -133,6 +134,29 @@ export function MachineLearningSecurityCommonProvider({ getService }: FtrProvide
|
|||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [{ base: [], feature: { discover: ['read'] }, spaces: ['default'] }],
|
||||
},
|
||||
{
|
||||
name: 'ft_ml_disabled',
|
||||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
kibana: [
|
||||
{
|
||||
base: [],
|
||||
feature: {
|
||||
// FIXME: We need permission to save search in Discover to test the data viz embeddable
|
||||
// change permission back to read once tests are moved out of ML
|
||||
discover: ['all'],
|
||||
visualize: ['add'],
|
||||
dashboard: ['all'],
|
||||
actions: ['all'],
|
||||
savedObjectsManagement: ['all'],
|
||||
advancedSettings: ['all'],
|
||||
indexPatterns: ['all'],
|
||||
generalCases: ['all'],
|
||||
ml: ['none'],
|
||||
},
|
||||
spaces: ['*'],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'ft_all_space_ml_none',
|
||||
elasticsearch: { cluster: [], indices: [], run_as: [] },
|
||||
|
@ -230,6 +254,12 @@ export function MachineLearningSecurityCommonProvider({ getService }: FtrProvide
|
|||
password: 'mlu001',
|
||||
roles: ['ft_default_space_ml_none', 'ft_ml_source_readonly'],
|
||||
},
|
||||
{
|
||||
name: 'ft_ml_disabled',
|
||||
full_name: 'ML Disabled',
|
||||
password: 'mlud001',
|
||||
roles: ['ft_ml_disabled'],
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue