useAppIdFromCtx helper
This commit is contained in:
parent
c26357c347
commit
b85f198fc2
|
@ -2,7 +2,6 @@ import Router from "@koa/router"
|
||||||
import * as controller from "../controllers/backup"
|
import * as controller from "../controllers/backup"
|
||||||
import authorized from "../../middleware/authorized"
|
import authorized from "../../middleware/authorized"
|
||||||
import { permissions } from "@budibase/backend-core"
|
import { permissions } from "@budibase/backend-core"
|
||||||
import { UserCtx } from "@budibase/types"
|
|
||||||
import ensureTenantAppOwnership from "../../middleware/ensureTenantAppOwnership"
|
import ensureTenantAppOwnership from "../../middleware/ensureTenantAppOwnership"
|
||||||
|
|
||||||
const router: Router = new Router()
|
const router: Router = new Router()
|
||||||
|
@ -10,7 +9,7 @@ const router: Router = new Router()
|
||||||
router.post(
|
router.post(
|
||||||
"/api/backups/export",
|
"/api/backups/export",
|
||||||
authorized(permissions.BUILDER),
|
authorized(permissions.BUILDER),
|
||||||
ensureTenantAppOwnership((ctx: UserCtx) => ctx.query.appId as string),
|
ensureTenantAppOwnership,
|
||||||
controller.exportAppDump
|
controller.exportAppDump
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import { tenancy } from "@budibase/backend-core"
|
import { tenancy, utils } from "@budibase/backend-core"
|
||||||
import { UserCtx } from "@budibase/types"
|
import { UserCtx } from "@budibase/types"
|
||||||
|
|
||||||
function ensureTenantAppOwnership(appIdGetter: (ctx: UserCtx) => string) {
|
async function ensureTenantAppOwnership(ctx: UserCtx, next: any) {
|
||||||
return async (ctx: UserCtx, next: any) => {
|
const appId = await utils.getAppIdFromCtx(ctx)
|
||||||
const appId = appIdGetter(ctx)
|
if (!appId) {
|
||||||
|
ctx.throw(400, "appId must be provided")
|
||||||
|
}
|
||||||
const exportAppId = tenancy.getTenantIDFromAppID(appId)
|
const exportAppId = tenancy.getTenantIDFromAppID(appId)
|
||||||
const tenantId = tenancy.getTenantId()
|
const tenantId = tenancy.getTenantId()
|
||||||
if (exportAppId !== tenantId) {
|
if (exportAppId !== tenantId) {
|
||||||
ctx.throw(403, `Cannot export app from another tenant`)
|
ctx.throw(403, `Cannot export app from another tenant`)
|
||||||
}
|
}
|
||||||
await next()
|
await next()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ensureTenantAppOwnership
|
export default ensureTenantAppOwnership
|
||||||
|
|
|
@ -1,26 +1,31 @@
|
||||||
import ensureTenantAppOwnership from "../ensureTenantAppOwnership"
|
import ensureTenantAppOwnership from "../ensureTenantAppOwnership"
|
||||||
import { tenancy } from "@budibase/backend-core"
|
import { tenancy, utils } from "@budibase/backend-core"
|
||||||
|
|
||||||
jest.mock("@budibase/backend-core", () => ({
|
jest.mock("@budibase/backend-core", () => ({
|
||||||
tenancy: {
|
tenancy: {
|
||||||
getTenantId: jest.fn(),
|
getTenantId: jest.fn(),
|
||||||
getTenantIDFromAppID: jest.fn(),
|
getTenantIDFromAppID: jest.fn(),
|
||||||
},
|
},
|
||||||
|
utils: {
|
||||||
|
getAppIdFromCtx: jest.fn(),
|
||||||
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
class TestConfiguration {
|
class TestConfiguration {
|
||||||
constructor() {
|
constructor(appId = "app_123") {
|
||||||
this.next = jest.fn()
|
this.next = jest.fn()
|
||||||
this.throw = jest.fn()
|
this.throw = jest.fn()
|
||||||
this.middleware = ensureTenantAppOwnership(() => "app_123")
|
this.middleware = ensureTenantAppOwnership
|
||||||
|
|
||||||
this.ctx = {
|
this.ctx = {
|
||||||
next: this.next,
|
next: this.next,
|
||||||
throw: this.throw,
|
throw: this.throw,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
utils.getAppIdFromCtx.mockResolvedValue(appId)
|
||||||
}
|
}
|
||||||
|
|
||||||
executeMiddleware() {
|
async executeMiddleware() {
|
||||||
return this.middleware(this.ctx, this.next)
|
return this.middleware(this.ctx, this.next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +50,8 @@ describe("Ensure Tenant Ownership Middleware", () => {
|
||||||
tenancy.getTenantId.mockReturnValue("tenant_1")
|
tenancy.getTenantId.mockReturnValue("tenant_1")
|
||||||
|
|
||||||
await config.executeMiddleware()
|
await config.executeMiddleware()
|
||||||
|
|
||||||
|
expect(utils.getAppIdFromCtx).toHaveBeenCalledWith(config.ctx)
|
||||||
expect(config.next).toHaveBeenCalled()
|
expect(config.next).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -53,9 +60,19 @@ describe("Ensure Tenant Ownership Middleware", () => {
|
||||||
tenancy.getTenantId.mockReturnValue("tenant_1")
|
tenancy.getTenantId.mockReturnValue("tenant_1")
|
||||||
|
|
||||||
await config.executeMiddleware()
|
await config.executeMiddleware()
|
||||||
|
|
||||||
|
expect(utils.getAppIdFromCtx).toHaveBeenCalledWith(config.ctx)
|
||||||
expect(config.throw).toHaveBeenCalledWith(
|
expect(config.throw).toHaveBeenCalledWith(
|
||||||
403,
|
403,
|
||||||
"Cannot export app from another tenant"
|
"Cannot export app from another tenant"
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("throws 400 when appId is missing", async () => {
|
||||||
|
utils.getAppIdFromCtx.mockResolvedValue(null)
|
||||||
|
|
||||||
|
await config.executeMiddleware()
|
||||||
|
|
||||||
|
expect(config.throw).toHaveBeenCalledWith(400, "appId must be provided")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue