mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Cases] Adding files configuration fields (#154013)
Fixes: https://github.com/elastic/kibana/issues/151935 This PR allows the mime types and max file size for the files functionality within cases to be configured through the kibana.yml. We set the defaults maxSize to be 100 mb and if it is not set by the user we also restrict images to be 10 mb. If the `maxSize` is set by the user we use it for all mime types including images (or whatever the user has specified in `allowedMimeTypes`). The file service changes are just mocks to help with testing some of the configuration options. New fields ``` { files: { allowedMimeTypes: string[] maxSize: positive number (minimum 0) <-- exposed to the browser } } ``` ## Release Notes Cases added two configuration options to allow users to control which files mime types are allowed to be attached to cases and the approved max size of a file being upload. `xpack.cases.files.allowedMimeTypes` - An array of strings representing the allowed mime types to be attached to a case. `xpack.cases.files.maxSize` - A number representing the file size limit for files being attached to a case (in bytes).
This commit is contained in:
parent
210a7eb335
commit
234d48d9bc
18 changed files with 1065 additions and 36 deletions
|
@ -8,10 +8,25 @@
|
|||
|
||||
import { createMockFilesClient as createBaseMocksFilesClient } from '@kbn/shared-ux-file-mocks';
|
||||
import type { DeeplyMockedKeys } from '@kbn/utility-types-jest';
|
||||
import type { FilesClient } from './types';
|
||||
import { FilesSetup } from '.';
|
||||
import type { FilesClient, FilesClientFactory } from './types';
|
||||
|
||||
export const createMockFilesClient = (): DeeplyMockedKeys<FilesClient> => ({
|
||||
...createBaseMocksFilesClient(),
|
||||
getMetrics: jest.fn(),
|
||||
publicDownload: jest.fn(),
|
||||
});
|
||||
|
||||
export const createMockFilesSetup = (): DeeplyMockedKeys<FilesSetup> => {
|
||||
return {
|
||||
filesClientFactory: createMockFilesClientFactory(),
|
||||
registerFileKind: jest.fn(),
|
||||
};
|
||||
};
|
||||
|
||||
export const createMockFilesClientFactory = (): DeeplyMockedKeys<FilesClientFactory> => {
|
||||
return {
|
||||
asScoped: jest.fn(),
|
||||
asUnscoped: jest.fn(),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ import { KibanaRequest } from '@kbn/core/server';
|
|||
import { DeeplyMockedKeys } from '@kbn/utility-types-jest';
|
||||
import * as stream from 'stream';
|
||||
import { File } from '../common';
|
||||
import { FileClient, FileServiceFactory, FileServiceStart } from '.';
|
||||
import { FileClient, FileServiceFactory, FileServiceStart, FilesSetup } from '.';
|
||||
|
||||
export const createFileServiceMock = (): DeeplyMockedKeys<FileServiceStart> => ({
|
||||
create: jest.fn(),
|
||||
|
@ -78,3 +78,9 @@ export const createFileClientMock = (): DeeplyMockedKeys<FileClient> => {
|
|||
listShares: jest.fn().mockResolvedValue({ shares: [] }),
|
||||
};
|
||||
};
|
||||
|
||||
export const createFilesSetupMock = (): DeeplyMockedKeys<FilesSetup> => {
|
||||
return {
|
||||
registerFileKind: jest.fn(),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -165,6 +165,8 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.apm.serviceMapEnabled (boolean)',
|
||||
'xpack.apm.ui.enabled (boolean)',
|
||||
'xpack.apm.ui.maxTraceItems (number)',
|
||||
'xpack.cases.files.allowedMimeTypes (array)',
|
||||
'xpack.cases.files.maxSize (number)',
|
||||
'xpack.cases.markdownPlugins.lens (boolean)',
|
||||
'xpack.ccr.ui.enabled (boolean)',
|
||||
'xpack.cloud.base_url (string)',
|
||||
|
|
|
@ -6,5 +6,6 @@
|
|||
*/
|
||||
|
||||
export const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 MiB
|
||||
export const MAX_IMAGE_FILE_SIZE = 10 * 1024 * 1024; // 10 MiB
|
||||
export const MAX_FILES_PER_CASE = 100;
|
||||
export const MAX_DELETE_FILES = 50;
|
||||
|
|
|
@ -15,7 +15,7 @@ export const SECURITY_SOLUTION_OWNER = 'securitySolution' as const;
|
|||
export const OBSERVABILITY_OWNER = 'observability' as const;
|
||||
export const GENERAL_CASES_OWNER = APP_ID;
|
||||
|
||||
export const OWNERS = [SECURITY_SOLUTION_OWNER, OBSERVABILITY_OWNER, GENERAL_CASES_OWNER] as const;
|
||||
export const OWNERS = [GENERAL_CASES_OWNER, OBSERVABILITY_OWNER, SECURITY_SOLUTION_OWNER] as const;
|
||||
|
||||
interface RouteInfo {
|
||||
id: Owner;
|
||||
|
|
|
@ -52,6 +52,10 @@ export interface CasesUiConfigType {
|
|||
markdownPlugins: {
|
||||
lens: boolean;
|
||||
};
|
||||
files: {
|
||||
maxSize?: number;
|
||||
allowedMimeTypes: string[];
|
||||
};
|
||||
}
|
||||
|
||||
export const StatusAll = 'all' as const;
|
||||
|
|
|
@ -19,7 +19,10 @@ export class KibanaServices {
|
|||
http,
|
||||
kibanaVersion,
|
||||
config,
|
||||
}: GlobalServices & { kibanaVersion: string; config: CasesUiConfigType }) {
|
||||
}: GlobalServices & {
|
||||
kibanaVersion: string;
|
||||
config: CasesUiConfigType;
|
||||
}) {
|
||||
this.services = { http };
|
||||
this.kibanaVersion = kibanaVersion;
|
||||
this.config = config;
|
||||
|
|
98
x-pack/plugins/cases/public/files/index.test.ts
Normal file
98
x-pack/plugins/cases/public/files/index.test.ts
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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 { MAX_FILE_SIZE } from '../../common/constants';
|
||||
import { createMockFilesSetup } from '@kbn/files-plugin/public/mocks';
|
||||
import { registerCaseFileKinds } from '.';
|
||||
import type { FilesConfig } from './types';
|
||||
|
||||
describe('ui files index', () => {
|
||||
describe('registerCaseFileKinds', () => {
|
||||
const mockFilesSetup = createMockFilesSetup();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('allowedMimeTypes', () => {
|
||||
const config: FilesConfig = {
|
||||
allowedMimeTypes: ['abc'],
|
||||
maxSize: undefined,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
registerCaseFileKinds(config, mockFilesSetup);
|
||||
});
|
||||
|
||||
it('sets cases allowed mime types to abc', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[0][0].allowedMimeTypes).toEqual(['abc']);
|
||||
});
|
||||
|
||||
it('sets observability allowed mime types to abc', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[1][0].allowedMimeTypes).toEqual(['abc']);
|
||||
});
|
||||
|
||||
it('sets securitySolution allowed mime types to 100 mb', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[2][0].allowedMimeTypes).toEqual(['abc']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('max file size', () => {
|
||||
describe('default max file size', () => {
|
||||
const config: FilesConfig = {
|
||||
allowedMimeTypes: [],
|
||||
maxSize: undefined,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
registerCaseFileKinds(config, mockFilesSetup);
|
||||
});
|
||||
|
||||
it('sets cases max file size to 100 mb', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[0][0].maxSizeBytes).toEqual(
|
||||
MAX_FILE_SIZE
|
||||
);
|
||||
});
|
||||
|
||||
it('sets observability max file size to 100 mb', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[1][0].maxSizeBytes).toEqual(
|
||||
MAX_FILE_SIZE
|
||||
);
|
||||
});
|
||||
|
||||
it('sets securitySolution max file size to 100 mb', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[2][0].maxSizeBytes).toEqual(
|
||||
MAX_FILE_SIZE
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('custom file size', () => {
|
||||
const config: FilesConfig = {
|
||||
allowedMimeTypes: [],
|
||||
maxSize: 5,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
registerCaseFileKinds(config, mockFilesSetup);
|
||||
});
|
||||
|
||||
it('sets cases max file size to 5', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[0][0].maxSizeBytes).toEqual(5);
|
||||
});
|
||||
|
||||
it('sets observability max file size to 5', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[1][0].maxSizeBytes).toEqual(5);
|
||||
});
|
||||
|
||||
it('sets securitySolution max file size to 5', () => {
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[2][0].maxSizeBytes).toEqual(5);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -7,31 +7,36 @@
|
|||
|
||||
import type { FilesSetup } from '@kbn/files-plugin/public';
|
||||
import type { FileKindBrowser } from '@kbn/shared-ux-file-types';
|
||||
import { ALLOWED_MIME_TYPES } from '../../common/constants/mime_types';
|
||||
import { MAX_FILE_SIZE } from '../../common/constants';
|
||||
import { MAX_FILE_SIZE, OWNERS } from '../../common/constants';
|
||||
import type { Owner } from '../../common/constants/types';
|
||||
import { APP_ID, OBSERVABILITY_OWNER, SECURITY_SOLUTION_OWNER } from '../../common';
|
||||
import { constructFileKindIdByOwner } from '../../common/files';
|
||||
import type { CaseFileKinds, FilesConfig } from './types';
|
||||
|
||||
const buildFileKind = (owner: Owner): FileKindBrowser => {
|
||||
const buildFileKind = (config: FilesConfig, owner: Owner): FileKindBrowser => {
|
||||
return {
|
||||
id: constructFileKindIdByOwner(owner),
|
||||
allowedMimeTypes: ALLOWED_MIME_TYPES,
|
||||
maxSizeBytes: MAX_FILE_SIZE,
|
||||
allowedMimeTypes: config.allowedMimeTypes,
|
||||
maxSizeBytes: config.maxSize ?? MAX_FILE_SIZE,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* The file kind definition for interacting with the file service for the UI
|
||||
*/
|
||||
const CASES_FILE_KINDS: Record<Owner, FileKindBrowser> = {
|
||||
[APP_ID]: buildFileKind(APP_ID),
|
||||
[SECURITY_SOLUTION_OWNER]: buildFileKind(SECURITY_SOLUTION_OWNER),
|
||||
[OBSERVABILITY_OWNER]: buildFileKind(OBSERVABILITY_OWNER),
|
||||
const createFileKinds = (config: FilesConfig): CaseFileKinds => {
|
||||
const caseFileKinds = new Map<Owner, FileKindBrowser>();
|
||||
|
||||
for (const owner of OWNERS) {
|
||||
caseFileKinds.set(owner, buildFileKind(config, owner));
|
||||
}
|
||||
|
||||
return caseFileKinds;
|
||||
};
|
||||
|
||||
export const registerCaseFileKinds = (filesSetupPlugin: FilesSetup) => {
|
||||
for (const fileKind of Object.values(CASES_FILE_KINDS)) {
|
||||
export const registerCaseFileKinds = (config: FilesConfig, filesSetupPlugin: FilesSetup) => {
|
||||
const fileKinds = createFileKinds(config);
|
||||
|
||||
for (const fileKind of fileKinds.values()) {
|
||||
filesSetupPlugin.registerFileKind(fileKind);
|
||||
}
|
||||
};
|
||||
|
|
14
x-pack/plugins/cases/public/files/types.ts
Normal file
14
x-pack/plugins/cases/public/files/types.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 type { FileKindBrowser } from '@kbn/shared-ux-file-types';
|
||||
import type { Owner } from '../../common/constants/types';
|
||||
import type { CasesUiConfigType } from '../containers/types';
|
||||
|
||||
export type FilesConfig = CasesUiConfigType['files'];
|
||||
|
||||
export type CaseFileKinds = Map<Owner, FileKindBrowser>;
|
|
@ -53,7 +53,8 @@ export class CasesUiPlugin
|
|||
const externalReferenceAttachmentTypeRegistry = this.externalReferenceAttachmentTypeRegistry;
|
||||
const persistableStateAttachmentTypeRegistry = this.persistableStateAttachmentTypeRegistry;
|
||||
|
||||
registerCaseFileKinds(plugins.files);
|
||||
const config = this.initializerContext.config.get<CasesUiConfigType>();
|
||||
registerCaseFileKinds(config.files, plugins.files);
|
||||
|
||||
if (plugins.home) {
|
||||
plugins.home.featureCatalogue.register({
|
||||
|
@ -106,7 +107,13 @@ export class CasesUiPlugin
|
|||
|
||||
public start(core: CoreStart, plugins: CasesPluginStart): CasesUiStart {
|
||||
const config = this.initializerContext.config.get<CasesUiConfigType>();
|
||||
KibanaServices.init({ ...core, ...plugins, kibanaVersion: this.kibanaVersion, config });
|
||||
|
||||
KibanaServices.init({
|
||||
...core,
|
||||
...plugins,
|
||||
kibanaVersion: this.kibanaVersion,
|
||||
config,
|
||||
});
|
||||
|
||||
/**
|
||||
* getCasesContextLazy returns a new component each time is being called. To avoid re-renders
|
||||
|
|
113
x-pack/plugins/cases/server/config.test.ts
Normal file
113
x-pack/plugins/cases/server/config.test.ts
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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 { ConfigSchema } from './config';
|
||||
|
||||
describe('config validation', () => {
|
||||
describe('defaults', () => {
|
||||
it('sets the defaults correctly', () => {
|
||||
expect(ConfigSchema.validate({})).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"files": Object {
|
||||
"allowedMimeTypes": Array [
|
||||
"image/aces",
|
||||
"image/apng",
|
||||
"image/avci",
|
||||
"image/avcs",
|
||||
"image/avif",
|
||||
"image/bmp",
|
||||
"image/cgm",
|
||||
"image/dicom-rle",
|
||||
"image/dpx",
|
||||
"image/emf",
|
||||
"image/example",
|
||||
"image/fits",
|
||||
"image/g3fax",
|
||||
"image/heic",
|
||||
"image/heic-sequence",
|
||||
"image/heif",
|
||||
"image/heif-sequence",
|
||||
"image/hej2k",
|
||||
"image/hsj2",
|
||||
"image/jls",
|
||||
"image/jp2",
|
||||
"image/jpeg",
|
||||
"image/jph",
|
||||
"image/jphc",
|
||||
"image/jpm",
|
||||
"image/jpx",
|
||||
"image/jxr",
|
||||
"image/jxrA",
|
||||
"image/jxrS",
|
||||
"image/jxs",
|
||||
"image/jxsc",
|
||||
"image/jxsi",
|
||||
"image/jxss",
|
||||
"image/ktx",
|
||||
"image/ktx2",
|
||||
"image/naplps",
|
||||
"image/png",
|
||||
"image/prs.btif",
|
||||
"image/prs.pti",
|
||||
"image/pwg-raster",
|
||||
"image/svg+xml",
|
||||
"image/t38",
|
||||
"image/tiff",
|
||||
"image/tiff-fx",
|
||||
"image/vnd.adobe.photoshop",
|
||||
"image/vnd.airzip.accelerator.azv",
|
||||
"image/vnd.cns.inf2",
|
||||
"image/vnd.dece.graphic",
|
||||
"image/vnd.djvu",
|
||||
"image/vnd.dwg",
|
||||
"image/vnd.dxf",
|
||||
"image/vnd.dvb.subtitle",
|
||||
"image/vnd.fastbidsheet",
|
||||
"image/vnd.fpx",
|
||||
"image/vnd.fst",
|
||||
"image/vnd.fujixerox.edmics-mmr",
|
||||
"image/vnd.fujixerox.edmics-rlc",
|
||||
"image/vnd.globalgraphics.pgb",
|
||||
"image/vnd.microsoft.icon",
|
||||
"image/vnd.mix",
|
||||
"image/vnd.ms-modi",
|
||||
"image/vnd.mozilla.apng",
|
||||
"image/vnd.net-fpx",
|
||||
"image/vnd.pco.b16",
|
||||
"image/vnd.radiance",
|
||||
"image/vnd.sealed.png",
|
||||
"image/vnd.sealedmedia.softseal.gif",
|
||||
"image/vnd.sealedmedia.softseal.jpg",
|
||||
"image/vnd.svf",
|
||||
"image/vnd.tencent.tap",
|
||||
"image/vnd.valve.source.texture",
|
||||
"image/vnd.wap.wbmp",
|
||||
"image/vnd.xiff",
|
||||
"image/vnd.zbrush.pcx",
|
||||
"image/webp",
|
||||
"image/wmf",
|
||||
"text/plain",
|
||||
"text/csv",
|
||||
"text/json",
|
||||
"application/json",
|
||||
"application/zip",
|
||||
"application/gzip",
|
||||
"application/x-bzip",
|
||||
"application/x-bzip2",
|
||||
"application/x-7z-compressed",
|
||||
"application/x-tar",
|
||||
"application/pdf",
|
||||
],
|
||||
},
|
||||
"markdownPlugins": Object {
|
||||
"lens": true,
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -7,11 +7,19 @@
|
|||
|
||||
import type { TypeOf } from '@kbn/config-schema';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { ALLOWED_MIME_TYPES } from '../common/constants/mime_types';
|
||||
|
||||
export const ConfigSchema = schema.object({
|
||||
markdownPlugins: schema.object({
|
||||
lens: schema.boolean({ defaultValue: true }),
|
||||
}),
|
||||
files: schema.object({
|
||||
allowedMimeTypes: schema.arrayOf(schema.string({ minLength: 1 }), {
|
||||
defaultValue: ALLOWED_MIME_TYPES,
|
||||
}),
|
||||
// intentionally not setting a default here so that we can determine if the user set it
|
||||
maxSize: schema.maybe(schema.number({ min: 0 })),
|
||||
}),
|
||||
});
|
||||
|
||||
export type ConfigType = TypeOf<typeof ConfigSchema>;
|
||||
|
|
720
x-pack/plugins/cases/server/files/index.test.ts
Normal file
720
x-pack/plugins/cases/server/files/index.test.ts
Normal file
|
@ -0,0 +1,720 @@
|
|||
/*
|
||||
* 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 { MAX_FILE_SIZE, MAX_IMAGE_FILE_SIZE } from '../../common/constants';
|
||||
import { createFilesSetupMock } from '@kbn/files-plugin/server/mocks';
|
||||
import type { FileJSON } from '@kbn/shared-ux-file-types';
|
||||
import { createMaxCallback, registerCaseFileKinds } from '.';
|
||||
import { ConfigSchema } from '../config';
|
||||
|
||||
describe('server files', () => {
|
||||
describe('registerCaseFileKinds', () => {
|
||||
const mockFilesSetup = createFilesSetupMock();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('file sizes', () => {
|
||||
it('sets the max image file size to 10 mb', () => {
|
||||
const schema = ConfigSchema.validate({});
|
||||
|
||||
const maxFileSizeFn = createMaxCallback(schema.files);
|
||||
|
||||
expect(
|
||||
maxFileSizeFn({
|
||||
mimeType: 'image/png',
|
||||
} as unknown as FileJSON)
|
||||
).toEqual(MAX_IMAGE_FILE_SIZE);
|
||||
});
|
||||
|
||||
it('sets the max file size to 1 when an image is passed but the configuration was specified', () => {
|
||||
const schema = ConfigSchema.validate({
|
||||
files: {
|
||||
maxSize: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const maxFileSizeFn = createMaxCallback(schema.files);
|
||||
|
||||
expect(
|
||||
maxFileSizeFn({
|
||||
mimeType: 'image/png',
|
||||
} as unknown as FileJSON)
|
||||
).toEqual(1);
|
||||
});
|
||||
|
||||
it('sets the max non-image file size to default 100 mb', () => {
|
||||
const schema = ConfigSchema.validate({});
|
||||
|
||||
const maxFileSizeFn = createMaxCallback(schema.files);
|
||||
|
||||
expect(
|
||||
maxFileSizeFn({
|
||||
mimeType: 'text/plain',
|
||||
} as unknown as FileJSON)
|
||||
).toEqual(MAX_FILE_SIZE);
|
||||
});
|
||||
|
||||
it('returns 100 mb when images are not allowed in the mime type and an image is passed', () => {
|
||||
const schemaNoImages = ConfigSchema.validate({
|
||||
files: {
|
||||
allowedMimeTypes: ['abc/123'],
|
||||
},
|
||||
});
|
||||
|
||||
const maxFn = createMaxCallback(schemaNoImages.files);
|
||||
|
||||
expect(
|
||||
maxFn({
|
||||
mimeType: 'image/png',
|
||||
} as unknown as FileJSON)
|
||||
).toEqual(MAX_FILE_SIZE);
|
||||
});
|
||||
|
||||
it('returns 100 mb when the mime type is not recognized', () => {
|
||||
const schemaNoImages = ConfigSchema.validate({
|
||||
files: {
|
||||
allowedMimeTypes: ['abc/123'],
|
||||
},
|
||||
});
|
||||
|
||||
const maxFn = createMaxCallback(schemaNoImages.files);
|
||||
|
||||
expect(
|
||||
maxFn({
|
||||
mimeType: 'hi/bye',
|
||||
} as unknown as FileJSON)
|
||||
).toEqual(MAX_FILE_SIZE);
|
||||
});
|
||||
|
||||
it('returns 100 mb when the mime type is undefined', () => {
|
||||
const schemaNoImages = ConfigSchema.validate({
|
||||
files: {
|
||||
allowedMimeTypes: ['abc/123'],
|
||||
},
|
||||
});
|
||||
|
||||
const maxFn = createMaxCallback(schemaNoImages.files);
|
||||
|
||||
expect(
|
||||
maxFn({
|
||||
mimeType: undefined,
|
||||
} as unknown as FileJSON)
|
||||
).toEqual(MAX_FILE_SIZE);
|
||||
});
|
||||
});
|
||||
|
||||
describe('allowed mime types', () => {
|
||||
describe('image png', () => {
|
||||
const schema = ConfigSchema.validate({ files: { allowedMimeTypes: ['image/png'] } });
|
||||
|
||||
it('sets the cases file kind allowed mime types to only image png', () => {
|
||||
registerCaseFileKinds(schema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [
|
||||
"image/png",
|
||||
],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "casesFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('sets the observability file kind allowed mime types to only image png', () => {
|
||||
registerCaseFileKinds(schema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[1]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [
|
||||
"image/png",
|
||||
],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "observabilityFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('sets the security solution file kind allowed mime types to only image png', () => {
|
||||
registerCaseFileKinds(schema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[2]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [
|
||||
"image/png",
|
||||
],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "securitySolutionFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('no mime types', () => {
|
||||
const schema = ConfigSchema.validate({ files: { allowedMimeTypes: [] } });
|
||||
|
||||
it('sets the cases file kind allowed mime types to an empty array', () => {
|
||||
registerCaseFileKinds(schema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "casesFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('sets the observability file kind allowed mime types to an empty array', () => {
|
||||
registerCaseFileKinds(schema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[1]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "observabilityFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('sets the security solution file kind allowed mime types to an empty array', () => {
|
||||
registerCaseFileKinds(schema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[2]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "securitySolutionFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('defaults', () => {
|
||||
const defaultSchema = ConfigSchema.validate({});
|
||||
|
||||
it('sets the cases file kind with defaults correctly', () => {
|
||||
registerCaseFileKinds(defaultSchema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [
|
||||
"image/aces",
|
||||
"image/apng",
|
||||
"image/avci",
|
||||
"image/avcs",
|
||||
"image/avif",
|
||||
"image/bmp",
|
||||
"image/cgm",
|
||||
"image/dicom-rle",
|
||||
"image/dpx",
|
||||
"image/emf",
|
||||
"image/example",
|
||||
"image/fits",
|
||||
"image/g3fax",
|
||||
"image/heic",
|
||||
"image/heic-sequence",
|
||||
"image/heif",
|
||||
"image/heif-sequence",
|
||||
"image/hej2k",
|
||||
"image/hsj2",
|
||||
"image/jls",
|
||||
"image/jp2",
|
||||
"image/jpeg",
|
||||
"image/jph",
|
||||
"image/jphc",
|
||||
"image/jpm",
|
||||
"image/jpx",
|
||||
"image/jxr",
|
||||
"image/jxrA",
|
||||
"image/jxrS",
|
||||
"image/jxs",
|
||||
"image/jxsc",
|
||||
"image/jxsi",
|
||||
"image/jxss",
|
||||
"image/ktx",
|
||||
"image/ktx2",
|
||||
"image/naplps",
|
||||
"image/png",
|
||||
"image/prs.btif",
|
||||
"image/prs.pti",
|
||||
"image/pwg-raster",
|
||||
"image/svg+xml",
|
||||
"image/t38",
|
||||
"image/tiff",
|
||||
"image/tiff-fx",
|
||||
"image/vnd.adobe.photoshop",
|
||||
"image/vnd.airzip.accelerator.azv",
|
||||
"image/vnd.cns.inf2",
|
||||
"image/vnd.dece.graphic",
|
||||
"image/vnd.djvu",
|
||||
"image/vnd.dwg",
|
||||
"image/vnd.dxf",
|
||||
"image/vnd.dvb.subtitle",
|
||||
"image/vnd.fastbidsheet",
|
||||
"image/vnd.fpx",
|
||||
"image/vnd.fst",
|
||||
"image/vnd.fujixerox.edmics-mmr",
|
||||
"image/vnd.fujixerox.edmics-rlc",
|
||||
"image/vnd.globalgraphics.pgb",
|
||||
"image/vnd.microsoft.icon",
|
||||
"image/vnd.mix",
|
||||
"image/vnd.ms-modi",
|
||||
"image/vnd.mozilla.apng",
|
||||
"image/vnd.net-fpx",
|
||||
"image/vnd.pco.b16",
|
||||
"image/vnd.radiance",
|
||||
"image/vnd.sealed.png",
|
||||
"image/vnd.sealedmedia.softseal.gif",
|
||||
"image/vnd.sealedmedia.softseal.jpg",
|
||||
"image/vnd.svf",
|
||||
"image/vnd.tencent.tap",
|
||||
"image/vnd.valve.source.texture",
|
||||
"image/vnd.wap.wbmp",
|
||||
"image/vnd.xiff",
|
||||
"image/vnd.zbrush.pcx",
|
||||
"image/webp",
|
||||
"image/wmf",
|
||||
"text/plain",
|
||||
"text/csv",
|
||||
"text/json",
|
||||
"application/json",
|
||||
"application/zip",
|
||||
"application/gzip",
|
||||
"application/x-bzip",
|
||||
"application/x-bzip2",
|
||||
"application/x-7z-compressed",
|
||||
"application/x-tar",
|
||||
"application/pdf",
|
||||
],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:casesFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "casesFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('sets the observability file kind with defaults correctly', () => {
|
||||
registerCaseFileKinds(defaultSchema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[1]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [
|
||||
"image/aces",
|
||||
"image/apng",
|
||||
"image/avci",
|
||||
"image/avcs",
|
||||
"image/avif",
|
||||
"image/bmp",
|
||||
"image/cgm",
|
||||
"image/dicom-rle",
|
||||
"image/dpx",
|
||||
"image/emf",
|
||||
"image/example",
|
||||
"image/fits",
|
||||
"image/g3fax",
|
||||
"image/heic",
|
||||
"image/heic-sequence",
|
||||
"image/heif",
|
||||
"image/heif-sequence",
|
||||
"image/hej2k",
|
||||
"image/hsj2",
|
||||
"image/jls",
|
||||
"image/jp2",
|
||||
"image/jpeg",
|
||||
"image/jph",
|
||||
"image/jphc",
|
||||
"image/jpm",
|
||||
"image/jpx",
|
||||
"image/jxr",
|
||||
"image/jxrA",
|
||||
"image/jxrS",
|
||||
"image/jxs",
|
||||
"image/jxsc",
|
||||
"image/jxsi",
|
||||
"image/jxss",
|
||||
"image/ktx",
|
||||
"image/ktx2",
|
||||
"image/naplps",
|
||||
"image/png",
|
||||
"image/prs.btif",
|
||||
"image/prs.pti",
|
||||
"image/pwg-raster",
|
||||
"image/svg+xml",
|
||||
"image/t38",
|
||||
"image/tiff",
|
||||
"image/tiff-fx",
|
||||
"image/vnd.adobe.photoshop",
|
||||
"image/vnd.airzip.accelerator.azv",
|
||||
"image/vnd.cns.inf2",
|
||||
"image/vnd.dece.graphic",
|
||||
"image/vnd.djvu",
|
||||
"image/vnd.dwg",
|
||||
"image/vnd.dxf",
|
||||
"image/vnd.dvb.subtitle",
|
||||
"image/vnd.fastbidsheet",
|
||||
"image/vnd.fpx",
|
||||
"image/vnd.fst",
|
||||
"image/vnd.fujixerox.edmics-mmr",
|
||||
"image/vnd.fujixerox.edmics-rlc",
|
||||
"image/vnd.globalgraphics.pgb",
|
||||
"image/vnd.microsoft.icon",
|
||||
"image/vnd.mix",
|
||||
"image/vnd.ms-modi",
|
||||
"image/vnd.mozilla.apng",
|
||||
"image/vnd.net-fpx",
|
||||
"image/vnd.pco.b16",
|
||||
"image/vnd.radiance",
|
||||
"image/vnd.sealed.png",
|
||||
"image/vnd.sealedmedia.softseal.gif",
|
||||
"image/vnd.sealedmedia.softseal.jpg",
|
||||
"image/vnd.svf",
|
||||
"image/vnd.tencent.tap",
|
||||
"image/vnd.valve.source.texture",
|
||||
"image/vnd.wap.wbmp",
|
||||
"image/vnd.xiff",
|
||||
"image/vnd.zbrush.pcx",
|
||||
"image/webp",
|
||||
"image/wmf",
|
||||
"text/plain",
|
||||
"text/csv",
|
||||
"text/json",
|
||||
"application/json",
|
||||
"application/zip",
|
||||
"application/gzip",
|
||||
"application/x-bzip",
|
||||
"application/x-bzip2",
|
||||
"application/x-7z-compressed",
|
||||
"application/x-tar",
|
||||
"application/pdf",
|
||||
],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:observabilityFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "observabilityFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('sets the securitySolution file kind with defaults correctly', () => {
|
||||
registerCaseFileKinds(defaultSchema.files, mockFilesSetup);
|
||||
|
||||
expect(mockFilesSetup.registerFileKind.mock.calls[2]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allowedMimeTypes": Array [
|
||||
"image/aces",
|
||||
"image/apng",
|
||||
"image/avci",
|
||||
"image/avcs",
|
||||
"image/avif",
|
||||
"image/bmp",
|
||||
"image/cgm",
|
||||
"image/dicom-rle",
|
||||
"image/dpx",
|
||||
"image/emf",
|
||||
"image/example",
|
||||
"image/fits",
|
||||
"image/g3fax",
|
||||
"image/heic",
|
||||
"image/heic-sequence",
|
||||
"image/heif",
|
||||
"image/heif-sequence",
|
||||
"image/hej2k",
|
||||
"image/hsj2",
|
||||
"image/jls",
|
||||
"image/jp2",
|
||||
"image/jpeg",
|
||||
"image/jph",
|
||||
"image/jphc",
|
||||
"image/jpm",
|
||||
"image/jpx",
|
||||
"image/jxr",
|
||||
"image/jxrA",
|
||||
"image/jxrS",
|
||||
"image/jxs",
|
||||
"image/jxsc",
|
||||
"image/jxsi",
|
||||
"image/jxss",
|
||||
"image/ktx",
|
||||
"image/ktx2",
|
||||
"image/naplps",
|
||||
"image/png",
|
||||
"image/prs.btif",
|
||||
"image/prs.pti",
|
||||
"image/pwg-raster",
|
||||
"image/svg+xml",
|
||||
"image/t38",
|
||||
"image/tiff",
|
||||
"image/tiff-fx",
|
||||
"image/vnd.adobe.photoshop",
|
||||
"image/vnd.airzip.accelerator.azv",
|
||||
"image/vnd.cns.inf2",
|
||||
"image/vnd.dece.graphic",
|
||||
"image/vnd.djvu",
|
||||
"image/vnd.dwg",
|
||||
"image/vnd.dxf",
|
||||
"image/vnd.dvb.subtitle",
|
||||
"image/vnd.fastbidsheet",
|
||||
"image/vnd.fpx",
|
||||
"image/vnd.fst",
|
||||
"image/vnd.fujixerox.edmics-mmr",
|
||||
"image/vnd.fujixerox.edmics-rlc",
|
||||
"image/vnd.globalgraphics.pgb",
|
||||
"image/vnd.microsoft.icon",
|
||||
"image/vnd.mix",
|
||||
"image/vnd.ms-modi",
|
||||
"image/vnd.mozilla.apng",
|
||||
"image/vnd.net-fpx",
|
||||
"image/vnd.pco.b16",
|
||||
"image/vnd.radiance",
|
||||
"image/vnd.sealed.png",
|
||||
"image/vnd.sealedmedia.softseal.gif",
|
||||
"image/vnd.sealedmedia.softseal.jpg",
|
||||
"image/vnd.svf",
|
||||
"image/vnd.tencent.tap",
|
||||
"image/vnd.valve.source.texture",
|
||||
"image/vnd.wap.wbmp",
|
||||
"image/vnd.xiff",
|
||||
"image/vnd.zbrush.pcx",
|
||||
"image/webp",
|
||||
"image/wmf",
|
||||
"text/plain",
|
||||
"text/csv",
|
||||
"text/json",
|
||||
"application/json",
|
||||
"application/zip",
|
||||
"application/gzip",
|
||||
"application/x-bzip",
|
||||
"application/x-bzip2",
|
||||
"application/x-7z-compressed",
|
||||
"application/x-tar",
|
||||
"application/pdf",
|
||||
],
|
||||
"http": Object {
|
||||
"create": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesCreate",
|
||||
],
|
||||
},
|
||||
"download": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"getById": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
"list": Object {
|
||||
"tags": Array [
|
||||
"access:securitySolutionFilesCasesRead",
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "securitySolutionFilesCases",
|
||||
"maxSizeBytes": [Function],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -10,20 +10,22 @@ import type { FilesSetup } from '@kbn/files-plugin/server';
|
|||
import {
|
||||
APP_ID,
|
||||
MAX_FILE_SIZE,
|
||||
MAX_IMAGE_FILE_SIZE,
|
||||
OBSERVABILITY_OWNER,
|
||||
SECURITY_SOLUTION_OWNER,
|
||||
} from '../../common/constants';
|
||||
import type { Owner } from '../../common/constants/types';
|
||||
import { HttpApiTagOperation } from '../../common/constants/types';
|
||||
import { ALLOWED_MIME_TYPES, IMAGE_MIME_TYPES } from '../../common/constants/mime_types';
|
||||
import { IMAGE_MIME_TYPES } from '../../common/constants/mime_types';
|
||||
import type { FilesConfig } from './types';
|
||||
import { constructFileKindIdByOwner, constructFilesHttpOperationTag } from '../../common/files';
|
||||
|
||||
const buildFileKind = (owner: Owner): FileKind => {
|
||||
const buildFileKind = (config: FilesConfig, owner: Owner): FileKind => {
|
||||
return {
|
||||
id: constructFileKindIdByOwner(owner),
|
||||
http: fileKindHttpTags(owner),
|
||||
maxSizeBytes,
|
||||
allowedMimeTypes: ALLOWED_MIME_TYPES,
|
||||
maxSizeBytes: createMaxCallback(config),
|
||||
allowedMimeTypes: config.allowedMimeTypes,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -44,27 +46,44 @@ const buildTag = (owner: Owner, operation: HttpApiTagOperation) => {
|
|||
};
|
||||
};
|
||||
|
||||
const MAX_IMAGE_FILE_SIZE = 10 * 1024 * 1024; // 10 MiB
|
||||
export const createMaxCallback =
|
||||
(config: FilesConfig) =>
|
||||
(file: FileJSON): number => {
|
||||
// if the user set a max size, always return that
|
||||
if (config.maxSize != null) {
|
||||
return config.maxSize;
|
||||
}
|
||||
|
||||
const maxSizeBytes = (file: FileJSON): number => {
|
||||
if (file.mimeType != null && IMAGE_MIME_TYPES.has(file.mimeType)) {
|
||||
return MAX_IMAGE_FILE_SIZE;
|
||||
}
|
||||
const allowedMimeTypesSet = new Set(config.allowedMimeTypes);
|
||||
|
||||
return MAX_FILE_SIZE;
|
||||
};
|
||||
// if we have the mime type for the file and it exists within the allowed types and it is an image then return the
|
||||
// image size
|
||||
if (
|
||||
file.mimeType != null &&
|
||||
allowedMimeTypesSet.has(file.mimeType) &&
|
||||
IMAGE_MIME_TYPES.has(file.mimeType)
|
||||
) {
|
||||
return MAX_IMAGE_FILE_SIZE;
|
||||
}
|
||||
|
||||
return MAX_FILE_SIZE;
|
||||
};
|
||||
|
||||
/**
|
||||
* The file kind definition for interacting with the file service for the backend
|
||||
*/
|
||||
const CASES_FILE_KINDS: Record<Owner, FileKind> = {
|
||||
[APP_ID]: buildFileKind(APP_ID),
|
||||
[SECURITY_SOLUTION_OWNER]: buildFileKind(SECURITY_SOLUTION_OWNER),
|
||||
[OBSERVABILITY_OWNER]: buildFileKind(OBSERVABILITY_OWNER),
|
||||
const createFileKinds = (config: FilesConfig): Record<Owner, FileKind> => {
|
||||
return {
|
||||
[APP_ID]: buildFileKind(config, APP_ID),
|
||||
[OBSERVABILITY_OWNER]: buildFileKind(config, OBSERVABILITY_OWNER),
|
||||
[SECURITY_SOLUTION_OWNER]: buildFileKind(config, SECURITY_SOLUTION_OWNER),
|
||||
};
|
||||
};
|
||||
|
||||
export const registerCaseFileKinds = (filesSetupPlugin: FilesSetup) => {
|
||||
for (const fileKind of Object.values(CASES_FILE_KINDS)) {
|
||||
export const registerCaseFileKinds = (config: FilesConfig, filesSetupPlugin: FilesSetup) => {
|
||||
const fileKinds = createFileKinds(config);
|
||||
|
||||
for (const fileKind of Object.values(fileKinds)) {
|
||||
filesSetupPlugin.registerFileKind(fileKind);
|
||||
}
|
||||
};
|
||||
|
|
10
x-pack/plugins/cases/server/files/types.ts
Normal file
10
x-pack/plugins/cases/server/files/types.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 type { ConfigType } from '../config';
|
||||
|
||||
export type FilesConfig = ConfigType['files'];
|
|
@ -15,6 +15,7 @@ export const config: PluginConfigDescriptor<ConfigType> = {
|
|||
schema: ConfigSchema,
|
||||
exposeToBrowser: {
|
||||
markdownPlugins: true,
|
||||
files: { maxSize: true, allowedMimeTypes: true },
|
||||
},
|
||||
deprecations: ({ renameFromRoot }) => [
|
||||
renameFromRoot('xpack.case.enabled', 'xpack.cases.enabled', { level: 'critical' }),
|
||||
|
|
|
@ -59,6 +59,7 @@ import { UserProfileService } from './services';
|
|||
import { LICENSING_CASE_ASSIGNMENT_FEATURE } from './common/constants';
|
||||
import { registerInternalAttachments } from './internal_attachments';
|
||||
import { registerCaseFileKinds } from './files';
|
||||
import type { ConfigType } from './config';
|
||||
|
||||
export interface PluginsSetup {
|
||||
actions: ActionsPluginSetup;
|
||||
|
@ -84,6 +85,7 @@ export interface PluginsStart {
|
|||
}
|
||||
|
||||
export class CasePlugin {
|
||||
private readonly caseConfig: ConfigType;
|
||||
private readonly logger: Logger;
|
||||
private readonly kibanaVersion: PluginInitializerContext['env']['packageInfo']['version'];
|
||||
private clientFactory: CasesClientFactory;
|
||||
|
@ -94,6 +96,7 @@ export class CasePlugin {
|
|||
private userProfileService: UserProfileService;
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext) {
|
||||
this.caseConfig = initializerContext.config.get<ConfigType>();
|
||||
this.kibanaVersion = initializerContext.env.packageInfo.version;
|
||||
this.logger = this.initializerContext.logger.get();
|
||||
this.clientFactory = new CasesClientFactory(this.logger);
|
||||
|
@ -110,7 +113,7 @@ export class CasePlugin {
|
|||
);
|
||||
|
||||
registerInternalAttachments(this.externalReferenceAttachmentTypeRegistry);
|
||||
registerCaseFileKinds(plugins.files);
|
||||
registerCaseFileKinds(this.caseConfig.files, plugins.files);
|
||||
|
||||
this.securityPluginSetup = plugins.security;
|
||||
this.lensEmbeddableFactory = plugins.lens.lensEmbeddableFactory;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue