Make sure calculation views cannot be used to write or modify rows.
This commit is contained in:
parent
5dc85230d9
commit
0182d4a09f
|
@ -27,6 +27,7 @@ import {
|
||||||
} from "../../../utilities/rowProcessor"
|
} from "../../../utilities/rowProcessor"
|
||||||
import { cloneDeep } from "lodash"
|
import { cloneDeep } from "lodash"
|
||||||
import { generateIdForRow } from "./utils"
|
import { generateIdForRow } from "./utils"
|
||||||
|
import { helpers } from "@budibase/shared-core"
|
||||||
|
|
||||||
export async function handleRequest<T extends Operation>(
|
export async function handleRequest<T extends Operation>(
|
||||||
operation: T,
|
operation: T,
|
||||||
|
@ -42,6 +43,11 @@ export async function handleRequest<T extends Operation>(
|
||||||
|
|
||||||
export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
||||||
const source = await utils.getSource(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 = await utils.getTableFromSource(source)
|
const table = await utils.getTableFromSource(source)
|
||||||
const { _id, ...rowData } = ctx.request.body
|
const { _id, ...rowData } = ctx.request.body
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,20 @@ import sdk from "../../../sdk"
|
||||||
import { getLinkedTableIDs } from "../../../db/linkedRows/linkUtils"
|
import { getLinkedTableIDs } from "../../../db/linkedRows/linkUtils"
|
||||||
import { flatten } from "lodash"
|
import { flatten } from "lodash"
|
||||||
import { findRow } from "../../../sdk/app/rows/internal"
|
import { findRow } from "../../../sdk/app/rows/internal"
|
||||||
|
import { helpers } from "@budibase/shared-core"
|
||||||
|
|
||||||
export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
||||||
const { tableId } = utils.getSourceId(ctx)
|
const { tableId } = utils.getSourceId(ctx)
|
||||||
const source = await utils.getSource(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)
|
const table = sdk.views.isView(source)
|
||||||
? await sdk.views.getTable(source.id)
|
? await sdk.views.getTable(source.id)
|
||||||
: source
|
: source
|
||||||
|
|
||||||
const inputs = ctx.request.body
|
const inputs = ctx.request.body
|
||||||
const isUserTable = tableId === InternalTables.USER_METADATA
|
const isUserTable = tableId === InternalTables.USER_METADATA
|
||||||
let oldRow
|
let oldRow
|
||||||
|
|
|
@ -1978,6 +1978,30 @@ describe.each([
|
||||||
expect(newRow.one).toBeUndefined()
|
expect(newRow.one).toBeUndefined()
|
||||||
expect(newRow.two).toEqual("bar")
|
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", () => {
|
describe("patch", () => {
|
||||||
|
@ -2042,6 +2066,40 @@ describe.each([
|
||||||
expect(row.one).toEqual("foo")
|
expect(row.one).toEqual("foo")
|
||||||
expect(row.two).toEqual("newBar")
|
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", () => {
|
describe("destroy", () => {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
} from "../../../utilities/rowProcessor"
|
} from "../../../utilities/rowProcessor"
|
||||||
import cloneDeep from "lodash/fp/cloneDeep"
|
import cloneDeep from "lodash/fp/cloneDeep"
|
||||||
import { tryExtractingTableAndViewId } from "./utils"
|
import { tryExtractingTableAndViewId } from "./utils"
|
||||||
|
import { helpers } from "@budibase/shared-core"
|
||||||
|
|
||||||
export async function getRow(
|
export async function getRow(
|
||||||
sourceId: string | Table | ViewV2,
|
sourceId: string | Table | ViewV2,
|
||||||
|
@ -54,6 +55,10 @@ export async function save(
|
||||||
source = await sdk.tables.getTable(tableId)
|
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 row = await inputProcessing(userId, cloneDeep(source), inputs)
|
||||||
|
|
||||||
const validateResult = await sdk.rows.utils.validate({
|
const validateResult = await sdk.rows.utils.validate({
|
||||||
|
|
|
@ -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 { Row, Table, ViewV2 } from "@budibase/types"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import { finaliseRow } from "../../../api/controllers/row/staticFormula"
|
import { finaliseRow } from "../../../api/controllers/row/staticFormula"
|
||||||
|
@ -10,6 +10,7 @@ import * as linkRows from "../../../db/linkedRows"
|
||||||
import { InternalTables } from "../../../db/utils"
|
import { InternalTables } from "../../../db/utils"
|
||||||
import { getFullUser } from "../../../utilities/users"
|
import { getFullUser } from "../../../utilities/users"
|
||||||
import { getSource, tryExtractingTableAndViewId } from "./utils"
|
import { getSource, tryExtractingTableAndViewId } from "./utils"
|
||||||
|
import { helpers } from "@budibase/shared-core"
|
||||||
|
|
||||||
export async function save(
|
export async function save(
|
||||||
tableOrViewId: string,
|
tableOrViewId: string,
|
||||||
|
@ -29,6 +30,10 @@ export async function save(
|
||||||
table = source
|
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) {
|
if (!inputs._rev && !inputs._id) {
|
||||||
inputs._id = db.generateRowID(inputs.tableId)
|
inputs._id = db.generateRowID(inputs.tableId)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue