Skip to content

Commit

Permalink
Add real usernames to migration savedObjects
Browse files Browse the repository at this point in the history
In addition to the SOs themselves giving us observability into what
migration actions were performed, this gives us the additional info of
_who_ performed the action.
  • Loading branch information
rylnd committed Dec 14, 2020
1 parent d387f26 commit 2bb03bc
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { updateMigrationSavedObject } from './update_migration_saved_object';
* @param soClient An {@link SavedObjectsClientContract}
* @param migration the migration to be finalized {@link SignalsMigrationSO}
* @param signalsAlias the alias for signals indices
* @param username name of the user initiating the deletion
*
* @returns the migration SavedObject {@link SignalsMigrationSO}
* @throws if the migration is invalid or a client throws
Expand All @@ -29,11 +30,13 @@ export const deleteMigration = async ({
migration,
signalsAlias,
soClient,
username,
}: {
esClient: ElasticsearchClient;
migration: SignalsMigrationSO;
signalsAlias: string;
soClient: SavedObjectsClientContract;
username: string;
}): Promise<SignalsMigrationSO> => {
if (isMigrationPending(migration) || isMigrationDeleted(migration)) {
return migration;
Expand All @@ -59,7 +62,7 @@ export const deleteMigration = async ({
}

const deletedMigration = await updateMigrationSavedObject({
username: 'TODO',
username,
soClient,
id: migration.id,
attributes: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { updateMigrationSavedObject } from './update_migration_saved_object';
* @param soClient An {@link SavedObjectsClientContract}
* @param migration the migration to be finalized {@link SignalsMigrationSO}
* @param signalsAlias the alias for signals indices
* @param username name of the user initiating the finalization
*
* @returns the migration SavedObject {@link SignalsMigrationSO}
* @throws if the migration is invalid or a client throws
Expand All @@ -32,11 +33,13 @@ export const finalizeMigration = async ({
migration,
signalsAlias,
soClient,
username,
}: {
esClient: ElasticsearchClient;
migration: SignalsMigrationSO;
signalsAlias: string;
soClient: SavedObjectsClientContract;
username: string;
}): Promise<SignalsMigrationSO> => {
if (isMigrationDeleted(migration) || !isMigrationPending(migration)) {
return migration;
Expand All @@ -53,7 +56,7 @@ export const finalizeMigration = async ({
const destinationCount = await getIndexCount({ esClient, index: destinationIndex });
if (sourceCount !== destinationCount) {
const updatedMigration = await updateMigrationSavedObject({
username: 'TODO',
username,
soClient,
id: migration.id,
attributes: {
Expand Down Expand Up @@ -85,7 +88,7 @@ export const finalizeMigration = async ({
await esClient.delete({ index: '.tasks', id: taskId });

const updatedMigration = await updateMigrationSavedObject({
username: 'TODO',
username,
soClient,
id: migration.id,
attributes: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export interface SignalsMigrationService {
export const signalsMigrationService = ({
esClient,
soClient,
username = 'system',
username,
}: {
esClient: ElasticsearchClient;
soClient: SavedObjectsClientContract;
Expand All @@ -64,13 +64,15 @@ export const signalsMigrationService = ({
migration,
signalsAlias,
soClient,
username,
}),
delete: ({ migration, signalsAlias }) =>
deleteMigration({
esClient,
migration,
signalsAlias,
soClient,
username,
}),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { requestMock, serverMock } from '../__mocks__';
import { SetupPlugins } from '../../../../plugin';
import { SignalsReindexOptions } from '../../../../../common/detection_engine/schemas/request/create_signals_migration_schema';
import { DETECTION_ENGINE_SIGNALS_MIGRATION_URL } from '../../../../../common/constants';
import { getCreateSignalsMigrationSchemaMock } from '../../../../../common/detection_engine/schemas/request/create_signals_migration_schema.mock';
Expand Down Expand Up @@ -35,7 +36,13 @@ describe('creating signals migrations route', () => {
(getIndexVersionsByIndex as jest.Mock).mockResolvedValue({ 'my-signals-index': -1 });
(getSignalVersionsByIndex as jest.Mock).mockResolvedValue({ 'my-signals-index': [] });

createSignalsMigrationRoute(server.router);
const securityMock = ({
authc: {
getCurrentUser: jest.fn().mockReturnValue({ user: { username: 'my-username' } }),
},
} as unknown) as SetupPlugins['security'];

createSignalsMigrationRoute(server.router, securityMock);
});

it('passes options to the createMigration', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { IRouter } from 'src/core/server';
import { SetupPlugins } from '../../../../plugin';
import { DETECTION_ENGINE_SIGNALS_MIGRATION_URL } from '../../../../../common/constants';
import { createSignalsMigrationSchema } from '../../../../../common/detection_engine/schemas/request/create_signals_migration_schema';
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
Expand All @@ -18,7 +19,10 @@ import { getIndexVersionsByIndex } from '../../migrations/get_index_versions_by_
import { getSignalVersionsByIndex } from '../../migrations/get_signal_versions_by_index';
import { SIGNALS_TEMPLATE_VERSION } from '../index/get_signals_template';

export const createSignalsMigrationRoute = (router: IRouter) => {
export const createSignalsMigrationRoute = (
router: IRouter,
security: SetupPlugins['security']
) => {
router.post(
{
path: DETECTION_ENGINE_SIGNALS_MIGRATION_URL,
Expand All @@ -36,11 +40,16 @@ export const createSignalsMigrationRoute = (router: IRouter) => {
try {
const esClient = context.core.elasticsearch.client.asCurrentUser;
const soClient = context.core.savedObjects.client;
const migrationService = signalsMigrationService({ esClient, soClient, username: 'TODO' });
const appClient = context.securitySolution?.getAppClient();
if (!appClient) {
return siemResponse.error({ statusCode: 404 });
}
const user = await security?.authc.getCurrentUser(request);
const migrationService = signalsMigrationService({
esClient,
soClient,
username: user?.username ?? 'elastic',
});

const signalsAlias = appClient.getSignalsIndex();
const currentVersion = await getTemplateVersion({
Expand All @@ -50,7 +59,7 @@ export const createSignalsMigrationRoute = (router: IRouter) => {

if (isOutdated({ current: currentVersion, target: SIGNALS_TEMPLATE_VERSION })) {
throw new BadRequestError(
'Cannot migrate due to the signals template being out of date. Please visit Detections to automatically update your template, then try again.'
`Cannot migrate due to the signals template being out of date. Latest version: [${SIGNALS_TEMPLATE_VERSION}], template version: [${currentVersion}]. Please visit Detections to automatically update your template, then try again.`
);
}
const signalsIndexAliases = await getIndexAliases({ esClient, alias: signalsAlias });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { IRouter } from 'src/core/server';
import { SetupPlugins } from '../../../../plugin';
import { DETECTION_ENGINE_SIGNALS_MIGRATION_URL } from '../../../../../common/constants';
import { deleteSignalsMigrationSchema } from '../../../../../common/detection_engine/schemas/request/delete_signals_migration_schema';
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
Expand All @@ -13,7 +14,10 @@ import { BadRequestError } from '../../errors/bad_request_error';
import { signalsMigrationService } from '../../migrations/migration_service';
import { getMigrationSavedObjectsByIndex } from '../../migrations/get_migration_saved_objects_by_index';

export const deleteSignalsMigrationRoute = (router: IRouter) => {
export const deleteSignalsMigrationRoute = (
router: IRouter,
security: SetupPlugins['security']
) => {
router.delete(
{
path: DETECTION_ENGINE_SIGNALS_MIGRATION_URL,
Expand All @@ -31,12 +35,18 @@ export const deleteSignalsMigrationRoute = (router: IRouter) => {
try {
const esClient = context.core.elasticsearch.client.asCurrentUser;
const soClient = context.core.savedObjects.client;
const migrationService = signalsMigrationService({ esClient, soClient, username: 'TODO' });
const appClient = context.securitySolution?.getAppClient();
if (!appClient) {
return siemResponse.error({ statusCode: 404 });
}

const user = await security?.authc.getCurrentUser(request);
const migrationService = signalsMigrationService({
esClient,
soClient,
username: user?.username ?? 'elastic',
});

const signalsAlias = appClient.getSignalsIndex();
const migrationsByIndex = await getMigrationSavedObjectsByIndex({
index: indices,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { serverMock } from '../__mocks__';
import { SetupPlugins } from '../../../../plugin';
import { getFinalizeSignalsMigrationRequest } from '../__mocks__/request_responses';
import { getMigrationSavedObjectsByIndex } from '../../migrations/get_migration_saved_objects_by_index';
import { getSignalsMigrationSavedObjectMock } from '../../migrations/saved_objects_schema.mock';
Expand All @@ -18,7 +19,12 @@ describe('finalizing signals migrations', () => {
beforeEach(() => {
server = serverMock.create();

finalizeSignalsMigrationRoute(server.router);
const securityMock = ({
authc: {
getCurrentUser: jest.fn().mockReturnValue({ user: { username: 'my-username' } }),
},
} as unknown) as SetupPlugins['security'];
finalizeSignalsMigrationRoute(server.router, securityMock);
});

it('returns an inline error if no migration exists', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { IRouter } from 'src/core/server';
import { SetupPlugins } from '../../../../plugin';
import { DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL } from '../../../../../common/constants';
import { finalizeSignalsMigrationSchema } from '../../../../../common/detection_engine/schemas/request/finalize_signals_migration_schema';
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
Expand All @@ -14,7 +15,10 @@ import { signalsMigrationService } from '../../migrations/migration_service';
import { buildSiemResponse, transformError } from '../utils';
import { getMigrationSavedObjectsByIndex } from '../../migrations/get_migration_saved_objects_by_index';

export const finalizeSignalsMigrationRoute = (router: IRouter) => {
export const finalizeSignalsMigrationRoute = (
router: IRouter,
security: SetupPlugins['security']
) => {
router.post(
{
path: DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL,
Expand All @@ -36,7 +40,12 @@ export const finalizeSignalsMigrationRoute = (router: IRouter) => {
if (!appClient) {
return siemResponse.error({ statusCode: 404 });
}
const migrationService = signalsMigrationService({ esClient, soClient, username: 'TODO' });
const user = await security?.authc.getCurrentUser(request);
const migrationService = signalsMigrationService({
esClient,
soClient,
username: user?.username ?? 'elastic',
});
const migrationsByIndex = await getMigrationSavedObjectsByIndex({
soClient,
index: indices,
Expand Down
6 changes: 3 additions & 3 deletions x-pack/plugins/security_solution/server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ export const initRoutes = (
setSignalsStatusRoute(router);
querySignalsRoute(router);
getSignalsMigrationStatusRoute(router);
createSignalsMigrationRoute(router);
finalizeSignalsMigrationRoute(router);
deleteSignalsMigrationRoute(router);
createSignalsMigrationRoute(router, security);
finalizeSignalsMigrationRoute(router, security);
deleteSignalsMigrationRoute(router, security);

// Detection Engine index routes that have the REST endpoints of /api/detection_engine/index
// All REST index creation, policy management for spaces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export default ({ getService }: FtrProviderContext): void => {
.set('kbn-xsrf', 'true')
.auth(ROLES.t1_analyst, 'changeme')
.send({ index: [legacySignalsIndexName] })
.expect(403);
.expect(400);
});
});
};

0 comments on commit 2bb03bc

Please sign in to comment.