Skip to content

Commit e483afb

Browse files
authored
chore(api-gateway): Remove sql-runner routes (#6166)
1 parent 387020d commit e483afb

File tree

5 files changed

+3
-448
lines changed

5 files changed

+3
-448
lines changed

packages/cubejs-api-gateway/src/gateway.ts

Lines changed: 0 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ import { SQLServer } from './sql-server';
8080
import { makeSchema } from './graphql';
8181
import { ConfigItem, prepareAnnotation } from './helpers/prepareAnnotation';
8282
import transformData from './helpers/transformData';
83-
import { shouldAddLimit } from './helpers/shouldAddLimit';
8483
import {
8584
transformCube,
8685
transformMeasure,
@@ -387,11 +386,6 @@ class ApiGateway {
387386
this.requestLoggerMiddleware
388387
];
389388

390-
const sqlRunnerMiddlewares = [
391-
...systemMiddlewares,
392-
this.checkSqlRunnerScope,
393-
];
394-
395389
app.get('/cubejs-system/v1/context', systemMiddlewares, this.createSystemContextHandler(this.basePath));
396390

397391
app.get('/cubejs-system/v1/pre-aggregations', systemMiddlewares, (async (req, res) => {
@@ -455,39 +449,6 @@ class ApiGateway {
455449
res: this.resToResultFn(res)
456450
});
457451
}));
458-
459-
app.post(
460-
'/cubejs-system/v1/sql-runner',
461-
jsonParser,
462-
sqlRunnerMiddlewares,
463-
async (req: Request, res: Response) => {
464-
await this.sqlRunner({
465-
query: req.body.query,
466-
context: req.context!,
467-
res: this.resToResultFn(res),
468-
});
469-
}
470-
);
471-
472-
app.get(
473-
'/cubejs-system/v1/data-sources',
474-
jsonParser,
475-
sqlRunnerMiddlewares,
476-
async (req: Request, res: Response) => {
477-
await this.dataSources({
478-
context: req.context,
479-
res: this.resToResultFn(res),
480-
});
481-
}
482-
);
483-
484-
app.post('/cubejs-system/v1/db-schema', jsonParser, systemMiddlewares, (async (req: Request, res: Response) => {
485-
await this.dbSchema({
486-
query: req.body.query,
487-
context: req.context,
488-
res: this.resToResultFn(res),
489-
});
490-
}));
491452
}
492453

493454
app.use(this.handleErrorMiddleware);
@@ -1113,171 +1074,6 @@ class ApiGateway {
11131074
});
11141075
}
11151076
}
1116-
1117-
protected async dataSources({ context, res }: { context?: RequestContext, res: ResponseResultFn }) {
1118-
const requestStarted = new Date();
1119-
1120-
try {
1121-
const orchestratorApi = await this.getAdapterApi(context);
1122-
const { dataSources } = await this.getCompilerApi(context).dataSources(orchestratorApi);
1123-
1124-
res({ dataSources });
1125-
} catch (e) {
1126-
this.handleError({
1127-
e,
1128-
context,
1129-
res,
1130-
requestStarted,
1131-
});
1132-
}
1133-
}
1134-
1135-
protected async sqlRunner({ query, context, res }: QueryRequest) {
1136-
const requestStarted = new Date();
1137-
try {
1138-
if (!query) {
1139-
throw new UserError('A user\'s query must contain a body');
1140-
}
1141-
1142-
if (!Array.isArray(query) && !query.query) {
1143-
throw new UserError(
1144-
'A user\'s query must contain at least one query param.'
1145-
);
1146-
}
1147-
1148-
query = {
1149-
...query,
1150-
requestId: context.requestId,
1151-
};
1152-
1153-
const orchestratorApi = this.getAdapterApi(context);
1154-
1155-
if (shouldAddLimit(query.query)) {
1156-
if (
1157-
!query.limit ||
1158-
!Number.isInteger(query.limit) ||
1159-
query.limit < 0
1160-
) {
1161-
throw new UserError(
1162-
'A user\'s query must contain limit query param and it must be positive number'
1163-
);
1164-
}
1165-
1166-
if (query.limit > getEnv('dbQueryDefaultLimit')) {
1167-
throw new UserError('The query limit has been exceeded');
1168-
}
1169-
1170-
if (
1171-
query.resultFilter?.objectTypes &&
1172-
!Array.isArray(query.resultFilter.objectTypes)
1173-
) {
1174-
throw new UserError(
1175-
'A query.resultFilter.objectTypes must be an array of strings'
1176-
);
1177-
}
1178-
1179-
query.query = query.query.trim();
1180-
if (query.query.charAt(query.query.length - 1) === ';') {
1181-
query.query = query.query.slice(0, -1);
1182-
}
1183-
1184-
const driver = await orchestratorApi
1185-
.driverFactory(query.dataSource || 'default');
1186-
1187-
driver.wrapQueryWithLimit(query);
1188-
}
1189-
1190-
this.log(
1191-
{
1192-
type: 'Load SQL Runner Request',
1193-
query,
1194-
},
1195-
context
1196-
);
1197-
1198-
const result = await orchestratorApi.executeQuery(query);
1199-
1200-
if (result.data.length) {
1201-
const objectLimit = Number(query.resultFilter?.objectLimit) || 100;
1202-
const stringLimit = Number(query.resultFilter?.stringLimit) || 100;
1203-
const objectTypes = query.resultFilter?.objectTypes || [];
1204-
const limit = Number(query.resultFilter?.limit) || 20;
1205-
const offset = Number(query.resultFilter?.offset) || 0;
1206-
result.total = result.data.length;
1207-
result.offset = offset;
1208-
result.data = result.data.slice(offset, offset + limit);
1209-
result.data = result.data.map((row) => {
1210-
Object.keys(row).forEach((key) => {
1211-
if (
1212-
typeof row[key] === 'object' && row[key] !== null && row[key].type &&
1213-
(objectTypes.length === 0 || !objectTypes.includes(row[key].type))
1214-
) {
1215-
row[key] = row[key].type;
1216-
} else if (typeof row[key] === 'object' && row[key] !== null) {
1217-
row[key] = JSON.stringify(row[key].data || row[key]).slice(0, objectLimit);
1218-
} else if (typeof row[key] === 'string') {
1219-
row[key] = row[key].slice(0, stringLimit);
1220-
}
1221-
});
1222-
1223-
return row;
1224-
});
1225-
}
1226-
1227-
this.log(
1228-
{
1229-
type: 'Load SQL Runner Request Success',
1230-
query,
1231-
duration: this.duration(requestStarted),
1232-
dbType: result.dbType,
1233-
},
1234-
context
1235-
);
1236-
1237-
res(result);
1238-
} catch (e) {
1239-
this.handleError({
1240-
e, context, query, res, requestStarted
1241-
});
1242-
}
1243-
}
1244-
1245-
protected async dbSchema({ query, context, res }: {
1246-
query: {
1247-
dataSource: string;
1248-
};
1249-
context?: RequestContext;
1250-
res: ResponseResultFn;
1251-
}) {
1252-
const requestStarted = new Date();
1253-
try {
1254-
if (!query) {
1255-
throw new UserError(
1256-
'A user\'s query must contain a body'
1257-
);
1258-
}
1259-
1260-
if (!query.dataSource) {
1261-
throw new UserError(
1262-
'A user\'s query must contain dataSource.'
1263-
);
1264-
}
1265-
1266-
const orchestratorApi = await this.getAdapterApi(context);
1267-
1268-
const schema = await orchestratorApi
1269-
.getQueryOrchestrator()
1270-
.fetchSchema(query.dataSource);
1271-
1272-
res({ data: schema });
1273-
} catch (e) {
1274-
this.handleError({ e,
1275-
context,
1276-
res,
1277-
requestStarted,
1278-
});
1279-
}
1280-
}
12811077

12821078
/**
12831079
* Convert incoming query parameter (JSON fetched from the HTTP) to
@@ -2258,24 +2054,6 @@ class ApiGateway {
22582054
await this.checkAuthWrapper(this.checkAuthSystemFn, req, res, next);
22592055
};
22602056

2261-
protected checkSqlRunnerScope: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {
2262-
await this.checkAuthWrapper(
2263-
async () => {
2264-
if (
2265-
!getEnv('devMode') &&
2266-
(!req.context?.securityContext?.scope ||
2267-
!Array.isArray(req.context?.securityContext?.scope) ||
2268-
!req.context?.securityContext?.scope.includes('sql-runner'))
2269-
) {
2270-
throw new CubejsHandlerError(403, 'Forbidden', 'Sql-runner scope is missing.');
2271-
}
2272-
},
2273-
req,
2274-
res,
2275-
next
2276-
);
2277-
};
2278-
22792057
protected requestContextMiddleware: RequestHandler = async (req: Request, res: Response, next: NextFunction) => {
22802058
try {
22812059
req.context = await this.contextByReq(req, req.securityContext, getRequestIdFromRequest(req));

packages/cubejs-api-gateway/src/helpers/shouldAddLimit.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

packages/cubejs-api-gateway/test/helpers/shouldAddLimit.test.ts

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)