Browse Source

feat: validate fields and filters

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/6770/head
Pranav C 1 year ago
parent
commit
54e4cad366
  1. 10
      packages/nocodb/src/db/BaseModelSqlv2.ts
  2. 14
      packages/nocodb/src/helpers/getAst.ts
  3. 11
      packages/nocodb/src/services/data-table.service.ts
  4. 3
      packages/nocodb/src/services/datas.service.ts

10
packages/nocodb/src/db/BaseModelSqlv2.ts

@ -141,9 +141,11 @@ class BaseModelSqlv2 {
{
ignoreView = false,
getHiddenColumn = false,
throwErrorIfInvalidParams = false,
}: {
ignoreView?: boolean;
getHiddenColumn?: boolean;
throwErrorIfInvalidParams?: boolean;
} = {},
): Promise<any> {
const qb = this.dbDriver(this.tnPath);
@ -153,6 +155,7 @@ class BaseModelSqlv2 {
model: this.model,
view: ignoreView ? null : this.viewId && (await View.get(this.viewId)),
getHiddenColumn,
throwErrorIfInvalidParams
});
await this.selectObject({
@ -369,6 +372,7 @@ class BaseModelSqlv2 {
public async count(
args: { where?: string; limit?; filterArr?: Filter[] } = {},
ignoreViewFilterAndSort = false,
throwErrorIfInvalidParams = false,
): Promise<any> {
await this.model.getColumns();
const { where } = this._getListArgs(args);
@ -377,7 +381,7 @@ class BaseModelSqlv2 {
// qb.xwhere(where, await this.model.getAliasColMapping());
const aliasColObjMap = await this.model.getAliasColObjMap();
const filterObj = extractFilterFromXwhere(where, aliasColObjMap);
const filterObj = extractFilterFromXwhere(where, aliasColObjMap,throwErrorIfInvalidParams);
if (!ignoreViewFilterAndSort && this.viewId) {
await conditionV2(
@ -401,6 +405,8 @@ class BaseModelSqlv2 {
...(args.filterArr || []),
],
qb,
undefined,
throwErrorIfInvalidParams
);
} else {
await conditionV2(
@ -419,6 +425,8 @@ class BaseModelSqlv2 {
...(args.filterArr || []),
],
qb,
undefined,
throwErrorIfInvalidParams
);
}

14
packages/nocodb/src/helpers/getAst.ts

@ -5,6 +5,7 @@ import type {
LookupColumn,
Model,
} from '~/models';
import { NcError } from '~/helpers/catchError';
import { GalleryView, KanbanView, View } from '~/models';
const getAst = async ({
@ -19,6 +20,7 @@ const getAst = async ({
fieldsSet: new Set(),
},
getHiddenColumn = query?.['getHiddenColumn'],
throwErrorIfInvalidParams = false,
}: {
query?: RequestQuery;
extractOnlyPrimaries?: boolean;
@ -27,6 +29,7 @@ const getAst = async ({
view?: View;
dependencyFields?: DependantFields;
getHiddenColumn?: boolean;
throwErrorIfInvalidParams?: boolean;
}) => {
// set default values of dependencyFields and nested
dependencyFields.nested = dependencyFields.nested || {};
@ -63,6 +66,15 @@ const getAst = async ({
let fields = query?.fields || query?.f;
if (fields && fields !== '*') {
fields = Array.isArray(fields) ? fields : fields.split(',');
if (throwErrorIfInvalidParams) {
const colAliasMap = model.getColAliasMapping();
const invalidFields = fields.filter((f) => !colAliasMap[f]);
if (invalidFields.length) {
NcError.unprocessableEntity(
`Following fields are invalid: ${invalidFields.join(', ')}`,
);
}
}
} else {
fields = null;
}
@ -99,6 +111,7 @@ const getAst = async ({
nested: {},
fieldsSet: new Set(),
}),
throwErrorIfInvalidParams,
});
value = ast;
@ -126,6 +139,7 @@ const getAst = async ({
nested: {},
fieldsSet: new Set(),
}),
throwErrorIfInvalidParams,
})
).ast;
}

11
packages/nocodb/src/services/data-table.service.ts

@ -25,6 +25,7 @@ export class DataTableService {
model,
view,
query: param.query,
throwErrorIfInvalidParams: true,
});
}
@ -45,7 +46,9 @@ export class DataTableService {
dbDriver: await NcConnectionMgrv2.get(source),
});
const row = await baseModel.readByPk(param.rowId, false, param.query);
const row = await baseModel.readByPk(param.rowId, false, param.query, {
throwErrorIfInvalidParams: true,
});
if (!row) {
NcError.notFound('Row not found');
@ -167,7 +170,7 @@ export class DataTableService {
countArgs.filterArr = JSON.parse(countArgs.filterArrJson);
} catch (e) {}
const count: number = await baseModel.count(countArgs);
const count: number = await baseModel.count(countArgs, false, true);
return { count };
}
@ -368,7 +371,7 @@ export class DataTableService {
modelId: string;
columnId: string;
query: any;
refRowIds: string | string[] | number | number[]| Record<string, any>;
refRowIds: string | string[] | number | number[] | Record<string, any>;
rowId: string;
}) {
this.validateIds(param.refRowIds);
@ -403,7 +406,7 @@ export class DataTableService {
modelId: string;
columnId: string;
query: any;
refRowIds: string | string[] | number | number[]| Record<string, any>;
refRowIds: string | string[] | number | number[] | Record<string, any>;
rowId: string;
}) {
this.validateIds(param.refRowIds);

3
packages/nocodb/src/services/datas.service.ts

@ -133,6 +133,7 @@ export class DatasService {
view?: View;
query: any;
baseModel?: BaseModelSqlv2;
throwErrorIfInvalidParams?: boolean;
}) {
const { model, view, query = {} } = param;
@ -146,7 +147,7 @@ export class DatasService {
dbDriver: await NcConnectionMgrv2.get(source),
}));
const { ast, dependencyFields } = await getAst({ model, query, view });
const { ast, dependencyFields } = await getAst({ model, query, view, throwErrorIfInvalidParams: param.throwErrorIfInvalidParams });
const listArgs: any = dependencyFields;
try {

Loading…
Cancel
Save