mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Files] Add default file kind (#144803)
## Summary Introduce a default file kind for images in Kibana. This file kind will be the download/upload target usable for all images across Kibana. Consider the following: A Kibana user wants to add a branding logo to their dashboard. They need to create a new image or select from a set of existing images (i.e., images already uploaded). This set of images is the "default image" set. The idea will be this set of images can be access across dashboards and solutions. For example, the same user can access the branding image they uploaded in Cases. ## How it works * We added a new default file kind specifically for images, this is registered from the files plugin * In order to access these files over HTTP users will need the `files:defaultImage` privilege * This is a distinct privilege from the file management privilege and allows users to access HTTP endpoints controlled by `access:files:defaultImage` as well as the underlying `file` saved object * Consider a dashboard user that wants to add an image embeddable: they will need access to `file` saved object as well as the endpoints for creating/reading/deleting the default file kind. In order to get this their role must grant the new "Shared images" privilege. <img width="749" alt="Screenshot 2022-11-22 at 10 34 25" src="https://user-images.githubusercontent.com/8155004/203295230-24a0be94-9c59-4a53-8757-336e9fc8f6c4.png">
This commit is contained in:
parent
b6dcb8b088
commit
6de90aab9b
12 changed files with 202 additions and 8 deletions
35
src/plugins/files/common/default_image_file_kind.ts
Normal file
35
src/plugins/files/common/default_image_file_kind.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { FileKind } from './types';
|
||||
|
||||
const id = 'defaultImage' as const;
|
||||
const tag = 'files:defaultImage' as const;
|
||||
const tags = [`access:${tag}`];
|
||||
const tenMebiBytes = 1024 * 1024 * 10;
|
||||
|
||||
/**
|
||||
* A file kind that is available to all plugins to use for uploading images
|
||||
* intended to be reused across Kibana.
|
||||
*/
|
||||
export const defaultImageFileKind: FileKind = {
|
||||
id,
|
||||
maxSizeBytes: tenMebiBytes,
|
||||
blobStoreSettings: {},
|
||||
// tried using "image/*" but it did not work with the HTTP endpoint (got 415 Unsupported Media Type)
|
||||
allowedMimeTypes: ['image/png', 'image/jpeg', 'image/webp', 'image/avif'],
|
||||
http: {
|
||||
create: { tags },
|
||||
delete: { tags },
|
||||
download: { tags },
|
||||
getById: { tags },
|
||||
list: { tags },
|
||||
share: { tags },
|
||||
update: { tags },
|
||||
},
|
||||
};
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
export { FILE_SO_TYPE, PLUGIN_ID, PLUGIN_NAME, ES_FIXED_SIZE_INDEX_BLOB_STORE } from './constants';
|
||||
export { defaultImageFileKind } from './default_image_file_kind';
|
||||
|
||||
export type {
|
||||
File,
|
||||
|
|
15
src/plugins/files/common/register_default_file_kinds.ts
Normal file
15
src/plugins/files/common/register_default_file_kinds.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { getFileKindsRegistry } from './file_kinds_registry';
|
||||
import { defaultImageFileKind } from '.';
|
||||
|
||||
export function registerDefaultFileKinds() {
|
||||
const registry = getFileKindsRegistry();
|
||||
registry.register(defaultImageFileKind);
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
import { FilesPlugin } from './plugin';
|
||||
export { defaultImageFileKind } from '../common/default_image_file_kind';
|
||||
export type { FilesSetup, FilesStart } from './plugin';
|
||||
export type {
|
||||
FilesClient,
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
import type { FilesClient, FilesClientFactory } from './types';
|
||||
import { createFilesClient } from './files_client';
|
||||
import { FileKind } from '../common';
|
||||
import { registerDefaultFileKinds } from '../common/register_default_file_kinds';
|
||||
import { ScopedFilesClient } from '.';
|
||||
|
||||
/**
|
||||
|
@ -59,6 +60,7 @@ export class FilesPlugin implements Plugin<FilesSetup, FilesStart> {
|
|||
return createFilesClient({ http: core.http }) as FilesClient<M>;
|
||||
},
|
||||
};
|
||||
registerDefaultFileKinds();
|
||||
return {
|
||||
filesClientFactory: this.filesClientFactory,
|
||||
registerFileKind: (fileKind: FileKind) => {
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
getFileKindsRegistry,
|
||||
FileKindsRegistryImpl,
|
||||
} from '../common/file_kinds_registry';
|
||||
import { registerDefaultFileKinds } from '../common/register_default_file_kinds';
|
||||
|
||||
import { BlobStorageService } from './blob_storage_service';
|
||||
import { FileServiceFactory } from './file_service';
|
||||
|
@ -91,6 +92,9 @@ export class FilesPlugin implements Plugin<FilesSetup, FilesStart, FilesPluginSe
|
|||
getFileService: () => this.fileServiceFactory?.asInternal(),
|
||||
});
|
||||
|
||||
// Now that everything is set up:
|
||||
registerDefaultFileKinds();
|
||||
|
||||
return {
|
||||
registerFileKind(fileKind) {
|
||||
getFileKindsRegistry().register(fileKind);
|
||||
|
|
|
@ -169,6 +169,10 @@ Array [
|
|||
"id": "filesManagement",
|
||||
"subFeatures": undefined,
|
||||
},
|
||||
Object {
|
||||
"id": "filesSharedImage",
|
||||
"subFeatures": undefined,
|
||||
},
|
||||
Object {
|
||||
"id": "savedObjectsManagement",
|
||||
"subFeatures": undefined,
|
||||
|
@ -457,6 +461,10 @@ Array [
|
|||
"id": "filesManagement",
|
||||
"subFeatures": undefined,
|
||||
},
|
||||
Object {
|
||||
"id": "filesSharedImage",
|
||||
"subFeatures": undefined,
|
||||
},
|
||||
Object {
|
||||
"id": "savedObjectsManagement",
|
||||
"subFeatures": undefined,
|
||||
|
@ -773,6 +781,7 @@ Array [
|
|||
"privilege": Object {
|
||||
"api": Array [
|
||||
"files:manageFiles",
|
||||
"files:defaultImage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
|
@ -784,7 +793,8 @@ Array [
|
|||
},
|
||||
"savedObject": Object {
|
||||
"all": Array [
|
||||
"files",
|
||||
"file",
|
||||
"fileShare",
|
||||
],
|
||||
"read": Array [],
|
||||
},
|
||||
|
@ -796,6 +806,7 @@ Array [
|
|||
"privilege": Object {
|
||||
"api": Array [
|
||||
"files:manageFiles",
|
||||
"files:defaultImage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
|
@ -808,7 +819,49 @@ Array [
|
|||
"savedObject": Object {
|
||||
"all": Array [],
|
||||
"read": Array [
|
||||
"files",
|
||||
"file",
|
||||
"fileShare",
|
||||
],
|
||||
},
|
||||
"ui": Array [],
|
||||
},
|
||||
"privilegeId": "read",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`buildOSSFeatures with a basic license returns the filesSharedImage feature augmented with appropriate sub feature privileges 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"privilege": Object {
|
||||
"api": Array [
|
||||
"files:defaultImage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
],
|
||||
"savedObject": Object {
|
||||
"all": Array [
|
||||
"file",
|
||||
],
|
||||
"read": Array [],
|
||||
},
|
||||
"ui": Array [],
|
||||
},
|
||||
"privilegeId": "all",
|
||||
},
|
||||
Object {
|
||||
"privilege": Object {
|
||||
"api": Array [
|
||||
"files:defaultImage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
],
|
||||
"savedObject": Object {
|
||||
"all": Array [],
|
||||
"read": Array [
|
||||
"file",
|
||||
],
|
||||
},
|
||||
"ui": Array [],
|
||||
|
@ -1332,6 +1385,7 @@ Array [
|
|||
"privilege": Object {
|
||||
"api": Array [
|
||||
"files:manageFiles",
|
||||
"files:defaultImage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
|
@ -1343,7 +1397,8 @@ Array [
|
|||
},
|
||||
"savedObject": Object {
|
||||
"all": Array [
|
||||
"files",
|
||||
"file",
|
||||
"fileShare",
|
||||
],
|
||||
"read": Array [],
|
||||
},
|
||||
|
@ -1355,6 +1410,7 @@ Array [
|
|||
"privilege": Object {
|
||||
"api": Array [
|
||||
"files:manageFiles",
|
||||
"files:defaultImage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
|
@ -1367,7 +1423,49 @@ Array [
|
|||
"savedObject": Object {
|
||||
"all": Array [],
|
||||
"read": Array [
|
||||
"files",
|
||||
"file",
|
||||
"fileShare",
|
||||
],
|
||||
},
|
||||
"ui": Array [],
|
||||
},
|
||||
"privilegeId": "read",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`buildOSSFeatures with a enterprise license returns the filesSharedImage feature augmented with appropriate sub feature privileges 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"privilege": Object {
|
||||
"api": Array [
|
||||
"files:defaultImage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
],
|
||||
"savedObject": Object {
|
||||
"all": Array [
|
||||
"file",
|
||||
],
|
||||
"read": Array [],
|
||||
},
|
||||
"ui": Array [],
|
||||
},
|
||||
"privilegeId": "all",
|
||||
},
|
||||
Object {
|
||||
"privilege": Object {
|
||||
"api": Array [
|
||||
"files:defaultImage",
|
||||
],
|
||||
"app": Array [
|
||||
"kibana",
|
||||
],
|
||||
"savedObject": Object {
|
||||
"all": Array [],
|
||||
"read": Array [
|
||||
"file",
|
||||
],
|
||||
},
|
||||
"ui": Array [],
|
||||
|
|
|
@ -441,11 +441,11 @@ export const buildOSSFeatures = ({
|
|||
kibana: ['filesManagement'],
|
||||
},
|
||||
savedObject: {
|
||||
all: ['files'],
|
||||
all: ['file', 'fileShare'],
|
||||
read: [],
|
||||
},
|
||||
ui: [],
|
||||
api: ['files:manageFiles'],
|
||||
api: ['files:manageFiles', 'files:defaultImage'],
|
||||
},
|
||||
read: {
|
||||
app: ['kibana'],
|
||||
|
@ -454,10 +454,43 @@ export const buildOSSFeatures = ({
|
|||
},
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: ['files'],
|
||||
read: ['file', 'fileShare'],
|
||||
},
|
||||
ui: [],
|
||||
api: ['files:manageFiles'],
|
||||
api: ['files:manageFiles', 'files:defaultImage'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'filesSharedImage',
|
||||
name: i18n.translate('xpack.features.filesSharedImagesFeatureName', {
|
||||
defaultMessage: 'Shared images',
|
||||
}),
|
||||
order: 1600,
|
||||
category: DEFAULT_APP_CATEGORIES.management,
|
||||
app: ['kibana'],
|
||||
catalogue: [],
|
||||
privilegesTooltip: i18n.translate('xpack.features.filesSharedImagesPrivilegesTooltip', {
|
||||
defaultMessage: 'Required to access images stored in Kibana.',
|
||||
}),
|
||||
privileges: {
|
||||
all: {
|
||||
app: ['kibana'],
|
||||
savedObject: {
|
||||
all: ['file'],
|
||||
read: [],
|
||||
},
|
||||
ui: [],
|
||||
api: ['files:defaultImage'],
|
||||
},
|
||||
read: {
|
||||
app: ['kibana'],
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: ['file'],
|
||||
},
|
||||
ui: [],
|
||||
api: ['files:defaultImage'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -67,6 +67,7 @@ describe('Features Plugin', () => {
|
|||
"advancedSettings",
|
||||
"indexPatterns",
|
||||
"filesManagement",
|
||||
"filesSharedImage",
|
||||
"savedObjectsManagement",
|
||||
]
|
||||
`);
|
||||
|
|
|
@ -101,6 +101,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
'actions',
|
||||
'enterpriseSearch',
|
||||
'filesManagement',
|
||||
'filesSharedImage',
|
||||
'advancedSettings',
|
||||
'indexPatterns',
|
||||
'graph',
|
||||
|
|
|
@ -79,6 +79,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
'packs_read',
|
||||
],
|
||||
filesManagement: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
filesSharedImage: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
},
|
||||
reserved: ['fleet-setup', 'ml_user', 'ml_admin', 'ml_apm_user', 'monitoring'],
|
||||
};
|
||||
|
|
|
@ -46,6 +46,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
stackAlerts: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
actions: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
filesManagement: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
filesSharedImage: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
},
|
||||
global: ['all', 'read'],
|
||||
space: ['all', 'read'],
|
||||
|
@ -133,6 +134,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
advancedSettings: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
indexPatterns: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
filesManagement: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
filesSharedImage: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
savedObjectsManagement: ['all', 'read', 'minimal_all', 'minimal_read'],
|
||||
osquery: [
|
||||
'all',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue