Skip to content

Commit

Permalink
fix: patch validation (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbystedt authored May 2, 2024
1 parent fde51bd commit 0a2c5a6
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/intention/action.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class ActionService {
if (account) {
action.user.group = {
...(action.user.group ?? {}),
id: account.id.toString(),
id: account.id,
name: account.name,
domain: 'broker',
};
Expand Down
1 change: 1 addition & 0 deletions src/intention/dto/action.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class ActionDto {
@IsOptional()
@ApiHideProperty()
@Column(() => UserDto)
@Type(() => UserDto)
user?: UserDto;

@IsOptional()
Expand Down
10 changes: 8 additions & 2 deletions src/intention/dto/user-group.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import { IsOptional, IsString } from 'class-validator';
import { ObjectId } from 'mongodb';
import { Column, Entity } from 'typeorm';

@Entity()
Expand All @@ -8,10 +11,13 @@ export class UserGroupDto {
@Column()
domain: string;

@IsString()
@IsOptional()
@Column()
id: string;
@ApiProperty({ type: () => String })
@Transform((value) =>
value.obj.id ? new ObjectId(value.obj.id.toString()) : null,
)
id: ObjectId;

@IsString()
@IsOptional()
Expand Down
30 changes: 18 additions & 12 deletions src/intention/intention.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { plainToInstance } from 'class-transformer';
import { ObjectId } from 'mongodb';
import { FindOptionsWhere } from 'typeorm';
import merge from 'lodash.merge';
import { validate } from 'class-validator';

import { IntentionDto } from './dto/intention.dto';
import {
Expand Down Expand Up @@ -47,6 +48,9 @@ import { ArtifactSearchQuery } from './dto/artifact-search-query.dto';
import { ActionUtil, FindArtifactActionOptions } from '../util/action.util';
import { CollectionNameEnum } from '../persistence/dto/collection-dto-union.type';
import { ActionPatchRestDto } from './dto/action-patch-rest.dto';
import { PackageDto } from './dto/package.dto';
import { CloudDto } from './dto/cloud.dto';
import { CloudObjectDto } from './dto/cloud-object.dto';

export interface IntentionOpenResponse {
actions: {
Expand Down Expand Up @@ -634,10 +638,10 @@ export class IntentionService {
// Patch according to action
if (action.action === 'package-build') {
if (patchAction?.package) {
action.package = {
action.package = plainToInstance(PackageDto, {
...(action.package ?? {}),
...patchAction.package,
};
});
} else {
throw new BadRequestException({
statusCode: 400,
Expand All @@ -648,10 +652,10 @@ export class IntentionService {
} else if (action.action === 'package-installation') {
if (patchAction?.cloud?.target) {
if (!action?.cloud) {
action.cloud = { target: {} };
action.cloud = plainToInstance(CloudDto, { target: {} });
}
if (!action?.cloud.target) {
action.cloud.target = {};
action.cloud.target = plainToInstance(CloudObjectDto, {});
}
merge(action.cloud.target, patchAction.cloud.target);
} else {
Expand All @@ -663,19 +667,21 @@ export class IntentionService {
}
}

const errors = await validate(action, {
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
});
if (errors.length > 0) {
throw new BadRequestException('Validation failed');
}
// TODO: call this.actionService.validate to ensure this is still a valid intention

// replace with patched action
intention.actions = intention.actions.map((intentionAction) =>
intentionAction.action !== action.action ? intentionAction : action,
);

// Ensure this is still a valid intention -- copied as open modifies intention
await this.open(
req,
plainToInstance(IntentionDto, JSON.parse(JSON.stringify(intention))),
INTENTION_DEFAULT_TTL_SECONDS,
true,
);

this.auditService.recordIntentionActionUsage(
req,
intention,
Expand Down
13 changes: 9 additions & 4 deletions src/persistence/dto/user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { ApiHideProperty } from '@nestjs/swagger';
import { Entity, ObjectIdColumn, ObjectId, Column } from 'typeorm';
import { ApiHideProperty, ApiProperty } from '@nestjs/swagger';
import { Entity, ObjectIdColumn, Column } from 'typeorm';
import { IsDefined, IsOptional, IsString } from 'class-validator';
import { VertexPointerDto } from './vertex-pointer.dto';
import { Transform } from 'class-transformer';
import { ObjectId } from 'mongodb';
import { VertexPointerDto } from './vertex-pointer.dto';

export class UserGroupDto {
@Column()
domain?: string;

@Column()
id?: string;
@ApiProperty({ type: () => String })
@Transform((value) =>
value.obj.id ? new ObjectId(value.obj.id.toString()) : null,
)
id?: ObjectId;

@Column()
name?: string;
Expand Down

0 comments on commit 0a2c5a6

Please sign in to comment.