Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Cases] Validate attributes before create SOs #158590

Merged
merged 15 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions x-pack/plugins/cases/common/api/cases/comment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,21 @@ const CommentAttributesWithoutRefsRt = rt.union([
AttributesTypePersistableStateRt,
]);

export const CommentRequestRt = rt.union([
const BasicCommentRequestRt = rt.union([
ContextTypeUserRt,
AlertCommentRequestRt,
ActionsCommentRequestRt,
ExternalReferenceNoSORt,
ExternalReferenceSORt,
PersistableStateAttachmentRt,
]);

export const CommentRequestRt = rt.union([...BasicCommentRequestRt.types, ExternalReferenceSORt]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it work to do:

export const CommentRequestRt = rt.union([BasicCommentRequestRt, ExternalReferenceSORt]);

Copy link
Member Author

Choose a reason for hiding this comment

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

It seems so!


export const CommentRequestWithoutRefsRt = rt.union([
...BasicCommentRequestRt.types,
ExternalReferenceSOWithoutRefsRt,
]);

export const CommentRt = rt.intersection([
CommentAttributesRt,
rt.strict({
Expand Down
13 changes: 12 additions & 1 deletion x-pack/plugins/cases/common/api/cases/user_actions/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,26 @@
*/

import * as rt from 'io-ts';
import { CommentRequestRt } from '../comment';
import { CommentRequestRt, CommentRequestWithoutRefsRt } from '../comment';
import type { UserActionWithAttributes } from './common';
import { ActionTypes } from './common';

export const CommentUserActionPayloadRt = rt.strict({ comment: CommentRequestRt });
export const CommentUserActionPayloadWithoutIdsRt = rt.strict({
comment: CommentRequestWithoutRefsRt,
});

export const CommentUserActionRt = rt.strict({
type: rt.literal(ActionTypes.comment),
payload: CommentUserActionPayloadRt,
});

export const CommentUserActionWithoutIdsRt = rt.strict({
Copy link
Member Author

Choose a reason for hiding this comment

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

I needed this type so I can validate the attributes passed to the so client when you creating a user action. The attributes do not contain any ids as they are in the references array.

type: rt.literal(ActionTypes.comment),
payload: CommentUserActionPayloadWithoutIdsRt,
});

export type CommentUserAction = UserActionWithAttributes<rt.TypeOf<typeof CommentUserActionRt>>;
export type CommentUserActionPayloadWithoutIds = UserActionWithAttributes<
rt.TypeOf<typeof CommentUserActionPayloadWithoutIdsRt>
>;
30 changes: 18 additions & 12 deletions x-pack/plugins/cases/common/api/cases/user_actions/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from './common';
import { CreateCaseUserActionRt, CreateCaseUserActionWithoutConnectorIdRt } from './create_case';
import { DescriptionUserActionRt } from './description';
import { CommentUserActionRt } from './comment';
import { CommentUserActionRt, CommentUserActionWithoutIdsRt } from './comment';
import { ConnectorUserActionRt, ConnectorUserActionWithoutConnectorIdRt } from './connector';
import { PushedUserActionRt, PushedUserActionWithoutConnectorIdRt } from './pushed';
import { TagsUserActionRt } from './tags';
Expand All @@ -28,36 +28,42 @@ import { SeverityUserActionRt } from './severity';
import { AssigneesUserActionRt } from './assignees';
import { CaseUserActionStatsRt } from './stats';

const CommonUserActionsRt = rt.union([
const BasicUserActionsRt = rt.union([
DescriptionUserActionRt,
CommentUserActionRt,
TagsUserActionRt,
TitleUserActionRt,
SettingsUserActionRt,
StatusUserActionRt,
SeverityUserActionRt,
AssigneesUserActionRt,
DeleteCaseUserActionRt,
]);

const CommonUserActionsWithIdsRt = rt.union([...BasicUserActionsRt.types, CommentUserActionRt]);

const CommonUserActionsWithoutIdsRt = rt.union([
...BasicUserActionsRt.types,
CommentUserActionWithoutIdsRt,
]);

const UserActionPayloadRt = rt.union([
CommonUserActionsRt,
CommonUserActionsWithIdsRt,
CreateCaseUserActionRt,
ConnectorUserActionRt,
PushedUserActionRt,
DeleteCaseUserActionRt,
]);

const UserActionsWithoutConnectorIdRt = rt.union([
CommonUserActionsRt,
const UserActionsWithoutIdsRt = rt.union([
CommonUserActionsWithoutIdsRt,
CreateCaseUserActionWithoutConnectorIdRt,
ConnectorUserActionWithoutConnectorIdRt,
PushedUserActionWithoutConnectorIdRt,
DeleteCaseUserActionRt,
]);

const CaseUserActionBasicRt = rt.intersection([UserActionPayloadRt, UserActionCommonAttributesRt]);
const CaseUserActionBasicWithoutConnectorIdRt = rt.intersection([
UserActionsWithoutConnectorIdRt,

export const CaseUserActionWithoutReferenceIdsRt = rt.intersection([
UserActionsWithoutIdsRt,
UserActionCommonAttributesRt,
]);

Expand Down Expand Up @@ -86,8 +92,8 @@ export const UserActionsRt = rt.array(UserActionRt);
export const CaseUserActionsDeprecatedResponseRt = rt.array(CaseUserActionDeprecatedResponseRt);
export const CaseUserActionStatsResponseRt = CaseUserActionStatsRt;

export type CaseUserActionAttributesWithoutConnectorId = rt.TypeOf<
typeof CaseUserActionBasicWithoutConnectorIdRt
export type CaseUserActionWithoutReferenceIds = rt.TypeOf<
typeof CaseUserActionWithoutReferenceIdsRt
>;
export type CaseUserActionStatsResponse = rt.TypeOf<typeof CaseUserActionStatsRt>;
export type UserActions = rt.TypeOf<typeof UserActionsRt>;
Expand Down
19 changes: 0 additions & 19 deletions x-pack/plugins/cases/server/client/cases/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import type {
Comment,
CommentResponseAlertsType,
CaseUserActionsDeprecatedResponse,
ConnectorMappings,
} from '../../../common/api';
import {
CommentType,
Expand Down Expand Up @@ -242,24 +241,6 @@ export const basicParams = {
...entity,
};

export const mappings: ConnectorMappings = [
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved on level up.

{
source: 'title',
target: 'short_description',
action_type: 'overwrite',
},
{
source: 'description',
target: 'description',
action_type: 'append',
},
{
source: 'comments',
target: 'comments',
action_type: 'append',
},
];

export const userActions: CaseUserActionsDeprecatedResponse = [
{
action: Actions.create,
Expand Down
3 changes: 1 addition & 2 deletions x-pack/plugins/cases/server/client/cases/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
userActions,
commentAlert,
commentAlertMultipleIds,
mappings,
isolateCommentActions,
releaseCommentActions,
isolateCommentActionsMultipleTargets,
Expand All @@ -34,7 +33,7 @@ import { flattenCaseSavedObject } from '../../common/utils';
import { SECURITY_SOLUTION_OWNER } from '../../../common/constants';
import { casesConnectors } from '../../connectors';
import { userProfiles, userProfilesMap } from '../user_profiles.mock';
import { mockCases } from '../../mocks';
import { mappings, mockCases } from '../../mocks';

const allComments = [
commentObj,
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/cases/server/common/types/user_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import type { SavedObject } from '@kbn/core/server';
import type { UserActionAttributes } from '../../../common/api';
import { UserActionAttributesRt } from '../../../common/api';
import { CaseUserActionWithoutReferenceIdsRt, UserActionAttributesRt } from '../../../common/api';
import type { User } from './user';

interface UserActionCommonPersistedAttributes {
Expand All @@ -23,6 +23,7 @@ export interface UserActionPersistedAttributes extends UserActionCommonPersisted
}

export const UserActionTransformedAttributesRt = UserActionAttributesRt;
export const UserActionPersistedAttributesRt = CaseUserActionWithoutReferenceIdsRt;

export type UserActionTransformedAttributes = UserActionAttributes;
export type UserActionSavedObjectTransformed = SavedObject<UserActionTransformedAttributes>;
19 changes: 19 additions & 0 deletions x-pack/plugins/cases/server/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
CommentAttributes,
CommentRequestAlertType,
CommentRequestUserType,
ConnectorMappings,
} from '../common/api';
import { CaseSeverity, CaseStatuses, CommentType, ConnectorTypes } from '../common/api';
import { SECURITY_SOLUTION_OWNER } from '../common/constants';
Expand Down Expand Up @@ -448,6 +449,24 @@ export const multipleAlert: CommentRequestAlertType = {
index: ['test-index-3', 'test-index-4', 'test-index-5'],
};

export const mappings: ConnectorMappings = [
{
source: 'title',
target: 'short_description',
action_type: 'overwrite',
},
{
source: 'description',
target: 'description',
action_type: 'append',
},
{
source: 'comments',
target: 'comments',
action_type: 'append',
},
];

const casesClientMock = createCasesClientMock();

export const mockCasesContract = (): CasesStart => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type {
SavedObjectsExportTransformContext,
} from '@kbn/core/server';
import type {
CaseUserActionAttributesWithoutConnectorId,
CaseUserActionWithoutReferenceIds,
CommentAttributesWithoutRefs,
} from '../../../common/api';
import {
Expand All @@ -40,9 +40,7 @@ export async function handleExport({
}): Promise<
Array<
SavedObject<
| CasePersistedAttributes
| CommentAttributesWithoutRefs
| CaseUserActionAttributesWithoutConnectorId
CasePersistedAttributes | CommentAttributesWithoutRefs | CaseUserActionWithoutReferenceIds
>
>
> {
Expand Down Expand Up @@ -75,17 +73,15 @@ export async function handleExport({
async function getAttachmentsAndUserActionsForCases(
savedObjectsClient: SavedObjectsClientContract,
caseIds: string[]
): Promise<
Array<SavedObject<CommentAttributesWithoutRefs | CaseUserActionAttributesWithoutConnectorId>>
> {
): Promise<Array<SavedObject<CommentAttributesWithoutRefs | CaseUserActionWithoutReferenceIds>>> {
const [attachments, userActions] = await Promise.all([
getAssociatedObjects<CommentAttributesWithoutRefs>({
savedObjectsClient,
caseIds,
sortField: defaultSortField,
type: CASE_COMMENT_SAVED_OBJECT,
}),
getAssociatedObjects<CaseUserActionAttributesWithoutConnectorId>({
getAssociatedObjects<CaseUserActionWithoutReferenceIds>({
savedObjectsClient,
caseIds,
sortField: defaultSortField,
Expand Down
Loading