diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientfactory.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientfactory.md
index 09c6d63f03dd7..724c1ebbeadf4 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientfactory.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientfactory.md
@@ -9,7 +9,8 @@ Describes the factory used to create instances of the Saved Objects Client.
Signature:
```typescript
-export declare type SavedObjectsClientFactory = ({ request, }: {
+export declare type SavedObjectsClientFactory = ({ request, includedHiddenTypes, }: {
request: KibanaRequest;
+ includedHiddenTypes?: string[];
}) => SavedObjectsClientContract;
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md
new file mode 100644
index 0000000000000..a9483e34b38ce
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsClientProviderOptions](./kibana-plugin-core-server.savedobjectsclientprovideroptions.md) > [includedHiddenTypes](./kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md)
+
+## SavedObjectsClientProviderOptions.includedHiddenTypes property
+
+Signature:
+
+```typescript
+includedHiddenTypes?: string[];
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.md
index 4291de765fd44..be1f73f064843 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsclientprovideroptions.md
@@ -17,4 +17,5 @@ export interface SavedObjectsClientProviderOptions
| Property | Type | Description |
| --- | --- | --- |
| [excludedWrappers](./kibana-plugin-core-server.savedobjectsclientprovideroptions.excludedwrappers.md) | string[]
| |
+| [includedHiddenTypes](./kibana-plugin-core-server.savedobjectsclientprovideroptions.includedhiddentypes.md) | string[]
| |
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md
index c4b19ca15910f..e39ce020b930c 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md
@@ -9,5 +9,5 @@ Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsre
Signature:
```typescript
-createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository;
+createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository;
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md
index b9007d16d0234..9cd0df9094277 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md
@@ -9,5 +9,5 @@ Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsre
Signature:
```typescript
-createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository;
+createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository;
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.md
index 35b29918edced..dec768b68cd3a 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsrepositoryfactory.md
@@ -16,6 +16,6 @@ export interface SavedObjectsRepositoryFactory
| Property | Type | Description |
| --- | --- | --- |
-| [createInternalRepository](./kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md) | (extraTypes?: string[]) => ISavedObjectsRepository
| Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the internal Kibana user for authenticating with Elasticsearch. |
-| [createScopedRepository](./kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md) | (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository
| Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. |
+| [createInternalRepository](./kibana-plugin-core-server.savedobjectsrepositoryfactory.createinternalrepository.md) | (includedHiddenTypes?: string[]) => ISavedObjectsRepository
| Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the internal Kibana user for authenticating with Elasticsearch. |
+| [createScopedRepository](./kibana-plugin-core-server.savedobjectsrepositoryfactory.createscopedrepository.md) | (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository
| Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. |
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md
index 4467dd23d87b6..d03e9ca223c53 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md
@@ -9,5 +9,5 @@ Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsre
Signature:
```typescript
-createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository;
+createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository;
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md
index 2840a377026e7..762f77b98e74d 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md
@@ -9,7 +9,7 @@ Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsre
Signature:
```typescript
-createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository;
+createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository;
```
## Remarks
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.md
index 5f592adf7acd9..17655bb4878a7 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicestart.md
@@ -16,8 +16,8 @@ export interface SavedObjectsServiceStart
| Property | Type | Description |
| --- | --- | --- |
-| [createInternalRepository](./kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md) | (extraTypes?: string[]) => ISavedObjectsRepository
| Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the internal Kibana user for authenticating with Elasticsearch. |
-| [createScopedRepository](./kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md) | (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository
| Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. |
+| [createInternalRepository](./kibana-plugin-core-server.savedobjectsservicestart.createinternalrepository.md) | (includedHiddenTypes?: string[]) => ISavedObjectsRepository
| Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the internal Kibana user for authenticating with Elasticsearch. |
+| [createScopedRepository](./kibana-plugin-core-server.savedobjectsservicestart.createscopedrepository.md) | (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository
| Creates a [Saved Objects repository](./kibana-plugin-core-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. |
| [createSerializer](./kibana-plugin-core-server.savedobjectsservicestart.createserializer.md) | () => SavedObjectsSerializer
| Creates a [serializer](./kibana-plugin-core-server.savedobjectsserializer.md) that is aware of all registered types. |
| [getScopedClient](./kibana-plugin-core-server.savedobjectsservicestart.getscopedclient.md) | (req: KibanaRequest, options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract
| Creates a [Saved Objects client](./kibana-plugin-core-server.savedobjectsclientcontract.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. If other plugins have registered Saved Objects client wrappers, these will be applied to extend the functionality of the client.A client that is already scoped to the incoming request is also exposed from the route handler context see [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md). |
| [getTypeRegistry](./kibana-plugin-core-server.savedobjectsservicestart.gettyperegistry.md) | () => ISavedObjectTypeRegistry
| Returns the [registry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) containing all registered [saved object types](./kibana-plugin-core-server.savedobjectstype.md) |
diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts
index 819d79803f371..7dea7a017a47d 100644
--- a/src/core/server/saved_objects/saved_objects_service.test.ts
+++ b/src/core/server/saved_objects/saved_objects_service.test.ts
@@ -35,6 +35,10 @@ import { legacyServiceMock } from '../legacy/legacy_service.mock';
import { httpServiceMock } from '../http/http_service.mock';
import { SavedObjectsClientFactoryProvider } from './service/lib';
import { NodesVersionCompatibility } from '../elasticsearch/version_check/ensure_es_version';
+import { SavedObjectsRepository } from './service/lib/repository';
+import { KibanaRequest } from '../http';
+
+jest.mock('./service/lib/repository');
describe('SavedObjectsService', () => {
const createCoreContext = ({
@@ -269,5 +273,86 @@ describe('SavedObjectsService', () => {
expect(getTypeRegistry()).toBe(typeRegistryInstanceMock);
});
});
+
+ describe('#createScopedRepository', () => {
+ it('creates a respository scoped to the user', async () => {
+ const coreContext = createCoreContext({ skipMigration: false });
+ const soService = new SavedObjectsService(coreContext);
+ const coreSetup = createSetupDeps();
+ await soService.setup(coreSetup);
+ const { createScopedRepository } = await soService.start({});
+
+ const req = {} as KibanaRequest;
+ createScopedRepository(req);
+
+ expect(coreSetup.elasticsearch.adminClient.asScoped).toHaveBeenCalledWith(req);
+
+ const [
+ {
+ value: { callAsCurrentUser },
+ },
+ ] = coreSetup.elasticsearch.adminClient.asScoped.mock.results;
+
+ const [
+ [, , , callCluster, includedHiddenTypes],
+ ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls;
+
+ expect(callCluster).toBe(callAsCurrentUser);
+ expect(includedHiddenTypes).toEqual([]);
+ });
+
+ it('creates a respository including hidden types when specified', async () => {
+ const coreContext = createCoreContext({ skipMigration: false });
+ const soService = new SavedObjectsService(coreContext);
+ const coreSetup = createSetupDeps();
+ await soService.setup(coreSetup);
+ const { createScopedRepository } = await soService.start({});
+
+ const req = {} as KibanaRequest;
+ createScopedRepository(req, ['someHiddenType']);
+
+ const [
+ [, , , , includedHiddenTypes],
+ ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls;
+
+ expect(includedHiddenTypes).toEqual(['someHiddenType']);
+ });
+ });
+
+ describe('#createInternalRepository', () => {
+ it('creates a respository using the admin user', async () => {
+ const coreContext = createCoreContext({ skipMigration: false });
+ const soService = new SavedObjectsService(coreContext);
+ const coreSetup = createSetupDeps();
+ await soService.setup(coreSetup);
+ const { createInternalRepository } = await soService.start({});
+
+ createInternalRepository();
+
+ const [
+ [, , , callCluster, includedHiddenTypes],
+ ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls;
+
+ expect(coreSetup.elasticsearch.adminClient.callAsInternalUser).toBe(callCluster);
+ expect(callCluster).toBe(coreSetup.elasticsearch.adminClient.callAsInternalUser);
+ expect(includedHiddenTypes).toEqual([]);
+ });
+
+ it('creates a respository including hidden types when specified', async () => {
+ const coreContext = createCoreContext({ skipMigration: false });
+ const soService = new SavedObjectsService(coreContext);
+ const coreSetup = createSetupDeps();
+ await soService.setup(coreSetup);
+ const { createInternalRepository } = await soService.start({});
+
+ createInternalRepository(['someHiddenType']);
+
+ const [
+ [, , , , includedHiddenTypes],
+ ] = (SavedObjectsRepository.createRepository as jest.Mocked).mock.calls;
+
+ expect(includedHiddenTypes).toEqual(['someHiddenType']);
+ });
+ });
});
});
diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts
index ed4ffef5729ab..373b8bd1d2bc6 100644
--- a/src/core/server/saved_objects/saved_objects_service.ts
+++ b/src/core/server/saved_objects/saved_objects_service.ts
@@ -198,20 +198,23 @@ export interface SavedObjectsServiceStart {
* Elasticsearch.
*
* @param req - The request to create the scoped repository from.
- * @param extraTypes - A list of additional hidden types the repository should have access to.
+ * @param includedHiddenTypes - A list of additional hidden types the repository should have access to.
*
* @remarks
* Prefer using `getScopedClient`. This should only be used when using methods
* not exposed on {@link SavedObjectsClientContract}
*/
- createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository;
+ createScopedRepository: (
+ req: KibanaRequest,
+ includedHiddenTypes?: string[]
+ ) => ISavedObjectsRepository;
/**
* Creates a {@link ISavedObjectsRepository | Saved Objects repository} that
* uses the internal Kibana user for authenticating with Elasticsearch.
*
- * @param extraTypes - A list of additional hidden types the repository should have access to.
+ * @param includedHiddenTypes - A list of additional hidden types the repository should have access to.
*/
- createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository;
+ createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository;
/**
* Creates a {@link SavedObjectsSerializer | serializer} that is aware of all registered types.
*/
@@ -246,16 +249,19 @@ export interface SavedObjectsRepositoryFactory {
* uses the credentials from the passed in request to authenticate with
* Elasticsearch.
*
- * @param extraTypes - A list of additional hidden types the repository should have access to.
+ * @param includedHiddenTypes - A list of additional hidden types the repository should have access to.
*/
- createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository;
+ createScopedRepository: (
+ req: KibanaRequest,
+ includedHiddenTypes?: string[]
+ ) => ISavedObjectsRepository;
/**
* Creates a {@link ISavedObjectsRepository | Saved Objects repository} that
* uses the internal Kibana user for authenticating with Elasticsearch.
*
- * @param extraTypes - A list of additional hidden types the repository should have access to.
+ * @param includedHiddenTypes - A list of additional hidden types the repository should have access to.
*/
- createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository;
+ createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository;
}
/** @internal */
@@ -417,26 +423,26 @@ export class SavedObjectsService
await migrator.runMigrations();
}
- const createRepository = (callCluster: APICaller, extraTypes: string[] = []) => {
+ const createRepository = (callCluster: APICaller, includedHiddenTypes: string[] = []) => {
return SavedObjectsRepository.createRepository(
migrator,
this.typeRegistry,
kibanaConfig.index,
callCluster,
- extraTypes
+ includedHiddenTypes
);
};
const repositoryFactory: SavedObjectsRepositoryFactory = {
- createInternalRepository: (extraTypes?: string[]) =>
- createRepository(adminClient.callAsInternalUser, extraTypes),
- createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) =>
- createRepository(adminClient.asScoped(req).callAsCurrentUser, extraTypes),
+ createInternalRepository: (includedHiddenTypes?: string[]) =>
+ createRepository(adminClient.callAsInternalUser, includedHiddenTypes),
+ createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) =>
+ createRepository(adminClient.asScoped(req).callAsCurrentUser, includedHiddenTypes),
};
const clientProvider = new SavedObjectsClientProvider({
- defaultClientFactory({ request }) {
- const repository = repositoryFactory.createScopedRepository(request);
+ defaultClientFactory({ request, includedHiddenTypes }) {
+ const repository = repositoryFactory.createScopedRepository(request, includedHiddenTypes);
return new SavedObjectsClient(repository);
},
typeRegistry: this.typeRegistry,
diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts
index 61027130e0eb7..f76b05c4af1b9 100644
--- a/src/core/server/saved_objects/service/lib/repository.ts
+++ b/src/core/server/saved_objects/service/lib/repository.ts
@@ -132,7 +132,7 @@ export class SavedObjectsRepository {
typeRegistry: SavedObjectTypeRegistry,
indexName: string,
callCluster: APICaller,
- extraTypes: string[] = [],
+ includedHiddenTypes: string[] = [],
injectedConstructor: any = SavedObjectsRepository
): ISavedObjectsRepository {
const mappings = migrator.getActiveMappings();
@@ -140,14 +140,14 @@ export class SavedObjectsRepository {
const serializer = new SavedObjectsSerializer(typeRegistry);
const visibleTypes = allTypes.filter(type => !typeRegistry.isHidden(type));
- const missingTypeMappings = extraTypes.filter(type => !allTypes.includes(type));
+ const missingTypeMappings = includedHiddenTypes.filter(type => !allTypes.includes(type));
if (missingTypeMappings.length > 0) {
throw new Error(
`Missing mappings for saved objects types: '${missingTypeMappings.join(', ')}'`
);
}
- const allowedTypes = [...new Set(visibleTypes.concat(extraTypes))];
+ const allowedTypes = [...new Set(visibleTypes.concat(includedHiddenTypes))];
return new injectedConstructor({
index: indexName,
diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js
index aa9448e61009d..a0e1530ed2e26 100644
--- a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js
+++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js
@@ -167,3 +167,23 @@ test(`allows all wrappers to be excluded`, () => {
expect(firstClientWrapperFactoryMock).not.toHaveBeenCalled();
expect(secondClientWrapperFactoryMock).not.toHaveBeenCalled();
});
+
+test(`allows hidden typed to be included`, () => {
+ const defaultClient = Symbol();
+ const defaultClientFactoryMock = jest.fn().mockReturnValue(defaultClient);
+ const clientProvider = new SavedObjectsClientProvider({
+ defaultClientFactory: defaultClientFactoryMock,
+ typeRegistry: typeRegistryMock.create(),
+ });
+ const request = Symbol();
+
+ const actualClient = clientProvider.getClient(request, {
+ includedHiddenTypes: ['task'],
+ });
+
+ expect(actualClient).toBe(defaultClient);
+ expect(defaultClientFactoryMock).toHaveBeenCalledWith({
+ request,
+ includedHiddenTypes: ['task'],
+ });
+});
diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts
index 24813cd8d9ab8..3250737e1287d 100644
--- a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts
+++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts
@@ -46,8 +46,10 @@ export type SavedObjectsClientWrapperFactory = (
*/
export type SavedObjectsClientFactory = ({
request,
+ includedHiddenTypes,
}: {
request: KibanaRequest;
+ includedHiddenTypes?: string[];
}) => SavedObjectsClientContract;
/**
@@ -64,6 +66,7 @@ export type SavedObjectsClientFactoryProvider = (
*/
export interface SavedObjectsClientProviderOptions {
excludedWrappers?: string[];
+ includedHiddenTypes?: string[];
}
/**
@@ -121,14 +124,13 @@ export class SavedObjectsClientProvider {
getClient(
request: KibanaRequest,
- options: SavedObjectsClientProviderOptions = {}
+ { includedHiddenTypes, excludedWrappers = [] }: SavedObjectsClientProviderOptions = {}
): SavedObjectsClientContract {
const client = this._clientFactory({
request,
+ includedHiddenTypes,
});
- const excludedWrappers = options.excludedWrappers || [];
-
return this._wrapperFactories
.toPrioritizedArray()
.reduceRight((clientToWrap, { id, factory }) => {
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index bb8ee1d8e7a31..fcf9a9e2dedc2 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -1840,8 +1840,9 @@ export class SavedObjectsClient {
export type SavedObjectsClientContract = Pick;
// @public
-export type SavedObjectsClientFactory = ({ request, }: {
+export type SavedObjectsClientFactory = ({ request, includedHiddenTypes, }: {
request: KibanaRequest;
+ includedHiddenTypes?: string[];
}) => SavedObjectsClientContract;
// @public
@@ -1851,6 +1852,8 @@ export type SavedObjectsClientFactoryProvider = (repositoryFactory: SavedObjects
export interface SavedObjectsClientProviderOptions {
// (undocumented)
excludedWrappers?: string[];
+ // (undocumented)
+ includedHiddenTypes?: string[];
}
// @public
@@ -2213,7 +2216,7 @@ export class SavedObjectsRepository {
// Warning: (ae-forgotten-export) The symbol "KibanaMigrator" needs to be exported by the entry point index.d.ts
//
// @internal
- static createRepository(migrator: KibanaMigrator, typeRegistry: SavedObjectTypeRegistry, indexName: string, callCluster: APICaller, extraTypes?: string[], injectedConstructor?: any): ISavedObjectsRepository;
+ static createRepository(migrator: KibanaMigrator, typeRegistry: SavedObjectTypeRegistry, indexName: string, callCluster: APICaller, includedHiddenTypes?: string[], injectedConstructor?: any): ISavedObjectsRepository;
delete(type: string, id: string, options?: SavedObjectsDeleteOptions): Promise<{}>;
deleteByNamespace(namespace: string, options?: SavedObjectsDeleteByNamespaceOptions): Promise;
deleteFromNamespaces(type: string, id: string, namespaces: string[], options?: SavedObjectsDeleteFromNamespacesOptions): Promise<{}>;
@@ -2233,8 +2236,8 @@ export class SavedObjectsRepository {
// @public
export interface SavedObjectsRepositoryFactory {
- createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository;
- createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository;
+ createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository;
+ createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository;
}
// @public
@@ -2285,8 +2288,8 @@ export interface SavedObjectsServiceSetup {
// @public
export interface SavedObjectsServiceStart {
- createInternalRepository: (extraTypes?: string[]) => ISavedObjectsRepository;
- createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository;
+ createInternalRepository: (includedHiddenTypes?: string[]) => ISavedObjectsRepository;
+ createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) => ISavedObjectsRepository;
createSerializer: () => SavedObjectsSerializer;
getScopedClient: (req: KibanaRequest, options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract;
getTypeRegistry: () => ISavedObjectTypeRegistry;
diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.js b/src/legacy/server/saved_objects/saved_objects_mixin.js
index 3e71e1989ae7a..26fecc68fda4b 100644
--- a/src/legacy/server/saved_objects/saved_objects_mixin.js
+++ b/src/legacy/server/saved_objects/saved_objects_mixin.js
@@ -50,17 +50,17 @@ export function savedObjectsMixin(kbnServer, server) {
const serializer = kbnServer.newPlatform.start.core.savedObjects.createSerializer();
- const createRepository = (callCluster, extraTypes = []) => {
+ const createRepository = (callCluster, includedHiddenTypes = []) => {
if (typeof callCluster !== 'function') {
throw new TypeError('Repository requires a "callCluster" function to be provided.');
}
// throw an exception if an extraType is not defined.
- extraTypes.forEach(type => {
+ includedHiddenTypes.forEach(type => {
if (!allTypes.includes(type)) {
throw new Error(`Missing mappings for saved objects type '${type}'`);
}
});
- const combinedTypes = visibleTypes.concat(extraTypes);
+ const combinedTypes = visibleTypes.concat(includedHiddenTypes);
const allowedTypes = [...new Set(combinedTypes)];
const config = server.config();
diff --git a/x-pack/plugins/actions/server/lib/action_executor.test.ts b/x-pack/plugins/actions/server/lib/action_executor.test.ts
index 4594fc1ddf6d9..f1e5a10e5bbd2 100644
--- a/x-pack/plugins/actions/server/lib/action_executor.test.ts
+++ b/x-pack/plugins/actions/server/lib/action_executor.test.ts
@@ -18,7 +18,7 @@ import { actionsMock } from '../mocks';
const actionExecutor = new ActionExecutor({ isESOUsingEphemeralEncryptionKey: false });
const services = actionsMock.createServices();
const savedObjectsClient = services.savedObjectsClient;
-const encryptedSavedObjectsPlugin = encryptedSavedObjectsMock.createStart();
+const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient();
const actionTypeRegistry = actionTypeRegistryMock.create();
const executeParams = {
@@ -35,7 +35,7 @@ actionExecutor.initialize({
spaces: spacesMock,
getServices: () => services,
actionTypeRegistry,
- encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient,
eventLogger: eventLoggerMock.create(),
preconfiguredActions: [],
});
@@ -67,11 +67,11 @@ test('successfully executes', async () => {
references: [],
};
savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
actionTypeRegistry.get.mockReturnValueOnce(actionType);
await actionExecutor.execute(executeParams);
- expect(encryptedSavedObjectsPlugin.getDecryptedAsInternalUser).toHaveBeenCalledWith(
+ expect(encryptedSavedObjectsClient.getDecryptedAsInternalUser).toHaveBeenCalledWith(
'action',
'1',
{ namespace: 'some-namespace' }
@@ -108,7 +108,7 @@ test('provides empty config when config and / or secrets is empty', async () =>
references: [],
};
savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
actionTypeRegistry.get.mockReturnValueOnce(actionType);
await actionExecutor.execute(executeParams);
@@ -138,7 +138,7 @@ test('throws an error when config is invalid', async () => {
references: [],
};
savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
actionTypeRegistry.get.mockReturnValueOnce(actionType);
const result = await actionExecutor.execute(executeParams);
@@ -171,7 +171,7 @@ test('throws an error when params is invalid', async () => {
references: [],
};
savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
actionTypeRegistry.get.mockReturnValueOnce(actionType);
const result = await actionExecutor.execute(executeParams);
@@ -206,7 +206,7 @@ test('throws an error if actionType is not enabled', async () => {
references: [],
};
savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
actionTypeRegistry.get.mockReturnValueOnce(actionType);
actionTypeRegistry.ensureActionTypeEnabled.mockImplementationOnce(() => {
throw new Error('not enabled for test');
@@ -240,7 +240,7 @@ test('should not throws an error if actionType is preconfigured', async () => {
references: [],
};
savedObjectsClient.get.mockResolvedValueOnce(actionSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject);
actionTypeRegistry.get.mockReturnValueOnce(actionType);
actionTypeRegistry.ensureActionTypeEnabled.mockImplementationOnce(() => {
throw new Error('not enabled for test');
@@ -269,7 +269,7 @@ test('throws an error when passing isESOUsingEphemeralEncryptionKey with value o
spaces: spacesMock,
getServices: () => services,
actionTypeRegistry,
- encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient,
eventLogger: eventLoggerMock.create(),
preconfiguredActions: [],
});
diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts
index 3e9262c05efac..aad93a04248eb 100644
--- a/x-pack/plugins/actions/server/lib/action_executor.ts
+++ b/x-pack/plugins/actions/server/lib/action_executor.ts
@@ -14,7 +14,7 @@ import {
PreConfiguredAction,
Services,
} from '../types';
-import { EncryptedSavedObjectsPluginStart } from '../../../encrypted_saved_objects/server';
+import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server';
import { SpacesServiceSetup } from '../../../spaces/server';
import { EVENT_LOG_ACTIONS } from '../plugin';
import { IEvent, IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '../../../event_log/server';
@@ -23,7 +23,7 @@ export interface ActionExecutorContext {
logger: Logger;
spaces?: SpacesServiceSetup;
getServices: GetServicesFunction;
- encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart;
+ encryptedSavedObjectsClient: EncryptedSavedObjectsClient;
actionTypeRegistry: ActionTypeRegistryContract;
eventLogger: IEventLogger;
preconfiguredActions: PreConfiguredAction[];
@@ -72,7 +72,7 @@ export class ActionExecutor {
const {
spaces,
getServices,
- encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient,
actionTypeRegistry,
eventLogger,
preconfiguredActions,
@@ -84,7 +84,7 @@ export class ActionExecutor {
const { actionTypeId, name, config, secrets } = await getActionInfo(
services,
- encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient,
preconfiguredActions,
actionId,
namespace.namespace
@@ -196,7 +196,7 @@ interface ActionInfo {
async function getActionInfo(
services: Services,
- encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart,
+ encryptedSavedObjectsClient: EncryptedSavedObjectsClient,
preconfiguredActions: PreConfiguredAction[],
actionId: string,
namespace: string | undefined
@@ -222,7 +222,7 @@ async function getActionInfo(
const {
attributes: { secrets },
- } = await encryptedSavedObjectsPlugin.getDecryptedAsInternalUser('action', actionId, {
+ } = await encryptedSavedObjectsClient.getDecryptedAsInternalUser('action', actionId, {
namespace: namespace === 'default' ? undefined : namespace,
});
diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts
index f070f714ee508..42ccf5a33ebaa 100644
--- a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts
+++ b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts
@@ -18,7 +18,7 @@ import { ActionTypeDisabledError } from './errors';
const spaceIdToNamespace = jest.fn();
const actionTypeRegistry = actionTypeRegistryMock.create();
-const mockedEncryptedSavedObjectsPlugin = encryptedSavedObjectsMock.createStart();
+const mockedEncryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient();
const mockedActionExecutor = actionExecutorMock.create();
let fakeTimer: sinon.SinonFakeTimers;
@@ -59,7 +59,7 @@ const actionExecutorInitializerParams = {
logger: loggingServiceMock.create().get(),
getServices: jest.fn().mockReturnValue(services),
actionTypeRegistry,
- encryptedSavedObjectsPlugin: mockedEncryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient: mockedEncryptedSavedObjectsClient,
eventLogger: eventLoggerMock.create(),
preconfiguredActions: [],
};
@@ -67,7 +67,7 @@ const taskRunnerFactoryInitializerParams = {
spaceIdToNamespace,
actionTypeRegistry,
logger: loggingServiceMock.create().get(),
- encryptedSavedObjectsPlugin: mockedEncryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient: mockedEncryptedSavedObjectsClient,
getBasePath: jest.fn().mockReturnValue(undefined),
getScopedSavedObjectsClient: jest.fn().mockReturnValue(services.savedObjectsClient),
};
@@ -106,7 +106,7 @@ test('executes the task by calling the executor with proper parameters', async (
mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' });
spaceIdToNamespace.mockReturnValueOnce('namespace-test');
- mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '3',
type: 'action_task_params',
attributes: {
@@ -122,7 +122,7 @@ test('executes the task by calling the executor with proper parameters', async (
expect(runnerResult).toBeUndefined();
expect(spaceIdToNamespace).toHaveBeenCalledWith('test');
expect(
- mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser
+ mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser
).toHaveBeenCalledWith('action_task_params', '3', { namespace: 'namespace-test' });
expect(mockedActionExecutor.execute).toHaveBeenCalledWith({
actionId: '2',
@@ -154,7 +154,7 @@ test('cleans up action_task_params object', async () => {
mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' });
spaceIdToNamespace.mockReturnValueOnce('namespace-test');
- mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '3',
type: 'action_task_params',
attributes: {
@@ -177,7 +177,7 @@ test('runs successfully when cleanup fails and logs the error', async () => {
mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' });
spaceIdToNamespace.mockReturnValueOnce('namespace-test');
- mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '3',
type: 'action_task_params',
attributes: {
@@ -202,7 +202,7 @@ test('throws an error with suggested retry logic when return status is error', a
taskInstance: mockedTaskInstance,
});
- mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '3',
type: 'action_task_params',
attributes: {
@@ -237,7 +237,7 @@ test('uses API key when provided', async () => {
mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' });
spaceIdToNamespace.mockReturnValueOnce('namespace-test');
- mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '3',
type: 'action_task_params',
attributes: {
@@ -280,7 +280,7 @@ test(`doesn't use API key when not provided`, async () => {
mockedActionExecutor.execute.mockResolvedValueOnce({ status: 'ok', actionId: '2' });
spaceIdToNamespace.mockReturnValueOnce('namespace-test');
- mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '3',
type: 'action_task_params',
attributes: {
@@ -317,7 +317,7 @@ test(`throws an error when license doesn't support the action type`, async () =>
taskInstance: mockedTaskInstance,
});
- mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '3',
type: 'action_task_params',
attributes: {
diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.ts
index 08c5b90edbcb7..a962497f906a9 100644
--- a/x-pack/plugins/actions/server/lib/task_runner_factory.ts
+++ b/x-pack/plugins/actions/server/lib/task_runner_factory.ts
@@ -8,7 +8,7 @@ import { ActionExecutorContract } from './action_executor';
import { ExecutorError } from './executor_error';
import { Logger, CoreStart, KibanaRequest } from '../../../../../src/core/server';
import { RunContext } from '../../../task_manager/server';
-import { EncryptedSavedObjectsPluginStart } from '../../../encrypted_saved_objects/server';
+import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server';
import { ActionTypeDisabledError } from './errors';
import {
ActionTaskParams,
@@ -21,7 +21,7 @@ import {
export interface TaskRunnerContext {
logger: Logger;
actionTypeRegistry: ActionTypeRegistryContract;
- encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart;
+ encryptedSavedObjectsClient: EncryptedSavedObjectsClient;
spaceIdToNamespace: SpaceIdToNamespaceFunction;
getBasePath: GetBasePathFunction;
getScopedSavedObjectsClient: CoreStart['savedObjects']['getScopedClient'];
@@ -52,7 +52,7 @@ export class TaskRunnerFactory {
const { actionExecutor } = this;
const {
logger,
- encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient,
spaceIdToNamespace,
getBasePath,
getScopedSavedObjectsClient,
@@ -65,7 +65,7 @@ export class TaskRunnerFactory {
const {
attributes: { actionId, params, apiKey },
- } = await encryptedSavedObjectsPlugin.getDecryptedAsInternalUser(
+ } = await encryptedSavedObjectsClient.getDecryptedAsInternalUser(
'action_task_params',
actionTaskParamsId,
{ namespace }
diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts
index bc7440c8bee4d..75e15815d0787 100644
--- a/x-pack/plugins/actions/server/plugin.ts
+++ b/x-pack/plugins/actions/server/plugin.ts
@@ -232,12 +232,14 @@ export class ActionsPlugin implements Plugin, Plugi
preconfiguredActions,
} = this;
+ const encryptedSavedObjectsClient = plugins.encryptedSavedObjects.getClient();
+
actionExecutor!.initialize({
logger,
eventLogger: this.eventLogger!,
spaces: this.spaces,
getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch),
- encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects,
+ encryptedSavedObjectsClient,
actionTypeRegistry: actionTypeRegistry!,
preconfiguredActions,
});
@@ -245,7 +247,7 @@ export class ActionsPlugin implements Plugin, Plugi
taskRunnerFactory!.initialize({
logger,
actionTypeRegistry: actionTypeRegistry!,
- encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects,
+ encryptedSavedObjectsClient,
getBasePath: this.getBasePath,
spaceIdToNamespace: this.spaceIdToNamespace,
getScopedSavedObjectsClient: core.savedObjects.getScopedClient,
diff --git a/x-pack/plugins/alerting/server/alerts_client.test.ts b/x-pack/plugins/alerting/server/alerts_client.test.ts
index 6601ccc4f5a73..93b98f6a0fe03 100644
--- a/x-pack/plugins/alerting/server/alerts_client.test.ts
+++ b/x-pack/plugins/alerting/server/alerts_client.test.ts
@@ -17,7 +17,7 @@ import { encryptedSavedObjectsMock } from '../../../plugins/encrypted_saved_obje
const taskManager = taskManagerMock.start();
const alertTypeRegistry = alertTypeRegistryMock.create();
const savedObjectsClient = savedObjectsClientMock.create();
-const encryptedSavedObjects = encryptedSavedObjectsMock.createStart();
+const encryptedSavedObjects = encryptedSavedObjectsMock.createClient();
const alertsClientParams = {
taskManager,
@@ -29,7 +29,7 @@ const alertsClientParams = {
createAPIKey: jest.fn(),
invalidateAPIKey: jest.fn(),
logger: loggingServiceMock.create().get(),
- encryptedSavedObjectsPlugin: encryptedSavedObjects,
+ encryptedSavedObjectsClient: encryptedSavedObjects,
preconfiguredActions: [],
};
diff --git a/x-pack/plugins/alerting/server/alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client.ts
index ff501055ba9fe..01687f33f631d 100644
--- a/x-pack/plugins/alerting/server/alerts_client.ts
+++ b/x-pack/plugins/alerting/server/alerts_client.ts
@@ -32,7 +32,7 @@ import {
GrantAPIKeyResult as SecurityPluginGrantAPIKeyResult,
InvalidateAPIKeyResult as SecurityPluginInvalidateAPIKeyResult,
} from '../../../plugins/security/server';
-import { EncryptedSavedObjectsPluginStart } from '../../../plugins/encrypted_saved_objects/server';
+import { EncryptedSavedObjectsClient } from '../../../plugins/encrypted_saved_objects/server';
import { TaskManagerStartContract } from '../../../plugins/task_manager/server';
import { taskInstanceToAlertTaskInstance } from './task_runner/alert_task_instance';
import { deleteTaskIfItExists } from './lib/delete_task_if_it_exists';
@@ -50,7 +50,7 @@ interface ConstructorOptions {
taskManager: TaskManagerStartContract;
savedObjectsClient: SavedObjectsClientContract;
alertTypeRegistry: AlertTypeRegistry;
- encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart;
+ encryptedSavedObjectsClient: EncryptedSavedObjectsClient;
spaceId?: string;
namespace?: string;
getUserName: () => Promise;
@@ -128,7 +128,7 @@ export class AlertsClient {
params: InvalidateAPIKeyParams
) => Promise;
private preconfiguredActions: PreConfiguredAction[];
- encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart;
+ encryptedSavedObjectsClient: EncryptedSavedObjectsClient;
constructor({
alertTypeRegistry,
@@ -140,7 +140,7 @@ export class AlertsClient {
getUserName,
createAPIKey,
invalidateAPIKey,
- encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient,
preconfiguredActions,
}: ConstructorOptions) {
this.logger = logger;
@@ -152,7 +152,7 @@ export class AlertsClient {
this.savedObjectsClient = savedObjectsClient;
this.createAPIKey = createAPIKey;
this.invalidateAPIKey = invalidateAPIKey;
- this.encryptedSavedObjectsPlugin = encryptedSavedObjectsPlugin;
+ this.encryptedSavedObjectsClient = encryptedSavedObjectsClient;
this.preconfiguredActions = preconfiguredActions;
}
@@ -252,7 +252,7 @@ export class AlertsClient {
let apiKeyToInvalidate: string | null = null;
try {
- const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser<
+ const decryptedAlert = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<
RawAlert
>('alert', id, { namespace: this.namespace });
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
@@ -281,7 +281,7 @@ export class AlertsClient {
let alertSavedObject: SavedObject;
try {
- alertSavedObject = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser<
+ alertSavedObject = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<
RawAlert
>('alert', id, { namespace: this.namespace });
} catch (e) {
@@ -377,7 +377,7 @@ export class AlertsClient {
let version: string | undefined;
try {
- const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser<
+ const decryptedAlert = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<
RawAlert
>('alert', id, { namespace: this.namespace });
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
@@ -435,7 +435,7 @@ export class AlertsClient {
let version: string | undefined;
try {
- const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser<
+ const decryptedAlert = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<
RawAlert
>('alert', id, { namespace: this.namespace });
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
@@ -479,7 +479,7 @@ export class AlertsClient {
let version: string | undefined;
try {
- const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser<
+ const decryptedAlert = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<
RawAlert
>('alert', id, { namespace: this.namespace });
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
@@ -543,7 +543,7 @@ export class AlertsClient {
alertId: string;
alertInstanceId: string;
}) {
- const { attributes, version } = await this.savedObjectsClient.get('alert', alertId);
+ const { attributes, version } = await this.savedObjectsClient.get('alert', alertId);
const mutedInstanceIds = attributes.mutedInstanceIds || [];
if (!attributes.muteAll && !mutedInstanceIds.includes(alertInstanceId)) {
mutedInstanceIds.push(alertInstanceId);
@@ -566,7 +566,7 @@ export class AlertsClient {
alertId: string;
alertInstanceId: string;
}) {
- const { attributes, version } = await this.savedObjectsClient.get('alert', alertId);
+ const { attributes, version } = await this.savedObjectsClient.get('alert', alertId);
const mutedInstanceIds = attributes.mutedInstanceIds || [];
if (!attributes.muteAll && mutedInstanceIds.includes(alertInstanceId)) {
await this.savedObjectsClient.update(
diff --git a/x-pack/plugins/alerting/server/alerts_client_factory.test.ts b/x-pack/plugins/alerting/server/alerts_client_factory.test.ts
index e5aa0a674eccf..cc792d11c890d 100644
--- a/x-pack/plugins/alerting/server/alerts_client_factory.test.ts
+++ b/x-pack/plugins/alerting/server/alerts_client_factory.test.ts
@@ -24,7 +24,7 @@ const alertsClientFactoryParams: jest.Mocked = {
alertTypeRegistry: alertTypeRegistryMock.create(),
getSpaceId: jest.fn(),
spaceIdToNamespace: jest.fn(),
- encryptedSavedObjectsPlugin: encryptedSavedObjectsMock.createStart(),
+ encryptedSavedObjectsClient: encryptedSavedObjectsMock.createClient(),
preconfiguredActions: [],
};
const fakeRequest = ({
@@ -64,7 +64,7 @@ test('creates an alerts client with proper constructor arguments', async () => {
getUserName: expect.any(Function),
createAPIKey: expect.any(Function),
invalidateAPIKey: expect.any(Function),
- encryptedSavedObjectsPlugin: alertsClientFactoryParams.encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient: alertsClientFactoryParams.encryptedSavedObjectsClient,
preconfiguredActions: [],
});
});
diff --git a/x-pack/plugins/alerting/server/alerts_client_factory.ts b/x-pack/plugins/alerting/server/alerts_client_factory.ts
index 734417e72733e..913b4e2e81fe1 100644
--- a/x-pack/plugins/alerting/server/alerts_client_factory.ts
+++ b/x-pack/plugins/alerting/server/alerts_client_factory.ts
@@ -9,7 +9,7 @@ import { AlertsClient } from './alerts_client';
import { AlertTypeRegistry, SpaceIdToNamespaceFunction } from './types';
import { KibanaRequest, Logger, SavedObjectsClientContract } from '../../../../src/core/server';
import { InvalidateAPIKeyParams, SecurityPluginSetup } from '../../../plugins/security/server';
-import { EncryptedSavedObjectsPluginStart } from '../../../plugins/encrypted_saved_objects/server';
+import { EncryptedSavedObjectsClient } from '../../../plugins/encrypted_saved_objects/server';
import { TaskManagerStartContract } from '../../../plugins/task_manager/server';
export interface AlertsClientFactoryOpts {
@@ -19,7 +19,7 @@ export interface AlertsClientFactoryOpts {
securityPluginSetup?: SecurityPluginSetup;
getSpaceId: (request: KibanaRequest) => string | undefined;
spaceIdToNamespace: SpaceIdToNamespaceFunction;
- encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart;
+ encryptedSavedObjectsClient: EncryptedSavedObjectsClient;
preconfiguredActions: PreConfiguredAction[];
}
@@ -31,7 +31,7 @@ export class AlertsClientFactory {
private securityPluginSetup?: SecurityPluginSetup;
private getSpaceId!: (request: KibanaRequest) => string | undefined;
private spaceIdToNamespace!: SpaceIdToNamespaceFunction;
- private encryptedSavedObjectsPlugin!: EncryptedSavedObjectsPluginStart;
+ private encryptedSavedObjectsClient!: EncryptedSavedObjectsClient;
private preconfiguredActions!: PreConfiguredAction[];
public initialize(options: AlertsClientFactoryOpts) {
@@ -45,7 +45,7 @@ export class AlertsClientFactory {
this.alertTypeRegistry = options.alertTypeRegistry;
this.securityPluginSetup = options.securityPluginSetup;
this.spaceIdToNamespace = options.spaceIdToNamespace;
- this.encryptedSavedObjectsPlugin = options.encryptedSavedObjectsPlugin;
+ this.encryptedSavedObjectsClient = options.encryptedSavedObjectsClient;
this.preconfiguredActions = options.preconfiguredActions;
}
@@ -62,7 +62,7 @@ export class AlertsClientFactory {
alertTypeRegistry: this.alertTypeRegistry,
savedObjectsClient,
namespace: this.spaceIdToNamespace(spaceId),
- encryptedSavedObjectsPlugin: this.encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient: this.encryptedSavedObjectsClient,
async getUserName() {
if (!securityPluginSetup) {
return null;
diff --git a/x-pack/plugins/alerting/server/plugin.test.ts b/x-pack/plugins/alerting/server/plugin.test.ts
index 267e68930a5d7..0411899290ab2 100644
--- a/x-pack/plugins/alerting/server/plugin.test.ts
+++ b/x-pack/plugins/alerting/server/plugin.test.ts
@@ -81,6 +81,7 @@ describe('Alerting Plugin', () => {
execute: jest.fn(),
getActionsClientWithRequest: jest.fn(),
},
+ encryptedSavedObjects: encryptedSavedObjectsMock.createStart(),
} as unknown) as AlertingPluginsStart
);
@@ -125,6 +126,7 @@ describe('Alerting Plugin', () => {
getActionsClientWithRequest: jest.fn(),
},
spaces: () => null,
+ encryptedSavedObjects: encryptedSavedObjectsMock.createStart(),
} as unknown) as AlertingPluginsStart
);
diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts
index 7bd515616a3c1..0835365635990 100644
--- a/x-pack/plugins/alerting/server/plugin.ts
+++ b/x-pack/plugins/alerting/server/plugin.ts
@@ -201,12 +201,14 @@ export class AlertingPlugin {
security,
} = this;
+ const encryptedSavedObjectsClient = plugins.encryptedSavedObjects.getClient();
+
alertsClientFactory.initialize({
alertTypeRegistry: alertTypeRegistry!,
logger,
taskManager: plugins.taskManager,
securityPluginSetup: security,
- encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects,
+ encryptedSavedObjectsClient,
spaceIdToNamespace: this.spaceIdToNamespace,
getSpaceId(request: KibanaRequest) {
return spaces?.getSpaceId(request);
@@ -219,7 +221,7 @@ export class AlertingPlugin {
getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch),
spaceIdToNamespace: this.spaceIdToNamespace,
actionsPlugin: plugins.actions,
- encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects,
+ encryptedSavedObjectsClient,
getBasePath: this.getBasePath,
eventLogger: this.eventLogger!,
});
diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts
index e5ec8f587b9d7..98824b8cf4e1a 100644
--- a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts
+++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts
@@ -54,7 +54,7 @@ describe('Task Runner', () => {
afterAll(() => fakeTimer.restore());
- const encryptedSavedObjectsPlugin = encryptedSavedObjectsMock.createStart();
+ const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient();
const services = alertsMock.createAlertServices();
const savedObjectsClient = services.savedObjectsClient;
@@ -64,7 +64,7 @@ describe('Task Runner', () => {
} = {
getServices: jest.fn().mockReturnValue(services),
actionsPlugin: actionsMock.createStart(),
- encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient,
logger: loggingServiceMock.create().get(),
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
getBasePath: jest.fn().mockReturnValue(undefined),
@@ -123,7 +123,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -197,7 +197,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -316,7 +316,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -403,7 +403,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -434,7 +434,7 @@ describe('Task Runner', () => {
...mockedAlertTypeSavedObject,
references: [],
});
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -462,7 +462,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -498,7 +498,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {},
@@ -537,7 +537,7 @@ describe('Task Runner', () => {
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -588,7 +588,7 @@ describe('Task Runner', () => {
});
test('recovers gracefully when the Alert Task Runner throws an exception when fetching the encrypted attributes', async () => {
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockImplementation(() => {
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockImplementation(() => {
throw new Error('OMG');
});
@@ -624,7 +624,7 @@ describe('Task Runner', () => {
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -656,7 +656,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
@@ -688,7 +688,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);
- encryptedSavedObjectsPlugin.getDecryptedAsInternalUser.mockResolvedValueOnce({
+ encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts
index bf005301adc07..a36152fa17544 100644
--- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts
+++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts
@@ -62,7 +62,7 @@ export class TaskRunner {
// scoped with the API key to fetch the remaining data.
const {
attributes: { apiKey },
- } = await this.context.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser(
+ } = await this.context.encryptedSavedObjectsClient.getDecryptedAsInternalUser(
'alert',
alertId,
{ namespace }
diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts
index 96d89bebcc66f..c1318bac48dfb 100644
--- a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts
+++ b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts
@@ -56,7 +56,7 @@ describe('Task Runner Factory', () => {
const taskRunnerFactoryInitializerParams: jest.Mocked = {
getServices: jest.fn().mockReturnValue(services),
actionsPlugin: actionsMock.createStart(),
- encryptedSavedObjectsPlugin,
+ encryptedSavedObjectsClient: encryptedSavedObjectsPlugin.getClient(),
logger: loggingServiceMock.create().get(),
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
getBasePath: jest.fn().mockReturnValue(undefined),
diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts
index b58db8c74f7bb..c50e288d2e520 100644
--- a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts
+++ b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts
@@ -5,7 +5,7 @@
*/
import { Logger } from '../../../../../src/core/server';
import { RunContext } from '../../../../plugins/task_manager/server';
-import { EncryptedSavedObjectsPluginStart } from '../../../../plugins/encrypted_saved_objects/server';
+import { EncryptedSavedObjectsClient } from '../../../../plugins/encrypted_saved_objects/server';
import { PluginStartContract as ActionsPluginStartContract } from '../../../../plugins/actions/server';
import {
AlertType,
@@ -21,7 +21,7 @@ export interface TaskRunnerContext {
getServices: GetServicesFunction;
actionsPlugin: ActionsPluginStartContract;
eventLogger: IEventLogger;
- encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart;
+ encryptedSavedObjectsClient: EncryptedSavedObjectsClient;
spaceIdToNamespace: SpaceIdToNamespaceFunction;
getBasePath: GetBasePathFunction;
}
diff --git a/x-pack/plugins/encrypted_saved_objects/server/index.ts b/x-pack/plugins/encrypted_saved_objects/server/index.ts
index 3b4b91de355c7..c8f7acf952c22 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/index.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/index.ts
@@ -10,6 +10,7 @@ import { Plugin } from './plugin';
export { EncryptedSavedObjectTypeRegistration, EncryptionError } from './crypto';
export { EncryptedSavedObjectsPluginSetup, EncryptedSavedObjectsPluginStart } from './plugin';
+export { EncryptedSavedObjectsClient } from './saved_objects';
export const config = { schema: ConfigSchema };
export const plugin = (initializerContext: PluginInitializerContext) =>
diff --git a/x-pack/plugins/encrypted_saved_objects/server/mocks.ts b/x-pack/plugins/encrypted_saved_objects/server/mocks.ts
index 13d7127db7835..bbc3eb1540562 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/mocks.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/mocks.ts
@@ -5,6 +5,7 @@
*/
import { EncryptedSavedObjectsPluginSetup, EncryptedSavedObjectsPluginStart } from './plugin';
+import { EncryptedSavedObjectsClient } from './saved_objects';
function createEncryptedSavedObjectsSetupMock() {
return {
@@ -17,11 +18,18 @@ function createEncryptedSavedObjectsSetupMock() {
function createEncryptedSavedObjectsStartMock() {
return {
isEncryptionError: jest.fn(),
- getDecryptedAsInternalUser: jest.fn(),
+ getClient: jest.fn(() => createEncryptedSavedObjectsClienttMock()),
} as jest.Mocked;
}
+function createEncryptedSavedObjectsClienttMock() {
+ return {
+ getDecryptedAsInternalUser: jest.fn(),
+ } as jest.Mocked;
+}
+
export const encryptedSavedObjectsMock = {
createSetup: createEncryptedSavedObjectsSetupMock,
createStart: createEncryptedSavedObjectsStartMock,
+ createClient: createEncryptedSavedObjectsClienttMock,
};
diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts
index 117adba5794d7..e8568e9964c2f 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts
@@ -30,12 +30,20 @@ describe('EncryptedSavedObjects Plugin', () => {
it('exposes proper contract', async () => {
const plugin = new Plugin(coreMock.createPluginInitializerContext());
await plugin.setup(coreMock.createSetup(), { security: securityMock.createSetup() });
- await expect(plugin.start()).toMatchInlineSnapshot(`
+
+ const startContract = plugin.start();
+ await expect(startContract).toMatchInlineSnapshot(`
Object {
- "getDecryptedAsInternalUser": [Function],
+ "getClient": [Function],
"isEncryptionError": [Function],
}
`);
+
+ expect(startContract.getClient()).toMatchInlineSnapshot(`
+ Object {
+ "getDecryptedAsInternalUser": [Function],
+ }
+ `);
});
});
});
diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts
index 02212f271cf83..948cb94512f2c 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts
@@ -4,12 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import {
- Logger,
- SavedObjectsBaseOptions,
- PluginInitializerContext,
- CoreSetup,
-} from 'src/core/server';
+import { Logger, PluginInitializerContext, CoreSetup } from 'src/core/server';
import { first } from 'rxjs/operators';
import { SecurityPluginSetup } from '../../security/server';
import { createConfig$ } from './config';
@@ -31,8 +26,9 @@ export interface EncryptedSavedObjectsPluginSetup {
usingEphemeralEncryptionKey: boolean;
}
-export interface EncryptedSavedObjectsPluginStart extends SavedObjectsSetup {
+export interface EncryptedSavedObjectsPluginStart {
isEncryptionError: (error: Error) => boolean;
+ getClient: SavedObjectsSetup;
}
/**
@@ -97,12 +93,9 @@ export class Plugin {
public start() {
this.logger.debug('Starting plugin');
-
return {
isEncryptionError: (error: Error) => error instanceof EncryptionError,
- getDecryptedAsInternalUser: (type: string, id: string, options?: SavedObjectsBaseOptions) => {
- return this.savedObjectsSetup.getDecryptedAsInternalUser(type, id, options);
- },
+ getClient: (includedHiddenTypes?: string[]) => this.savedObjectsSetup(includedHiddenTypes),
};
}
diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.test.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.test.ts
index c11f6a2b2afa8..8f0eb855676ad 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.test.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.test.ts
@@ -25,12 +25,13 @@ import { EncryptedSavedObjectsService } from '../crypto';
describe('#setupSavedObjects', () => {
let setupContract: SavedObjectsSetup;
+ let coreStartMock: ReturnType;
let coreSetupMock: ReturnType;
let mockSavedObjectsRepository: jest.Mocked;
let mockSavedObjectTypeRegistry: jest.Mocked;
let mockEncryptedSavedObjectsService: jest.Mocked;
beforeEach(() => {
- const coreStartMock = coreMock.createStart();
+ coreStartMock = coreMock.createStart();
mockSavedObjectsRepository = savedObjectsRepositoryMock.create();
coreStartMock.savedObjects.createInternalRepository.mockReturnValue(mockSavedObjectsRepository);
@@ -70,6 +71,33 @@ describe('#setupSavedObjects', () => {
).toBeInstanceOf(EncryptedSavedObjectsClientWrapper);
});
+ it('properly registers client wrapper factory with', () => {
+ expect(coreSetupMock.savedObjects.addClientWrapper).toHaveBeenCalledTimes(1);
+ expect(coreSetupMock.savedObjects.addClientWrapper).toHaveBeenCalledWith(
+ Number.MAX_SAFE_INTEGER,
+ 'encryptedSavedObjects',
+ expect.any(Function)
+ );
+
+ const [[, , clientFactory]] = coreSetupMock.savedObjects.addClientWrapper.mock.calls;
+ expect(
+ clientFactory({
+ client: savedObjectsClientMock.create(),
+ typeRegistry: savedObjectsTypeRegistryMock.create(),
+ request: httpServerMock.createKibanaRequest(),
+ })
+ ).toBeInstanceOf(EncryptedSavedObjectsClientWrapper);
+ });
+
+ describe('#setupContract', () => {
+ it('includes hiddenTypes when specified', async () => {
+ await setupContract(['hiddenType']);
+ expect(coreStartMock.savedObjects.createInternalRepository).toHaveBeenCalledWith([
+ 'hiddenType',
+ ]);
+ });
+ });
+
describe('#getDecryptedAsInternalUser', () => {
it('includes `namespace` for single-namespace saved objects', async () => {
const mockSavedObject: SavedObject = {
@@ -82,7 +110,7 @@ describe('#setupSavedObjects', () => {
mockSavedObjectTypeRegistry.isSingleNamespace.mockReturnValue(true);
await expect(
- setupContract.getDecryptedAsInternalUser(mockSavedObject.type, mockSavedObject.id, {
+ setupContract().getDecryptedAsInternalUser(mockSavedObject.type, mockSavedObject.id, {
namespace: 'some-ns',
})
).resolves.toEqual({
@@ -115,7 +143,7 @@ describe('#setupSavedObjects', () => {
mockSavedObjectTypeRegistry.isSingleNamespace.mockReturnValue(false);
await expect(
- setupContract.getDecryptedAsInternalUser(mockSavedObject.type, mockSavedObject.id, {
+ setupContract().getDecryptedAsInternalUser(mockSavedObject.type, mockSavedObject.id, {
namespace: 'some-ns',
})
).resolves.toEqual({
diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts
index 9eca93ffd0b9e..67bbaab75425a 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/index.ts
@@ -23,7 +23,9 @@ interface SetupSavedObjectsParams {
getStartServices: StartServicesAccessor;
}
-export interface SavedObjectsSetup {
+export type SavedObjectsSetup = (includedHiddenTypes?: string[]) => EncryptedSavedObjectsClient;
+
+export interface EncryptedSavedObjectsClient {
getDecryptedAsInternalUser: (
type: string,
id: string,
@@ -54,33 +56,34 @@ export function setupSavedObjects({
})
);
- const internalRepositoryAndTypeRegistryPromise = getStartServices().then(
- ([core]) =>
- [core.savedObjects.createInternalRepository(), core.savedObjects.getTypeRegistry()] as [
- ISavedObjectsRepository,
- ISavedObjectTypeRegistry
- ]
- );
-
- return {
- getDecryptedAsInternalUser: async (
- type: string,
- id: string,
- options?: SavedObjectsBaseOptions
- ): Promise> => {
- const [internalRepository, typeRegistry] = await internalRepositoryAndTypeRegistryPromise;
- const savedObject = await internalRepository.get(type, id, options);
- return {
- ...savedObject,
- attributes: (await service.decryptAttributes(
- {
- type,
- id,
- namespace: typeRegistry.isSingleNamespace(type) ? options?.namespace : undefined,
- },
- savedObject.attributes as Record
- )) as T,
- };
- },
+ return (includedHiddenTypes?: string[]) => {
+ const internalRepositoryAndTypeRegistryPromise = getStartServices().then(
+ ([core]) =>
+ [
+ core.savedObjects.createInternalRepository(includedHiddenTypes),
+ core.savedObjects.getTypeRegistry(),
+ ] as [ISavedObjectsRepository, ISavedObjectTypeRegistry]
+ );
+ return {
+ getDecryptedAsInternalUser: async (
+ type: string,
+ id: string,
+ options?: SavedObjectsBaseOptions
+ ): Promise> => {
+ const [internalRepository, typeRegistry] = await internalRepositoryAndTypeRegistryPromise;
+ const savedObject = await internalRepository.get(type, id, options);
+ return {
+ ...savedObject,
+ attributes: (await service.decryptAttributes(
+ {
+ type,
+ id,
+ namespace: typeRegistry.isSingleNamespace(type) ? options?.namespace : undefined,
+ },
+ savedObject.attributes as Record
+ )) as T,
+ };
+ },
+ };
};
}
diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts
index ae0dedce178a8..0d22529fdb031 100644
--- a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts
+++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts
@@ -22,11 +22,15 @@ import { IngestManagerAppContext } from '../../plugin';
describe('test agent acks services', () => {
it('should succeed on valid and matched actions', async () => {
const mockSavedObjectsClient = savedObjectsClientMock.create();
- const mockStartEncryptedSOClient = encryptedSavedObjectsMock.createStart();
+ const mockStartEncryptedSOPlugin = encryptedSavedObjectsMock.createStart();
appContextService.start(({
- encryptedSavedObjects: mockStartEncryptedSOClient,
+ encryptedSavedObjects: mockStartEncryptedSOPlugin,
} as unknown) as IngestManagerAppContext);
+ const [
+ { value: mockStartEncryptedSOClient },
+ ] = mockStartEncryptedSOPlugin.getClient.mock.results;
+
mockStartEncryptedSOClient.getDecryptedAsInternalUser.mockReturnValue(
Promise.resolve({
id: 'action1',
diff --git a/x-pack/plugins/ingest_manager/server/services/app_context.ts b/x-pack/plugins/ingest_manager/server/services/app_context.ts
index 91b09d651bf5c..9e6220b6958f1 100644
--- a/x-pack/plugins/ingest_manager/server/services/app_context.ts
+++ b/x-pack/plugins/ingest_manager/server/services/app_context.ts
@@ -6,14 +6,14 @@
import { BehaviorSubject, Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { SavedObjectsServiceStart, HttpServiceSetup, Logger } from 'src/core/server';
-import { EncryptedSavedObjectsPluginStart } from '../../../encrypted_saved_objects/server';
+import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server';
import { SecurityPluginSetup } from '../../../security/server';
import { IngestManagerConfigType } from '../../common';
import { IngestManagerAppContext } from '../plugin';
import { CloudSetup } from '../../../cloud/server';
class AppContextService {
- private encryptedSavedObjects: EncryptedSavedObjectsPluginStart | undefined;
+ private encryptedSavedObjects: EncryptedSavedObjectsClient | undefined;
private security: SecurityPluginSetup | undefined;
private config$?: Observable;
private configSubject$?: BehaviorSubject;
@@ -25,7 +25,7 @@ class AppContextService {
private httpSetup?: HttpServiceSetup;
public async start(appContext: IngestManagerAppContext) {
- this.encryptedSavedObjects = appContext.encryptedSavedObjects;
+ this.encryptedSavedObjects = appContext.encryptedSavedObjects?.getClient();
this.security = appContext.security;
this.savedObjects = appContext.savedObjects;
this.isProductionMode = appContext.isProductionMode;
diff --git a/x-pack/plugins/security/server/saved_objects/index.ts b/x-pack/plugins/security/server/saved_objects/index.ts
index 7dac745fcf84b..40c17e5429aa8 100644
--- a/x-pack/plugins/security/server/saved_objects/index.ts
+++ b/x-pack/plugins/security/server/saved_objects/index.ts
@@ -31,12 +31,12 @@ export function setupSavedObjects({
const getKibanaRequest = (request: KibanaRequest | LegacyRequest) =>
request instanceof KibanaRequest ? request : KibanaRequest.from(request);
- savedObjects.setClientFactoryProvider(repositoryFactory => ({ request }) => {
+ savedObjects.setClientFactoryProvider(repositoryFactory => ({ request, includedHiddenTypes }) => {
const kibanaRequest = getKibanaRequest(request);
return new SavedObjectsClient(
authz.mode.useRbacForRequest(kibanaRequest)
- ? repositoryFactory.createInternalRepository()
- : repositoryFactory.createScopedRepository(kibanaRequest)
+ ? repositoryFactory.createInternalRepository(includedHiddenTypes)
+ : repositoryFactory.createScopedRepository(kibanaRequest, includedHiddenTypes)
);
});
diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/server/plugin.ts
index 0e9c71d8c20c8..4908b3338a10a 100644
--- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/server/plugin.ts
+++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/server/plugin.ts
@@ -48,9 +48,11 @@ export class FixturePlugin implements Plugin,
+ deps: PluginsSetup,
+ hiddenTypes: string[]
+) {
+ router.get(
+ {
+ path: '/api/hidden_saved_objects/get-decrypted-as-internal-user/{type}/{id}',
+ validate: { params: value => ({ value }) },
+ },
+ async (context, request, response) => {
+ const [, { encryptedSavedObjects }] = await core.getStartServices();
+ const spaceId = deps.spaces.spacesService.getSpaceId(request);
+ const namespace = deps.spaces.spacesService.spaceIdToNamespace(spaceId);
+ try {
+ return response.ok({
+ body: await encryptedSavedObjects
+ .getClient([request.params.type])
+ .getDecryptedAsInternalUser(request.params.type, request.params.id, { namespace }),
+ });
+ } catch (err) {
+ if (encryptedSavedObjects.isEncryptionError(err)) {
+ return response.badRequest({ body: 'Failed to encrypt attributes' });
+ }
+
+ return response.customError({ body: err, statusCode: 500 });
+ }
+ }
+ );
+
+ router.get(
+ {
+ path: '/api/hidden_saved_objects/_find',
+ validate: {
+ query: schema.object({
+ per_page: schema.number({ min: 0, defaultValue: 20 }),
+ page: schema.number({ min: 0, defaultValue: 1 }),
+ type: schema.oneOf([schema.string(), schema.arrayOf(schema.string())]),
+ search: schema.maybe(schema.string()),
+ default_search_operator: schema.oneOf([schema.literal('OR'), schema.literal('AND')], {
+ defaultValue: 'OR',
+ }),
+ search_fields: schema.maybe(
+ schema.oneOf([schema.string(), schema.arrayOf(schema.string())])
+ ),
+ sort_field: schema.maybe(schema.string()),
+ has_reference: schema.maybe(
+ schema.object({
+ type: schema.string(),
+ id: schema.string(),
+ })
+ ),
+ fields: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
+ filter: schema.maybe(schema.string()),
+ }),
+ },
+ },
+ async (context, request, response) => {
+ const query = request.query;
+ const [{ savedObjects }] = await core.getStartServices();
+ return response.ok({
+ body: await savedObjects
+ .getScopedClient(request, { includedHiddenTypes: hiddenTypes })
+ .find({
+ perPage: query.per_page,
+ page: query.page,
+ type: Array.isArray(query.type) ? query.type : [query.type],
+ search: query.search,
+ defaultSearchOperator: query.default_search_operator,
+ searchFields:
+ typeof query.search_fields === 'string' ? [query.search_fields] : query.search_fields,
+ sortField: query.sort_field,
+ hasReference: query.has_reference,
+ fields: typeof query.fields === 'string' ? [query.fields] : query.fields,
+ filter: query.filter,
+ }),
+ });
+ }
+ );
+
+ router.get(
+ {
+ path: '/api/hidden_saved_objects/{type}/{id}',
+ validate: { params: value => ({ value }) },
+ },
+ async (context, request, response) => {
+ const [{ savedObjects }] = await core.getStartServices();
+ return response.ok({
+ body: await savedObjects
+ .getScopedClient(request, { includedHiddenTypes: hiddenTypes })
+ .get(request.params.type, request.params.id),
+ });
+ }
+ );
+ router.post(
+ {
+ path: '/api/hidden_saved_objects/{type}',
+ validate: {
+ params: schema.object({
+ type: schema.string(),
+ id: schema.maybe(schema.string()),
+ }),
+ query: schema.object({
+ overwrite: schema.boolean({ defaultValue: false }),
+ }),
+ body: schema.object({
+ attributes: schema.recordOf(schema.string(), schema.any()),
+ migrationVersion: schema.maybe(schema.recordOf(schema.string(), schema.string())),
+ references: schema.maybe(
+ schema.arrayOf(
+ schema.object({
+ name: schema.string(),
+ type: schema.string(),
+ id: schema.string(),
+ })
+ )
+ ),
+ }),
+ },
+ },
+ async (context, request, response) => {
+ const [{ savedObjects }] = await core.getStartServices();
+ const { type, id } = request.params;
+ const { attributes, migrationVersion, references } = request.body as any;
+ const options = { id, migrationVersion, references };
+ const so = await savedObjects
+ .getScopedClient(request, { includedHiddenTypes: hiddenTypes })
+ .create(type, attributes, options);
+ return response.ok({
+ body: so,
+ });
+ }
+ );
+ router.put(
+ {
+ path: '/api/hidden_saved_objects/{type}/{id}',
+ validate: {
+ params: schema.object({
+ type: schema.string(),
+ id: schema.string(),
+ }),
+ body: schema.object({
+ attributes: schema.recordOf(schema.string(), schema.any()),
+ version: schema.maybe(schema.string()),
+ references: schema.maybe(
+ schema.arrayOf(
+ schema.object({
+ name: schema.string(),
+ type: schema.string(),
+ id: schema.string(),
+ })
+ )
+ ),
+ }),
+ },
+ },
+ async (context, request, response) => {
+ const [{ savedObjects }] = await core.getStartServices();
+ const { type, id } = request.params as any;
+ const { attributes, version, references } = request.body as any;
+ const options = { version, references };
+ return response.ok({
+ body: await savedObjects
+ .getScopedClient(request, { includedHiddenTypes: hiddenTypes })
+ .update(type, id, attributes, options),
+ });
+ }
+ );
+ router.post(
+ {
+ path: '/api/hidden_saved_objects/_bulk_get',
+ validate: {
+ body: schema.arrayOf(
+ schema.object({
+ type: schema.string(),
+ id: schema.string(),
+ fields: schema.maybe(schema.arrayOf(schema.string())),
+ })
+ ),
+ },
+ },
+ async (context, request, response) => {
+ const [{ savedObjects }] = await core.getStartServices();
+ return response.ok({
+ body: await savedObjects
+ .getScopedClient(request, { includedHiddenTypes: hiddenTypes })
+ .bulkGet(request.body as any),
+ });
+ }
+ );
+ router.post(
+ {
+ path: '/api/hidden_saved_objects/_bulk_create',
+ validate: {
+ body: schema.arrayOf(
+ schema.object({
+ type: schema.string(),
+ id: schema.maybe(schema.string()),
+ attributes: schema.recordOf(schema.string(), schema.any()),
+ version: schema.maybe(schema.string()),
+ migrationVersion: schema.maybe(schema.recordOf(schema.string(), schema.string())),
+ references: schema.maybe(
+ schema.arrayOf(
+ schema.object({
+ name: schema.string(),
+ type: schema.string(),
+ id: schema.string(),
+ })
+ )
+ ),
+ })
+ ),
+ },
+ },
+ async (context, request, response) => {
+ const [{ savedObjects }] = await core.getStartServices();
+ return response.ok({
+ body: await savedObjects
+ .getScopedClient(request, { includedHiddenTypes: hiddenTypes })
+ .bulkCreate(request.body as any),
+ });
+ }
+ );
+}
diff --git a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts
index 46bb7f8024620..b0b73a54ceefe 100644
--- a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts
+++ b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts
@@ -15,31 +15,34 @@ import {
EncryptedSavedObjectsPluginStart,
} from '../../../../../plugins/encrypted_saved_objects/server';
import { SpacesPluginSetup } from '../../../../../plugins/spaces/server';
+import { registerHiddenSORoutes } from './hidden_saved_object_routes';
const SAVED_OBJECT_WITH_SECRET_TYPE = 'saved-object-with-secret';
+const HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE = 'hidden-saved-object-with-secret';
const SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE =
'saved-object-with-secret-and-multiple-spaces';
const SAVED_OBJECT_WITHOUT_SECRET_TYPE = 'saved-object-without-secret';
-interface PluginsSetup {
+export interface PluginsSetup {
encryptedSavedObjects: EncryptedSavedObjectsPluginSetup;
spaces: SpacesPluginSetup;
}
-interface PluginsStart {
+export interface PluginsStart {
encryptedSavedObjects: EncryptedSavedObjectsPluginStart;
spaces: never;
}
export const plugin: PluginInitializer = () => ({
setup(core: CoreSetup, deps) {
- for (const [name, namespaceType] of [
- [SAVED_OBJECT_WITH_SECRET_TYPE, 'single'],
- [SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE, 'multiple'],
- ] as Array<[string, SavedObjectsNamespaceType]>) {
+ for (const [name, namespaceType, hidden] of [
+ [SAVED_OBJECT_WITH_SECRET_TYPE, 'single', false],
+ [HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE, 'single', true],
+ [SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE, 'multiple', false],
+ ] as Array<[string, SavedObjectsNamespaceType, boolean]>) {
core.savedObjects.registerType({
name,
- hidden: false,
+ hidden,
namespaceType,
mappings: deepFreeze({
properties: {
@@ -68,7 +71,8 @@ export const plugin: PluginInitializer =
mappings: deepFreeze({ properties: { publicProperty: { type: 'keyword' } } }),
});
- core.http.createRouter().get(
+ const router = core.http.createRouter();
+ router.get(
{
path: '/api/saved_objects/get-decrypted-as-internal-user/{type}/{id}',
validate: { params: value => ({ value }) },
@@ -80,11 +84,9 @@ export const plugin: PluginInitializer =
try {
return response.ok({
- body: await encryptedSavedObjects.getDecryptedAsInternalUser(
- request.params.type,
- request.params.id,
- { namespace }
- ),
+ body: await encryptedSavedObjects
+ .getClient()
+ .getDecryptedAsInternalUser(request.params.type, request.params.id, { namespace }),
});
} catch (err) {
if (encryptedSavedObjects.isEncryptionError(err)) {
@@ -95,6 +97,8 @@ export const plugin: PluginInitializer =
}
}
);
+
+ registerHiddenSORoutes(router, core, deps, [HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE]);
},
start() {},
stop() {},
diff --git a/x-pack/test/encrypted_saved_objects_api_integration/tests/encrypted_saved_objects_api.ts b/x-pack/test/encrypted_saved_objects_api_integration/tests/encrypted_saved_objects_api.ts
index 54b1f00616c94..2c97640b8d650 100644
--- a/x-pack/test/encrypted_saved_objects_api_integration/tests/encrypted_saved_objects_api.ts
+++ b/x-pack/test/encrypted_saved_objects_api_integration/tests/encrypted_saved_objects_api.ts
@@ -14,6 +14,7 @@ export default function({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const SAVED_OBJECT_WITH_SECRET_TYPE = 'saved-object-with-secret';
+ const HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE = 'hidden-saved-object-with-secret';
const SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE =
'saved-object-with-secret-and-multiple-spaces';
const SAVED_OBJECT_WITHOUT_SECRET_TYPE = 'saved-object-without-secret';
@@ -438,7 +439,7 @@ export default function({ getService }: FtrProviderContext) {
afterEach(async () => {
await es.deleteByQuery({
index: '.kibana',
- q: `type:${SAVED_OBJECT_WITH_SECRET_TYPE} OR type:${SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE} OR type:${SAVED_OBJECT_WITHOUT_SECRET_TYPE}`,
+ q: `type:${SAVED_OBJECT_WITH_SECRET_TYPE} OR type:${HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE} OR type:${SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE} OR type:${SAVED_OBJECT_WITHOUT_SECRET_TYPE}`,
refresh: true,
});
});
@@ -452,6 +453,14 @@ export default function({ getService }: FtrProviderContext) {
);
});
+ describe('hidden type with `single` namespace saved object', () => {
+ runTests(
+ HIDDEN_SAVED_OBJECT_WITH_SECRET_TYPE,
+ () => '/api/hidden_saved_objects/',
+ (id, type) => generateRawId(id, type)
+ );
+ });
+
describe('with `multiple` namespace saved object', () => {
runTests(
SAVED_OBJECT_WITH_SECRET_AND_MULTIPLE_SPACES_TYPE,