Make sure calculation views cannot be used to write or modify rows.

This commit is contained in:
Sam Rose 2024-10-08 17:55:42 +01:00
parent 5dc85230d9
commit 0182d4a09f
No known key found for this signature in database
5 changed files with 82 additions and 1 deletions

View File

@ -27,6 +27,7 @@ import {
} from "../../../utilities/rowProcessor"
import { cloneDeep } from "lodash"
import { generateIdForRow } from "./utils"
import { helpers } from "@budibase/shared-core"
export async function handleRequest<T extends Operation>(
operation: T,
@ -42,6 +43,11 @@ export async function handleRequest<T extends Operation>(
export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
const source = await utils.getSource(ctx)
if (sdk.views.isView(source) && helpers.views.isCalculationView(source)) {
ctx.throw(400, "Cannot update rows through a calculation view")
}
const table = await utils.getTableFromSource(source)
const { _id, ...rowData } = ctx.request.body

View File

@ -22,13 +22,20 @@ import sdk from "../../../sdk"
import { getLinkedTableIDs } from "../../../db/linkedRows/linkUtils"
import { flatten } from "lodash"
import { findRow } from "../../../sdk/app/rows/internal"
import { helpers } from "@budibase/shared-core"
export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
const { tableId } = utils.getSourceId(ctx)
const source = await utils.getSource(ctx)
if (sdk.views.isView(source) && helpers.views.isCalculationView(source)) {
ctx.throw(400, "Cannot update rows through a calculation view")
}
const table = sdk.views.isView(source)
? await sdk.views.getTable(source.id)
: source
const inputs = ctx.request.body
const isUserTable = tableId === InternalTables.USER_METADATA
let oldRow

View File

@ -1978,6 +1978,30 @@ describe.each([
expect(newRow.one).toBeUndefined()
expect(newRow.two).toEqual("bar")
})
it("should not be possible to create a row in a calculation view", async () => {
const view = await config.api.viewV2.create({
tableId: table._id!,
name: generator.guid(),
type: ViewV2Type.CALCULATION,
schema: {
id: { visible: true },
one: { visible: true },
},
})
await config.api.row.save(
view.id,
{ one: "foo" },
{
status: 400,
body: {
message: "Cannot insert rows through a calculation view",
status: 400,
},
}
)
})
})
describe("patch", () => {
@ -2042,6 +2066,40 @@ describe.each([
expect(row.one).toEqual("foo")
expect(row.two).toEqual("newBar")
})
it("should not be possible to modify a row in a calculation view", async () => {
const view = await config.api.viewV2.create({
tableId: table._id!,
name: generator.guid(),
type: ViewV2Type.CALCULATION,
schema: {
id: { visible: true },
one: { visible: true },
},
})
const newRow = await config.api.row.save(table._id!, {
one: "foo",
two: "bar",
})
await config.api.row.patch(
view.id,
{
tableId: table._id!,
_id: newRow._id!,
_rev: newRow._rev!,
one: "newFoo",
two: "newBar",
},
{
status: 400,
body: {
message: "Cannot update rows through a calculation view",
},
}
)
})
})
describe("destroy", () => {

View File

@ -15,6 +15,7 @@ import {
} from "../../../utilities/rowProcessor"
import cloneDeep from "lodash/fp/cloneDeep"
import { tryExtractingTableAndViewId } from "./utils"
import { helpers } from "@budibase/shared-core"
export async function getRow(
sourceId: string | Table | ViewV2,
@ -54,6 +55,10 @@ export async function save(
source = await sdk.tables.getTable(tableId)
}
if (sdk.views.isView(source) && helpers.views.isCalculationView(source)) {
throw new HTTPError("Cannot insert rows through a calculation view", 400)
}
const row = await inputProcessing(userId, cloneDeep(source), inputs)
const validateResult = await sdk.rows.utils.validate({

View File

@ -1,4 +1,4 @@
import { context, db } from "@budibase/backend-core"
import { context, db, HTTPError } from "@budibase/backend-core"
import { Row, Table, ViewV2 } from "@budibase/types"
import sdk from "../../../sdk"
import { finaliseRow } from "../../../api/controllers/row/staticFormula"
@ -10,6 +10,7 @@ import * as linkRows from "../../../db/linkedRows"
import { InternalTables } from "../../../db/utils"
import { getFullUser } from "../../../utilities/users"
import { getSource, tryExtractingTableAndViewId } from "./utils"
import { helpers } from "@budibase/shared-core"
export async function save(
tableOrViewId: string,
@ -29,6 +30,10 @@ export async function save(
table = source
}
if (sdk.views.isView(source) && helpers.views.isCalculationView(source)) {
throw new HTTPError("Cannot insert rows through a calculation view", 400)
}
if (!inputs._rev && !inputs._id) {
inputs._id = db.generateRowID(inputs.tableId)
}