Merge pull request #2975 from Budibase/no-access-role

No access role / public by default
This commit is contained in:
Rory Powell 2021-10-18 11:08:45 +01:00 committed by GitHub
commit a94becac9c
6 changed files with 70 additions and 19 deletions

View File

@ -34,6 +34,12 @@
const publishedAppsOnly = app => app.status === AppStatus.DEPLOYED
$: publishedApps = $apps.filter(publishedAppsOnly)
$: userApps = $auth.user?.builder?.global
? publishedApps
: publishedApps.filter(app =>
Object.keys($auth.user?.roles).includes(app.prodId)
)
</script>
{#if $auth.user && loaded}
@ -82,11 +88,11 @@
</Body>
</Layout>
<Divider />
{#if publishedApps.length}
{#if userApps.length}
<Heading>Apps</Heading>
<div class="group">
<Layout gap="S" noPadding>
{#each publishedApps as app, idx (app.appId)}
{#each userApps as app, idx (app.appId)}
<a class="app" target="_blank" href={`/${app.prodId}`}>
<div class="preview" use:gradient={{ seed: app.name }} />
<div class="app-info">

View File

@ -34,9 +34,13 @@
role: {},
}
$: defaultRoleId = $userFetch?.data?.builder?.global ? "ADMIN" : "BASIC"
const noRoleSchema = {
name: { displayName: "App" },
}
$: defaultRoleId = $userFetch?.data?.builder?.global ? "ADMIN" : ""
// Merge the Apps list and the roles response to get something that makes sense for the table
$: appList = Object.keys($apps?.data).map(id => {
$: allAppList = Object.keys($apps?.data).map(id => {
const roleId = $userFetch?.data?.roles?.[id] || defaultRoleId
const role = $apps?.data?.[id].roles.find(role => role._id === roleId)
return {
@ -45,6 +49,15 @@
role: [role],
}
})
$: appList = allAppList.filter(app => !!app.role[0])
$: noRoleAppList = allAppList
.filter(app => !app.role[0])
.map(app => {
delete app.role
return app
})
let selectedApp
const userFetch = fetchData(`/api/global/users/${userId}`)
@ -173,6 +186,7 @@
<Divider size="S" />
<Layout gap="S" noPadding>
<Heading size="S">Configure roles</Heading>
<Body>Specify a role to grant access to an app.</Body>
<Table
on:click={openUpdateRolesModal}
schema={roleSchema}
@ -183,6 +197,21 @@
customRenderers={[{ column: "role", component: TagsRenderer }]}
/>
</Layout>
<Layout gap="S" noPadding>
<Heading size="XS">No Access</Heading>
<Body
>Apps do not appear in the users portal. Public pages may still be viewed
if visited directly.</Body
>
<Table
on:click={openUpdateRolesModal}
schema={noRoleSchema}
data={noRoleAppList}
allowEditColumns={false}
allowEditRows={false}
allowSelectRows={false}
/>
</Layout>
<Divider size="S" />
<Layout gap="XS" noPadding>
<Heading size="S">Delete user</Heading>

View File

@ -6,22 +6,38 @@
export let app
export let user
const NO_ACCESS = "NO_ACCESS"
const dispatch = createEventDispatcher()
const roles = app.roles
let options = roles
.filter(role => role._id !== "PUBLIC")
.map(role => ({ value: role._id, label: role.name }))
let options = roles.map(role => ({ value: role._id, label: role.name }))
options.push({ value: NO_ACCESS, label: "No Access" })
let selectedRole = user?.roles?.[app?._id]
async function updateUserRoles() {
const res = await users.save({
...user,
roles: {
...user.roles,
[app._id]: selectedRole,
},
})
let res
if (selectedRole === NO_ACCESS) {
// remove the user role
const filteredRoles = { ...user.roles }
delete filteredRoles[app?._id]
res = await users.save({
...user,
roles: {
...filteredRoles,
},
})
} else {
// add the user role
res = await users.save({
...user,
roles: {
...user.roles,
[app._id]: selectedRole,
},
})
}
if (res.status === 400) {
notifications.error("Failed to update role")
} else {

View File

@ -45,7 +45,7 @@ module.exports = async (ctx, next) => {
const globalUser = await getCachedSelf(ctx, requestAppId)
appId = requestAppId
// retrieving global user gets the right role
roleId = globalUser.roleId || BUILTIN_ROLE_IDS.BASIC
roleId = globalUser.roleId || roleId
}
// nothing more to do

View File

@ -127,8 +127,8 @@ describe("Current app middleware", () => {
} else {
expect(cookieFn).not.toHaveBeenCalled()
}
expect(config.ctx.roleId).toEqual("BASIC")
expect(config.ctx.user.role._id).toEqual("BASIC")
expect(config.ctx.roleId).toEqual("PUBLIC")
expect(config.ctx.user.role._id).toEqual("PUBLIC")
expect(config.ctx.appId).toEqual("app_test")
expect(config.next).toHaveBeenCalled()
}
@ -163,7 +163,7 @@ describe("Current app middleware", () => {
return "app_test"
},
setCookie: jest.fn(),
getCookie: () => ({appId: "app_test", roleId: "BASIC"}),
getCookie: () => ({appId: "app_test", roleId: "PUBLIC"}),
},
constants: { Cookies: {} },
}))

View File

@ -26,7 +26,7 @@ exports.updateAppRole = (appId, user) => {
if (!user.roleId && user.builder && user.builder.global) {
user.roleId = BUILTIN_ROLE_IDS.ADMIN
} else if (!user.roleId) {
user.roleId = BUILTIN_ROLE_IDS.BASIC
user.roleId = BUILTIN_ROLE_IDS.PUBLIC
}
delete user.roles
return user