Skip to content

Commit

Permalink
[8.15] [ML] Hide ML embeddables from the Add panel flyout when ML fea…
Browse files Browse the repository at this point in the history
…ture isn't available (#187639) (#187857)

# Backport

This will backport the following commits from `main` to `8.15`:
- [[ML] Hide ML embeddables from the "Add panel" flyout when
ML feature isn't available
(#187639)](#187639)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Dima
Arnautov","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-07-09T12:21:20Z","message":"[ML]
Hide ML embeddables from the \"Add panel\" flyout when ML feature isn't
available (#187639)\n\n## Summary\r\n\r\nFixes #187007 \r\n\r\nHides ML
embeddables from the \"Add panel\" flyout when\r\n1. ML feature isn't
available for the user role \r\n2. ML is hidden in a current space
\r\n\r\n\r\n### How to test \r\n1. Create a custom role with disabled ML
privilege and assign it to
a\r\nuser\r\n\r\n![image](https://github.com/elastic/kibana/assets/5236598/07fe2865-2ebe-448f-8e31-c36581b57b28)\r\n\r\n2.
Remove ML feature visibility in a current space
\r\n\r\n![image](https://github.com/elastic/kibana/assets/5236598/dc3f19fa-cb29-424a-a04d-677518bb45fa)\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"7997d6fe33cfea1d5e0897c8b95156fe3830b30a","branchLabelMapping":{"^v8.16.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix",":ml","Team:ML","Feature:Embeddables","v8.15.0","v8.16.0"],"title":"[ML]
Hide ML embeddables from the \"Add panel\" flyout when ML feature isn't
available","number":187639,"url":"https://github.com/elastic/kibana/pull/187639","mergeCommit":{"message":"[ML]
Hide ML embeddables from the \"Add panel\" flyout when ML feature isn't
available (#187639)\n\n## Summary\r\n\r\nFixes #187007 \r\n\r\nHides ML
embeddables from the \"Add panel\" flyout when\r\n1. ML feature isn't
available for the user role \r\n2. ML is hidden in a current space
\r\n\r\n\r\n### How to test \r\n1. Create a custom role with disabled ML
privilege and assign it to
a\r\nuser\r\n\r\n![image](https://github.com/elastic/kibana/assets/5236598/07fe2865-2ebe-448f-8e31-c36581b57b28)\r\n\r\n2.
Remove ML feature visibility in a current space
\r\n\r\n![image](https://github.com/elastic/kibana/assets/5236598/dc3f19fa-cb29-424a-a04d-677518bb45fa)\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"7997d6fe33cfea1d5e0897c8b95156fe3830b30a"}},"sourceBranch":"main","suggestedTargetBranches":["8.15"],"targetPullRequestStates":[{"branch":"8.15","label":"v8.15.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/187639","number":187639,"mergeCommit":{"message":"[ML]
Hide ML embeddables from the \"Add panel\" flyout when ML feature isn't
available (#187639)\n\n## Summary\r\n\r\nFixes #187007 \r\n\r\nHides ML
embeddables from the \"Add panel\" flyout when\r\n1. ML feature isn't
available for the user role \r\n2. ML is hidden in a current space
\r\n\r\n\r\n### How to test \r\n1. Create a custom role with disabled ML
privilege and assign it to
a\r\nuser\r\n\r\n![image](https://github.com/elastic/kibana/assets/5236598/07fe2865-2ebe-448f-8e31-c36581b57b28)\r\n\r\n2.
Remove ML feature visibility in a current space
\r\n\r\n![image](https://github.com/elastic/kibana/assets/5236598/dc3f19fa-cb29-424a-a04d-677518bb45fa)\r\n\r\n###
Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"7997d6fe33cfea1d5e0897c8b95156fe3830b30a"}}]}]
BACKPORT-->

Co-authored-by: Dima Arnautov <[email protected]>
  • Loading branch information
kibanamachine and darnautov authored Jul 9, 2024
1 parent d52cf92 commit ca4b2e7
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 5 deletions.
9 changes: 7 additions & 2 deletions test/functional/services/dashboard/add_panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion x-pack/plugins/aiops/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/ml/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
26 changes: 25 additions & 1 deletion x-pack/test/functional/apps/ml/permissions/no_ml_access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }];

Expand Down Expand Up @@ -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);
});
});
});
}
7 changes: 7 additions & 0 deletions x-pack/test/functional/services/ml/dashboard_embeddables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
) {
Expand Down
30 changes: 30 additions & 0 deletions x-pack/test/functional/services/ml/security_common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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: [] },
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit ca4b2e7

Please sign in to comment.