Skip to content

Commit

Permalink
[ML] API tests for ML's _has_privileges (#197274)
Browse files Browse the repository at this point in the history
Calls ML's `_has_privileges` endpoint with various users.
Also ensures upgrade mode status is correctly returned.
  • Loading branch information
jgowdyelastic authored Oct 23, 2024
1 parent 598706c commit fc812e3
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 0 deletions.
143 changes: 143 additions & 0 deletions x-pack/test/api_integration/apis/ml/system/has_privileges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* 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 expect from '@kbn/expect';

import { MlHasPrivilegesResponse } from '@kbn/ml-plugin/public/application/services/ml_api_service';
import { FtrProviderContext } from '../../../ftr_provider_context';
import { getCommonRequestHeader } from '../../../../functional/services/ml/common_api';
import { USER } from '../../../../functional/services/ml/security_common';

export default ({ getService }: FtrProviderContext) => {
const esArchiver = getService('esArchiver');
const supertest = getService('supertestWithoutAuth');
const ml = getService('ml');

async function runRequest(
user: USER,
index: any,
expectedStatusCode = 200
): Promise<MlHasPrivilegesResponse> {
const { body, status } = await supertest
.post(`/internal/ml/_has_privileges`)
.auth(user, ml.securityCommon.getPasswordForUser(user))
.set(getCommonRequestHeader('1'))
.send({ index });
ml.api.assertResponseStatusCode(expectedStatusCode, status, body);

return body;
}

const testData = [
{
user: USER.ML_POWERUSER,
index: [
{
names: ['ft_farequote_small'],
privileges: ['read'],
},
{
names: ['ft_farequote_small'],
privileges: ['write'],
},
],
expectedResponse: {
hasPrivileges: {
username: 'ft_ml_poweruser',
has_all_requested: false,
cluster: {},
index: {
ft_farequote_small: {
read: true,
write: false,
},
},
application: {},
},
upgradeInProgress: false,
},
expectedStatusCode: 200,
},
{
user: USER.ML_VIEWER,
index: [
{
names: ['ft_farequote_small'],
privileges: ['read'],
},
{
names: ['ft_farequote_small'],
privileges: ['write'],
},
],
expectedResponse: {
hasPrivileges: {
username: 'ft_ml_viewer',
has_all_requested: false,
cluster: {},
index: {
ft_farequote_small: {
read: true,
write: false,
},
},
application: {},
},
upgradeInProgress: false,
},

expectedStatusCode: 200,
},
{
user: USER.ML_UNAUTHORIZED,
index: [
{
names: ['ft_farequote_small'],
privileges: ['read'],
},
{
names: ['ft_farequote_small'],
privileges: ['write'],
},
],
expectedResponse: { statusCode: 403, error: 'Forbidden', message: 'Forbidden' },
expectedStatusCode: 403,
},
];

describe("ML's _has_privileges", () => {
before(async () => {
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote_small');
});
after(async () => {
await ml.api.setUpgradeMode(false);
});

it('should return correct privileges for test data', async () => {
for (const { user, index, expectedResponse, expectedStatusCode } of testData) {
const response = await runRequest(user, index, expectedStatusCode);
expect(response).to.eql(
expectedResponse,
`expected ${JSON.stringify(expectedResponse)}, got ${JSON.stringify(response)}`
);
}
});

it('should return correct upgrade in progress', async () => {
const index = testData[0].index;
const expectedResponse = { ...testData[0].expectedResponse, upgradeInProgress: true };
await ml.api.setUpgradeMode(true);
await ml.api.assertUpgradeMode(true);

const response = await runRequest(USER.ML_POWERUSER, index);
expect(response).to.eql(
expectedResponse,
`expected ${JSON.stringify(expectedResponse)}, got ${JSON.stringify(response)}`
);
});
});
};
1 change: 1 addition & 0 deletions x-pack/test/api_integration/apis/ml/system/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./index_exists'));
loadTestFile(require.resolve('./info'));
loadTestFile(require.resolve('./node_count'));
loadTestFile(require.resolve('./has_privileges'));
});
}
28 changes: 28 additions & 0 deletions x-pack/test/functional/services/ml/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1696,5 +1696,33 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) {
this.assertResponseStatusCode(200, status, module);
return module;
},

async setUpgradeMode(enabled: boolean) {
log.debug(`Setting upgrade mode to "${enabled}"`);
const { body, status } = await esSupertest.post(`/_ml/set_upgrade_mode?enabled=${enabled}`);
this.assertResponseStatusCode(200, status, body);

log.debug(`Upgrade mode set to "${enabled}"`);
},

async assertUpgradeMode(expectedMode: boolean) {
log.debug(`Asserting upgrade mode is "${expectedMode}"`);
const { body, status } = await esSupertest.get('/_ml/info');
this.assertResponseStatusCode(200, status, body);

expect(body.upgrade_mode).to.eql(
expectedMode,
`Expected upgrade mode to be ${expectedMode}, got ${body.upgrade_mode}`
);
},

async getMlInfo() {
log.debug(`Getting ML info`);
const { body, status } = await kbnSupertest
.get(`/internal/ml/info`)
.set(getCommonRequestHeader('1'));
this.assertResponseStatusCode(200, status, body);
return body;
},
};
}

0 comments on commit fc812e3

Please sign in to comment.