Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SOM] Add visibleInManagement option to management metadata #112073

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ async function getDeprecations({ esClient, savedObjectsClient }: GetDeprecations
const deprecations: DeprecationsDetails[] = [];
const count = await getFooCount(savedObjectsClient);
if (count > 0) {
// Example of a manual correctiveAction
deprecations.push({
title: i18n.translate('xpack.foo.deprecations.title', {
defaultMessage: `Foo's are deprecated`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export interface SavedObjectsTypeManagementDefinition<Attributes = any>
| [isExportable](./kibana-plugin-core-server.savedobjectstypemanagementdefinition.isexportable.md) | <code>SavedObjectsExportablePredicate&lt;Attributes&gt;</code> | Optional hook to specify whether an object should be exportable.<!-- -->If specified, <code>isExportable</code> will be called during export for each of this type's objects in the export, and the ones not matching the predicate will be excluded from the export.<!-- -->When implementing both <code>isExportable</code> and <code>onExport</code>, it is mandatory that <code>isExportable</code> returns the same value for an object before and after going though the export transform. E.g <code>isExportable(objectBeforeTransform) === isExportable(objectAfterTransform)</code> |
| [onExport](./kibana-plugin-core-server.savedobjectstypemanagementdefinition.onexport.md) | <code>SavedObjectsExportTransform&lt;Attributes&gt;</code> | An optional export transform function that can be used transform the objects of the registered type during the export process.<!-- -->It can be used to either mutate the exported objects, or add additional objects (of any type) to the export list.<!-- -->See [the transform type documentation](./kibana-plugin-core-server.savedobjectsexporttransform.md) for more info and examples.<!-- -->When implementing both <code>isExportable</code> and <code>onExport</code>, it is mandatory that <code>isExportable</code> returns the same value for an object before and after going though the export transform. E.g <code>isExportable(objectBeforeTransform) === isExportable(objectAfterTransform)</code> |
| [onImport](./kibana-plugin-core-server.savedobjectstypemanagementdefinition.onimport.md) | <code>SavedObjectsImportHook&lt;Attributes&gt;</code> | An optional [import hook](./kibana-plugin-core-server.savedobjectsimporthook.md) to use when importing given type.<!-- -->Import hooks are executed during the savedObjects import process and allow to interact with the imported objects. See the [hook documentation](./kibana-plugin-core-server.savedobjectsimporthook.md) for more info. |
| [visibleInManagement](./kibana-plugin-core-server.savedobjectstypemanagementdefinition.visibleinmanagement.md) | <code>boolean</code> | When set to false, the type will not be listed or searchable in the SO management section. Main usage of setting this property to false for a type is when objects from the type should be included in the export via references or export hooks, but should not directly appear in the SOM. Defaults to <code>true</code>. |

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsTypeManagementDefinition](./kibana-plugin-core-server.savedobjectstypemanagementdefinition.md) &gt; [visibleInManagement](./kibana-plugin-core-server.savedobjectstypemanagementdefinition.visibleinmanagement.md)

## SavedObjectsTypeManagementDefinition.visibleInManagement property

When set to false, the type will not be listed or searchable in the SO management section. Main usage of setting this property to false for a type is when objects from the type should be included in the export via references or export hooks, but should not directly appear in the SOM. Defaults to `true`<!-- -->.

<b>Signature:</b>

```typescript
visibleInManagement?: boolean;
```

## Remarks

`importableAndExportable` must be `true` to specify this property.

53 changes: 53 additions & 0 deletions src/core/server/saved_objects/saved_objects_type_registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,59 @@ describe('SavedObjectTypeRegistry', () => {
}).toThrowErrorMatchingInlineSnapshot(`"Type 'typeA' is already registered"`);
});

it('throws when `management.visibleInManagement` is specified but `management.importableAndExportable` is undefined or false', () => {
expect(() => {
registry.registerType(
createType({
name: 'typeA',
management: {
visibleInManagement: true,
},
})
);
}).toThrowErrorMatchingInlineSnapshot(
`"Type typeA: 'management.importableAndExportable' must be 'true' when specifying 'management.visibleInManagement'"`
);

expect(() => {
registry.registerType(
createType({
name: 'typeA',
management: {
visibleInManagement: false,
},
})
);
}).toThrowErrorMatchingInlineSnapshot(
`"Type typeA: 'management.importableAndExportable' must be 'true' when specifying 'management.visibleInManagement'"`
);

expect(() => {
registry.registerType(
createType({
name: 'typeA',
management: {
importableAndExportable: false,
visibleInManagement: false,
},
})
);
}).toThrowErrorMatchingInlineSnapshot(
`"Type typeA: 'management.importableAndExportable' must be 'true' when specifying 'management.visibleInManagement'"`
);
expect(() => {
registry.registerType(
createType({
name: 'typeA',
management: {
importableAndExportable: true,
visibleInManagement: false,
},
})
);
}).not.toThrow();
});

it('throws when `management.onExport` is specified but `management.importableAndExportable` is undefined or false', () => {
expect(() => {
registry.registerType(
Expand Down
5 changes: 5 additions & 0 deletions src/core/server/saved_objects/saved_objects_type_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,10 @@ const validateType = ({ name, management }: SavedObjectsType) => {
`Type ${name}: 'management.importableAndExportable' must be 'true' when specifying 'management.onExport'`
);
}
if (management.visibleInManagement !== undefined && !management.importableAndExportable) {
throw new Error(
`Type ${name}: 'management.importableAndExportable' must be 'true' when specifying 'management.visibleInManagement'`
);
}
}
};
9 changes: 9 additions & 0 deletions src/core/server/saved_objects/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,15 @@ export interface SavedObjectsTypeManagementDefinition<Attributes = any> {
* Is the type importable or exportable. Defaults to `false`.
*/
importableAndExportable?: boolean;
/**
* When set to false, the type will not be listed or searchable in the SO management section.
* Main usage of setting this property to false for a type is when objects from the type should
* be included in the export via references or export hooks, but should not directly appear in the SOM.
* Defaults to `true`.
*
* @remarks `importableAndExportable` must be `true` to specify this property.
*/
visibleInManagement?: boolean;
/**
* The default search field to use for this type. Defaults to `id`.
*/
Expand Down
1 change: 1 addition & 0 deletions src/core/server/server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2751,6 +2751,7 @@ export interface SavedObjectsTypeManagementDefinition<Attributes = any> {
isExportable?: SavedObjectsExportablePredicate<Attributes>;
onExport?: SavedObjectsExportTransform<Attributes>;
onImport?: SavedObjectsImportHook<Attributes>;
visibleInManagement?: boolean;
}

// @public
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const registerGetAllowedTypesRoute = (router: IRouter) => {
async (context, req, res) => {
const allowedTypes = context.core.savedObjects.typeRegistry
.getImportableAndExportableTypes()
.filter((type) => type.management!.visibleInManagement ?? true)
.map((type) => type.name);
Comment on lines 19 to 21
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I could have added the same filtering in other SOM routes (e.g find, scroll_count), but I think it's not worth it because:

  • The list of type from the _allowed_types endpoint is the source of truth for the UI regarding the types the user can search for or list in the SOM
  • Even if the user was to manually call the SOM endpoint while specifying types that are exportable but not visible in management, it's not a vulnerability or a privilege escalation, as it would have been allowed to do the same using the public SO apis)


return res.ok({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"type": "doc",
"value": {
"id": "test-not-visible-in-management:vim-1",
"index": ".kibana",
"source": {
"coreMigrationVersion": "7.14.0",
"references": [
],
"test-not-visible-in-management": {
"enabled": true,
"title": "vim-1"
},
"type": "test-not-visible-in-management",
"updated_at": "2018-12-21T00:43:07.096Z"
},
"type": "_doc"
}
}

Loading