budibase/packages/server/src/middleware/triggerRowActionAuthorised.ts

84 lines
2.4 KiB
TypeScript
Raw Normal View History

2024-08-26 17:13:52 +02:00
import { Next } from "koa"
2024-09-04 10:16:59 +02:00
import { PermissionLevel, PermissionType, UserCtx } from "@budibase/types"
2024-08-26 17:13:52 +02:00
import { paramSubResource } from "./resourceId"
import { docIds } from "@budibase/backend-core"
import * as utils from "../db/utils"
import sdk from "../sdk"
2024-09-04 10:16:59 +02:00
import { authorizedResource } from "./authorized"
2024-09-03 17:53:25 +02:00
2024-08-26 17:13:52 +02:00
export function triggerRowActionAuthorised(
sourcePath: string,
actionPath: string
) {
2024-09-04 10:16:59 +02:00
return async (ctx: UserCtx, next: Next) => {
async function getResourceIds() {
// Reusing the existing middleware to extract the value
await paramSubResource(sourcePath, actionPath)(ctx, () => {})
const sourceId: string = ctx.resourceId
const rowActionId: string = ctx.subResourceId
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 viewId = isTableId ? undefined : sourceId
return { tableId, viewId, rowActionId }
2024-08-26 17:13:52 +02:00
}
2024-09-04 10:16:59 +02:00
async function guardResourcePermissions(
ctx: UserCtx,
tableId: string,
viewId?: string
) {
const { params } = ctx
try {
if (!viewId) {
ctx.params = { tableId }
await authorizedResource(
PermissionType.TABLE,
PermissionLevel.READ,
"tableId"
)(ctx, () => {})
} else {
ctx.params = { viewId }
await authorizedResource(
PermissionType.VIEW,
PermissionLevel.READ,
"__viewId"
)(ctx, () => {})
}
} finally {
ctx.params = params
}
}
2024-09-03 17:21:13 +02:00
2024-09-04 10:16:59 +02:00
const { tableId, viewId, rowActionId } = await getResourceIds()
2024-08-26 18:00:14 +02:00
2024-08-26 17:13:52 +02:00
const rowAction = await sdk.rowActions.get(tableId, rowActionId)
2024-09-03 17:21:13 +02:00
if (!viewId && !rowAction.permissions.table.runAllowed) {
2024-08-26 17:13:52 +02:00
ctx.throw(
403,
2024-09-03 17:21:13 +02:00
`Row action '${rowActionId}' is not enabled for table '${tableId}'`
2024-08-26 17:13:52 +02:00
)
2024-09-03 17:21:13 +02:00
} else if (viewId && !rowAction.permissions.views[viewId]?.runAllowed) {
2024-08-26 17:13:52 +02:00
ctx.throw(
403,
2024-09-03 17:21:13 +02:00
`Row action '${rowActionId}' is not enabled for view '${viewId}'`
2024-08-26 17:13:52 +02:00
)
}
2024-09-04 10:16:59 +02:00
await guardResourcePermissions(ctx, tableId, viewId)
2024-08-26 18:00:14 +02:00
// Enrich tableId
ctx.params.tableId = tableId
2024-08-26 17:13:52 +02:00
return next()
}
}