Add triggerRowActionAuthorised

This commit is contained in:
Adria Navarro 2024-08-26 17:13:52 +02:00
parent f193df41f1
commit 868d193015
3 changed files with 88 additions and 3 deletions

View File

@ -2,9 +2,10 @@ import Router from "@koa/router"
import Joi from "joi"
import { middleware, permissions } from "@budibase/backend-core"
import * as rowActionController from "../controllers/rowAction"
import authorized, { authorizedResource } from "../../middleware/authorized"
import authorized from "../../middleware/authorized"
import { triggerRowActionAuthorised } from "../../middleware/triggerRowActionAuthorised"
const { PermissionLevel, PermissionType, BUILDER } = permissions
const { BUILDER } = permissions
function rowActionValidator() {
return middleware.joiValidator.body(
@ -65,7 +66,7 @@ router
.post(
"/api/tables/:sourceId/actions/:actionId/trigger",
rowTriggerValidator(),
authorizedResource(PermissionType.TABLE, PermissionLevel.READ, "tableId"),
triggerRowActionAuthorised("sourceId", "actionId"),
rowActionController.run
)

View File

@ -726,5 +726,47 @@ describe("/rowsActions", () => {
}),
])
})
it("rejects triggering from a non-allowed view", async () => {
const viewId = (
await config.api.viewV2.create(
setup.structures.viewV2.createRequest(tableId)
)
).id
await config.api.rowAction.trigger(
viewId,
rowAction.id,
{
rowId: row._id!,
},
{
status: 403,
body: {
message: `Row action '${rowAction.id}' is not enabled for view '${viewId}'"`,
},
}
)
const { data: automationLogs } = await config.doInContext(
config.getProdAppId(),
async () =>
automations.logs.logSearch({
startDate: await automations.logs.oldestLogDate(),
})
)
expect(automationLogs).toEqual([
expect.objectContaining({
automationId: rowAction.automationId,
trigger: expect.objectContaining({
outputs: {
fields: {},
row: await config.api.row.get(tableId, row._id!),
table: await config.api.table.get(tableId),
},
}),
}),
])
})
})
})

View File

@ -0,0 +1,42 @@
import { Next } from "koa"
import { Ctx } from "@budibase/types"
import { paramSubResource } from "./resourceId"
import { docIds } from "@budibase/backend-core"
import * as utils from "../db/utils"
import sdk from "../sdk"
export function triggerRowActionAuthorised(
sourcePath: string,
actionPath: string
) {
return async (ctx: Ctx, next: Next) => {
// Reusing the existing middleware to extract the value
paramSubResource(sourcePath, actionPath)(ctx, () => {})
const { resourceId: sourceId, subResourceId: rowActionId } = ctx
const isTableId = docIds.isTableId(sourceId)
const isViewId = utils.isViewID(sourceId)
if (!isTableId && !isViewId) {
ctx.throw(400, `'${sourceId}' is not a valid source id`)
}
const tableId = isTableId
? sourceId
: utils.extractViewInfoFromID(sourceId).tableId
const rowAction = await sdk.rowActions.get(tableId, rowActionId)
if (isTableId && !rowAction.permissions.table.runAllowed) {
ctx.throw(
403,
`Row action '${rowActionId}' is not enabled for table '${sourceId}'`
)
} else if (isViewId && !rowAction.permissions.views[sourceId]?.runAllowed) {
ctx.throw(
403,
`Row action '${rowActionId}' is not enabled for view '${sourceId}'`
)
}
return next()
}
}