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

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

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

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

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

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

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

Loading…
Cancel
Save