mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[ResponseOps][Cases] Refactoring client args and authentication (#137345)
* Refactoring services, auth * Fixing type errors
This commit is contained in:
parent
4f77f768bd
commit
724f9264c5
42 changed files with 329 additions and 154 deletions
|
@ -11,10 +11,9 @@
|
|||
"kibanaVersion":"kibana",
|
||||
"optionalPlugins":[
|
||||
"home",
|
||||
"security",
|
||||
"spaces",
|
||||
"taskManager",
|
||||
"usageCollection"
|
||||
"security",
|
||||
"taskManager",
|
||||
"usageCollection"
|
||||
],
|
||||
"owner":{
|
||||
"githubTeam":"response-ops",
|
||||
|
@ -30,7 +29,8 @@
|
|||
"kibanaReact",
|
||||
"kibanaUtils",
|
||||
"triggersActionsUi",
|
||||
"management"
|
||||
"management",
|
||||
"spaces"
|
||||
],
|
||||
"requiredBundles": [
|
||||
"savedObjects"
|
||||
|
|
|
@ -31,11 +31,11 @@ export class AuthorizationAuditLogger {
|
|||
*/
|
||||
private static createAuditMsg({ operation, error, entity }: CreateAuditMsgParams): AuditEvent {
|
||||
const doc =
|
||||
entity !== undefined
|
||||
entity?.id !== undefined
|
||||
? `${operation.savedObjectType} [id=${entity.id}]`
|
||||
: `a ${operation.docType}`;
|
||||
|
||||
const ownerText = entity === undefined ? 'as any owners' : `as owner "${entity.owner}"`;
|
||||
const ownerText = entity?.owner === undefined ? 'as any owners' : `as owner "${entity.owner}"`;
|
||||
|
||||
let message: string;
|
||||
let outcome: EcsEventOutcome;
|
||||
|
@ -59,7 +59,7 @@ export class AuthorizationAuditLogger {
|
|||
type: [operation.ecsType],
|
||||
outcome,
|
||||
},
|
||||
...(entity !== undefined && {
|
||||
...(entity?.id !== undefined && {
|
||||
kibana: {
|
||||
saved_object: { type: operation.savedObjectType, id: entity.id },
|
||||
},
|
||||
|
|
|
@ -9,7 +9,8 @@ import { securityMock } from '@kbn/security-plugin/server/mocks';
|
|||
import { httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
import { featuresPluginMock } from '@kbn/features-plugin/server/mocks';
|
||||
import { Authorization, Operations } from '.';
|
||||
import { Space } from '@kbn/spaces-plugin/server';
|
||||
import { Space, SpacesPluginStart } from '@kbn/spaces-plugin/server';
|
||||
import { spacesMock } from '@kbn/spaces-plugin/server/mocks';
|
||||
import { AuthorizationAuditLogger } from './audit_logger';
|
||||
import { KibanaRequest } from '@kbn/core/server';
|
||||
import { KibanaFeature } from '@kbn/features-plugin/common';
|
||||
|
@ -17,6 +18,17 @@ import { AuditLogger, SecurityPluginStart } from '@kbn/security-plugin/server';
|
|||
import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks';
|
||||
import { PluginStartContract as FeaturesPluginStart } from '@kbn/features-plugin/server';
|
||||
|
||||
const createSpacesDisabledFeaturesMock = (disabledFeatures: string[] = []) => {
|
||||
const spacesStart: jest.Mocked<SpacesPluginStart> = spacesMock.createStart();
|
||||
(spacesStart.spacesService.getActiveSpace as jest.Mock).mockImplementation(async () => {
|
||||
return {
|
||||
disabledFeatures: [],
|
||||
};
|
||||
});
|
||||
|
||||
return spacesStart;
|
||||
};
|
||||
|
||||
describe('authorization', () => {
|
||||
let request: KibanaRequest;
|
||||
let mockLogger: jest.Mocked<AuditLogger>;
|
||||
|
@ -29,9 +41,12 @@ describe('authorization', () => {
|
|||
describe('create', () => {
|
||||
let securityStart: jest.Mocked<SecurityPluginStart>;
|
||||
let featuresStart: jest.Mocked<FeaturesPluginStart>;
|
||||
let spacesStart: jest.Mocked<SpacesPluginStart>;
|
||||
|
||||
beforeEach(() => {
|
||||
securityStart = securityMock.createStart();
|
||||
spacesStart = createSpacesDisabledFeaturesMock();
|
||||
|
||||
featuresStart = featuresPluginMock.createStart();
|
||||
featuresStart.getKibanaFeatures.mockReturnValue([
|
||||
{ id: '1', cases: ['a'] },
|
||||
|
@ -41,11 +56,10 @@ describe('authorization', () => {
|
|||
it('creates an Authorization object', async () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const getSpace = jest.fn();
|
||||
const authPromise = Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace,
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -58,14 +72,14 @@ describe('authorization', () => {
|
|||
it('throws and error when a failure occurs', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const getSpace = jest.fn(async () => {
|
||||
(spacesStart.spacesService.getActiveSpace as jest.Mock).mockImplementation(() => {
|
||||
throw new Error('space error');
|
||||
});
|
||||
|
||||
const authPromise = Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace,
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -80,6 +94,7 @@ describe('authorization', () => {
|
|||
|
||||
let securityStart: ReturnType<typeof securityMock.createStart>;
|
||||
let featuresStart: jest.Mocked<FeaturesPluginStart>;
|
||||
let spacesStart: jest.Mocked<SpacesPluginStart>;
|
||||
let auth: Authorization;
|
||||
|
||||
beforeEach(async () => {
|
||||
|
@ -92,10 +107,12 @@ describe('authorization', () => {
|
|||
featuresStart = featuresPluginMock.createStart();
|
||||
featuresStart.getKibanaFeatures.mockReturnValue([feature] as unknown as KibanaFeature[]);
|
||||
|
||||
spacesStart = createSpacesDisabledFeaturesMock();
|
||||
|
||||
auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(mockLogger),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -121,7 +138,7 @@ describe('authorization', () => {
|
|||
|
||||
auth = await Authorization.create({
|
||||
request,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -240,10 +257,14 @@ describe('authorization', () => {
|
|||
it('throws an error when owner does not exist because it was from a disabled plugin', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
(spacesStart.spacesService.getActiveSpace as jest.Mock).mockImplementation(() => {
|
||||
return { disabledFeatures: [feature.id] } as Space;
|
||||
});
|
||||
|
||||
auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace: jest.fn(async () => ({ disabledFeatures: [feature.id] } as Space)),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -272,7 +293,7 @@ describe('authorization', () => {
|
|||
auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -299,7 +320,7 @@ describe('authorization', () => {
|
|||
auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -326,7 +347,7 @@ describe('authorization', () => {
|
|||
auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(mockLogger),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -396,6 +417,7 @@ describe('authorization', () => {
|
|||
|
||||
let securityStart: ReturnType<typeof securityMock.createStart>;
|
||||
let featuresStart: jest.Mocked<FeaturesPluginStart>;
|
||||
let spacesStart: jest.Mocked<SpacesPluginStart>;
|
||||
let auth: Authorization;
|
||||
|
||||
beforeEach(async () => {
|
||||
|
@ -412,10 +434,12 @@ describe('authorization', () => {
|
|||
featuresStart = featuresPluginMock.createStart();
|
||||
featuresStart.getKibanaFeatures.mockReturnValue([feature] as unknown as KibanaFeature[]);
|
||||
|
||||
spacesStart = createSpacesDisabledFeaturesMock();
|
||||
|
||||
auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(mockLogger),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -430,7 +454,7 @@ describe('authorization', () => {
|
|||
auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(mockLogger),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -472,7 +496,7 @@ describe('authorization', () => {
|
|||
|
||||
auth = await Authorization.create({
|
||||
request,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(mockLogger),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
@ -742,7 +766,7 @@ describe('authorization', () => {
|
|||
auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: securityStart.authz,
|
||||
getSpace: jest.fn(),
|
||||
spaces: spacesStart,
|
||||
features: featuresStart,
|
||||
auditLogger: new AuthorizationAuditLogger(mockLogger),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
|
|
|
@ -9,7 +9,8 @@ import { KibanaRequest, Logger } from '@kbn/core/server';
|
|||
import Boom from '@hapi/boom';
|
||||
import { SecurityPluginStart } from '@kbn/security-plugin/server';
|
||||
import { PluginStartContract as FeaturesPluginStart } from '@kbn/features-plugin/server';
|
||||
import { AuthFilterHelpers, GetSpaceFn, OwnerEntity } from './types';
|
||||
import { Space, SpacesPluginStart } from '@kbn/spaces-plugin/server';
|
||||
import { AuthFilterHelpers, OwnerEntity } from './types';
|
||||
import { getOwnersFilter } from './utils';
|
||||
import { AuthorizationAuditLogger, OperationDetails } from '.';
|
||||
import { createCaseError } from '../common/error';
|
||||
|
@ -47,22 +48,26 @@ export class Authorization {
|
|||
static async create({
|
||||
request,
|
||||
securityAuth,
|
||||
getSpace,
|
||||
spaces,
|
||||
features,
|
||||
auditLogger,
|
||||
logger,
|
||||
}: {
|
||||
request: KibanaRequest;
|
||||
securityAuth?: SecurityPluginStart['authz'];
|
||||
getSpace: GetSpaceFn;
|
||||
spaces: SpacesPluginStart;
|
||||
features: FeaturesPluginStart;
|
||||
auditLogger: AuthorizationAuditLogger;
|
||||
logger: Logger;
|
||||
}): Promise<Authorization> {
|
||||
const getSpace = async (): Promise<Space> => {
|
||||
return spaces.spacesService.getActiveSpace(request);
|
||||
};
|
||||
|
||||
// Since we need to do async operations, this static method handles that before creating the Auth class
|
||||
let caseOwners: Set<string>;
|
||||
try {
|
||||
const disabledFeatures = new Set((await getSpace(request))?.disabledFeatures ?? []);
|
||||
const disabledFeatures = new Set((await getSpace()).disabledFeatures ?? []);
|
||||
|
||||
caseOwners = new Set(
|
||||
features
|
||||
|
@ -87,7 +92,7 @@ export class Authorization {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks that the user making the request for the passed in owners and operation has the correct authorization. This
|
||||
* Checks that the user making the request for the passed in owner, saved object, and operation has the correct authorization. This
|
||||
* function will throw if the user is not authorized for the requested operation and owners.
|
||||
*
|
||||
* @param entities an array of entities describing the case owners in conjunction with the saved object ID attempting
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EcsEventType, KibanaRequest } from '@kbn/core/server';
|
||||
import { EcsEventType } from '@kbn/core/server';
|
||||
import type { KueryNode } from '@kbn/es-query';
|
||||
import { Space } from '@kbn/spaces-plugin/server';
|
||||
import { CasesSupportedOperations } from '@kbn/security-plugin/server';
|
||||
|
||||
/**
|
||||
|
@ -19,8 +18,6 @@ export interface Verbs {
|
|||
past: string;
|
||||
}
|
||||
|
||||
export type GetSpaceFn = (request: KibanaRequest) => Promise<Space | undefined>;
|
||||
|
||||
/**
|
||||
* Read operations for the cases APIs.
|
||||
*
|
||||
|
@ -80,7 +77,7 @@ export interface OperationDetails {
|
|||
*/
|
||||
name: CasesSupportedOperations;
|
||||
/**
|
||||
* The ECS `event.action` field, should be in the form of <entity>_<operation> e.g comment_get, case_fined
|
||||
* The ECS `event.action` field, should be in the form of <entity>_<operation> e.g comment_get, case_find
|
||||
*/
|
||||
action: string;
|
||||
/**
|
||||
|
|
|
@ -39,14 +39,14 @@ describe('getAlerts', () => {
|
|||
esClient.mget.mockResolvedValue({ docs });
|
||||
|
||||
it('returns an empty array if the alert info are empty', async () => {
|
||||
const clientArgs = { alertsService } as unknown as CasesClientArgs;
|
||||
const clientArgs = { services: { alertsService } } as unknown as CasesClientArgs;
|
||||
const res = await getAlerts([], clientArgs);
|
||||
|
||||
expect(res).toEqual([]);
|
||||
});
|
||||
|
||||
it('returns the alerts correctly', async () => {
|
||||
const clientArgs = { alertsService } as unknown as CasesClientArgs;
|
||||
const clientArgs = { services: { alertsService } } as unknown as CasesClientArgs;
|
||||
const res = await getAlerts(
|
||||
[
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ describe('getAlerts', () => {
|
|||
},
|
||||
],
|
||||
});
|
||||
const clientArgs = { alertsService } as unknown as CasesClientArgs;
|
||||
const clientArgs = { services: { alertsService } } as unknown as CasesClientArgs;
|
||||
|
||||
const res = await getAlerts(
|
||||
[
|
||||
|
@ -113,7 +113,7 @@ describe('getAlerts', () => {
|
|||
},
|
||||
],
|
||||
});
|
||||
const clientArgs = { alertsService } as unknown as CasesClientArgs;
|
||||
const clientArgs = { services: { alertsService } } as unknown as CasesClientArgs;
|
||||
|
||||
const res = await getAlerts(
|
||||
[
|
||||
|
|
|
@ -21,7 +21,7 @@ export const getAlerts = async (
|
|||
alertsInfo: AlertInfo[],
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CasesClientGetAlertsResponse> => {
|
||||
const { alertsService } = clientArgs;
|
||||
const { alertsService } = clientArgs.services;
|
||||
if (alertsInfo.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -51,9 +51,7 @@ export async function deleteAll(
|
|||
const {
|
||||
user,
|
||||
unsecuredSavedObjectsClient,
|
||||
caseService,
|
||||
attachmentService,
|
||||
userActionService,
|
||||
services: { caseService, attachmentService, userActionService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
@ -118,8 +116,7 @@ export async function deleteComment(
|
|||
const {
|
||||
user,
|
||||
unsecuredSavedObjectsClient,
|
||||
attachmentService,
|
||||
userActionService,
|
||||
services: { attachmentService, userActionService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
|
|
@ -102,7 +102,12 @@ export const getAllAlertsAttachToCase = async (
|
|||
clientArgs: CasesClientArgs,
|
||||
casesClient: CasesClient
|
||||
): Promise<AlertResponse> => {
|
||||
const { unsecuredSavedObjectsClient, authorization, attachmentService, logger } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
authorization,
|
||||
services: { attachmentService },
|
||||
logger,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
// This will perform an authorization check to ensure the user has access to the parent case
|
||||
|
@ -146,7 +151,12 @@ export async function find(
|
|||
{ caseID, queryParams }: FindArgs,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CommentsResponse> {
|
||||
const { unsecuredSavedObjectsClient, caseService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { caseService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const { filter: authorizationFilter, ensureSavedObjectsAreAuthorized } =
|
||||
|
@ -218,7 +228,12 @@ export async function get(
|
|||
{ attachmentID, caseID }: GetArgs,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CommentResponse> {
|
||||
const { attachmentService, unsecuredSavedObjectsClient, logger, authorization } = clientArgs;
|
||||
const {
|
||||
services: { attachmentService },
|
||||
unsecuredSavedObjectsClient,
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const comment = await attachmentService.get({
|
||||
|
@ -250,7 +265,11 @@ export async function getAll(
|
|||
{ caseID }: GetAllArgs,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<AllCommentsResponse> {
|
||||
const { caseService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
services: { caseService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const { filter, ensureSavedObjectsAreAuthorized } = await authorization.getAuthorizationFilter(
|
||||
|
|
|
@ -39,7 +39,12 @@ export async function update(
|
|||
{ caseID, updateRequest: queryParams }: UpdateArgs,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CaseResponse> {
|
||||
const { attachmentService, unsecuredSavedObjectsClient, logger, authorization } = clientArgs;
|
||||
const {
|
||||
services: { attachmentService },
|
||||
unsecuredSavedObjectsClient,
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const {
|
||||
|
|
|
@ -41,8 +41,7 @@ export const create = async (
|
|||
): Promise<CaseResponse> => {
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
caseService,
|
||||
userActionService,
|
||||
services: { caseService, userActionService },
|
||||
user,
|
||||
logger,
|
||||
authorization: auth,
|
||||
|
|
|
@ -22,10 +22,8 @@ import { Operations, OwnerEntity } from '../../authorization';
|
|||
export async function deleteCases(ids: string[], clientArgs: CasesClientArgs): Promise<void> {
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
caseService,
|
||||
attachmentService,
|
||||
user,
|
||||
userActionService,
|
||||
services: { caseService, attachmentService, userActionService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
|
|
@ -36,7 +36,11 @@ export const find = async (
|
|||
params: CasesFindRequest,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CasesFindResponse> => {
|
||||
const { caseService, authorization, logger } = clientArgs;
|
||||
const {
|
||||
services: { caseService },
|
||||
authorization,
|
||||
logger,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const fields = asArray(params.fields);
|
||||
|
|
|
@ -59,7 +59,11 @@ export const getCasesByAlertID = async (
|
|||
{ alertID, options }: CasesByAlertIDParams,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CasesByAlertId> => {
|
||||
const { caseService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
services: { caseService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const queryParams = pipe(
|
||||
|
@ -155,7 +159,11 @@ export const get = async (
|
|||
{ id, includeComments }: GetParams,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CaseResponse> => {
|
||||
const { caseService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
services: { caseService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const theCase: SavedObject<CaseAttributes> = await caseService.getCase({
|
||||
|
@ -205,7 +213,11 @@ export const resolve = async (
|
|||
{ id, includeComments }: GetParams,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CaseResolveResponse> => {
|
||||
const { caseService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
services: { caseService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const {
|
||||
|
@ -264,7 +276,12 @@ export async function getTags(
|
|||
params: AllTagsFindRequest,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<string[]> {
|
||||
const { unsecuredSavedObjectsClient, caseService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { caseService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const queryParams = pipe(
|
||||
|
@ -296,7 +313,12 @@ export async function getReporters(
|
|||
params: AllReportersFindRequest,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<User[]> {
|
||||
const { unsecuredSavedObjectsClient, caseService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { caseService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const queryParams = pipe(
|
||||
|
|
|
@ -50,8 +50,8 @@ function shouldCloseByPush(
|
|||
|
||||
const changeAlertsStatusToClose = async (
|
||||
caseId: string,
|
||||
caseService: CasesClientArgs['caseService'],
|
||||
alertsService: CasesClientArgs['alertsService']
|
||||
caseService: CasesClientArgs['services']['caseService'],
|
||||
alertsService: CasesClientArgs['services']['alertsService']
|
||||
) => {
|
||||
const alertAttachments = (await caseService.getAllCaseComments({
|
||||
id: [caseId],
|
||||
|
@ -99,11 +99,13 @@ export const push = async (
|
|||
): Promise<CaseResponse> => {
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
attachmentService,
|
||||
caseService,
|
||||
caseConfigureService,
|
||||
userActionService,
|
||||
alertsService,
|
||||
services: {
|
||||
attachmentService,
|
||||
caseService,
|
||||
caseConfigureService,
|
||||
userActionService,
|
||||
alertsService,
|
||||
},
|
||||
actionsClient,
|
||||
user,
|
||||
logger,
|
||||
|
|
|
@ -236,12 +236,10 @@ export const update = async (
|
|||
): Promise<CasesResponse> => {
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
caseService,
|
||||
userActionService,
|
||||
services: { caseService, userActionService, alertsService },
|
||||
user,
|
||||
logger,
|
||||
authorization,
|
||||
alertsService,
|
||||
} = clientArgs;
|
||||
const query = pipe(
|
||||
excess(CasesPatchRequestRt).decode(cases),
|
||||
|
|
|
@ -132,7 +132,12 @@ async function get(
|
|||
clientArgs: CasesClientArgs,
|
||||
casesClientInternal: CasesClientInternal
|
||||
): Promise<CasesConfigurationsResponse> {
|
||||
const { unsecuredSavedObjectsClient, caseConfigureService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { caseConfigureService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
try {
|
||||
const queryParams = pipe(
|
||||
excess(GetConfigureFindRequestRt).decode(params),
|
||||
|
@ -234,8 +239,13 @@ async function update(
|
|||
clientArgs: CasesClientArgs,
|
||||
casesClientInternal: CasesClientInternal
|
||||
): Promise<CasesConfigureResponse> {
|
||||
const { caseConfigureService, logger, unsecuredSavedObjectsClient, user, authorization } =
|
||||
clientArgs;
|
||||
const {
|
||||
services: { caseConfigureService },
|
||||
logger,
|
||||
unsecuredSavedObjectsClient,
|
||||
user,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const request = pipe(
|
||||
|
@ -343,8 +353,13 @@ async function create(
|
|||
clientArgs: CasesClientArgs,
|
||||
casesClientInternal: CasesClientInternal
|
||||
): Promise<CasesConfigureResponse> {
|
||||
const { unsecuredSavedObjectsClient, caseConfigureService, logger, user, authorization } =
|
||||
clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { caseConfigureService },
|
||||
logger,
|
||||
user,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
try {
|
||||
let error = null;
|
||||
|
||||
|
|
|
@ -16,7 +16,11 @@ export const createMappings = async (
|
|||
{ connector, owner, refresh }: CreateMappingsArgs,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<ConnectorMappingsAttributes[]> => {
|
||||
const { unsecuredSavedObjectsClient, connectorMappingsService, logger } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { connectorMappingsService },
|
||||
logger,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const mappings = casesConnectors.get(connector.type)?.getMapping() ?? [];
|
||||
|
|
|
@ -16,7 +16,11 @@ export const getMappings = async (
|
|||
{ connector }: MappingsArgs,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<SavedObjectsFindResponse<ConnectorMappings>['saved_objects']> => {
|
||||
const { unsecuredSavedObjectsClient, connectorMappingsService, logger } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { connectorMappingsService },
|
||||
logger,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const myConnectorMappings = await connectorMappingsService.find({
|
||||
|
|
|
@ -16,7 +16,11 @@ export const updateMappings = async (
|
|||
{ connector, mappingId, refresh }: UpdateMappingsArgs,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<ConnectorMappingsAttributes[]> => {
|
||||
const { unsecuredSavedObjectsClient, connectorMappingsService, logger } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { connectorMappingsService },
|
||||
logger,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const mappings = casesConnectors.get(connector.type)?.getMapping() ?? [];
|
||||
|
|
|
@ -10,14 +10,15 @@ import {
|
|||
SavedObjectsServiceStart,
|
||||
Logger,
|
||||
ElasticsearchClient,
|
||||
SavedObjectsClientContract,
|
||||
} from '@kbn/core/server';
|
||||
import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server';
|
||||
import { PluginStartContract as FeaturesPluginStart } from '@kbn/features-plugin/server';
|
||||
import { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server';
|
||||
import { LensServerPluginSetup } from '@kbn/lens-plugin/server';
|
||||
import { SpacesPluginStart } from '@kbn/spaces-plugin/server';
|
||||
import { SAVED_OBJECT_TYPES } from '../../common/constants';
|
||||
import { Authorization } from '../authorization/authorization';
|
||||
import { GetSpaceFn } from '../authorization/types';
|
||||
import {
|
||||
CaseConfigureService,
|
||||
CasesService,
|
||||
|
@ -31,11 +32,12 @@ import { AuthorizationAuditLogger } from '../authorization';
|
|||
import { CasesClient, createCasesClient } from '.';
|
||||
import { PersistableStateAttachmentTypeRegistry } from '../attachment_framework/persistable_state_registry';
|
||||
import { ExternalReferenceAttachmentTypeRegistry } from '../attachment_framework/external_reference_registry';
|
||||
import { CasesServices } from './types';
|
||||
|
||||
interface CasesClientFactoryArgs {
|
||||
securityPluginSetup?: SecurityPluginSetup;
|
||||
securityPluginStart?: SecurityPluginStart;
|
||||
getSpace: GetSpaceFn;
|
||||
spacesPluginStart: SpacesPluginStart;
|
||||
featuresPluginStart: FeaturesPluginStart;
|
||||
actionsPluginStart: ActionsPluginStart;
|
||||
lensEmbeddableFactory: LensServerPluginSetup['lensEmbeddableFactory'];
|
||||
|
@ -89,7 +91,7 @@ export class CasesClientFactory {
|
|||
const auth = await Authorization.create({
|
||||
request,
|
||||
securityAuth: this.options.securityPluginStart?.authz,
|
||||
getSpace: this.options.getSpace,
|
||||
spaces: this.options.spacesPluginStart,
|
||||
features: this.options.featuresPluginStart,
|
||||
auditLogger: new AuthorizationAuditLogger(auditLogger),
|
||||
logger: this.logger,
|
||||
|
@ -102,6 +104,38 @@ export class CasesClientFactory {
|
|||
excludedWrappers: ['security'],
|
||||
});
|
||||
|
||||
const services = this.createServices({
|
||||
unsecuredSavedObjectsClient,
|
||||
esClient: scopedClusterClient,
|
||||
});
|
||||
|
||||
const userInfo = services.caseService.getUser({ request });
|
||||
|
||||
return createCasesClient({
|
||||
services,
|
||||
unsecuredSavedObjectsClient,
|
||||
// We only want these fields from the userInfo object
|
||||
user: { username: userInfo.username, email: userInfo.email, full_name: userInfo.full_name },
|
||||
logger: this.logger,
|
||||
lensEmbeddableFactory: this.options.lensEmbeddableFactory,
|
||||
authorization: auth,
|
||||
actionsClient: await this.options.actionsPluginStart.getActionsClientWithRequest(request),
|
||||
persistableStateAttachmentTypeRegistry: this.options.persistableStateAttachmentTypeRegistry,
|
||||
externalReferenceAttachmentTypeRegistry: this.options.externalReferenceAttachmentTypeRegistry,
|
||||
});
|
||||
}
|
||||
|
||||
private createServices({
|
||||
unsecuredSavedObjectsClient,
|
||||
esClient,
|
||||
}: {
|
||||
unsecuredSavedObjectsClient: SavedObjectsClientContract;
|
||||
esClient: ElasticsearchClient;
|
||||
}): CasesServices {
|
||||
if (!this.isInitialized || !this.options) {
|
||||
throw new Error('CasesClientFactory must be initialized before calling create');
|
||||
}
|
||||
|
||||
const attachmentService = new AttachmentService(
|
||||
this.logger,
|
||||
this.options.persistableStateAttachmentTypeRegistry
|
||||
|
@ -113,13 +147,9 @@ export class CasesClientFactory {
|
|||
unsecuredSavedObjectsClient,
|
||||
attachmentService,
|
||||
});
|
||||
const userInfo = caseService.getUser({ request });
|
||||
|
||||
return createCasesClient({
|
||||
alertsService: new AlertService(scopedClusterClient, this.logger),
|
||||
unsecuredSavedObjectsClient,
|
||||
// We only want these fields from the userInfo object
|
||||
user: { username: userInfo.username, email: userInfo.email, full_name: userInfo.full_name },
|
||||
return {
|
||||
alertsService: new AlertService(esClient, this.logger),
|
||||
caseService,
|
||||
caseConfigureService: new CaseConfigureService(this.logger),
|
||||
connectorMappingsService: new ConnectorMappingsService(this.logger),
|
||||
|
@ -128,12 +158,6 @@ export class CasesClientFactory {
|
|||
this.options.persistableStateAttachmentTypeRegistry
|
||||
),
|
||||
attachmentService,
|
||||
logger: this.logger,
|
||||
lensEmbeddableFactory: this.options.lensEmbeddableFactory,
|
||||
authorization: auth,
|
||||
actionsClient: await this.options.actionsPluginStart.getActionsClientWithRequest(request),
|
||||
persistableStateAttachmentTypeRegistry: this.options.persistableStateAttachmentTypeRegistry,
|
||||
externalReferenceAttachmentTypeRegistry: this.options.externalReferenceAttachmentTypeRegistry,
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ const getAuthorizationFilter = jest.fn().mockResolvedValue({});
|
|||
|
||||
const clientArgs = {
|
||||
logger,
|
||||
attachmentService,
|
||||
services: { attachmentService },
|
||||
authorization: { getAuthorizationFilter },
|
||||
} as unknown as CasesClientArgs;
|
||||
|
||||
|
|
|
@ -24,8 +24,12 @@ export class Actions extends SingleCaseAggregationHandler {
|
|||
}
|
||||
|
||||
public async compute(): Promise<SingleCaseMetricsResponse> {
|
||||
const { unsecuredSavedObjectsClient, authorization, attachmentService, logger } =
|
||||
this.options.clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
authorization,
|
||||
services: { attachmentService },
|
||||
logger,
|
||||
} = this.options.clientArgs;
|
||||
const { casesClient } = this.options;
|
||||
|
||||
try {
|
||||
|
|
|
@ -21,7 +21,9 @@ const getAuthorizationFilter = jest.fn().mockResolvedValue({});
|
|||
|
||||
const clientArgs = {
|
||||
logger,
|
||||
attachmentService,
|
||||
services: {
|
||||
attachmentService,
|
||||
},
|
||||
authorization: { getAuthorizationFilter },
|
||||
} as unknown as CasesClientArgs;
|
||||
|
||||
|
|
|
@ -17,8 +17,12 @@ export class AlertsCount extends SingleCaseBaseHandler {
|
|||
}
|
||||
|
||||
public async compute(): Promise<SingleCaseMetricsResponse> {
|
||||
const { unsecuredSavedObjectsClient, authorization, attachmentService, logger } =
|
||||
this.options.clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
authorization,
|
||||
services: { attachmentService },
|
||||
logger,
|
||||
} = this.options.clientArgs;
|
||||
|
||||
const { casesClient } = this.options;
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ describe('AlertDetails', () => {
|
|||
const handler = new AlertDetails({
|
||||
caseId: '',
|
||||
casesClient: client,
|
||||
clientArgs: {} as CasesClientArgs,
|
||||
clientArgs: { services: {} } as CasesClientArgs,
|
||||
});
|
||||
expect(await handler.compute()).toEqual({});
|
||||
});
|
||||
|
@ -50,7 +50,7 @@ describe('AlertDetails', () => {
|
|||
const handler = new AlertDetails({
|
||||
caseId: '',
|
||||
casesClient: client,
|
||||
clientArgs: {} as CasesClientArgs,
|
||||
clientArgs: { services: {} } as CasesClientArgs,
|
||||
});
|
||||
handler.setupFeature('alerts.hosts');
|
||||
|
||||
|
@ -65,7 +65,7 @@ describe('AlertDetails', () => {
|
|||
});
|
||||
|
||||
it('returns the default zero values for hosts when the count aggregation returns undefined', async () => {
|
||||
mockServices.alertsService.executeAggregations.mockImplementation(async () => ({}));
|
||||
mockServices.services.alertsService.executeAggregations.mockImplementation(async () => ({}));
|
||||
|
||||
const handler = new AlertDetails(constructorOptions);
|
||||
handler.setupFeature('alerts.hosts');
|
||||
|
@ -81,7 +81,7 @@ describe('AlertDetails', () => {
|
|||
});
|
||||
|
||||
it('returns the default zero values for users when the count aggregation returns undefined', async () => {
|
||||
mockServices.alertsService.executeAggregations.mockImplementation(async () => ({}));
|
||||
mockServices.services.alertsService.executeAggregations.mockImplementation(async () => ({}));
|
||||
|
||||
const handler = new AlertDetails(constructorOptions);
|
||||
handler.setupFeature('alerts.users');
|
||||
|
@ -97,7 +97,7 @@ describe('AlertDetails', () => {
|
|||
});
|
||||
|
||||
it('returns the default zero values for hosts when the top hits aggregation returns undefined', async () => {
|
||||
mockServices.alertsService.executeAggregations.mockImplementation(async () => ({}));
|
||||
mockServices.services.alertsService.executeAggregations.mockImplementation(async () => ({}));
|
||||
|
||||
const handler = new AlertDetails(constructorOptions);
|
||||
handler.setupFeature('alerts.hosts');
|
||||
|
@ -113,7 +113,7 @@ describe('AlertDetails', () => {
|
|||
});
|
||||
|
||||
it('returns the default zero values for users when the top hits aggregation returns undefined', async () => {
|
||||
mockServices.alertsService.executeAggregations.mockImplementation(async () => ({}));
|
||||
mockServices.services.alertsService.executeAggregations.mockImplementation(async () => ({}));
|
||||
|
||||
const handler = new AlertDetails(constructorOptions);
|
||||
handler.setupFeature('alerts.users');
|
||||
|
@ -136,7 +136,7 @@ describe('AlertDetails', () => {
|
|||
const handler = new AlertDetails({
|
||||
caseId: '',
|
||||
casesClient: client,
|
||||
clientArgs: {} as CasesClientArgs,
|
||||
clientArgs: { services: {} } as CasesClientArgs,
|
||||
});
|
||||
expect(await handler.compute()).toEqual({});
|
||||
});
|
||||
|
@ -149,7 +149,7 @@ describe('AlertDetails', () => {
|
|||
const handler = new AlertDetails({
|
||||
caseId: '',
|
||||
casesClient: client,
|
||||
clientArgs: {} as CasesClientArgs,
|
||||
clientArgs: { services: {} } as CasesClientArgs,
|
||||
});
|
||||
expect(await handler.compute()).toEqual({});
|
||||
expect(await handler.compute()).toEqual({});
|
||||
|
@ -222,7 +222,9 @@ function createMockClientArgs() {
|
|||
|
||||
const clientArgs = {
|
||||
logger,
|
||||
alertsService,
|
||||
services: {
|
||||
alertsService,
|
||||
},
|
||||
};
|
||||
|
||||
return { mockServices: clientArgs, clientArgs: clientArgs as unknown as CasesClientArgs };
|
||||
|
|
|
@ -24,7 +24,10 @@ export class AlertDetails extends SingleCaseAggregationHandler {
|
|||
}
|
||||
|
||||
public async compute(): Promise<SingleCaseMetricsResponse> {
|
||||
const { alertsService, logger } = this.options.clientArgs;
|
||||
const {
|
||||
services: { alertsService },
|
||||
logger,
|
||||
} = this.options.clientArgs;
|
||||
const { casesClient } = this.options;
|
||||
|
||||
try {
|
||||
|
|
|
@ -21,7 +21,9 @@ const getAuthorizationFilter = jest.fn().mockResolvedValue({});
|
|||
|
||||
const clientArgs = {
|
||||
logger,
|
||||
caseService,
|
||||
services: {
|
||||
caseService,
|
||||
},
|
||||
authorization: { getAuthorizationFilter },
|
||||
} as unknown as CasesClientArgs;
|
||||
|
||||
|
|
|
@ -22,7 +22,11 @@ export class MTTR extends AllCasesAggregationHandler {
|
|||
}
|
||||
|
||||
public async compute(): Promise<CasesMetricsResponse> {
|
||||
const { authorization, caseService, logger } = this.options.clientArgs;
|
||||
const {
|
||||
authorization,
|
||||
services: { caseService },
|
||||
logger,
|
||||
} = this.options.clientArgs;
|
||||
|
||||
try {
|
||||
const { filter: authorizationFilter } = await authorization.getAuthorizationFilter(
|
||||
|
|
|
@ -19,7 +19,9 @@ describe('Connectors', () => {
|
|||
|
||||
const clientArgs = {
|
||||
logger,
|
||||
userActionService,
|
||||
services: {
|
||||
userActionService,
|
||||
},
|
||||
authorization: { getAuthorizationFilter },
|
||||
} as unknown as CasesClientArgs;
|
||||
|
||||
|
|
|
@ -17,8 +17,12 @@ export class Connectors extends SingleCaseBaseHandler {
|
|||
}
|
||||
|
||||
public async compute(): Promise<SingleCaseMetricsResponse> {
|
||||
const { unsecuredSavedObjectsClient, authorization, userActionService, logger } =
|
||||
this.options.clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
authorization,
|
||||
services: { userActionService },
|
||||
logger,
|
||||
} = this.options.clientArgs;
|
||||
|
||||
const { filter: authorizationFilter } = await authorization.getAuthorizationFilter(
|
||||
Operations.getUserActionMetrics
|
||||
|
|
|
@ -151,7 +151,7 @@ describe('getCaseMetrics', () => {
|
|||
clientArgs
|
||||
);
|
||||
|
||||
expect(mockServices.alertsService.executeAggregations).toBeCalledTimes(1);
|
||||
expect(mockServices.services.alertsService.executeAggregations).toBeCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -209,11 +209,13 @@ function createMockClientArgs() {
|
|||
const clientArgs = {
|
||||
authorization,
|
||||
unsecuredSavedObjectsClient: soClient,
|
||||
caseService,
|
||||
logger,
|
||||
attachmentService,
|
||||
alertsService,
|
||||
userActionService,
|
||||
services: {
|
||||
caseService,
|
||||
attachmentService,
|
||||
alertsService,
|
||||
userActionService,
|
||||
},
|
||||
};
|
||||
|
||||
return { mockServices: clientArgs, clientArgs: clientArgs as unknown as CasesClientArgs };
|
||||
|
|
|
@ -52,7 +52,10 @@ const checkAuthorization = async (
|
|||
params: SingleCaseMetricsRequest,
|
||||
clientArgs: CasesClientArgs
|
||||
) => {
|
||||
const { caseService, authorization } = clientArgs;
|
||||
const {
|
||||
services: { caseService },
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
const caseInfo = await caseService.getCase({
|
||||
id: params.caseId,
|
||||
|
|
|
@ -27,7 +27,9 @@ describe('getCasesMetrics', () => {
|
|||
|
||||
describe('MTTR', () => {
|
||||
beforeEach(() => {
|
||||
mockServices.caseService.executeAggregations.mockResolvedValue({ mttr: { value: 5 } });
|
||||
mockServices.services.caseService.executeAggregations.mockResolvedValue({
|
||||
mttr: { value: 5 },
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the mttr metric', async () => {
|
||||
|
@ -46,7 +48,8 @@ describe('getCasesMetrics', () => {
|
|||
client,
|
||||
clientArgs
|
||||
);
|
||||
expect(mockServices.caseService.executeAggregations.mock.calls[0][0]).toMatchInlineSnapshot(`
|
||||
expect(mockServices.services.caseService.executeAggregations.mock.calls[0][0])
|
||||
.toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"aggregationBuilders": Array [
|
||||
AverageDuration {},
|
||||
|
|
|
@ -24,7 +24,7 @@ describe('getStatusTotalsByType', () => {
|
|||
|
||||
describe('MTTR', () => {
|
||||
beforeEach(() => {
|
||||
mockServices.caseService.getCaseStatusStats.mockResolvedValue({
|
||||
mockServices.services.caseService.getCaseStatusStats.mockResolvedValue({
|
||||
open: 1,
|
||||
'in-progress': 2,
|
||||
closed: 1,
|
||||
|
@ -50,7 +50,8 @@ describe('getStatusTotalsByType', () => {
|
|||
clientArgs
|
||||
);
|
||||
|
||||
expect(mockServices.caseService.getCaseStatusStats.mock.calls[0][0]).toMatchInlineSnapshot(`
|
||||
expect(mockServices.services.caseService.getCaseStatusStats.mock.calls[0][0])
|
||||
.toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"searchOptions": Object {
|
||||
"filter": Object {
|
||||
|
|
|
@ -27,7 +27,11 @@ export async function getStatusTotalsByType(
|
|||
params: CasesStatusRequest,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CasesStatusResponse> {
|
||||
const { caseService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
services: { caseService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const queryParams = pipe(
|
||||
|
|
|
@ -26,8 +26,12 @@ export class Lifespan extends SingleCaseBaseHandler {
|
|||
}
|
||||
|
||||
public async compute(): Promise<SingleCaseMetricsResponse> {
|
||||
const { unsecuredSavedObjectsClient, authorization, userActionService, logger } =
|
||||
this.options.clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
authorization,
|
||||
services: { userActionService },
|
||||
logger,
|
||||
} = this.options.clientArgs;
|
||||
|
||||
const { casesClient } = this.options;
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@ export function createMockClientArgs() {
|
|||
const clientArgs = {
|
||||
authorization,
|
||||
unsecuredSavedObjectsClient: soClient,
|
||||
caseService,
|
||||
services: {
|
||||
caseService,
|
||||
},
|
||||
logger,
|
||||
};
|
||||
|
||||
|
|
|
@ -23,18 +23,22 @@ import {
|
|||
import { PersistableStateAttachmentTypeRegistry } from '../attachment_framework/persistable_state_registry';
|
||||
import { ExternalReferenceAttachmentTypeRegistry } from '../attachment_framework/external_reference_registry';
|
||||
|
||||
export interface CasesServices {
|
||||
alertsService: AlertService;
|
||||
caseService: CasesService;
|
||||
caseConfigureService: CaseConfigureService;
|
||||
connectorMappingsService: ConnectorMappingsService;
|
||||
userActionService: CaseUserActionService;
|
||||
attachmentService: AttachmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for initializing a cases client
|
||||
*/
|
||||
export interface CasesClientArgs {
|
||||
readonly caseConfigureService: CaseConfigureService;
|
||||
readonly caseService: CasesService;
|
||||
readonly connectorMappingsService: ConnectorMappingsService;
|
||||
readonly services: CasesServices;
|
||||
readonly user: User;
|
||||
readonly unsecuredSavedObjectsClient: SavedObjectsClientContract;
|
||||
readonly userActionService: CaseUserActionService;
|
||||
readonly alertsService: AlertService;
|
||||
readonly attachmentService: AttachmentService;
|
||||
readonly logger: Logger;
|
||||
readonly lensEmbeddableFactory: LensServerPluginSetup['lensEmbeddableFactory'];
|
||||
readonly authorization: PublicMethodsOf<Authorization>;
|
||||
|
|
|
@ -20,7 +20,12 @@ export const get = async (
|
|||
{ caseId }: UserActionGet,
|
||||
clientArgs: CasesClientArgs
|
||||
): Promise<CaseUserActionsResponse> => {
|
||||
const { unsecuredSavedObjectsClient, userActionService, logger, authorization } = clientArgs;
|
||||
const {
|
||||
unsecuredSavedObjectsClient,
|
||||
services: { userActionService },
|
||||
logger,
|
||||
authorization,
|
||||
} = clientArgs;
|
||||
|
||||
try {
|
||||
const userActions = await userActionService.getAll({
|
||||
|
|
|
@ -62,7 +62,7 @@ export class CaseCommentModel {
|
|||
id: string,
|
||||
options: CaseCommentModelParams
|
||||
): Promise<CaseCommentModel> {
|
||||
const savedObject = await options.caseService.getCase({
|
||||
const savedObject = await options.services.caseService.getCase({
|
||||
id,
|
||||
});
|
||||
|
||||
|
@ -93,7 +93,7 @@ export class CaseCommentModel {
|
|||
};
|
||||
|
||||
if (queryRestAttributes.type === CommentType.user && queryRestAttributes?.comment) {
|
||||
const currentComment = (await this.params.attachmentService.get({
|
||||
const currentComment = (await this.params.services.attachmentService.get({
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
attachmentId: id,
|
||||
})) as SavedObject<CommentRequestUserType>;
|
||||
|
@ -107,7 +107,7 @@ export class CaseCommentModel {
|
|||
}
|
||||
|
||||
const [comment, commentableCase] = await Promise.all([
|
||||
this.params.attachmentService.update({
|
||||
this.params.services.attachmentService.update({
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
attachmentId: id,
|
||||
updatedAttributes: {
|
||||
|
@ -141,7 +141,7 @@ export class CaseCommentModel {
|
|||
refresh: RefreshSetting
|
||||
): Promise<CaseCommentModel> {
|
||||
try {
|
||||
const updatedCase = await this.params.caseService.patchCase({
|
||||
const updatedCase = await this.params.services.caseService.patchCase({
|
||||
originalCase: this.caseInfo,
|
||||
caseId: this.caseInfo.id,
|
||||
updatedAttributes: {
|
||||
|
@ -180,7 +180,7 @@ export class CaseCommentModel {
|
|||
) {
|
||||
const { id, version, ...queryRestAttributes } = updateRequest;
|
||||
|
||||
await this.params.userActionService.createUserAction({
|
||||
await this.params.services.userActionService.createUserAction({
|
||||
type: ActionTypes.comment,
|
||||
action: Actions.update,
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
|
@ -210,7 +210,7 @@ export class CaseCommentModel {
|
|||
const references = [...this.buildRefsToCase(), ...this.getCommentReferences(commentReq)];
|
||||
|
||||
const [comment, commentableCase] = await Promise.all([
|
||||
this.params.attachmentService.create({
|
||||
this.params.services.attachmentService.create({
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
attributes: transformNewComment({
|
||||
createdDate,
|
||||
|
@ -273,10 +273,11 @@ export class CaseCommentModel {
|
|||
}
|
||||
|
||||
private async validateAlertsLimitOnCase(totalAlertsInReq: number) {
|
||||
const alertsValueCount = await this.params.attachmentService.valueCountAlertsAttachedToCase({
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
caseId: this.caseInfo.id,
|
||||
});
|
||||
const alertsValueCount =
|
||||
await this.params.services.attachmentService.valueCountAlertsAttachedToCase({
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
caseId: this.caseInfo.id,
|
||||
});
|
||||
|
||||
if (alertsValueCount + totalAlertsInReq > MAX_ALERTS_PER_CASE) {
|
||||
throw Boom.badRequest(ALERT_LIMIT_MSG);
|
||||
|
@ -326,14 +327,14 @@ export class CaseCommentModel {
|
|||
)
|
||||
.flat();
|
||||
|
||||
await this.params.alertsService.updateAlertsStatus(alertsToUpdate);
|
||||
await this.params.services.alertsService.updateAlertsStatus(alertsToUpdate);
|
||||
}
|
||||
|
||||
private async createCommentUserAction(
|
||||
comment: SavedObject<CommentAttributes>,
|
||||
req: CommentRequest
|
||||
) {
|
||||
await this.params.userActionService.createUserAction({
|
||||
await this.params.services.userActionService.createUserAction({
|
||||
type: ActionTypes.comment,
|
||||
action: Actions.create,
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
|
@ -348,7 +349,7 @@ export class CaseCommentModel {
|
|||
}
|
||||
|
||||
private async bulkCreateCommentUserAction(attachments: Array<{ id: string } & CommentRequest>) {
|
||||
await this.params.userActionService.bulkCreateAttachmentCreation({
|
||||
await this.params.services.userActionService.bulkCreateAttachmentCreation({
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
caseId: this.caseInfo.id,
|
||||
attachments: attachments.map(({ id, ...attachment }) => ({
|
||||
|
@ -371,7 +372,7 @@ export class CaseCommentModel {
|
|||
|
||||
public async encodeWithComments(): Promise<CaseResponse> {
|
||||
try {
|
||||
const comments = await this.params.caseService.getAllCaseComments({
|
||||
const comments = await this.params.services.caseService.getAllCaseComments({
|
||||
id: this.caseInfo.id,
|
||||
options: {
|
||||
fields: [],
|
||||
|
@ -409,7 +410,7 @@ export class CaseCommentModel {
|
|||
const caseReference = this.buildRefsToCase();
|
||||
|
||||
const [newlyCreatedAttachments, commentableCase] = await Promise.all([
|
||||
this.params.attachmentService.bulkCreate({
|
||||
this.params.services.attachmentService.bulkCreate({
|
||||
unsecuredSavedObjectsClient: this.params.unsecuredSavedObjectsClient,
|
||||
attachments: attachments.map(({ id, ...attachment }) => {
|
||||
return {
|
||||
|
|
|
@ -66,7 +66,7 @@ export interface PluginsStart {
|
|||
features: FeaturesPluginStart;
|
||||
taskManager?: TaskManagerStartContract;
|
||||
security?: SecurityPluginStart;
|
||||
spaces?: SpacesPluginStart;
|
||||
spaces: SpacesPluginStart;
|
||||
}
|
||||
|
||||
export class CasePlugin {
|
||||
|
@ -166,9 +166,7 @@ export class CasePlugin {
|
|||
this.clientFactory.initialize({
|
||||
securityPluginSetup: this.securityPluginSetup,
|
||||
securityPluginStart: plugins.security,
|
||||
getSpace: async (request: KibanaRequest) => {
|
||||
return plugins.spaces?.spacesService.getActiveSpace(request);
|
||||
},
|
||||
spacesPluginStart: plugins.spaces,
|
||||
featuresPluginStart: plugins.features,
|
||||
actionsPluginStart: plugins.actions,
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue