Skip to content

Commit

Permalink
Add runtime checks for 'input' columns
Browse files Browse the repository at this point in the history
  • Loading branch information
manelcecs committed Nov 29, 2024
1 parent e63c0d0 commit a94af2d
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 7 deletions.
80 changes: 77 additions & 3 deletions src/domain-services/flows/flow-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { type Database } from '@unocha/hpc-api-core/src/db';
import { type FlowId } from '@unocha/hpc-api-core/src/db/models/flow';
import { Op } from '@unocha/hpc-api-core/src/db/util/conditions';
import { type InstanceOfModel } from '@unocha/hpc-api-core/src/db/util/types';
import { createBrandedValue } from '@unocha/hpc-api-core/src/util/types';
import {
createBrandedValue,
getTableColumns,
} from '@unocha/hpc-api-core/src/util/types';
import { Service } from 'typedi';
import { FlowObjectService } from '../flow-object/flow-object-service';
import type {
Expand Down Expand Up @@ -52,11 +55,20 @@ export class FlowService {
orderBy: FlowOrderByWithSubEntity
): Promise<UniqueFlowEntity[]> {
const entity = orderBy.subEntity ?? orderBy.entity;
let columns: string[] = [];

// Get the entity list
// 'externalReference' is a special case
// because it does have a direct relation with flow
// and no direction
if (entity === 'externalReference') {
columns = getTableColumns(database.externalReference);
if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}

const column = orderBy.column as keyof InstanceOfModel<
Database['externalReference']
>;
Expand All @@ -78,17 +90,23 @@ export class FlowService {

const refDirection = orderBy.direction ?? 'source';

// Validate the variable using io-ts

let flowObjects = [];
let entityIDsSorted: number[] = [];

switch (entity) {
case 'emergency': {
columns = getTableColumns(database.emergency);
if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}

// Get emergency entities sorted
const column = orderBy.column as keyof InstanceOfModel<
Database['emergency']
>;

const orderByEmergency = { column, order: orderBy.order };

const emergencies = await database.emergency.find({
Expand All @@ -102,6 +120,13 @@ export class FlowService {
break;
}
case 'globalCluster': {
columns = getTableColumns(database.globalCluster);

if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}
// Get globalCluster entities sorted
const column = orderBy.column as keyof InstanceOfModel<
Database['globalCluster']
Expand All @@ -119,6 +144,13 @@ export class FlowService {
break;
}
case 'governingEntity': {
columns = getTableColumns(database.governingEntity);

if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}
// Get governingEntity entities sorted
const column = orderBy.column as keyof InstanceOfModel<
Database['governingEntity']
Expand All @@ -136,6 +168,13 @@ export class FlowService {
break;
}
case 'location': {
columns = getTableColumns(database.location);

if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}
// Get location entities sorted
const column = orderBy.column as keyof InstanceOfModel<
Database['location']
Expand All @@ -151,6 +190,13 @@ export class FlowService {
break;
}
case 'organization': {
columns = getTableColumns(database.organization);

if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}
// Get organization entities sorted
const column = orderBy.column as keyof InstanceOfModel<
Database['organization']
Expand All @@ -168,6 +214,13 @@ export class FlowService {
break;
}
case 'plan': {
columns = getTableColumns(database.plan);

if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}
// Get plan entities sorted
const column = orderBy.column as keyof InstanceOfModel<
Database['plan']
Expand All @@ -183,6 +236,13 @@ export class FlowService {
break;
}
case 'project': {
columns = getTableColumns(database.project);

if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}
// Get project entities sorted
const column = orderBy.column as keyof InstanceOfModel<
Database['project']
Expand All @@ -198,6 +258,13 @@ export class FlowService {
break;
}
case 'usageYear': {
columns = getTableColumns(database.usageYear);

if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}
// Get usageYear entities sorted
const column = orderBy.column as keyof InstanceOfModel<
Database['usageYear']
Expand All @@ -213,6 +280,13 @@ export class FlowService {
break;
}
case 'planVersion': {
columns = getTableColumns(database.planVersion);

if (!columns.includes(orderBy.column)) {
throw new Error(
`Invalid column ${orderBy.column} to sort by in ${orderBy.entity}`
);
}
// Get planVersion entities sorted
// Collect fisrt part of the entity key by the fisrt Case letter
const entityKey = `${
Expand Down
12 changes: 8 additions & 4 deletions src/domain-services/flows/strategy/impl/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Cond, Op } from '@unocha/hpc-api-core/src/db/util/conditions';
import type { InstanceDataOf } from '@unocha/hpc-api-core/src/db/util/model-definition';
import { type InstanceOfModel } from '@unocha/hpc-api-core/src/db/util/types';
import { createBrandedValue } from '@unocha/hpc-api-core/src/util/types';
import type * as t from 'io-ts';
import { type OrderBy } from '../../../../utils/database-types';
import { type SortOrder } from '../../../../utils/graphql/pagination';
import { type EntityDirection } from '../../../base-types';
Expand Down Expand Up @@ -40,7 +41,8 @@ export const defaultSearchFlowFilter: FlowWhere = {

type FlowOrderByCommon = {
order: SortOrder;
direction?: EntityDirection;
direction: EntityDirection;
subEntity?: string;
};

export type FlowOrderBy = FlowOrderByCommon &
Expand Down Expand Up @@ -91,6 +93,8 @@ export type FlowOrderBy = FlowOrderByCommon &
}
);

export type FlowOrderByCodec = t.Type<FlowOrderBy>;

export const mapFlowCategoryConditionsToWhereClause = (
flowCategoryConditions: FlowCategory[]
) => {
Expand Down Expand Up @@ -150,7 +154,7 @@ export const mapFlowCategoryConditionsToWhereClause = (
};

export const mapFlowOrderBy = (
orderBy?: FlowOrderByWithSubEntity
orderBy?: FlowOrderBy | FlowOrderByWithSubEntity
): OrderBy<FlowFieldsDefinition> => {
if (!orderBy || orderBy.entity !== 'flow') {
return defaultFlowOrderBy();
Expand Down Expand Up @@ -371,9 +375,9 @@ export const buildOrderBy = (
const orderBy: FlowOrderByWithSubEntity = {
column: sortField ?? 'updatedAt',
order: sortOrder ?? ('desc' as SortOrder),
direction: undefined,
direction: 'source' as EntityDirection,
entity: 'flow',
};
} satisfies FlowOrderByWithSubEntity;

// Check if sortField is a nested property
if (orderBy.column.includes('.')) {
Expand Down

0 comments on commit a94af2d

Please sign in to comment.