Some more fixes and test case for screen access.

This commit is contained in:
mike12345567 2024-10-15 17:53:48 +01:00
parent 808096f31b
commit 9fceef0fc2
2 changed files with 93 additions and 13 deletions

View File

@ -223,6 +223,11 @@ export function lowerBuiltinRoleID(roleId1?: string, roleId2?: string): string {
: roleId1 : roleId1
} }
function compareRoleIds(roleId1: string, roleId2: string) {
// make sure both role IDs are prefixed correctly
return prefixRoleID(roleId1) === prefixRoleID(roleId2)
}
/** /**
* Given a list of roles, this will pick the role out, accounting for built ins. * Given a list of roles, this will pick the role out, accounting for built ins.
*/ */
@ -239,7 +244,7 @@ export function findRole(
roleId = prefixRoleID(roleId) roleId = prefixRoleID(roleId)
} }
const dbRole = roles.find( const dbRole = roles.find(
role => role._id && role._id === getExternalRoleID(roleId, role.version) role => role._id && compareRoleIds(role._id, roleId)
) )
if (!dbRole && !isBuiltin(roleId) && opts?.defaultPublic) { if (!dbRole && !isBuiltin(roleId) && opts?.defaultPublic) {
return cloneDeep(BUILTIN_ROLES.PUBLIC) return cloneDeep(BUILTIN_ROLES.PUBLIC)
@ -474,7 +479,10 @@ export class AccessController {
this.userHierarchies[userRoleId] = roleIds this.userHierarchies[userRoleId] = roleIds
} }
return roleIds?.indexOf(tryingRoleId) !== -1 return (
roleIds?.find(roleId => compareRoleIds(roleId, tryingRoleId)) !==
undefined
)
} }
async checkScreensAccess(screens: Screen[], userRoleId: string) { async checkScreensAccess(screens: Screen[], userRoleId: string) {

View File

@ -1,7 +1,7 @@
import { checkBuilderEndpoint } from "./utilities/TestFunctions" import { checkBuilderEndpoint } from "./utilities/TestFunctions"
import * as setup from "./utilities" import * as setup from "./utilities"
import { events } from "@budibase/backend-core" import { events, roles } from "@budibase/backend-core"
import { Screen } from "@budibase/types" import { Screen, PermissionLevel, Role } from "@budibase/types"
const { basicScreen } = setup.structures const { basicScreen } = setup.structures
@ -32,16 +32,89 @@ describe("/screens", () => {
}) })
}) })
describe("save", () => { describe("permissions", () => {
const saveScreen = async (screen: Screen) => { let screen1: Screen, screen2: Screen
return await config.api.screen.save(screen, { status: 200 }) let role1: Role, role2: Role, multiRole: Role
beforeAll(async () => {
role1 = await config.api.roles.save({
name: "role1",
inherits: roles.BUILTIN_ROLE_IDS.BASIC,
permissionId: PermissionLevel.WRITE,
})
role2 = await config.api.roles.save({
name: "role2",
inherits: roles.BUILTIN_ROLE_IDS.BASIC,
permissionId: PermissionLevel.WRITE,
})
multiRole = await config.api.roles.save({
name: "multiRole",
inherits: [role1._id!, role2._id!],
permissionId: PermissionLevel.WRITE,
})
screen1 = await config.api.screen.save(
{
...basicScreen(),
routing: {
roleId: role1._id!,
route: "/foo",
homeScreen: false,
},
},
{ status: 200 }
)
screen2 = await config.api.screen.save(
{
...basicScreen(),
routing: {
roleId: role2._id!,
route: "/bar",
homeScreen: false,
},
},
{ status: 200 }
)
// get into prod app
await config.publish()
})
async function checkScreens(roleId: string, screenIds: string[]) {
await config.setRole(roleId, async () => {
const res = await config.api.application.getDefinition(
config.prodAppId!,
{
status: 200,
}
)
// basic and role1 screen
expect(res.screens.length).toEqual(screenIds.length)
expect(res.screens.map(s => s._id).sort()).toEqual(screenIds.sort())
})
} }
it("should be able to create a screen", async () => { it("should be able to fetch only screen1 with role1", async () => {
jest.clearAllMocks() await checkScreens(role1._id!, [screen._id!, screen1._id!])
})
it("should be able to fetch only screen2 with role2", async () => {
await checkScreens(role2._id!, [screen._id!, screen2._id!])
})
it("should be able to fetch all three screens with multi-inheritance role", async () => {
await checkScreens(multiRole._id!, [
screen._id!,
screen1._id!,
screen2._id!,
])
})
})
describe("save", () => {
it("should be able to create a screen", async () => {
const screen = basicScreen() const screen = basicScreen()
const responseScreen = await saveScreen(screen) const responseScreen = await config.api.screen.save(screen, {
status: 200,
})
expect(responseScreen._rev).toBeDefined() expect(responseScreen._rev).toBeDefined()
expect(responseScreen.name).toEqual(screen.name) expect(responseScreen.name).toEqual(screen.name)
@ -50,13 +123,12 @@ describe("/screens", () => {
it("should be able to update a screen", async () => { it("should be able to update a screen", async () => {
const screen = basicScreen() const screen = basicScreen()
let responseScreen = await saveScreen(screen) let responseScreen = await config.api.screen.save(screen, { status: 200 })
screen._id = responseScreen._id screen._id = responseScreen._id
screen._rev = responseScreen._rev screen._rev = responseScreen._rev
screen.name = "edit" screen.name = "edit"
jest.clearAllMocks()
responseScreen = await saveScreen(screen) responseScreen = await config.api.screen.save(screen, { status: 200 })
expect(responseScreen._rev).toBeDefined() expect(responseScreen._rev).toBeDefined()
expect(responseScreen.name).toEqual(screen.name) expect(responseScreen.name).toEqual(screen.name)